You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Pyglet 2中无法绘制vertex_list问题求助

问题原因与解决方法

你的代码存在两个核心问题,导致三角形无法正常显示:

1. 投影矩阵未传递给着色器Uniform

你在on_resize中创建了正交投影矩阵,但仅将其赋值给未定义的window.projection变量,并未传递给着色器中声明的projection Uniform。着色器默认使用单位矩阵,会将你的大数值顶点坐标转换到标准化设备坐标[-1,1]范围之外,导致图形被视口裁剪。

2. 着色器程序未在绘制时激活

尽管你通过program.vertex_list创建了顶点列表,但绘制时未激活对应的着色器程序,Batch无法使用正确的着色逻辑渲染图形。


修复后的完整代码

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, program):
        super().__init__(800, 600, resizable=True)
        self.set_minimum_size(320, 200)
        self.program = program
        # 初始化投影矩阵
        self.update_projection(self.width, self.height)

    def on_draw(self):
        self.clear()
        # 激活着色器程序
        self.program.use()
        batch.draw()
        
    def on_resize(self, width, height):
        glViewport(0, 0, *self.get_framebuffer_size())
        self.update_projection(width, height)
        return pyglet.event.EVENT_HANDLED
    
    def update_projection(self, width, height):
        # 创建正交投影矩阵并传递给着色器Uniform
        projection = Mat4.orthogonal_projection(0, width, 0, height, -255, 255)
        self.program['projection'] = projection


# 定义GLSL着色器
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)

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

# 调整顶点坐标到窗口左下象限(示例值)
vlist.position[:] = (100, 100,
                     200, 50,
                     200, 150)

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)

window = PictureWindow(program)

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

关键修改说明

  1. 传递投影矩阵:新增update_projection方法,通过self.program['projection'] = projection将矩阵直接传入着色器Uniform
  2. 激活着色器程序:在on_draw中调用self.program.use(),确保Batch使用正确的着色逻辑渲染
  3. 初始化投影矩阵:窗口创建时立即初始化投影矩阵,避免初始状态下无矩阵导致的渲染异常
  4. 调整顶点坐标:将顶点Y坐标修改为100以内,确保三角形完全处于窗口左下象限

内容的提问来源于stack exchange,提问作者Cadfael

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.22 02:17:30