SelymAI
SelymAI

Reputation: 57

How to Upload Vertex Data Using Vectors and Structs in OpenGL?

I've been trying to upload vertex data from a vector to a VBO to render a textured, colored square. When I run the program, it breaks at "glDrawArrays(...)" and I get a "First-chance exception at...nvoglv64.dll in Tutorial.exe: Access violation reading location..." I'm not sure what I've done incorrectly. Although my main goal is to use this in a sprite batcher, here's the simplified example:

Game::Game()
{
    Oreg::Core::init();

    //INIT VAO
    tex = Oreg::FileSys::getTex("Feels.png");

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

    glGenBuffers(1, &vbo);
    glBindBuffer(GL_VERTEX_ARRAY, vbo);

    GLuint posAtt = Oreg::DefShader::texture2D.getAtt("vert");
    GLuint texAtt = Oreg::DefShader::texture2D.getAtt("texcoords");
    GLuint colAtt = Oreg::DefShader::texture2D.getAtt("color");
    glEnableVertexAttribArray(posAtt);
    glEnableVertexAttribArray(texAtt);
    glEnableVertexAttribArray(colAtt);
    glVertexAttribPointer(posAtt, 2, GL_FLOAT, GL_FALSE, sizeof(Det::Vert), (GLvoid*)offsetof(Det::Vert, pos));
    glVertexAttribPointer(texAtt, 2, GL_FLOAT, GL_FALSE, sizeof(Det::Vert), (GLvoid*)offsetof(Det::Vert, uv));
    glVertexAttribPointer(colAtt, 4, GL_FLOAT, GL_FALSE, sizeof(Det::Vert), (GLvoid*)offsetof(Det::Vert, col));

    glBindVertexArray(0);

    std::cout<<"Size of GLfloat: "<<sizeof(GLfloat)<<"\n"; //4
    std::cout<<"Size of Vert: "<<sizeof(Det::Vert)<<"\n"; //32
    std::cout<<"Offset of Vert's pos: "<<offsetof(Det::Vert, pos)<<"\n"; //0
    std::cout<<"Offset of Vert's uv: "<<offsetof(Det::Vert, uv)<<"\n"; //8
    std::cout<<"Offset of Vert's col: "<<offsetof(Det::Vert, col)<<"\n"; //16

    //UPLOAD VERTS
    std::vector<Det::Vert> verts;

    verts.resize(6);
    verts.at(0).setPos(0, 0);
    verts.at(0).setUV(0, 0);
    verts.at(0).setCol(1, 0, 1, 1);
    verts.at(1).setPos(50, 0);
    verts.at(1).setUV(1, 0);
    verts.at(1).setCol(1, 0, 1, 1);
    verts.at(2).setPos(50, 50);
    verts.at(2).setUV(1, 1);
    verts.at(2).setCol(1, 0, 1, 1);
    verts.at(3).setPos(50, 50);
    verts.at(3).setUV(1, 1);
    verts.at(3).setCol(1, 0, 1, 1);
    verts.at(4).setPos(0, 50);
    verts.at(4).setUV(0, 1);
    verts.at(4).setCol(1, 0, 1, 1);
    verts.at(5).setPos(0, 0);
    verts.at(5).setUV(0, 0);
    verts.at(5).setCol(1, 0, 1, 1);

    glBindBuffer(GL_ARRAY_BUFFER, vbo);
    glBufferData(GL_ARRAY_BUFFER, verts.size()*sizeof(Det::Vert), verts.data(), GL_DYNAMIC_DRAW);
    glBindBuffer(GL_ARRAY_BUFFER, 0);
}

void Game::update()
{
    //BEGIN RENDER
    Oreg::Window::clear(0.0f, 0.06f, 0.09f, 1.0f);
    Oreg::Window::renderSettings();
    Oreg::DefShader::texture2D.use();
    glm::mat4 mat = glm::ortho(0.0f, (float)Oreg::Window::getRes().x, (float)Oreg::Window::getRes().y, 0.0f, -1.0f, 1.0f);
    glUniform1i(Oreg::DefShader::texture2D.getUni("tex"), 0);
    glUniformMatrix4fv(Oreg::DefShader::texture2D.getUni("matrix"), 1, GL_FALSE, glm::value_ptr(mat));
    glDisable(GL_DEPTH_TEST);
    glDisable(GL_CULL_FACE);

    //RENDER
    glBindVertexArray(vao);
    glBindTexture(GL_TEXTURE_2D, tex->id);
    glDrawArrays(GL_TRIANGLES, 0, 6);
    glBindVertexArray(0);

    //END RENDER
    glEnable(GL_CULL_FACE);
    glEnable(GL_DEPTH_TEST);
    glUseProgram(0);
    Oreg::Window::showBuffer();
}

Game::~Game(){ Oreg::Core::dest(); }

Upvotes: 0

Views: 571

Answers (1)

Reto Koradi
Reto Koradi

Reputation: 54592

There's a wrong argument in the glBindBuffer() calls close to the start:

glGenBuffers(1, &vbo);
glBindBuffer(GL_VERTEX_ARRAY, vbo);

GL_VERTEX_ARRAY is not valid as the first argument. It should be this instead:

glBindBuffer(GL_ARRAY_BUFFER, vbo);

You should always call glGetError() if your OpenGL code does not work as expected. In this case, you would get a GL_INVALID_ENUM error.

There's no direct indication that you have a problem with this, but just something to watch out for: Since you're making OpenGL calls in the constructor of this class, you'll have to make sure that you only instantiate objects of this class after you have a current OpenGL context.

Upvotes: 1

Related Questions