I am using pyglet and want to have a function that can draw a color to the background of the scene. I am currently just drawing a rectangle to the screen that goes from the bottom left to the top right. This works great until I start applying transformations. For instance if I use the Rotate command the 'background' rectangle gets rotated as well
I have tried using glGetFloatv to get the current matrix, reset it to the identity, then reset it back.
a = (GLfloat * 16)() # do something?
modelMat = glGetFloatv(GL_MODELVIEW_MATRIX, a) # save matrix
glLoadIdentity() # reset matrix
x1, y1, x2, y2 = 0, 0, self.width, self.height # get the coords
# self.width / self.height give the width and height of the screen
quad = pyglet.graphics.vertex_list(4,
('v2i', (x1, y1, x2, y1, x2, y2, x1, y2)),
('c4B', (
r, g, b, a,
r, g, b, a,
r, g, b, a,
r, g, b, a))
) # define the rectangle
quad.draw(GL_QUADS) # draw rectangle
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA) # do alpha
glMultMatrixf(modelMat) # reset matrix
This code returns this error:
Traceback (most recent call last):
File "/Users/jakemonsky/Development/pythonApps/PygletTest/main.py", line 34, in <module>
APP.run()
File "/Users/jakemonsky/Development/pythonApps/PygletTest/processing.py", line 364, in run
pyglet.app.run()
File "/Library/Frameworks/Python.framework/Versions/3.7/lib/python3.7/site-packages/pyglet/app/__init__.py", line 138, in run
event_loop.run()
File "/Library/Frameworks/Python.framework/Versions/3.7/lib/python3.7/site-packages/pyglet/app/base.py", line 142, in run
self._run()
File "/Library/Frameworks/Python.framework/Versions/3.7/lib/python3.7/site-packages/pyglet/app/base.py", line 154, in _run
timeout = self.idle()
File "/Library/Frameworks/Python.framework/Versions/3.7/lib/python3.7/site-packages/pyglet/app/base.py", line 281, in idle
window.dispatch_event('on_draw')
File "/Library/Frameworks/Python.framework/Versions/3.7/lib/python3.7/site-packages/pyglet/window/__init__.py", line 1232, in dispatch_event
if EventDispatcher.dispatch_event(self, *args) != False:
File "/Library/Frameworks/Python.framework/Versions/3.7/lib/python3.7/site-packages/pyglet/event.py", line 371, in dispatch_event
event_type, args, getattr(self, event_type))
File "/Library/Frameworks/Python.framework/Versions/3.7/lib/python3.7/site-packages/pyglet/event.py", line 367, in dispatch_event
if getattr(self, event_type)(*args):
File "/Users/jakemonsky/Development/pythonApps/PygletTest/processing.py", line 223, in on_draw
self.bind_draw(dt)
File "/Users/jakemonsky/Development/pythonApps/PygletTest/processing.py", line 41, in __call__
func(*args, **kwargs)
File "/Users/jakemonsky/Development/pythonApps/PygletTest/main.py", line 14, in draw
Background(0,0,0,255)
File "/Users/jakemonsky/Development/pythonApps/PygletTest/processingLocalizer.py", line 62, in Background
Application.Background(r, g, b, a)
File "/Users/jakemonsky/Development/pythonApps/PygletTest/processing.py", line 449, in Background
r, g, b, a))
File "/Library/Frameworks/Python.framework/Versions/3.7/lib/python3.7/site-packages/pyglet/graphics/__init__.py", line 292, in vertex_list
return _get_default_batch().add(count, 0, None, *data)
File "/Library/Frameworks/Python.framework/Versions/3.7/lib/python3.7/site-packages/pyglet/graphics/__init__.py", line 372, in add
vlist._set_attribute_data(i, array)
File "/Library/Frameworks/Python.framework/Versions/3.7/lib/python3.7/site-packages/pyglet/graphics/vertexdomain.py", line 443, in _set_attribute_data
region.array[:] = data
TypeError: incompatible types, c_float_Array_16 instance instead of c_ubyte instance
[Finished in 2.3s with exit code 1]
I am not sure what is causing this or if I am even approaching this problem correctly. I am very new to openGL and pyglet and not sure what is happening under the hood to cause this error. Is there a better way to 'reset' the transformations or a way to draw something to the screen in screen space instead of transformed space that I am missing?
EDIT: The error is because I am stupidly reusing a for the matrix (also my alpha channel) but now I just get the output
2019-07-05 11:03:46.789 Python[853:21283] ApplePersistenceIgnoreState: Existing state will not be touched. New state will be written to (null)
[Finished in 2.1s with exit code -11]
when the command is called and the program just ends. OSX also pops up a window asking if it closed properly
How to save the current view matrix using pyglet
There is a stack of matrices for the current matrix. A matrix can be pushed to and popped from the stack by glPushMatrix
glPopMatrix
.
Push the matrix before the transformation and pop it after:
glPushMatrix()
glLoadIdentity() # reset matrix
x1, y1, x2, y2 = 0, 0, self.width, self.height # get the coords
# self.width / self.height give the width and height of the screen
quad = pyglet.graphics.vertex_list(4,
('v2i', (x1, y1, x2, y1, x2, y2, x1, y2)),
('c4B', (
r, g, b, a,
r, g, b, a,
r, g, b, a,
r, g, b, a))
) # define the rectangle
quad.draw(GL_QUADS) # draw rectangle
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA) # do alpha
glPopMatrix()
Note there is a stack of matrices for each matrix mode (GL_MODELVIEW
, GL_PROJECTION
, GL_TEXTURE
and GL_COLOR
). See glMatrixMode
.
The error is caused, because glGetFloatv
doesn't return any value. It reads the matrix to the memory which is passed to the function.
You've to pass the array to glMultMatrixf
modelMat = (GLfloat * 16)()
glGetFloatv(GL_MODELVIEW_MATRIX, modelMat) # read to array "modelMat"
glLoadIdentity()
# [...]
glMultMatrixf(modelMat) # multiply matrix in the array "modelMat"
Note, as the name indicates, glMultMatrixf
multiplies the matrix to the current matrix. This works in your case, because the current matrix is the Identity matrix. A matrix can be loaded to the current matrix by glLoadMatrix
.