pyglet: on_resize ломает графику - PullRequest
0 голосов
/ 07 марта 2019

Я пишу приложение с pyglet, где все визуализированные объекты являются дочерними элементами класса окна. Я пытаюсь нарисовать простой прямоугольник, но использование 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

Я хотел бы иметь возможность сохранять отображаемые объекты как дочерние элементы класса окна, поскольку это значительно облегчает запуск обработчиков событий. Есть ли способ, которым я могу заставить это работать с обработчиком on_resize? Любая помощь приветствуется.

РЕДАКТИРОВАТЬ: я пытался удалить on_resize из класса Quad и заставить on_resize ничего не делать в классе Window. Кажется, что проблема заключается в существовании функции on_resize - если on_resize существует, pyglet не будет рисовать прямоугольник.

1 Ответ

0 голосов
/ 08 марта 2019

В методе 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()
...