Как сохранить текущую матрицу представления, используя pyglet - PullRequest
0 голосов
/ 05 июля 2019

Я использую pyglet и хочу иметь функцию, которая может рисовать цвет на фоне сцены. В настоящее время я просто рисую прямоугольник на экране, который идет от нижнего левого до верхнего правого. Это прекрасно работает, пока я не начну применять преобразования. Например, если я использую команду «Повернуть», прямоугольник «фона» также поворачивается

Я попытался использовать glGetFloatv, чтобы получить текущую матрицу, сбросить ее до идентификатора, а затем сбросить обратно.

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

Этот код возвращает эту ошибку:

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]

Я не уверен, что является причиной этого или я даже правильно подхожу к этой проблеме. Я очень новичок в openGL и pyglet и не уверен, что происходит под капотом, чтобы вызвать эту ошибку. Есть ли лучший способ «сбросить» преобразования или нарисовать что-то на экране в пространстве экрана вместо преобразованного пространства, которое мне не хватает?

EDIT: Ошибка в том, что я тупо повторно использую a для матрицы (также моего альфа-канала), но теперь я просто получаю вывод

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]

когда команда вызывается и программа просто заканчивается. OSX также выскакивает окно с вопросом, правильно ли он закрылся

1 Ответ

1 голос
/ 05 июля 2019

Как сохранить текущую матрицу вида с помощью pyglet

Существует стек матриц для текущей матрицы.Матрица может быть помещена в стек и извлечена из нее с помощью glPushMatrix glPopMatrix.

Нажмите матрицу перед преобразованием и вставьте ее после:

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()

Обратите внимание, что для каждого режима матрицы есть стек матриц (GL_MODELVIEW, GL_PROJECTION, GL_TEXTURE и GL_COLOR).См. glMatrixMode.


Ошибка вызвана тем, что glGetFloatv не возвращает никакого значения.Он считывает матрицу в память, которая передается функции.
Вы должны передать массив в glMultMatrixf

modelMat = (GLfloat * 16)()
glGetFloatv(GL_MODELVIEW_MATRIX, modelMat) # read to array "modelMat"
glLoadIdentity() 

# [...]

glMultMatrixf(modelMat) # multiply matrix in the array "modelMat"

Обратите внимание, как видно из названия,glMultMatrixf умножает матрицу на текущую матрицу.Это работает в вашем случае, потому что текущей матрицей является Identity matrix .Матрица может быть загружена в текущую матрицу с помощью glLoadMatrix.

...