openGL3+ 上的 glGenVertexArrays 错误

glGenVertexArrays error on openGL3+

我的教授刚刚给了我们一个绘制三角形的简单代码,它在大学实验室中运行良好。但是,在我的个人计算机上,我 运行 遇到了一些奇怪的错误,我似乎无法在线找到解决方案。到目前为止,所有 openGL 代码在我的计算机上都运行良好,所以如果有人能告诉我发生了什么,我将不胜感激。问题出在函数 glGenVertexArrays(1, vao) 上,当代码执行时出现以下错误:

ValueError: glGenVertexArrays requires 1 arguments (n), received 2: (1, c_uint(0L))

据我所知,它只需要一个参数,但给出了 2 个参数,因此我继续删除了 1 得到 glGenVertexArrays(vao)。但这也给我一个错误:

TypeError: ('an integer is required', 'Failure in cConverter <OpenGL.converters.SizedOutput object at 0x7f582456c380>', (c_uint(0L),), 1, <OpenGL.platform.baseplatform.glGenVertexArrays object at 0x7f58244f3a28>)

从那个错误中我知道我确实需要那个整数,在查看函数 glGenVertexArrays 的文档后我意识到这个整数只是告诉有多少个数组所以它确实应该在那里.在绝望的尝试中,我完全删除了该功能并且代码有效,向我显示了一个红色三角形。但是 glGenVertexArrays 在这一切中扮演什么角色呢?我应该删除它吗?经过一些研究,它发现 VAO's 在 openGL3+ 之后成为必需的,然后我感到困惑,因为这是 openGL3+,它使用着色器并且它不是固定的功能,我在这里缺少什么?

这是python中的代码:

import sys
import numpy as np

from OpenGL.GL import *
from OpenGL.GL import shaders
from OpenGL.GLUT import *

vao = None;
vbo = None;
shaderProgram = None;

def readShaderFile(filename):
    with open('shader330/' + filename, 'r') as myfile:
        return myfile.read()

def init():
    global shaderProgram
    global vao
    global vbo

    glClearColor(0, 0, 0, 0);

    vertex_code = readShaderFile('hello.vp')
    fragment_code = readShaderFile('hello.fp')

    # compile shaders and program
    vertexShader = shaders.compileShader(vertex_code, GL_VERTEX_SHADER)
    fragmentShader = shaders.compileShader(fragment_code, GL_FRAGMENT_SHADER)
    shaderProgram = shaders.compileProgram(vertexShader, fragmentShader)

    # Create and bind the Vertex Array Object
    vao = GLuint(0)
    glGenVertexArrays(1, vao)
    glBindVertexArray(vao)

    # Create and bind the Vertex Buffer Object
    vertices = np.array([[0, 1, 0], [-1, -1, 0], [1, -1, 0]], dtype='f')
    vbo = glGenBuffers(1)
    glBindBuffer(GL_ARRAY_BUFFER, vbo)
    glBufferData(GL_ARRAY_BUFFER, vertices, GL_STATIC_DRAW)

    glVertexAttribPointer(0, 3, GL_FLOAT, False, 0, None)  # first 0 is the location in shader
    glBindAttribLocation(shaderProgram, 0, 'vertexPosition')  # name of attribute in shader
    glEnableVertexAttribArray(0);  # 0=location do atributo, tem que ativar todos os atributos inicialmente sao desabilitados por padrao

    # Note that this is allowed, the call to glVertexAttribPointer registered VBO
    # as the currently bound vertex buffer object so afterwards we can safely unbind
    glBindBuffer(GL_ARRAY_BUFFER, 0);
    # Unbind VAO (it's always a good thing to unbind any buffer/array to prevent strange bugs)
    glBindVertexArray(0);

def display():
    global shaderProgram
    global vao

    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT)

    # load everthing back
    glUseProgram(shaderProgram)
    glBindVertexArray(vao)
    glBindBuffer(GL_ARRAY_BUFFER, vbo)

    # glDrawArrays( mode , first, count)
    glDrawArrays(GL_TRIANGLES, 0, 3)

    #clean things up
    glBindBuffer(GL_ARRAY_BUFFER, 0)
    glBindVertexArray(0)
    glUseProgram(0)

    glutSwapBuffers()  # necessario para windows!

def reshape(width, height):
    glViewport(0, 0, width, height)

if __name__ == '__main__':
    glutInit()
    glutInitContextVersion(3, 0)
    glutInitContextProfile(GLUT_CORE_PROFILE);
    glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGB | GLUT_DEPTH)

    glutInitWindowSize(640, 480);
    glutCreateWindow(b'Hello world!')

    glutReshapeFunc(reshape)
    glutDisplayFunc(display)

    init()

    glutMainLoop()

不确定为什么它在您的实验室中有效,可能是您的代码有问题。我很确定 pyopengl 文档是错误的。

如果您查看 openGL 的 c++ doc,它会显示

void glGenVertexArrays( GLsizei n, GLuint *arrays);

n - Specifies the number of vertex array object names to generate.

arrays - Specifies an array in which the generated vertex array object names are stored.

但是如果你看here它说不需要传递所述指针,这是python绑定之间的区别之一opengl 和 c++ 库。

并且 glBindVertexArray(vao) 对对象执行 binding the array 的工作。

所以你只需要通过 1 离开 vao

而且错误里也写的很清楚 -

ValueError: glGenVertexArrays requires 1 arguments (n)