OpenGL glUniform1i 无效操作

Posted

技术标签:

【中文标题】OpenGL glUniform1i 无效操作【英文标题】:OpenGL glUniform1i Invalid Operation 【发布时间】:2017-05-23 15:24:55 【问题描述】:

所以我一直在单独关注learnopengl.com 这本书,并且在让纹理单元工作时遇到了麻烦。起初我像他在书中所做的那样在主循环中调用 glGetUniform1i,但被建议(通过#learnprogramming IRC)将任何纹理操作限制在主循环之前。使用本书的代码,问题是纹理没有按照片段着色器中的定义正确混合,并且仅渲染绑定到 GL_TEXTURE_2D 的第二个纹理(在本例中为“faceTexture”)。颠倒渲染顺序会渲染过去先出现的纹理。

但是,将纹理单元代码放在主循环之前会导致 glUniform1i 调用的操作无效:

File "C:/Users/1117254/Documents/Python Experiments/OpenGL/OpenGL Testing/main.py", line 171, in main
     glUniform1i(wood_texture_loc, 0)
File "C:\Users\1117254\AppData\Local\Programs\Python\Python36\lib\site-packages\OpenGL\platform\baseplatform.py", line 402, in __call__
     return self( *args, **named )
File "errorchecker.pyx", line 53, in 
     OpenGL_accelerate.errorchecker._ErrorChecker.glCheckError (src\errorchecker.c:1218)
     OpenGL.error.GLError: GLError(
err = 1282,
description = b'invalid operation',
baseOperation = glUniform1i,
cArguments = (23724032, 0)
)

对我来说,错误似乎与碎片着色器中统一变量的位置有关,但我不确定 glGetUniformLocation 给出的位置(似乎是 23724032)是否有效。

以下相关来源以及顶点和片段着色器:

# Shader
shader = shader_loader.Shader("vertex.vs", "fragment.fs")

# Vertex Buffering
vao = GLuint(0)
vbo = GLuint(0)
ebo = GLuint(0)

glGenVertexArrays(1, vao)
glGenBuffers(1, vbo)
glGenBuffers(1, ebo)

glBindVertexArray(vao)
glBindBuffer(GL_ARRAY_BUFFER, vbo)
glBufferData(GL_ARRAY_BUFFER, 4 * len(vertices), vertices, GL_STATIC_DRAW)

glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, ebo)
glBufferData(GL_ELEMENT_ARRAY_BUFFER, 4 * len(indices), indices, GL_STATIC_DRAW)

# Position attribute
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 8 * 4, ctypes.c_void_p(0))
glEnableVertexAttribArray(0)

# Color attribute
glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, 8 * 4, ctypes.c_void_p(3 * 4))
glEnableVertexAttribArray(1)

# Texture attribute
glVertexAttribPointer(2, 2, GL_FLOAT, GL_FALSE, 8 * 4, ctypes.c_void_p(6 * 4))
glEnableVertexAttribArray(2)

# Unbinding buffers
glBindVertexArray(0)

# Texturing
wood = Image.open("resources/wood.jpg")
wood.load()
face = Image.open("resources/awesomeface.jpg")
face.load()
# face.transpose(Image.FLIP_LEFT_RIGHT)

wood_texture_loc = glGetUniformLocation(shader.shader_program, "woodTexture")
face_texture_loc = glGetUniformLocation(shader.shader_program, "faceTexture")

wood_data = list(wood.getdata())
wood_data = numpy.array(wood_data, dtype=numpy.uint8)
face_data = list(face.getdata())
face_data = numpy.array(face_data, dtype=numpy.uint8)

# Wood texture
texture1 = GLuint(0)
glGenTextures(1, texture1)
glBindTexture(GL_TEXTURE_2D, texture1)

glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT)
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT)
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR)
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR)

glTexImage2D(GL_TEXTURE_2D,
             0,
             GL_RGB,
             wood.size[0], wood.size[1],
             0,
             GL_RGB,
             GL_UNSIGNED_BYTE,
             wood_data)
glGenerateMipmap(GL_TEXTURE_2D)
glBindTexture(GL_TEXTURE_2D, 0)

# Face texture
texture2 = GLuint(0)
glGenTextures(1, texture2)
glBindTexture(GL_TEXTURE_2D, texture2)

glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT)
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT)
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR)
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR)

glTexImage2D(GL_TEXTURE_2D,
             0,
             GL_RGB,
             face.size[0], face.size[1],
             0,
             GL_RGB,
             GL_UNSIGNED_BYTE,
             face_data)
glGenerateMipmap(GL_TEXTURE_2D)
glBindTexture(GL_TEXTURE_2D, 0)

glActiveTexture(GL_TEXTURE0)
glBindTexture(GL_TEXTURE_2D, texture1)
glUniform1i(wood_texture_loc, 0)
glActiveTexture(GL_TEXTURE1)
glBindTexture(GL_TEXTURE_2D, texture2)
glUniform1i(face_texture_loc, 1)

while True:

    for event in pygame.event.get():
        if event.type == QUIT:
            terminate()
        elif event.type == KEYDOWN:
            if event.key == K_ESCAPE:
                terminate()

    glClearColor(0.4667, 0.7373, 1., 1.0)
    glClear(GL_COLOR_BUFFER_BIT)

    shader.use()

    glBindVertexArray(vao)
    glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_INT, None)
    glBindVertexArray(0)

    pygame.display.flip()
    clock.tick(fps)

顶点着色器:

#version 330
layout (location = 0) in vec3 position;
layout (location = 1) in vec3 color;
layout (location = 2) in vec2 texCoords;

out vec3 ourColor;
out vec2 texCoordsOut;

void main()

    gl_Position = vec4(position, 1.0f);
    ourColor = color;
    texCoordsOut = vec2(texCoords);

片段着色器:

#version 330
in vec3 ourColor;
in vec2 texCoordsOut;

out vec4 color;

uniform sampler2D woodTexture;
uniform sampler2D faceTexture;

void main()

    color = mix(texture(woodTexture, texCoordsOut), texture(faceTexture, 
texCoordsOut), 0.2);

非常感谢任何见解。

【问题讨论】:

"起初我在主循环中调用glGetUniform1i" 有问题的教程没有。它调用glGetUniformLocation,但这是一个不同的功能。你也不叫glGetUniform1i;确实,没有这样的功能。也许您的意思是glUniform1i,这又是一个不同的功能。 糟糕透了。是的,我的意思是 glUniform1i。 【参考方案1】:

glUniform* 不需要修改程序对象。因此,它会修改当前正在使用的程序。由于当前没有程序在使用,因此您会收到错误消息。

在调用这个函数之前使用程序。

【讨论】:

啊,好吧。这确实解决了这个问题。然而,仍然遇到只有第二个纹理定义渲染的问题。

以上是关于OpenGL glUniform1i 无效操作的主要内容,如果未能解决你的问题,请参考以下文章

使用 GLUT_3_2_CORE_PROFILE 时出现 OpenGL 错误 1282(无效操作)

OpenGL下多个sampler在shader中的使用

Android opengl 1.1 Render to Texture 1286错误(无效的帧缓冲操作)

我的OpenGL学习进阶之旅解决OpenGL在使用glUniform系列api时出现了 GL_INVALID_OPERATION 1282错误

我的OpenGL学习进阶之旅解决OpenGL在使用glUniform系列api时出现了 GL_INVALID_OPERATION 1282错误

glEnableVertexAttribArray 给出无效操作