Pyglet绑定ShaderPy着色器后图片渲染为黑块如何解决
故障根因
绑定自定义着色器后,OpenGL固定渲染管线的默认纹理、顶点处理逻辑会被完全替换。当前着色器没有对接Pyglet渲染精灵/图片时传入的顶点坐标、纹理坐标、纹理采样器参数,无法读取到图片的像素数据,所以只会渲染出无纹理的黑色矩形。
修复步骤
- 调整着色器实现,匹配Pyglet默认的顶点属性传参规则:
image.blit()、Sprite渲染时默认传入三组顶点属性,分别为位置坐标、纹理坐标、顶点颜色,顶点着色器必须正确接收这些属性并透传给片元着色器。 - 片元着色器需声明2D纹理采样器,手动将采样器绑定到Pyglet默认使用的0号纹理单元,才能正确读取加载的图片像素。
- 调整渲染顺序,将
window.clear()清屏操作移到着色器绑定逻辑外,避免清屏重置纹理绑定状态。
可用参考实现
首先编写匹配Pyglet传参规则的着色器:
- 顶点着色器
shader.vs
#version 120 attribute vec2 a_position; attribute vec2 a_texcoord; attribute vec4 a_color; varying vec2 v_texcoord; varying vec4 v_color; void main() { gl_Position = gl_ModelViewProjectionMatrix * vec4(a_position, 0.0, 1.0); v_texcoord = a_texcoord; v_color = a_color; }
- 片元着色器
shader.fs
#version 120 varying vec2 v_texcoord; varying vec4 v_color; uniform sampler2D u_texture; void main() { gl_FragColor = texture2D(u_texture, v_texcoord) * v_color; }
修正后的Python运行代码:
import pyglet from pyglet.gl import * import shaderpy # 加载图片资源 image = pyglet.image.load('image.png') # 创建窗口 window = pyglet.window.Window(1280,720) pyglet.gl.glClearColor(0.5,0,0,1) # 初始化着色器,提前绑定纹理采样器到0号单元 shader = shaderpy.Shader([ ('shader.vs', GL_VERTEX_SHADER), ('shader.fs', GL_FRAGMENT_SHADER) ]) shader.bind() shader.uniformi('u_texture', 0) shader.unbind() @window.event def on_draw(): window.clear() shader.bind() image.blit(0,0) shader.unbind() pyglet.app.run()
如果你使用330及以上版本的核心模式GLSL,需要手动通过
layout (location = x)语法指定顶点属性位置,自行传入投影矩阵uniform替代内置的gl_ModelViewProjectionMatrix,否则会出现坐标错乱、纹理读取失败的问题。ShaderPy本身不会自动适配Pyglet的渲染状态,所有固定管线的传参逻辑都需要手动在着色器中对接。
内容的提问来源于stack exchange,提问作者nela
相关产品推荐
相关产品推荐

