Qt – How to draw a rectangle using a Vertex Buffer Object in OpenGL with Qt

openglqt

I am trying to draw a quadrat using a Vertex Buffer Object in OpenGL with Qt.
Here is my geometry:

numVertices = 4;
vertices = new float[3*numVertices];
int i = 0;
vertices[i++] = 0.0f; vertices[i++] = 0.0f; vertices[i++] = 0.0f; // (0,0,0)
vertices[i++] = 1.0f; vertices[i++] = 0.0f; vertices[i++] = 0.0f; // (1,0,0)
vertices[i++] = 1.0f; vertices[i++] = 1.0f; vertices[i++] = 0.0f; // (1,1,0)
vertices[i++] = 0.0f; vertices[i++] = 1.0f; vertices[i++] = 0.0f; // (0,1,0)
i = 0;
// spilt quad into two triangles:
numTriangles = 2;
indices = new unsigned int[numTriangles*3];
indices[i++] = 0; indices[i++] = 1; indices[i++] = 2; 
indices[i++] = 0; indices[i++] = 2; indices[i++] = 3;

Next in initializeGL method:

QGLBuffer vertexBuffer;
vertexBuffer.create();
vertexBuffer.bind();
vertexBuffer.allocate(vertices, numVertices*sizeof(float));

QGLShaderProgram* shaderProgram_ = new QGLShaderProgram;
shaderProgram_->addShaderFromSourceFile(QGLShader::Vertex,"C:/src/light.vert.glsl") ) {
shaderProgram_->addShaderFromSourceFile(QGLShader::Fragment, "C:/src/light.frag.glsl");
bool ok = shaderProgram_->link();
ok = shaderProgram_->bind();

I think all the VBO part does is to copy vertices to GPU? (Why so many lines?)

The shader part worked fine with old style glBegin(GL_QUADS);

Next in my paintGL method:

shaderProgram_->setAttributeBuffer("vertex", GL_FLOAT, 0, 3, 0);
shaderProgram_->enableAttributeArray("vertex");
glDrawElements(GL_TRIANGLES, numTriangles, GL_UNSIGNED_INT, indices);

What are the two first lines doing? Maybe telling the shader that there is a vertex buffer named "vertex" of type GL_FLOAT?
However I did not specify any name when creating the VBO!? How do OpenGL know that this is "vertex"?

Anyway I am not seing anything!?
Are there any steps I am missing?
My shaders are simple pass trough:

# version 120  
varying vec4 color;
void main() {
    vec4 vertex = gl_Vertex;
    // pass trough:
    gl_Position = gl_ProjectionMatrix * gl_ModelViewMatrix * vertex; 
    color = gl_Color; 
}

# version 120 
varying vec4 color;
void main (void) 
{   
    // pass-trough:    
 gl_FragColor = color;
 }

Best Answer

I guess you've lost 3 here:

vertexBuffer.allocate(vertices, numVertices*sizeof(float));

->

vertexBuffer.allocate(vertices, numVertices*sizeof(float)*3);

I think all the VBO part does is to copy vertices to GPU? (Why so many lines?)

Yes. That's how OpenGL works. To store something in VBO you have to create it, bind it and copy data.

What are the two first lines doing? Maybe telling the shader that there is a vertex buffer named "vertex" of type GL_FLOAT? However I did not specify any name when creating the VBO!? How do OpenGL know that this is "vertex"?

First line:

QGLShaderProgram::setAttributeBuffer() "Sets an array of vertex values on the attribute called name in this shader program, starting at a specific offset in the currently bound vertex buffer." - from manual. Again, that's how OpenGL works. It's a state machine. You bind specific buffer to GL_ARRAY_BUFFER binding point, next tell OpenGL that this is the buffer where "vertex" attribute data is stored. "vertex" is attribute name that you have in your shader program. (May be you should change it to "gl_Vertex") Guess, Qt calls glVertexAttribLocation() to find location of your attribute and next calls glVertexAttribPointer().

Second line:

OpenGL must know that it should copy data from some buffer to some special place where shader program can find it. This is done by enabling attribute arrays for specific location. Guess, Qt calls glVertexAttribLocation() and glEnableAttribArray() here.

BTW: Do you specify any modelview and projection matrices in your code? I' not sure if they are set by default. Try removing these values form shaders for testing purposes.

Added:

glDrawElements(GL_TRIANGLES, numTriangles, GL_UNSIGNED_INT, indices);

Second parameter is not number of triangles but number of indices, that will be read from indices array. Here should be numTriangles*3

Related Topic