首页 > 解决方案 > Pyopengl - 在 glUseProgram 之前和之后有 glGetUniformLocation 和 glUniformMatrix4fv 有什么区别?

问题描述

每当我在下面运行此代码时,它都可以正常工作,但是如果我在调用 UseProgram 之前将 glGetUniformLocation 和 glUniformMatrix4fv 移动到,则会引发错误。为什么会这样,是否有在 UseProgram 之前访问 glGetUniformLocation 和 glUniformMatrix4fv 的替代方法?

代码:

import random
import numpy
import pyrr
from OpenGL.GL import *
from OpenGL.GL.shaders import *
from OpenGL.GLUT import *

shader = None
width, height = 500, 500


def draw():
    global shader
    triangle = [0.5, 0.0, 0.0, 1.0, 0.0, 0.0, 1.0,
                0.0, 0.5, 0.0, 1.0, 0.0, 1.0, 0.0,
                0.0, 0.0, 0.5, 1.0, 1.0, 0.0, 0.0]
    triangle = numpy.array(triangle,
                           dtype='float32')

    vertex_shader_ = """
        #version 140
        in vec4 position;
        in vec3 color;
        uniform mat4 transform;
        out vec4 out_color;
        void main(){
            
            gl_Position = position * transform;
            out_color = vec4(color.rgb, 1);

        };
    
    """

    fragment_shader_ = """
        #version 140
        in vec4 out_color;
        
        void main(){
        
            gl_FragColor = out_color;
        };
    
    """

    shader = compileProgram(compileShader(vertex_shader_, GL_VERTEX_SHADER),
                            compileShader(fragment_shader_, GL_FRAGMENT_SHADER))


    VBO = glGenBuffers(1)
    glBindBuffer(GL_ARRAY_BUFFER, VBO)
    glBufferData(GL_ARRAY_BUFFER, 84, triangle, GL_STATIC_DRAW)



    position = glGetAttribLocation(shader, "position")
    glVertexAttribPointer(position, 4, GL_FLOAT, GL_FALSE, 28, ctypes.c_void_p(0))
    glEnableVertexAttribArray(position)
    color = glGetAttribLocation(shader, "color")
    glVertexAttribPointer(color, 3, GL_FLOAT, GL_FALSE, 28, ctypes.c_void_p(16))
    glEnableVertexAttribArray(color)

    glUseProgram(shader)


def Screen():
    global shader
    glClearColor(0, 0, 0, 1)
    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT)
    glDrawArrays(GL_POLYGON, 0, 3)
    draw()
    transform = glGetUniformLocation(shader, "transform")
    print(transform)
    rotation = pyrr.Matrix44.from_x_rotation(3)
    glUniformMatrix4fv(transform, 1, GL_FALSE, rotation)
    glutSwapBuffers()


def reshapeWindow(x, y):
    global width, height
    width = x
    height = y
    print(x, y)
    glutReshapeWindow(width, height)
    glViewport(0, 0, width, height)


glutInit()
glutInitDisplayMode(GLUT_RGBA)
glutInitWindowSize(width, height)
window = glutCreateWindow("OpenGL")
glutDisplayFunc(Screen)
glutIdleFunc(Screen)
glutReshapeFunc(reshapeWindow)
while True:
    glutMainLoopEvent()
    glutPostRedisplay()

尝试将 glGetUniformLocation 和 glUniformMatrix4fv 放在 UseProgram 之前时出现错误消息:

OpenGL.error.GLError: GLError(
    err = 1282,
    description = b'invalid operation',
    baseOperation = glUniformMatrix4fv,
    pyArgs = (
        0,
        1,
        GL_FALSE,
        array([[ 1.       ,  0.       ,  0.       ,  0.       ],
       [ 0.       , -0.9899925, -0.14112  ,  0.       ],
   ...,
    ),
    cArgs = (
        0,
        1,
        GL_FALSE,
        array([[ 1.       ,  0.       ,  0.       ,  0.       ],
       [ 0.       , -0.9899925, -0.14112  ,  0.       ],
   ...,
    ),
    cArguments = (
        0,
        1,
        GL_FALSE,
        array([[ 1.       ,  0.       ,  0.       ,  0.       ],
       [ 0.       , -0.9899925, -0.14112  ,  0.       ],
   ...,
    )
)

标签: pythonopenglglslshaderpyopengl

解决方案


推荐阅读