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()
的输出,看起来是正确的。
我发现了问题。这是本教程没有提及的内容,但我需要重新绑定并重新激活每一帧上的纹理。虽然我不确定为什么它仍然适用于提供教程的人。
我最近一直在关注 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()
的输出,看起来是正确的。
我发现了问题。这是本教程没有提及的内容,但我需要重新绑定并重新激活每一帧上的纹理。虽然我不确定为什么它仍然适用于提供教程的人。