类 的顶点数组问题

Vertex array issue with classes

我正在从 youtube 上的 Chernov @sparky engine 教程学习 openGL 编程。目前我有一个顶点和一个片段着色器,需要 classes 用于 window ,着色器等管理。我可以使用单个顶点数组对象在屏幕上绘制,但是当通过创建 vertexArray class 完成相同操作时,它会失败。 顶点数组 class :

#include"vertexArray.h"
 namespace graphics{
VertexArray::VertexArray(){
    glGenVertexArrays(1,&arrayID);

}
void VertexArray::addBuffer(Buffer* buffer, GLint index){
    bind();

    glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, arrayID);
    glEnableVertexAttribArray(index);
    glVertexAttribPointer(index, buffer->getComCount(), GL_FLOAT, GL_FALSE, 0, 0);


}
void VertexArray::bind() const{
    glBindVertexArray(arrayID);
}
void VertexArray::unbind() const{
    glBindVertexArray(0);
}
VertexArray::~VertexArray(){
}
}

我的 main.cpp 文件

    #include"graphics\window.h"
    #include"utils\reader.h"
    #include"graphics\shader.h"
    #include"math\vec.h"
    #include"math\mat4.h"
    #include"graphics\buffers\buffer.h"
    #include"graphics\buffers\indexbuffer.h"
    #include"graphics\buffers\vertexArray.h"
    using namespace graphics;
    using namespace utils;
    using namespace math;
    int main(){
        Window window;
        glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
        glClearColor(0, 0, 0, 1);
        Reader read1("src/shaders/test.vert");
        Reader read2("src/shaders/test.frag");
        char * r1 = read1.getData();
        char * r2 = read2.getData();

        GLfloat vert[] = {
            0, 0, 0, 
            0, 3, 0, 
            8, 0, 0, 
            8, 3, 0, 
        };
        Buffer* vbo = new Buffer(vert,4*3,3);

        GLushort indices[] = { 
            0,1,2, 
            1,3,2
        };
        indexBuffer ibo(indices,6);

        Shader shader(r1, r2);
        shader.enable();
    #if 0
        GLuint sprite1;
        glGenVertexArrays(1, &sprite1);
        glBindVertexArray(sprite1);
        glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, sprite1);
        vbo->bind();
        glVertexAttribPointer(0, vbo->getComCount(), GL_FLOAT, 0, 0, 0);
        shader.setUniformMat4("pr_matrix", mat4::orthographic(0.0f, 16.0f, 0.0f, 9.0f, -1.0f, 1.0f));
        shader.setUniformMat4("ml_matrix", mat4::translation(vec3(0, 0, 0)));
        shader.setUniform2f("light_pos", vec2(8.0f, 4.5f));
        shader.setUniform4f("colour", vec4(0.2, 0.0, 0.4, 1));
        glEnableVertexAttribArray(0);
        glBindVertexArray(0);

        GLuint sprite2;
        glGenVertexArrays(1, &sprite2);
        glBindVertexArray(sprite2);
        glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, sprite2);
        vbo->bind();
        glVertexAttribPointer(5, vbo->getComCount(), GL_FLOAT, 0, 0, 0);
        shader.setUniformMat4("pr_matrix", mat4::orthographic(0.0f, 16.0f, 0.0f, 9.0f, -1.0f, 1.0f));
        shader.setUniformMat4("ml_matrix", mat4::translation(vec3(4, 3, 0)));
        shader.setUniform2f("light_pos", vec2(8.0f, 4.5f));
        shader.setUniform4f("colour", vec4(0.3, 0.0, 0.2, 1));
        glEnableVertexAttribArray(0);
        glBindVertexArray(0);
    #endif
        VertexArray vao;
        vao.addBuffer(vbo, 0);

        while (!window.closed()){

    #if 0 
            window.clear();

            glDrawArrays(GL_TRIANGLES, 0,6);
    #endif
            double x, y;
            x = window.getX();
            y = window.getY();

            vao.bind();
            ibo.bind();
            shader.setUniform2f("light_pos", vec2((float) (x*16.0f/960.0f)  , (float) (9- 9*y/540.0f)));

            glDrawElements(GL_TRIANGLES, ibo.getCount(), GL_UNSIGNED_SHORT, 0);
            window.update();

            vao.unbind();
            ibo.unbind();
        }
        return 0;
    }

请注意,如果我只是在 main 中为 GLuint 变量创建一个顶点数组并使用它,那么一切正常。 我似乎无法在这里找到问题。 非常感谢任何帮助..

您必须将数据绑定到缓冲区(参见 glBufferData)。

可以像这样创建顶点属性缓冲区:

 GLfloat vert[] = {
    0, 0, 0, 
    0, 3, 0, 
    8, 0, 0, 
    8, 3, 0, 
};

GLuint vbo;
glGenBuffers(1, &vbo);
glBindBuffer(GL_ARRAY_BUFFER, vbo);
glBufferData(GL_ARRAY_BUFFER, sizeof(GLfloat)*3*4, vert, GL_STATIC_DRAW);
glBindBuffer(GL_ARRAY_BUFFER, 0);

可以这样创建元素缓冲区:

GLushort indices[] = { 
    0,1,2, 
    1,3,2
};

GLuint ibo;
glGenBuffers(1, &ibo);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, ibo);
glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(GLushort)*3*2, indices, GL_STATIC_DRAW);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);

A Vertex Array Object 和顶点属性指针指定如下:

GLuint attr_index = 0; // attribute index according to the shader program

GLuint vao;
glGenVertexArrays( 1, &vao );
glBindVertexArray( vao );

glBindBuffer(GL_ARRAY_BUFFER, vbo);
glVertexAttribPointer(attr_index , 3, GL_FLOAT, GL_FALSE, 0, 0);
glEnableVertexAttribArray(attr_index );

glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, ibo);

glBindVertexArray( 0 );
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);

注意,Vertex Array Object 存储您指定的有关顶点属性(格式、大小、属性索引...)的所有信息,它指的是元素数组缓冲区。


最后你可以像这样绘制网格:

glBindVertexArray( vao );
glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_SHORT, 0);
glBindVertexArray( 0 );