C++ 如何正确使用glBindVertexArray中的glDrawElements

C++ 如何正确使用glBindVertexArray中的glDrawElements,c++,opengl,glsl,C++,Opengl,Glsl,我想做的是使用gldrawerelements在不冗余顶点的情况下绘制,如下所示: Model ModelManager::CreateModel(std::vector<glm::vec3>&vertices, std::vector<uint16_t>&vertexIndeces) { //Vertecies GLuint vertexArray; glGenVertexArrays(1, &vertexArray);

我想做的是使用
gldrawerelements
在不冗余顶点的情况下绘制,如下所示:

Model ModelManager::CreateModel(std::vector<glm::vec3>&vertices, std::vector<uint16_t>&vertexIndeces)
{
    //Vertecies
    GLuint vertexArray;

    glGenVertexArrays(1, &vertexArray);
    glBindVertexArray(vertexArray);

    GLuint vBufferId;
    glGenBuffers(1, &vBufferId);
    glBindBuffer(GL_ARRAY_BUFFER, vBufferId);
    glBufferData(GL_ARRAY_BUFFER, vertices.size(), vertices.data(), GL_STATIC_DRAW);
    glEnableVertexAttribArray(0);
    glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 0, 0);

    GLuint iBufferId;
    glGenBuffers(1, &iBufferId);
    glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, iBufferId);
    glBufferData(GL_ELEMENT_ARRAY_BUFFER, vertexIndeces.size(), vertexIndeces.data(), GL_STATIC_DRAW);

    glBindVertexArray(0);
    //
    return Model(vertexArray, vBufferId, iBufferId, vertexIndeces.size());
}
着色器:

#version 120


void main()
{
        gl_Position= gl_ModelViewProjectionMatrix*gl_Vertex;

}

#version 120


void main()
{
    gl_FragColor=vec4(1.0,0.0,0.0,0.0);
}
我试图加载的
obj
文件很容易,我手工制作了它:

v 0.0 0.0 0.0
v 1.0 1.0 0.0
v -1.0 1.0 0.0
v -1.0 -1.0 0.0
v 1.0 -1.0 0.0

f 1/1/1 2/1/1 3/1/1
f 1/1/1 4/1/1 5/1/1

所以它应该显示两个红色三角形,但它没有在屏幕上画任何东西

此代码中有几个问题:

  • 传递到
    glBufferData()
    的大小看起来错误:

    glBufferData(GL_ARRAY_BUFFER, vertices.size(), vertices.data(), GL_STATIC_DRAW);
    ...
    glBufferData(GL_ELEMENT_ARRAY_BUFFER, vertexIndeces.size(), vertexIndeces.data(), GL_STATIC_DRAW);
    
    顶点和
    顶点索引()都是向量。
    向量上的
    .size()
    方法给出了元素的数量,而
    glBufferData()
    需要以字节为单位的大小。要解决此问题,请将代码更改为:

    glBufferData(GL_ARRAY_BUFFER, vertices.size() * sizeof(vertices[0]),
                 vertices.data(), GL_STATIC_DRAW);
    ...
    glBufferData(GL_ELEMENT_ARRAY_BUFFER, vertexIndeces.size() * sizeof(vertexIndeces[0]),
                 vertexIndeces.data(), GL_STATIC_DRAW);
    
  • API调用混合使用固定函数属性和通用顶点属性。根据着色器代码中的版本和着色器代码本身(特别是使用
    gl\u Vertex
    ),您使用的是具有固定函数属性的OpenGL 2.1级别着色器。因此,您需要使用
    glEnableClientState()
    GlvertexInter()
    而不是
    GlenableVertexAttributeArray()
    GlvertexAttributePointer()

    您可以使用常规顶点属性,但随后需要在顶点着色器中声明类型为
    attribute
    的变量,而不是使用
    gl\u vertex


  • 在我看来这是正确的。我建议您后退几步,直到获得预期的渲染效果,然后尝试慢慢构建,看看渲染在哪里中断。你能在不使用顶点数组对象的情况下渲染你想要的东西吗?我在这里看到的唯一不同寻常的事情与你提到的任何一个API调用都没有关系。相反,在绘图方法中有一个奇怪的
    正在完成的
    逻辑。如果你正在加载模型,这是有道理的,但是这里你基本上只画了一次,然后如果(!isFinishedIniting)
    行阻止你再画一次模型。哦,对不起,我写了这个,没有复制粘贴它,所以这是错误的,我编辑了它。您应该做的第一件事是使用
    glGetError
    检查错误。当有OpenGL问题时,告诉您使用的是哪个操作系统,以及它是ATI还是Nvidia卡通常也很有帮助。@t.niese yeh,但没有错误/警告:-是的,因为版本不同,我已经修复了大小,但我没有时间在这里编辑tho,thnx!
    glBufferData(GL_ARRAY_BUFFER, vertices.size() * sizeof(vertices[0]),
                 vertices.data(), GL_STATIC_DRAW);
    ...
    glBufferData(GL_ELEMENT_ARRAY_BUFFER, vertexIndeces.size() * sizeof(vertexIndeces[0]),
                 vertexIndeces.data(), GL_STATIC_DRAW);
    
    glEnableClientState(GL_VERTEX_ARRAY);
    glVertexPointer(3, GL_FLOAT, 0, 0);