VertexArray glVertexAttribPointer GL_INVALID_VALUE 0x0501

VertexArray glVertexAttribPointer GL_INVALID_VALUE 0x0501

正在编写 OpenGL 程序在屏幕上绘制正方形,但 运行 出现无效值错误。调用 MyGLCall(glVertexAttribPointer(i, 时发生错误。 MyGLCallGLCALL 的抽象,我可以将错误代码打印到控制台,如下所示。

不确定此处的值是否无效。我相信 glVertexAttribPointer 的所有数据类型都是正确的,但这里遗漏了一些东西。

控制台输出

Rendering...
OpenGL version 3.3.0 NVIDIA 388.13
GL Extension Wrangler version 2.1.0
[!!! OpenGL ERROR!!!] (0x0501)
glVertexAttribPointer(i, element.elements_per_vertex, element.type, element.normalized, layout.get_stride(), (const void*) offset)

布局和元素数据类型

源代码

// bind vertex buffer and set memory layout
void VertexArray::add_buffer(const VertexBuffer& vb, const VertexBufferLayout& layout) 
{
    VertexArray::bind();
    vb.bind();
    // auto is std::vector<VertexBufferLayoutElement>
    const auto& elements = layout.get_elements();
    unsigned int offset = 0;
    for (unsigned int i = 0; i < elements.size(); i++) 
    {       
        const auto& element = elements[i];      
        // GL_INVALID_VALUE 0x0501
        MyGLCall(glEnableVertexAttribArray(i));
        MyGLCall(glVertexAttribPointer(i,
            element.elements_per_vertex,
            element.type,
            element.normalized,
            layout.get_stride(),
            (const void*) offset)); // heckin, what is this (const void*)???
        offset += element.elements_per_vertex * VertexBufferLayoutElement::get_size_of_type(element.type);
    }   
}

在我的 VertextBufferLayout 头文件中构造 VertexBufferLayoutElement

struct VertexBufferLayoutElement
{
    // nice mem alignment bro, mem size on most machines is
    unsigned int elements_per_vertex;   // 4 bytes
    unsigned int type;                  // 4 bytes
    unsigned char normalized;           // 1 byte
    static unsigned int get_size_of_type(unsigned int type)
    {
        switch (type)
        {
            case GL_FLOAT:          return 4;
            case GL_UNSIGNED_INT:   return 4;
            case GL_UNSIGNED_BYTE:  return 1;
        }
        ASSERT(false);
        return 0;
    }
};

上面这个头文件有错误

没有遵循 first c spec parameter list for the arrtrib pointer function 的正确参数顺序。 GL_FLOATelements_per_vertex 被交换导致错误,下面的屏幕截图是正确的顺序。

glVertexAttribPointer 的第二个参数是元组大小,必须为 1、2、3、4 或 GL_BGRA。第三个参数是类型(例如GL_UNSIGNED_BYTEGL_FLOAT)。

您将 element.elements_per_vertex 传递给第二个参数,将 element.type 传递给第三个参数,这似乎是正确的。但是参数的值被交换了:

elements_per_vertex : 5126
type                : 3   

注意,5126 是 0x1406,这是枚举常量 GL_FLOAT 的值。

设置

elements_per_vertex = 3
type = GL_FLOAT

解决问题。