I can't make working keyCallback function in OpenGL and glfw - opengl

import glfw
from OpenGL.GL import *
import numpy as np
currentMode = GL_LINE_LOOP
def render(currentMode):
def key_callback(window, key, scancode, action, mods):
if key==glfw.KEY_1:
if action==glfw.PRESS:
currentMode = GL_POINTS
elif key==glfw.KEY_2:
if action==glfw.PRESS:
currentMode = GL_LINES
elif key==glfw.KEY_3:
if action==glfw.PRESS:
currentMode = GL_LINE_STRIP
while not glfw.window_should_close(window):
glfw.poll_events()
render(currentMode)
glfw.swap_buffers(window)
print(currentMode)
glfw.terminate()
I try to change primitive type to use render function's parameter.
But, It doesn't work.
What should I do?

You missed the global statement in key_callback:
def key_callback(window, key, scancode, action, mods):
global currentMode # <--- THIS IS MISSING
if key==glfw.KEY_1:
if action==glfw.PRESS:
currentMode = GL_POINTS
# [...]
The variable currentMode exists twice. It is a variable in global namespace, and local variable in the scope of the function key_callback. Use the global statement to interpreted currentMode as global and to write to the global variable currentMode with key_callback.
Of course the same applies to the main function, too:
def main():
global currentMode
# [...]
Furthermore you have to clear the framebuffer in render:
def render(currentMode):
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT)
See the example:
import glfw
from OpenGL.GL import *
import numpy as np
def render(currentMode):
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT)
glLoadIdentity()
print(currentMode)
glBegin(currentMode)
#Draw Something
glVertex2f(-0.5, -0.5)
glVertex2f(0.5, 0.5)
glVertex2f(-0.5, 0.5)
glEnd()
def key_callback(window, key, scancode, action, mods):
global currentMode
if key==glfw.KEY_1:
if action==glfw.PRESS:
currentMode = GL_POINTS
elif key==glfw.KEY_2:
if action==glfw.PRESS:
currentMode = GL_LINES
elif key==glfw.KEY_3:
if action==glfw.PRESS:
currentMode = GL_LINE_STRIP
def main():
global currentMode
if not glfw.init():
return
window = glfw.create_window(480, 480, "Test", None, None)
if not window:
glfw.terminate()
return
glfw.make_context_current(window)
glfw.set_key_callback(window, key_callback)
glfw.swap_interval(1)
while not glfw.window_should_close(window):
glfw.poll_events()
render(currentMode)
glfw.swap_buffers(window)
glfw.terminate()
if __name__ == "__main__":
currentMode = GL_LINE_LOOP
main()

Related

argument 1 must be pygame.Surface, not Window

Not sure if what I am trying to do is wrong or impossible. Here is my code:
import pygame
class Window(object):
def __init__(self, (width, height), color, cap=' '):
self.width = width
self.height = height
self.color = color
self.cap = cap
self.screen = pygame.display.set_mode((self.width, self.height))
def display(self):
self.screen
#screen =
pygame.display.set_caption(self.cap)
self.screen.fill(self.color)
class Ball(object):
def __init__(self, window, (x, y), color, size, thick=None):
self.window = window
self.x = x
self.y = y
self.color = color
self.size = size
self.thick = thick
def draw(self):
pygame.draw.circle(self.window, self.color, (self.x, self.y),
self.size, self.thick)
def main():
black = (0, 0, 0)
white = (255, 255, 255)
screen = Window((600, 600), black, 'Pong')
screen.display()
ball = Ball(screen, (300, 300), white, 5)
ball.draw()
running = True
while running:
for event in pygame.event.get():
if event.type == pygame.QUIT:
running = False
pygame.display.flip()
pygame.quit()
main()
This is the error I get:
Traceback (most recent call last):
File "C:\Users\acmil\Desktop\Team 7\newPongLib.py", line 47, in <module>
main()
File "C:\Users\acmil\Desktop\Team 7\newPongLib.py", line 36, in main
ball.draw()
File "C:\Users\acmil\Desktop\Team 7\newPongLib.py", line 28, in draw
self.size, self.thick)
TypeError: argument 1 must be pygame.Surface, not Window
I don't understand if i make a Window object why it won't draw a ball to the screen. Any help is appreciated.
Change your Ball class to the following:
class Ball(object):
def __init__(self, window, (x, y), color, size, thick=0):
self.window = window
self.x = x
self.y = y
self.color = color
self.size = size
self.thick = thick
def draw(self):
pygame.draw.circle(self.window.screen, self.color, (self.x, self.y),
self.size, self.thick)
I made two modifications to your code.
First, as for the error you were getting, you were passing in a custom Window object that you had defined instead of the pygame's Screen object that pygame was expecting. Check out the documentation on this function here.
Second, your original constructor defined thick=None by default, but that pygame function expects an int, so I changed it to thick=0.
It should work after these two changes. Let me know if you still are having issues!

