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

如何在PyOpenGL中向着色器传递屏幕分辨率?代码报错求助

着色器传递屏幕分辨率问题解决

你的代码核心错误是混淆了Uniform变量和顶点属性的操作API:

  • iResolution是片段着色器中的uniform vec2变量,属于全局共享的Uniform类型,但你错误使用了获取顶点属性位置的glGetAttribLocation,所以返回值始终为-1。
  • 后续用glVertexAttrib2d尝试设置值也是错误的,这个函数是给顶点属性赋值的,不适合Uniform变量。

修正步骤:

  1. 获取Uniform变量的正确位置
    替换glGetAttribLocation为glGetUniformLocation,这才是获取Uniform变量位置的正确函数:

    k = glGetUniformLocation(program, 'iResolution')
    
  2. 正确设置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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.17 23:01:10