openglglslshaderprojectionpyglet

Can't seem to draw a vertex_list in Pyglet 2


I am trying to familiarize myself with the graphics system in Pyglet 2. I have a fair knowledge of older versions of OpenGL. I can't find any sample code that is up to date. I built the following code by stuffing together bits from the documentation. It is supposed to produce a window with a color triangle in the lower left quadrant.

It produces a blank window (probably the least helpful failure in OpenGL).

import pyglet
from pyglet.gl import *
from pyglet.math import *
from pyglet.graphics.shader import Shader, ShaderProgram


class PictureWindow(pyglet.window.Window):
    
    def __init__(self):
        super().__init__(800, 600,
                         resizable=True)

        self.set_minimum_size(320, 200)

    def on_draw(self):
        self.clear()
        batch.draw()
        
    def on_resize(self, width, height):
        glViewport(0, 0, *self.get_framebuffer_size())
        window.projection = Mat4.orthogonal_projection(0, width, 0, height, -255, 255)
        return pyglet.event.EVENT_HANDLED


window = PictureWindow()    # This must be the first graphics related call.

batch = pyglet.graphics.Batch()

# Define the GLSL Shaders.
vertex_source = """#version 150 core
    in vec2 position;
    in vec4 colors;
    out vec4 vertex_colors;

    uniform mat4 projection;

    void main()
    {
        gl_Position = projection * vec4(position, 0.0, 1.0);
        vertex_colors = colors;
    }
"""

fragment_source = """#version 150 core
    in vec4 vertex_colors;
    out vec4 final_color;

    void main()
    {
        final_color = vertex_colors;
    }
"""

vert_shader = Shader(vertex_source, 'vertex')
frag_shader = Shader(fragment_source, 'fragment')
program = ShaderProgram(vert_shader, frag_shader)

vlist = program.vertex_list(3, pyglet.gl.GL_TRIANGLES, batch=batch)

vlist.position[:] = (100, 300,
                     200, 250,
                     200, 350)

vlist.colors[:] = (1.0, 0.0, 0.0, 1.0,
                   0.0, 1.0, 0.0, 1.0,
                   0.0, 0.0, 1.0, 1.0)


if __name__ == '__main__':
    pyglet.app.run(interval=1/60)

It runs fine - no errors, but gives me an empty window. So, I figure I am missing a step, but I can't find it in the docs.

I have tried using integer colors as well - no change. I have also tried various Opacity (A) values in the colors.

It is acting like it is rendering out of the field of view, but if I am reading the projection function correctly, it should be in the lower left quadrant.


Solution

  • You must manually change the value of the corresponding uniform in the shader program when you change the projection matrix:

    class PictureWindow(pyglet.window.Window):
        # [...]
    
            def on_resize(self, width, height):
            glViewport(0, 0, *self.get_framebuffer_size())
    
            projection_matrix = Mat4.orthogonal_projection(0, width, 0, height, -255, 255)
            window.projection = projection_matrix
            program.uniforms['projection'].set(projection_matrix)
    
            return pyglet.event.EVENT_HANDLED