使用 glDrawElements 在 PyOpenGL 中进行索引绘图不绘制任何内容
Indexed drawing in PyOpenGL using glDrawElements doesn't draw anything
我是 OpenGL 的新手,我尝试重新创建 https://learnopengl.com/Getting-started/Hello-Triangle 中的教程以在 PyOpenGL 中绘制矩形。
本教程的第一部分仅使用 glDrawArrays 绘制三角形,但效果很好,但当我尝试使用 glDrawElements 时,什么也没有绘制。它甚至没有引发错误,只是显示黑屏。我很确定我将教程中的说明一一复制,因为没有错误消息,所以我不知道我做错了什么。
如有任何帮助,我将不胜感激。
我的代码:
from OpenGL.GL import *
import OpenGL.GL.shaders
import numpy as np
class Shaders:
def vertex(self):
v = """
#version 330 core
layout (location = 0) in vec3 aPos;
void main()
{
gl_Position = vec4(aPos.x, aPos.y, aPos.z, 1.0);
}
"""
return OpenGL.GL.shaders.compileShader(v, GL_VERTEX_SHADER)
def fragment(self):
f = """
#version 330 core
out vec4 FragColor;
void main()
{
FragColor = vec4(1.0f, 0.5f, 0.2f, 1.0f);
}
"""
return OpenGL.GL.shaders.compileShader(f, GL_FRAGMENT_SHADER)
def main():
# glfw: initialize and configure
if not glfw.init():
return
glfw.window_hint(glfw.CONTEXT_VERSION_MAJOR, 3)
glfw.window_hint(glfw.CONTEXT_VERSION_MINOR, 2)
glfw.window_hint(glfw.OPENGL_PROFILE, glfw.OPENGL_CORE_PROFILE)
glfw.window_hint(glfw.OPENGL_FORWARD_COMPAT, GL_TRUE)
window = glfw.create_window(1920, 1080, "Hello World", None, None)
if not window:
glfw.terminate()
return
glfw.make_context_current(window)
# build and compile shaders
s = Shaders()
shader = OpenGL.GL.shaders.compileProgram(s.vertex(), s.fragment())
# set up vertex data and buffers and configure vertex attributes
vertices = np.array([
0.5, 0.5, 0.0,
0.5, -0.5, 0.0,
-0.5, -0.5, 0.0,
-0.5, 0.5, 0.0
], dtype=np.float32)
indices = np.array([
0, 1, 3,
1, 2, 3
])
VAO = glGenVertexArrays(1)
VBO = glGenBuffers(1)
EBO = glGenBuffers(1)
glBindVertexArray(VAO)
glBindBuffer(GL_ARRAY_BUFFER, VBO)
glBufferData(GL_ARRAY_BUFFER, 48, vertices, GL_STATIC_DRAW)
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, EBO)
glBufferData(GL_ELEMENT_ARRAY_BUFFER, 12, indices, GL_STATIC_DRAW)
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 0, 0)
glEnableVertexAttribArray(0)
glBindBuffer(GL_ARRAY_BUFFER, 0)
glBindVertexArray(0)
# render loop
while not glfw.window_should_close(window):
glClearColor(0, 0, 0, 1.0)
glClear(GL_COLOR_BUFFER_BIT)
glUseProgram(shader)
glBindVertexArray(VAO)
glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_INT, None)
glfw.swap_buffers(window)
glfw.poll_events()
glfw.terminate()
if __name__ == "__main__":
main()
如果绑定了命名缓冲区对象,则 glVertexAttribPointer
的第 6 个参数被视为缓冲区对象数据存储中的字节偏移量。但是参数的类型无论如何都是指针(c_void_p
).
所以如果偏移量为0,那么第6个参数可以是None
或者c_void_p(0)
:
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 0, 0)
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 0, None)
索引缓冲区包含 6 个 uint32 类型的索引。因此索引缓冲区的大小是 24 而不是 12:
glBufferData(GL_ELEMENT_ARRAY_BUFFER, 12, indices, GL_STATIC_DRAW)
glBufferData(GL_ELEMENT_ARRAY_BUFFER, 24, indices, GL_STATIC_DRAW)
使用 PyOpenGL 时,可以省略 size 参数(参见 glBufferData
)。在这种情况下,使用数组的大小:
glBufferData(GL_ELEMENT_ARRAY_BUFFER, indices, GL_STATIC_DRAW)
我是 OpenGL 的新手,我尝试重新创建 https://learnopengl.com/Getting-started/Hello-Triangle 中的教程以在 PyOpenGL 中绘制矩形。
本教程的第一部分仅使用 glDrawArrays 绘制三角形,但效果很好,但当我尝试使用 glDrawElements 时,什么也没有绘制。它甚至没有引发错误,只是显示黑屏。我很确定我将教程中的说明一一复制,因为没有错误消息,所以我不知道我做错了什么。
如有任何帮助,我将不胜感激。
我的代码:
from OpenGL.GL import *
import OpenGL.GL.shaders
import numpy as np
class Shaders:
def vertex(self):
v = """
#version 330 core
layout (location = 0) in vec3 aPos;
void main()
{
gl_Position = vec4(aPos.x, aPos.y, aPos.z, 1.0);
}
"""
return OpenGL.GL.shaders.compileShader(v, GL_VERTEX_SHADER)
def fragment(self):
f = """
#version 330 core
out vec4 FragColor;
void main()
{
FragColor = vec4(1.0f, 0.5f, 0.2f, 1.0f);
}
"""
return OpenGL.GL.shaders.compileShader(f, GL_FRAGMENT_SHADER)
def main():
# glfw: initialize and configure
if not glfw.init():
return
glfw.window_hint(glfw.CONTEXT_VERSION_MAJOR, 3)
glfw.window_hint(glfw.CONTEXT_VERSION_MINOR, 2)
glfw.window_hint(glfw.OPENGL_PROFILE, glfw.OPENGL_CORE_PROFILE)
glfw.window_hint(glfw.OPENGL_FORWARD_COMPAT, GL_TRUE)
window = glfw.create_window(1920, 1080, "Hello World", None, None)
if not window:
glfw.terminate()
return
glfw.make_context_current(window)
# build and compile shaders
s = Shaders()
shader = OpenGL.GL.shaders.compileProgram(s.vertex(), s.fragment())
# set up vertex data and buffers and configure vertex attributes
vertices = np.array([
0.5, 0.5, 0.0,
0.5, -0.5, 0.0,
-0.5, -0.5, 0.0,
-0.5, 0.5, 0.0
], dtype=np.float32)
indices = np.array([
0, 1, 3,
1, 2, 3
])
VAO = glGenVertexArrays(1)
VBO = glGenBuffers(1)
EBO = glGenBuffers(1)
glBindVertexArray(VAO)
glBindBuffer(GL_ARRAY_BUFFER, VBO)
glBufferData(GL_ARRAY_BUFFER, 48, vertices, GL_STATIC_DRAW)
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, EBO)
glBufferData(GL_ELEMENT_ARRAY_BUFFER, 12, indices, GL_STATIC_DRAW)
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 0, 0)
glEnableVertexAttribArray(0)
glBindBuffer(GL_ARRAY_BUFFER, 0)
glBindVertexArray(0)
# render loop
while not glfw.window_should_close(window):
glClearColor(0, 0, 0, 1.0)
glClear(GL_COLOR_BUFFER_BIT)
glUseProgram(shader)
glBindVertexArray(VAO)
glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_INT, None)
glfw.swap_buffers(window)
glfw.poll_events()
glfw.terminate()
if __name__ == "__main__":
main()
如果绑定了命名缓冲区对象,则 glVertexAttribPointer
的第 6 个参数被视为缓冲区对象数据存储中的字节偏移量。但是参数的类型无论如何都是指针(c_void_p
).
所以如果偏移量为0,那么第6个参数可以是None
或者c_void_p(0)
:
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 0, 0)
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 0, None)
索引缓冲区包含 6 个 uint32 类型的索引。因此索引缓冲区的大小是 24 而不是 12:
glBufferData(GL_ELEMENT_ARRAY_BUFFER, 12, indices, GL_STATIC_DRAW)
glBufferData(GL_ELEMENT_ARRAY_BUFFER, 24, indices, GL_STATIC_DRAW)
使用 PyOpenGL 时,可以省略 size 参数(参见 glBufferData
)。在这种情况下,使用数组的大小:
glBufferData(GL_ELEMENT_ARRAY_BUFFER, indices, GL_STATIC_DRAW)