PDA

View Full Version : Problems drawing with multiple VAOs



Cloudy McStrife
11-02-2015, 05:42 PM
Hey guys,
I'm currently trying to draw 2 different meshes with help of vertex array objects.
Drawing one mesh multiple times is no problem. But two of them together in one scene does not work.
At first I thought that I overwrite one of the vaos with false information, but thats not the case.
If I try to render 2 meshes only the last draw call has an effect on the visuals of the scene.
Means: Last mesh initialized will be rendered.

Here's my code:
vertex_array_object.cpp


vertex_array_object::vertex_array_object()
{
//vao of type GLuint
glGenVertexArrays(1, &vao);
std::cout << "VAO: " << vao << std::endl;
}

vertex_array_object::~vertex_array_object()
{
glDeleteVertexArrays(1, &vao);
}

void vertex_array_object::bind(){
glBindVertexArray(vao);
}


vertex_buffer_object.cpp



vertex_buffer_object::vertex_buffer_object(std::ve ctor<graphic_util::Vertex>& vertices) : vertices_(vertices)
{
}

vertex_buffer_object::~vertex_buffer_object()
{
glDeleteBuffers(1,&vbo);
}

void vertex_buffer_object::bind(){
glGenBuffers(1,&vbo);
glBindBuffer(GL_ARRAY_BUFFER, vbo);
glBufferData(GL_ARRAY_BUFFER, sizeof(graphic_util::Vertex) * vertices_.size(), &vertices_[0], GL_STATIC_DRAW);
}


mesh.hpp


class mesh : public asset {
public:
mesh(std::vector<graphic_util::Vertex> vertices, std::vector<GLuint> indices)
:vertices_(vertices), indices_(indices)
{
//vao_ of type vertex_array_object vbo_ of type vertex_buffer_object
vao_.bind();
vbo_ = graphics::vertex_buffer_object (vertices_);
vbo_.bind();
}

~mesh(){}

void draw(){
vao_.bind();
glDrawArrays(GL_TRIANGLES, 0, vertices_.size());
}

std::vector<graphic_util::Vertex> vertices(){return vertices_;}
std::vector<GLuint> indices(){return indices_;}

private:
std::vector<graphic_util::Vertex> vertices_;
std::vector<GLuint> indices_;

graphics::vertex_array_object vao_;
graphics::vertex_buffer_object vbo_;
};
}


Thank you in advance :)

GClements
11-02-2015, 06:11 PM
You don't show any calls to glVertexAttribPointer() or glEnableVertexAttribArray(). Those should probably go in the mesh constructor, after the VAO is bound.

Note that what is actually stored in a VAO is the state modified by those calls, which includes the VBO which was bound to GL_ARRAY_BUFFER at the time of the glVertexAttribPointer() call, but doesn't include the current GL_ARRAY_BUFFER binding (so as it stands, the vbo_.bind() call in the mesh constructor is pointless).

Cloudy McStrife
11-02-2015, 07:18 PM
You don't show any calls to glVertexAttribPointer() or glEnableVertexAttribArray(). Those should probably go in the mesh constructor, after the VAO is bound.

Note that what is actually stored in a VAO is the state modified by those calls, which includes the VBO which was bound to GL_ARRAY_BUFFER at the time of the glVertexAttribPointer() call, but doesn't include the current GL_ARRAY_BUFFER binding (so as it stands, the vbo_.bind() call in the mesh constructor is pointless).

I didn't thought this is relevant because I can draw a mesh by itself.

But here's the code where I link my vertex shader in variables.

This is form my shader_program.cpp


void shader_program::link_attribute(const GLchar *attribName, int size, int stride, int offset){
GLint attrib = glGetAttribLocation(program, attribName);
glVertexAttribPointer(attrib, size, GL_FLOAT, GL_FALSE, sizeof(GLfloat)*stride, (void*)(sizeof(GLfloat)*offset));
glEnableVertexAttribArray(attrib);
}


These will be set after every mesh constructing.

Mesh Constructing
Program linking and using
linking variables to shader (Code above)
setting uniforms

GClements
11-02-2015, 07:46 PM
But here's the code where I link my vertex shader in variables.

This is form my shader_program.cpp


void shader_program::link_attribute(const GLchar *attribName, int size, int stride, int offset){
GLint attrib = glGetAttribLocation(program, attribName);
glVertexAttribPointer(attrib, size, GL_FLOAT, GL_FALSE, sizeof(GLfloat)*stride, (void*)(sizeof(GLfloat)*offset));
glEnableVertexAttribArray(attrib);
}


And which VBO and VAO are bound when you call that?

If that's called after the mesh constructor, when the mesh's VAO and VBO are bound, it should be fine.

OTOH, if you construct all of the meshes first, then link the attributes afterwards, all of the settings will be stored in the VAO for the last mesh which was constructed, as that's the one which will be bound at the time.

Cloudy McStrife
11-02-2015, 07:52 PM
So that means I have to link the same attributes for every vao over and over again?
Ok I will try that and write you if that worked ;)

Cloudy McStrife
11-02-2015, 07:55 PM
Wow thank you.
It finally worked ^^
Ok so I know that I gave to change a bit of the structure of my code ^^
Thank you very much.