gpt4 book ai didi

python - 为什么 glDrawElements 调用失败?

转载 作者:行者123 更新时间:2023-12-03 08:44:22 24 4
gpt4 key购买 nike

我正在尝试整合 https://gamedev.stackexchange.com/questions/10727/fastest-way-to-draw-quads-in-opengl-es 的建议和 How to draw with Vertex Array Objects and glDrawElements in PyOpenGL在 GLFW 提供的上下文中并使用辅助类,使用由 OpenGL.arrays.vbo.VBO 实现的索引缓冲区来渲染四边形。 (至少现在,我也依赖于 ctypes 来获取原始数据,而不是使用 Numpy。)

我生成了以下最小示例(如果我可以解决这个问题,我应该能够修复实际的代码):

import ctypes
import glfw
from OpenGL.arrays import vbo
from OpenGL.GL import *
from OpenGL.GL import shaders


def setup_window():
glfw.init()
glfw.window_hint(glfw.CONTEXT_VERSION_MAJOR, 3)
glfw.window_hint(glfw.CONTEXT_VERSION_MINOR, 3)
glfw.window_hint(glfw.OPENGL_FORWARD_COMPAT, True)
glfw.window_hint(glfw.OPENGL_PROFILE, glfw.OPENGL_CORE_PROFILE)
window = glfw.create_window(256,256,'test',None,None)
glfw.make_context_current(window)
glfw.set_input_mode(window, glfw.STICKY_KEYS, True)
return window


def get_program():
VERTEX_SHADER = shaders.compileShader("""
#version 330
layout(location = 0) in vec4 position;
void main()
{
gl_Position = position;
}
""", GL_VERTEX_SHADER)
FRAGMENT_SHADER = shaders.compileShader("""
#version 330
out vec4 outputColor;
void main()
{
outputColor = vec4(0.0f, 1.0f, 0.0f, 1.0f);
}
""", GL_FRAGMENT_SHADER)
return shaders.compileProgram(VERTEX_SHADER, FRAGMENT_SHADER)


window = setup_window()
glUseProgram(get_program())
vertices = vbo.VBO(
(ctypes.c_float * 16)(
-1, -1, 0, 0,
-1, 1, 0, 0,
1, 1, 0, 0,
1, -1, 0, 0
)
)
indices = vbo.VBO(
(ctypes.c_float * 6)(
0, 1, 2, 1, 2, 3
),
target=GL_ELEMENT_ARRAY_BUFFER
)


while (
glfw.get_key(window, glfw.KEY_ESCAPE) != glfw.PRESS
and not glfw.window_should_close(window)
):
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT)
with vertices, indices:
glVertexAttribPointer(0, 4, GL_FLOAT, False, 0, None)
glEnableVertexAttribArray(0)
glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_SHORT, None)
glfw.swap_buffers(window)
glfw.poll_events()

glDrawElements 调用失败,并出现完全无用的“无效操作”异常。当注释掉时,其他一切似乎都工作正常(当然除了没有绘制任何内容)。

这里到底出了什么问题?我知道使用 VBO 实例作为上下文管理器(with block )应该确保数据已绑定(bind),因此应该可用于 glDrawElements 渲染。

我也尝试过以下方法,但没有效果:

  • 在 VBO 上使用显式 .bind() 调用,而不是使用 with block
  • 使用空数据
  • glDrawElements 调用中的 size 参数更改为我能想象到的正确的所有其他数字

最佳答案

您正在使用核心配置文件OpenGL context :

glfw.window_hint(glfw.OPENGL_PROFILE, glfw.OPENGL_CORE_PROFILE)

在核心配置文件上下文中,您必须使用 Vertex Array Object ,因为默认的 VAO (0) 无效。
切换到兼容性配置文件 (glfw.OPENGL_COMPAT_PROFILE) 或创建顶点数组对象。我建议创建一个 VAO。

无论如何,必须在绑定(bind) VAO 后绑定(bind)缓冲区:

indices.bind()
vertices.bind()

索引的类型必须是整数,并且在 glDrawElements 中指定的类型必须与此类型相对应。例如c_int16GL_UNSIGNED_SHORT:

indices = vbo.VBO(
(ctypes.c_int16 * 6)(
0, 1, 2, 0, 2, 3
),
target=GL_ELEMENT_ARRAY_BUFFER
)

注意 Index buffers在 VAO 中声明,因此必须在绑定(bind) ELEMENT_ARRAY_BUFFER 之前绑定(bind) VAO。
glVertexAttribPointer将当前绑定(bind)的 ARRAY_BUFFER 关联到当前绑定(bind)的 VAO 中的指定属性索引。因此,VAO 和 Vertex Buffer Object必须先绑定(bind)。

示例:

window = setup_window()
program = get_program()
glUseProgram(program)

vao = glGenVertexArrays(1)
glBindVertexArray(vao)

vertices = vbo.VBO(
(ctypes.c_float * 16)(
-1, -1, 0, 1,
-1, 1, 0, 1,
1, 1, 0, 1,
1, -1, 0, 1
)
)
indices = vbo.VBO(
(ctypes.c_int16 * 6)(
0, 1, 2, 0, 2, 3
),
target=GL_ELEMENT_ARRAY_BUFFER
)

indices.bind()
vertices.bind()
glVertexAttribPointer(0, 4, GL_FLOAT, False, 0, None)
glEnableVertexAttribArray(0)

while (
glfw.get_key(window, glfw.KEY_ESCAPE) != glfw.PRESS
and not glfw.window_should_close(window)
):
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT)
glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_SHORT, None)
glfw.swap_buffers(window)
glfw.poll_events()

关于python - 为什么 glDrawElements 调用失败?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/62029875/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com