PyOpenGL 纹理渲染黑色

PyOpenGL texture rendering black

我最近一直在关注 OpenGL 的在线教程,以测试将 PyOpenGL 集成到带有 QOpenGLWidget 的 PyQt5 应用程序中。在 textures episode 之前,我能够毫无问题地关注每一集;我根本无法渲染纹理。
我的代码如下(为了简化代码去掉了包装器,但我已经测试过它以确保它是相同的):

def FirstFrame():
    positions = [
        -0.5, -0.5, 0.0, 0.0,
        +0.5, -0.5, 1.0, 0.0,
        +0.5, +0.5, 1.0, 1.0,
        -0.5, +0.5, 0.0, 1.0
    ]

    indices = [
        0, 1, 2,
        2, 3, 0,
    ]

    global g_vao
    vao = g_vao = glGenVertexArrays(1)
    glBindVertexArray(vao)

    global g_posBuffer
    posBuffer = g_posBuffer = glGenBuffers(1)
    glBindBuffer(GL_ARRAY_BUFFER, posBuffer)
    glBufferData(GL_ARRAY_BUFFER, (GLfloat * len(positions))(*positions), GL_STATIC_DRAW)

    glEnableVertexAttribArray(0)
    glVertexAttribPointer(0, 2, GL_FLOAT, GL_FALSE, 4 * sizeof(GLfloat), c_void_p(0))

    glEnableVertexAttribArray(1)
    glVertexAttribPointer(1, 2, GL_FLOAT, GL_FALSE, 4 * sizeof(GLfloat), c_void_p(8))

    global g_idxBuffer
    idxBuffer = g_idxBuffer = glGenBuffers(1)
    glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, idxBuffer)
    glBufferData(GL_ELEMENT_ARRAY_BUFFER, (GLuint * len(indices))(*indices), GL_STATIC_DRAW)

    vertexShader = """
        #version 330 core

        layout(location = 0) in vec4 position;
        layout(location = 1) in vec2 texCoord;

        out vec2 v_TexCoord;

        void main()
        {
            gl_Position = position;
            v_TexCoord = texCoord;
        }
    """

    fragmentShader = """
        #version 330 core

        layout(location = 0) out vec4 color;
        layout(location = 1) out vec4 colorTemp;

        in vec2 v_TexCoord;

        uniform sampler2D u_Texture;

        void main()
        {
            vec4 texColor = texture(u_Texture, v_TexCoord);
            color = texColor;
        }
    """

    global g_shader
    shader = g_shader = compileProgram(compileShader(vertexShader, GL_VERTEX_SHADER),
                                       compileShader(fragmentShader, GL_FRAGMENT_SHADER))
    glUseProgram(shader)

    global g_data
    g_data, width, height = ParseRGBA8DDS("ChernoLogo.dds")  # Parses input DDS file and returns bytearray of flipped texture
    localBuffer = (GLubyte * len(g_data)).from_buffer(g_data)  # Making a copy instead of using from_buffer does not work either

    global g_tex
    tex = g_tex = glGenTextures(1)
    glBindTexture(GL_TEXTURE_2D, tex)

    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR)
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR)
    glTexParameteri(GL_TEXTURE_2D, GL_GENERATE_MIPMAP, GL_FALSE)
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE)
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE)

    glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, width, height, 0, GL_RGBA, GL_UNSIGNED_BYTE, localBuffer)  # Passing g_data directly does not work either
    glBindTexture(GL_TEXTURE_2D, 0)

    glActiveTexture(GL_TEXTURE0 + 0)
    glBindTexture(GL_TEXTURE_2D, tex)

    global g_tex_loc
    tex_loc = g_tex_loc = glGetUniformLocation(shader, "u_Texture")
    assert tex_loc != -1
    glUniform1i(tex_loc, 0)


def MainLoopIteration():
    glClear(GL_COLOR_BUFFER_BIT)

    global g_shader, g_r, g_vao, g_idxBuffer

    glUseProgram(g_shader)

    glBindVertexArray(g_vao)
    glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, g_idxBuffer)

    glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_INT, c_void_p(0))

我已经在片段着色器中尝试 color = vec4(v_TexCoord, 0.0, 1.0)color = vec4(u_Texture, 0.0, 0.0, 1.0)(并绑定到插槽 1)以确保这些变量设置正确并且确实如此。
事实上,我已经检查了 texColor,所有像素看起来都是 (0.0, 0.0, 0.0, 1.0)
我还手动验证了 ParseRGBA8DDS() 的输出,看起来是正确的。

我发现了问题。这是本教程没有提及的内容,但我需要重新绑定并重新激活每一帧上的纹理。虽然我不确定为什么它仍然适用于提供教程的人。