Raspberry pi Video Capture freezes while writing to video

I am trying to display the webcam stream as well as write the video to a file simultaneously.But while am writing, it freezes the live stream. The problem is that OpenCV uses a loop to record video,the program gets stuck in the OpenCV loop and the user is unable to continue.It doesn't listen for user response. How can i simultaneously record video and listen for user responses?
code iam using :
import wx
import vlc
import os
import user
import numpy as np
import time
import cv, cv2
class MainWindow(wx.Panel):
def __init__(self, parent,capture):
wx.Panel.__init__(self, parent)
mainSizer = wx.BoxSizer(wx.VERTICAL)
# video
videoWarper = wx.StaticBox(self,size=(640,480)
videoBoxSizer = wx.StaticBoxSizer(videoWarper, wx.VERTICAL)
videoFrame = wx.Panel(self, -1,size=(640,480))
capture = ShowCapture(videoFrame, capture)
videoBoxSizer.Add(videoFrame,0)
mainSizer.Add(videoBoxSizer,0)
parent.Centre()
self.Show()
self.SetSizerAndFit(mainSizer)
# Panels
# The first panel holds the video and it's all black
self.videopanel = wx.Panel(self, -1)
self.videopanel.SetBackgroundColour(wx.BLACK)
# The second panel holds controls
ctrlpanel = wx.Panel(self, -1 )
self.timeslider = wx.Slider(ctrlpanel, -1, 0, 0, 1000)
self.timeslider.SetRange(0, 1000)
record = wx.Button(ctrlpanel, label="Record")
end = wx.Button(ctrlpanel, label="End")
# Bind controls to events
self.Bind(wx.EVT_BUTTON, self.OnRecord, record)
self.Bind(wx.EVT_BUTTON, self.OnEnd, end)
# Give a pretty layout to the controls
ctrlbox = wx.BoxSizer(wx.VERTICAL)
box = wx.BoxSizer(wx.HORIZONTAL)
# box contains some buttons and the volume controls
box.Add(record)
box.Add(end)
# Merge box to the ctrlsizer
ctrlbox.Add(box, flag=wx.EXPAND, border=10)
ctrlpanel.SetSizer(ctrlbox)
# Put everything togheter
sizer = wx.BoxSizer(wx.VERTICAL)
sizer.Add(ctrlpanel, flag=wx.EXPAND | wx.BOTTOM | wx.TOP, border=10)
self.SetSizer(sizer)
self.SetMinSize((350, 300))
# VLC player controls
self.Instance = vlc.Instance()
self.player = self.Instance.media_player_new()
def OnRecord(self, evt):
fourcc = cv2.cv.CV_FOURCC('D', 'I', 'V', 'X')
out = cv2.VideoWriter('video.avi', fourcc, 8.0, (640, 480))
counter = 0
while counter < 1:
ret,frame = capture.read()
out.write(frame)
def OnEnd(self, evt):
out = cv2.VideoWriter('video.avi', fourcc, 8.0, (640, 480))
out.release()
cv2.destroyAllWindows()
class ShowCapture(wx.Panel):
def __init__(self, parent, capture, fps=8):
wx.Panel.__init__(self, parent, wx.ID_ANY, (0,0), (640,480))
self.capture = capture
ret, frame = capture.read()
height, width = frame.shape[:2]
parent.SetSize((width, height))
frame = cv2.cvtColor(frame, cv2.COLOR_BGR2RGB)
self.bmp = wx.BitmapFromBuffer(width, height, frame)
self.timer = wx.Timer(self)
self.timer.Start(1000./fps)
self.Bind(wx.EVT_PAINT, self.OnPaint)
self.Bind(wx.EVT_TIMER, self.NextFrame)
def OnPaint(self, evt):
dc = wx.BufferedPaintDC(self)
dc.DrawBitmap(self.bmp, 0, 0)
def NextFrame(self, event):
ret, frame = self.capture.read()
if ret:
frame = cv2.cvtColor(frame, cv2.COLOR_BGR2RGB)
self.bmp.CopyFromBuffer(frame)
self.Refresh()
capture = cv2.VideoCapture(-1)
app = wx.App(False)
frame = wx.Frame(None, title='CamGUI')
panel = MainWindow(frame, capture)
frame.Show()
app.MainLoop()
Does raspberry pi capable of Read/write the video parallely or it hurts the performance of pi?
Hope for experts advice :)
Add a timer, that will allow you to test for input and other changes during the execution of the application.
wx.timer

