如何在PyOpenGL中向着色器传递屏幕分辨率?代码报错求助
着色器传递屏幕分辨率问题解决
你的代码核心错误是混淆了Uniform变量和顶点属性的操作API:
iResolution是片段着色器中的uniform vec2变量,属于全局共享的Uniform类型,但你错误使用了获取顶点属性位置的glGetAttribLocation,所以返回值始终为-1。- 后续用
glVertexAttrib2d尝试设置值也是错误的,这个函数是给顶点属性赋值的,不适合Uniform变量。
修正步骤:
获取Uniform变量的正确位置
替换glGetAttribLocation为glGetUniformLocation,这才是获取Uniform变量位置的正确函数:k = glGetUniformLocation(program, 'iResolution')正确设置Uniform变量的值
使用glUniform2f(对应着色器中的vec2类型)传递屏幕分辨率:glUniform2f(k, display[0], display[1])
修改后的完整代码:
import pygame from pygame.locals import * from OpenGL.GL import * def create_shader(shader_type, source): shader = glCreateShader(shader_type) glShaderSource(shader, source) glCompileShader(shader) return shader pygame.init() display = (1000, 800) screen = pygame.display.set_mode(display, DOUBLEBUF | OPENGL) fragment = create_shader(GL_FRAGMENT_SHADER, """ #version 330 uniform vec2 iResolution; void main() { gl_FragColor = vec4(gl_FragCoord.x / iResolution.x, 0.0, 1.0, 1.0); } """) program = glCreateProgram() glAttachShader(program, fragment) glLinkProgram(program) glUseProgram(program) # 修正:获取Uniform变量位置 k = glGetUniformLocation(program, 'iResolution') print(k) # 修正:设置Uniform变量的值 glUniform2f(k, display[0], display[1]) while True: for event in pygame.event.get(): if event.type == pygame.QUIT: pygame.quit() quit() glClearColor(0.0, 0.0, 0.0, 0.0) glClear(GL_COLOR_BUFFER_BIT) glPointSize(1000) glBegin(GL_POINTS) glVertex2f(0.0, 0.0) glVertex2f(0.5, 0.0) glEnd() pygame.display.flip()
补充说明:
- Uniform变量是全局的,所有片段着色器实例共享同一值,适合传递屏幕分辨率、时间这类全局数据。
- 顶点属性(Attribute)是每个顶点独有的数据,比如顶点位置、颜色,需要用
glVertexAttrib*系列函数赋值,且要和顶点数组配合使用。
内容的提问来源于stack exchange,提问作者Yevgeny Antonov
相关产品推荐
相关产品推荐

