PDA

View Full Version : Problem to render with VAO



Dartagnan
12-21-2016, 07:25 AM
Hi
I have a problem to render with a VAO. I want to set up a VAO and render with calls of glBindVertexArray() and glDrawArrays(), but I have to call glEnableVertexAttribArray() and glVertexAttribPointer() everytime I bind the VAO.
I wanted to set up a VAO in a class named grid and bind a VBO in a function, where I calculate vertex-data, like seen below.


glGenVertexArrays(1, &VAO);
glGenBuffers(1, &VBO);
glBindVertexArray(VAO);
glBindBuffer(GL_ARRAY_BUFFER, VBO);
glBufferData(GL_ARRAY_BUFFER, FLOATS_PER_VERTEX*numVertices*sizeof(GLfloat), vertices, GL_STATIC_DRAW);
glEnableVertexAttribArray(gridShader::loc_pos);
glEnableVertexAttribArray(gridShader::loc_col);
glVertexAttribPointer(gridShader::loc_pos, 3, GL_FLOAT, GL_FALSE, FLOATS_PER_VERTEX*sizeof(GLfloat), (GLvoid*)0);
glVertexAttribPointer(gridShader::loc_col, 3, GL_FLOAT, GL_FALSE, FLOATS_PER_VERTEX*sizeof(GLfloat), (GLvoid*)(3*sizeof(GLfloat)));
glBindVertexArray(0);

In paintGL() I just wan't to call glBindVertexArray() but nothing is rendered.


viewpointMatrix.setColumn(3, -viewpoint+QVector3D(0,0,zoom));
glBindVertexArray(grid->VAO);
gridShader::shaderProg.bind();
gridShader::shaderProg.setUniformValue(gridShader: :loc_projMatrix, projectionMatrix*viewpointMatrix);
glLineWidth(1);
glDrawArrays(GL_LINES, 0, grid->numVertices);
glBindVertexArray(0);

If all functions are called again in paintGL() everything works fine, but I think thats not the purpose of a VAO.


viewpointMatrix.setColumn(3, -viewpoint+QVector3D(0,0,zoom));
glBindVertexArray(grid->VAO);
gridShader::shaderProg.bind();
gridShader::shaderProg.setUniformValue(gridShader: :loc_projMatrix, projectionMatrix*viewpointMatrix);
glBindBuffer(GL_ARRAY_BUFFER, grid->VBO);
glEnableVertexAttribArray(gridShader::loc_pos);
glEnableVertexAttribArray(gridShader::loc_col);
glVertexAttribPointer(gridShader::loc_pos, 3, GL_FLOAT, GL_FALSE, FLOATS_PER_VERTEX*sizeof(GLfloat), (GLvoid*)0);
glVertexAttribPointer(gridShader::loc_col, 3, GL_FLOAT, GL_FALSE, FLOATS_PER_VERTEX*sizeof(GLfloat), (GLvoid*)(3*sizeof(GLfloat)));
glLineWidth(1);
glDrawArrays(GL_LINES, 0, grid->numVertices);
glBindVertexArray(0);

Hope that somebody can tell me what I'm doing wrong.
Thanks

GClements
12-21-2016, 11:00 AM
There's nothing wrong with the code which you posted, so the problem lies elsewhere.

Check for OpenGL errors, check whether the object is being re-initialised, check that the context which is bound when you create the VAO is the same one which is bound when you try to use it.

Dartagnan
12-22-2016, 02:41 AM
The problem was the current context, but I still have a problem when trying to run the program on linux.
On windows I can call makeCurrent() in the function where I set up the VAO. The context now is the same like in initializeGL() and the program is working.


void GLwidget::createGrid(GLuint size, GLfloat *vertices)
{
makeCurrent();
qDebug()<< QOpenGLContext::currentContext();
glBindVertexArray(gridVAO[0]);
glBindBuffer(GL_ARRAY_BUFFER, gridVBO[0]);
glBufferData(GL_ARRAY_BUFFER, size*sizeof(GLfloat), vertices, GL_STATIC_DRAW);
glEnableVertexAttribArray(gridShader::loc_pos);
glEnableVertexAttribArray(gridShader::loc_col);
glVertexAttribPointer(gridShader::loc_pos, 3, GL_FLOAT, GL_FALSE, FLOATS_PER_GRID_VERTEX*sizeof(GLfloat), (GLvoid*)0);
glVertexAttribPointer(gridShader::loc_col, 3, GL_FLOAT, GL_FALSE, FLOATS_PER_GRID_VERTEX*sizeof(GLfloat), (GLvoid*)(3*sizeof(GLfloat)));
glLineWidth(1);
glBindBuffer(GL_ARRAY_BUFFER, 0);
glBindVertexArray(0);
}

When I try to run it on Linux, makeCurrent() doesn't set the context to GLwidget. Do you know if I have to use another function?

GClements
12-22-2016, 08:13 AM
When I try to run it on Linux, makeCurrent() doesn't set the context to GLwidget. Do you know if I have to use another function?
makeCurrent() should have been called by Qt prior to calling initializeGL() or paintGL().

If you aren't using those methods, note that you can't call makeCurrent() before the widget has been realized.