简体   繁体   中英

How to save the current view matrix using pyglet

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 .

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM