为什么glDrawElements调用失败?

问题描述 投票:0回答:1

我正在尝试整合https://gamedev.stackexchange.com/questions/10727/fastest-way-to-draw-quads-in-opengl-esHow to draw with Vertex Array Objects and glDrawElements in PyOpenGL的建议,以便在GLFW提供的上下文中并使用helper类,使用由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块)应确保绑定数据,因此应可用于glDrawElements渲染。

我也尝试了以下操作,但没有效果:

  • 在VBO上使用显式.bind()调用而不是with
  • 使用空数据
  • size调用中的glDrawElements参数更改为我可以想象是正确的所有其他数字
python glfw pyopengl
1个回答
0
投票

您正在使用cor配置文件OpenGL上下文:

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

在核心配置文件上下文中,您必须使用Vertex Array Object,因为默认的VAO(0)无效。

要么切换到兼容性配置文件:

glfw.window_hint(glfw.OPENGL_PROFILE, glfw.OPENGL_COMPAT_PROFILE)

或创建一个顶点数组对象

© www.soinside.com 2019 - 2024. All rights reserved.