C++ 类的顶点数组问题

C++ 类的顶点数组问题,c++,opengl,visual-studio-2013,glfw,glew,C++,Opengl,Visual Studio 2013,Glfw,Glew,我正在学习youtube上Chernov@sparky engine的教程中的openGL编程。目前,我有一个顶点&一个片段着色器,它具有窗口、着色器等管理所需的类。我可以使用单顶点数组对象在屏幕上绘制,但如果通过创建vertexArray类来完成同样的操作,则会失败。 顶点数组类: #include"vertexArray.h" namespace graphics{ VertexArray::VertexArray(){ glGenVertexArrays(1,&array

我正在学习youtube上Chernov@sparky engine的教程中的openGL编程。目前,我有一个顶点&一个片段着色器,它具有窗口、着色器等管理所需的类。我可以使用单顶点数组对象在屏幕上绘制,但如果通过创建vertexArray类来完成同样的操作,则会失败。 顶点数组类:

#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变量的顶点数组并使用它,那么一切都可以正常工作。 我似乎在这里找不到问题。
非常感谢您的帮助。

您必须将数据绑定到缓冲区(请参阅)

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

 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);
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);
glBindVertexArray( vao );
glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_SHORT, 0);
glBindVertexArray( 0 );
元素缓冲区可以这样创建:

 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);
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);
glBindVertexArray( vao );
glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_SHORT, 0);
glBindVertexArray( 0 );
A和顶点属性指针的指定方式如下:

 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);
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);
glBindVertexArray( vao );
glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_SHORT, 0);
glBindVertexArray( 0 );
注意,a存储您指定的有关顶点属性(格式、大小、属性索引…)的所有信息,并引用元素数组缓冲区


最后,可以按如下方式绘制网格:

 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);
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);
glBindVertexArray( vao );
glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_SHORT, 0);
glBindVertexArray( 0 );

@拉比天哪!!非常感谢你。。。我一整天都不知道这件事。当它起作用时,我几乎高兴得哭了!!非常感谢@Rabbid76:“您必须为缓冲区使用适当的目标。”请不要提升键入的视点。事实并非如此。缓冲区对象的使用是类型化的,但缓冲区对象与类型没有直接关联。在为它们创建存储时,没有什么可以阻止您使用
GL\u COPY\u READ\u BUFFER
。@rabbi76:这意味着您打算稍后用于顶点数组的缓冲区对象必须通过绑定到
GL\u ARRAY\u BUFFER
来分配其存储。答案的其余部分很好。