pyglet:on_resize 破坏图形
pyglet: on_resize breaks graphics
我正在用 pyglet 编写一个应用程序,其中所有呈现的对象都是 window class 的子对象。我正在尝试绘制一个简单的矩形,但使用 on_resize 似乎会破坏一切。没有错误消息,只是没有绘制矩形。
这是我的文件结构:
main.py
lib
|-- window.py
|-- quad.py
此代码不起作用,但如果我删除 on_resize 方法,它会起作用:
-------------
FILE: main.py
-------------
import pyglet
import lib
window = lib.window.Window(1280, 720)
window.add_object(lib.quad.Quad())
pyglet.app.run()
-------------------
FILE: lib/window.py
-------------------
import pyglet
from . import quad
class Window(pyglet.window.Window):
def __init__(self, w, h):
super().__init__(width=w, height=h)
self.objects = []
def on_draw(self):
for obj in self.objects:
obj.on_draw()
def on_resize(self, width, height):
for obj in self.objects:
obj.on_resize(width, height)
def add_object(self, obj):
self.objects.extend([obj])
-------------
FILE: lib/quad.py
-------------
import pyglet
import pyglet.gl
class Quad():
def __init__(self):
self.quad = pyglet.graphics.vertex_list(4, ('v2i', (10, 10, 100, 10, 100, 100, 10, 100)), ('c3B', (0, 0, 255, 0, 0, 255, 0, 255, 0, 0, 255, 0)))
def on_draw(self):
self.quad.draw(pyglet.gl.GL_QUADS)
def on_resize(self, width, height):
pass
我希望能够将呈现的对象保留为 window class 的子对象,因为这使得 运行 事件处理程序更容易。有什么方法可以让 on_resize 处理程序工作吗?感谢任何帮助。
编辑:我尝试从 Quad class 中删除 on_resize,并让 on_resize 在 Window class 中不执行任何操作。 on_resize 函数的存在似乎是问题所在——如果 on_resize 存在,pyglet 将不会绘制矩形。
在on_resize方法中添加glViewport函数调用。并且不要忘记设置正交投影。看看我的代码,它在屏幕中央画了一个三角形。
from pyglet.gl import *
class Triangle:
def __init__(self):
self.vertices = pyglet.graphics.vertex_list(3, ('v3f', [0,0,0, 300,0,0, 150,300,0]),
('c3B', [255,0,0, 0,255,0, 0,0,255]))
def draw(self):
self.vertices.draw(GL_TRIANGLES)
class MyWindow(pyglet.window.Window):
def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
self.set_minimum_size(400, 300)
glClearColor(0.2, 0.25, 0.2, 1.0)
glOrtho(0, 1280, 0, 720, -10, 10) # setup orthogonal projection
self.triangle = Triangle()
def on_draw(self):
self.clear()
glPushMatrix()
glTranslatef(640-150 ,360-150, 0) # translate the Triangle to the center
self.triangle.draw()
glPopMatrix()
def on_resize(self, width, height):
glViewport(0, 0, width, height) # resize the viewport
if __name__ == "__main__":
MyWindow(1280, 720, 'My window', resizable=True)
pyglet.app.run()
问题是通过子类化 Window,(在本例中为 MyWindow),当您定义 on_resize() 事件处理程序时,您将继承的处理程序替换为您的自己的。您要做的是将 on_resize() 处理程序推送到事件处理堆栈上,以便调用两个处理程序。你想对其他人做同样的事情,比如 on_close()。示例:
class MyWindow(pyglet.window.Window):
def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
self.set_minimum_size(400, 300)
#
# Push your handler onto the on_resize handler stack
#
self.push_handlers(on_resize=self.local_on_resize)
def local_on_resize(self, x, y):
# Do stuff
def on_draw(self):
self.clear()
self.triangle.draw()
请注意,您可以通过让 local_on_resize() 处理程序 return 的值为 pyglet.event.EVENT_HANDLED 来重现失败(这将停止处理剩余的处理程序),并且图形不会呈现。
我正在用 pyglet 编写一个应用程序,其中所有呈现的对象都是 window class 的子对象。我正在尝试绘制一个简单的矩形,但使用 on_resize 似乎会破坏一切。没有错误消息,只是没有绘制矩形。
这是我的文件结构:
main.py
lib
|-- window.py
|-- quad.py
此代码不起作用,但如果我删除 on_resize 方法,它会起作用:
-------------
FILE: main.py
-------------
import pyglet
import lib
window = lib.window.Window(1280, 720)
window.add_object(lib.quad.Quad())
pyglet.app.run()
-------------------
FILE: lib/window.py
-------------------
import pyglet
from . import quad
class Window(pyglet.window.Window):
def __init__(self, w, h):
super().__init__(width=w, height=h)
self.objects = []
def on_draw(self):
for obj in self.objects:
obj.on_draw()
def on_resize(self, width, height):
for obj in self.objects:
obj.on_resize(width, height)
def add_object(self, obj):
self.objects.extend([obj])
-------------
FILE: lib/quad.py
-------------
import pyglet
import pyglet.gl
class Quad():
def __init__(self):
self.quad = pyglet.graphics.vertex_list(4, ('v2i', (10, 10, 100, 10, 100, 100, 10, 100)), ('c3B', (0, 0, 255, 0, 0, 255, 0, 255, 0, 0, 255, 0)))
def on_draw(self):
self.quad.draw(pyglet.gl.GL_QUADS)
def on_resize(self, width, height):
pass
我希望能够将呈现的对象保留为 window class 的子对象,因为这使得 运行 事件处理程序更容易。有什么方法可以让 on_resize 处理程序工作吗?感谢任何帮助。
编辑:我尝试从 Quad class 中删除 on_resize,并让 on_resize 在 Window class 中不执行任何操作。 on_resize 函数的存在似乎是问题所在——如果 on_resize 存在,pyglet 将不会绘制矩形。
在on_resize方法中添加glViewport函数调用。并且不要忘记设置正交投影。看看我的代码,它在屏幕中央画了一个三角形。
from pyglet.gl import *
class Triangle:
def __init__(self):
self.vertices = pyglet.graphics.vertex_list(3, ('v3f', [0,0,0, 300,0,0, 150,300,0]),
('c3B', [255,0,0, 0,255,0, 0,0,255]))
def draw(self):
self.vertices.draw(GL_TRIANGLES)
class MyWindow(pyglet.window.Window):
def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
self.set_minimum_size(400, 300)
glClearColor(0.2, 0.25, 0.2, 1.0)
glOrtho(0, 1280, 0, 720, -10, 10) # setup orthogonal projection
self.triangle = Triangle()
def on_draw(self):
self.clear()
glPushMatrix()
glTranslatef(640-150 ,360-150, 0) # translate the Triangle to the center
self.triangle.draw()
glPopMatrix()
def on_resize(self, width, height):
glViewport(0, 0, width, height) # resize the viewport
if __name__ == "__main__":
MyWindow(1280, 720, 'My window', resizable=True)
pyglet.app.run()
问题是通过子类化 Window,(在本例中为 MyWindow),当您定义 on_resize() 事件处理程序时,您将继承的处理程序替换为您的自己的。您要做的是将 on_resize() 处理程序推送到事件处理堆栈上,以便调用两个处理程序。你想对其他人做同样的事情,比如 on_close()。示例:
class MyWindow(pyglet.window.Window):
def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
self.set_minimum_size(400, 300)
#
# Push your handler onto the on_resize handler stack
#
self.push_handlers(on_resize=self.local_on_resize)
def local_on_resize(self, x, y):
# Do stuff
def on_draw(self):
self.clear()
self.triangle.draw()
请注意,您可以通过让 local_on_resize() 处理程序 return 的值为 pyglet.event.EVENT_HANDLED 来重现失败(这将停止处理剩余的处理程序),并且图形不会呈现。