Raspberry pi VideoCapture freezes while Recording

I have been trying to save the webcam stream of the raspberry pi using opencv videocapture.
My code is:
import wx
import vlc
import os
import user
import numpy as np
import time
import cv, cv2
class MainWindow(wx.Panel):
def __init__(self, parent,capture):
wx.Panel.__init__(self, parent)
mainSizer = wx.BoxSizer(wx.VERTICAL)
# video
videoWarper = wx.StaticBox(self,size=(640,480)
videoBoxSizer = wx.StaticBoxSizer(videoWarper, wx.VERTICAL)
videoFrame = wx.Panel(self, -1,size=(640,480))
capture = ShowCapture(videoFrame, capture)
videoBoxSizer.Add(videoFrame,0)
mainSizer.Add(videoBoxSizer,0)
parent.Centre()
self.Show()
self.SetSizerAndFit(mainSizer)
# Panels
# The first panel holds the video and it's all black
self.videopanel = wx.Panel(self, -1)
self.videopanel.SetBackgroundColour(wx.BLACK)
# The second panel holds controls
ctrlpanel = wx.Panel(self, -1 )
self.timeslider = wx.Slider(ctrlpanel, -1, 0, 0, 1000)
self.timeslider.SetRange(0, 1000)
record = wx.Button(ctrlpanel, label="Record")
end = wx.Button(ctrlpanel, label="End")
# Bind controls to events
self.Bind(wx.EVT_BUTTON, self.OnRecord, record)
self.Bind(wx.EVT_BUTTON, self.OnEnd, end)
# Give a pretty layout to the controls
ctrlbox = wx.BoxSizer(wx.VERTICAL)
box = wx.BoxSizer(wx.HORIZONTAL)
# box contains some buttons and the volume controls
box.Add(record)
box.Add(end)
# Merge box to the ctrlsizer
ctrlbox.Add(box, flag=wx.EXPAND, border=10)
ctrlpanel.SetSizer(ctrlbox)
# Put everything togheter
sizer = wx.BoxSizer(wx.VERTICAL)
sizer.Add(ctrlpanel, flag=wx.EXPAND | wx.BOTTOM | wx.TOP, border=10)
self.SetSizer(sizer)
self.SetMinSize((350, 300))
# VLC player controls
self.Instance = vlc.Instance()
self.player = self.Instance.media_player_new()
def OnRecord(self, evt):
fourcc = cv2.cv.CV_FOURCC('D', 'I', 'V', 'X')
out = cv2.VideoWriter('video.avi', fourcc, 8.0, (640, 480))
counter = 0
while counter < 1:
ret,frame = capture.read()
out.write(frame)
def OnEnd(self, evt):
out = cv2.VideoWriter('video.avi', fourcc, 8.0, (640, 480))
out.release()
cv2.destroyAllWindows()
class ShowCapture(wx.Panel):
def __init__(self, parent, capture, fps=8):
wx.Panel.__init__(self, parent, wx.ID_ANY, (0,0), (640,480))
self.capture = capture
ret, frame = capture.read()
height, width = frame.shape[:2]
parent.SetSize((width, height))
frame = cv2.cvtColor(frame, cv2.COLOR_BGR2RGB)
self.bmp = wx.BitmapFromBuffer(width, height, frame)
self.timer = wx.Timer(self)
self.timer.Start(1000./fps)
self.Bind(wx.EVT_PAINT, self.OnPaint)
self.Bind(wx.EVT_TIMER, self.NextFrame)
def OnPaint(self, evt):
dc = wx.BufferedPaintDC(self)
dc.DrawBitmap(self.bmp, 0, 0)
def NextFrame(self, event):
ret, frame = self.capture.read()
if ret:
frame = cv2.cvtColor(frame, cv2.COLOR_BGR2RGB)
self.bmp.CopyFromBuffer(frame)
self.Refresh()
capture = cv2.VideoCapture(-1)
app = wx.App(False)
frame = wx.Frame(None, title='CamGUI')
panel = MainWindow(frame, capture)
frame.Show()
app.MainLoop()
I have managed to get a video stream inside a GUI window but it freezes after i start Record a video and Livestream get struck up though it keep recording in background, until i close the python shell.
What might be the reason?

Python(2.7):Bug class program error of indentation

Whenever I compile my code
import pygame,sys
from classes import *
pygame.init()
SCREENWIDTH,SCREENHEIGHT = 640, 360
screen = pygame.display.set_mode ((SCREENWIDTH, SCREENHEIGHT))
clock = pygame.time.Clock()
FPS = 24
bug = Bug(0,100,40,40,"bug.png")
while True:
# PROCESSING
for event in pygame.event.get():
if event.type == pygame.QUIT:
pygame.quit()
sys.exit()
#LOGIC
bug.motion()
#LOGIC
#DRAW
screen.fill((0,0,0))
BaseClass.allsprites.draw(screen)
pygame.display.flip()
#DRAW
clock.tick(FPS)
It shows the following error:
File "practice.py", line 16
bug.motion()
^
IndentationError: unindent does not match any outer indentation level
Every line after sys.exit() has five spaces, when they should have four.
import pygame,sys
from classes import *
pygame.init()
SCREENWIDTH,SCREENHEIGHT = 640, 360
screen = pygame.display.set_mode ((SCREENWIDTH, SCREENHEIGHT))
clock = pygame.time.Clock()
FPS = 24
bug = Bug(0,100,40,40,"bug.png")
while True:
# PROCESSING
for event in pygame.event.get():
if event.type == pygame.QUIT:
pygame.quit()
sys.exit()
#LOGIC
bug.motion()
#LOGIC
#DRAW
screen.fill((0,0,0))
BaseClass.allsprites.draw(screen)
pygame.display.flip()
#DRAW
clock.tick(FPS)

How to make wxPython, DC background transparent?

How can i make the default white DC background become invisible (transparent)?
Run the following example, it shows a white background over a button. I would like to remove the white background of the DC. (to show only the red X)
import wx
class drawover(wx.Window):
def __init__(self, parent):
wx.Window.__init__(self, parent)
self.Bind(wx.EVT_PAINT, self.OnPaint)
self.Bind(wx.EVT_ERASE_BACKGROUND, self.OnErase)
self.Bind(wx.EVT_SET_FOCUS, self.OnFocus)
def OnFocus(self, evt):
self.GetParent().SetFocus()
def OnErase(self, evt):
pass
def OnPaint(self, evt):
dc = wx.PaintDC(self)
dc.BeginDrawing()
dc.SetPen(wx.Pen("RED", 1))
dc.DrawLineList([(0,0,100,100), (100,0,0,100)])
dc.EndDrawing()
class frame(wx.Frame):
def __init__(self):
wx.Frame.__init__(self, None, size=(600,600))
s = wx.BoxSizer(wx.VERTICAL)
self.tc1 = wx.TextCtrl(self, style=wx.TE_MULTILINE)
s.Add(self.tc1, 1, wx.EXPAND)
self.tc2 = wx.Button(self)
s.Add(self.tc2, 1, wx.EXPAND)
self.d = drawover(self.tc2)
self.tc2.Bind(wx.EVT_SIZE, self.OnSize2)
self.SetSizer(s)
self.Layout()
def OnSize2(self, evt):
self.d.SetSize((101,101))
if __name__ == '__main__':
a = wx.App(0)
b = frame()
b.Show(1)
a.MainLoop()
http://wiki.wxpython.org/Transparent%20Frames
If you are on windows just see above.
If not you basically have to capture the frame below it as an image and paint it (in your onpaint) to fake it
also see
http://wxpython-users.1045709.n5.nabble.com/Transparent-Panels-td2303275.html