Draw a cube with vbo opengl
-
Hi guys! I'm trying to do a cube with vbo, until now i did this based on the cube example of qt. But i dont understand what QOpenGLShaderProgram do, if that i need this for a QOpenglWidget, because my widget stays on a main window, is part of, on the qt example the widget is the window. The vector vertices is for the walls of my cube, i need draw them with GL_LINES and the vector floor i need draw with GL_QUADS. Am I doing this right? Whats missing?
Thanks!glwidget::drawCube(QOpenGLShaderProgram *program) { GLfloat vertices[]={0,0,0,1,0,0,1,0,1,0,0,1, //Frente-Front 0,0,0,0,1,0,0,1,1,0,0,1, //Esquerda-Left 0,1,0,0,1,1,1,1,1,1,1,0, //Trás-Behind 1,0,0,1,1,0,1,1,1,1,0,1//Direita-Right }; GLfloat floor[]={0,0,0,0,1,0,1,1,0,1,0,0}; this->faces.create(); this->floor.create(); this->faces.allocate(vertices,48*sizeof(GLfloat)); this->floor.allocate(floor,12*sizeof(GLfloat)); this->faces.bind(); this->floor.bind(); }
-
You can't call create() allocate() and bind() on the GLfloat types.
Also besides the vbos you will defenitly have to use a QOpenGLShaderProgram. When you have a opengl app, you can think of it has having 2 programs running in the same app, one in your cpu that does all the basic stuff, and other running in the gpu that does all the graphic part. Think of QOpenGLShaderProgram has the guy that does all the gpu fancy graphic stuff.
Lets start with the cube only, first somewhere in your glwidget.h you have to define 2 vbos, 1 for the geometry, another for the color (actually you dont need a vbo for the color if you want the cube to have the same color, but lets use it anyway, that way you can have different colors for different cube segments) . Also instead of GLfloat vertices[] I would go for QVector3D [], that way you can do it the Qt way.
QOpenGLBuffer m_vertexBufferCube; QOpenGLBuffer m_colorBufferCube; QVector3D vertices[number_of_necessary_vertex]; QVector3D vertices_color[number_of_necessary_vertex];
Then in your initializeGL() function you need to proper initialize the vertices, vertices_color, and the vbos:
vertices[0].setX(0.0f); vertices[0].setY(0.0f); vertices[0].setZ(0.0f); vertices[1].setX((1.0f); vertices[1].setY(0.0f); vertices[1].setZ(0.0f); ....
same for vertices_color....
now the vbos:
if (m_vertexBufferCube.create()) qDebug() << "Success creating vertex position buffer"; m_vertexBufferCube.setUsagePattern(QOpenGLBuffer::StaticDraw); if (m_vertexBufferCube.bind()) qDebug() << "Success biding vertex position buffer"; // lets send the vertice data to the vbo using allocate m_vertexBufferCube.allocate(vertices, 3 * number_of_necessary_vertex * sizeof(float)); and do the same for m_colorBufferCube
Now you have the vbo in place, loaded with vertice data, ready to be draw on your paintGL():
m_vertexBufferCube.bind(); m_shaderProgram.setAttributeBuffer("vertexPosition", GL_FLOAT, 0, 3); //vertexPosition is defined in your vertex shader: attribute vec4 vertexPosition; m_colorBufferCube.bind(); m_shaderProgram.setAttributeBuffer("vertexColor", GL_FLOAT, 0, 3); //vertexColor is defined in your vertex shader: attribute vec4 vertexColor; // finally lets draw it glDrawArrays(GL_LINES,0 ,number_of_necessary_vertex);
Lots of work so far for just a cube with vbos, but that should do it.
About the floor, if iirc you can't use GL_QUADS thats not available in the "new" opengl you have to draw to triangles to make a rectangle.
There was a great tutorial explaining all this I think it was a opengl white paper from the days that Qt was under Digia umbrella but I cant find it anymore. Also if you want have a look at a project I have, check the axis3D() function in https://github.com/joaodeus/mathgraphica/blob/master/graph3D/graph3d_opengl.cpp you should be able to try to "port it" to a cube. -
You can't call create() allocate() and bind() on the GLfloat types.
Also besides the vbos you will defenitly have to use a QOpenGLShaderProgram. When you have a opengl app, you can think of it has having 2 programs running in the same app, one in your cpu that does all the basic stuff, and other running in the gpu that does all the graphic part. Think of QOpenGLShaderProgram has the guy that does all the gpu fancy graphic stuff.
Lets start with the cube only, first somewhere in your glwidget.h you have to define 2 vbos, 1 for the geometry, another for the color (actually you dont need a vbo for the color if you want the cube to have the same color, but lets use it anyway, that way you can have different colors for different cube segments) . Also instead of GLfloat vertices[] I would go for QVector3D [], that way you can do it the Qt way.
QOpenGLBuffer m_vertexBufferCube; QOpenGLBuffer m_colorBufferCube; QVector3D vertices[number_of_necessary_vertex]; QVector3D vertices_color[number_of_necessary_vertex];
Then in your initializeGL() function you need to proper initialize the vertices, vertices_color, and the vbos:
vertices[0].setX(0.0f); vertices[0].setY(0.0f); vertices[0].setZ(0.0f); vertices[1].setX((1.0f); vertices[1].setY(0.0f); vertices[1].setZ(0.0f); ....
same for vertices_color....
now the vbos:
if (m_vertexBufferCube.create()) qDebug() << "Success creating vertex position buffer"; m_vertexBufferCube.setUsagePattern(QOpenGLBuffer::StaticDraw); if (m_vertexBufferCube.bind()) qDebug() << "Success biding vertex position buffer"; // lets send the vertice data to the vbo using allocate m_vertexBufferCube.allocate(vertices, 3 * number_of_necessary_vertex * sizeof(float)); and do the same for m_colorBufferCube
Now you have the vbo in place, loaded with vertice data, ready to be draw on your paintGL():
m_vertexBufferCube.bind(); m_shaderProgram.setAttributeBuffer("vertexPosition", GL_FLOAT, 0, 3); //vertexPosition is defined in your vertex shader: attribute vec4 vertexPosition; m_colorBufferCube.bind(); m_shaderProgram.setAttributeBuffer("vertexColor", GL_FLOAT, 0, 3); //vertexColor is defined in your vertex shader: attribute vec4 vertexColor; // finally lets draw it glDrawArrays(GL_LINES,0 ,number_of_necessary_vertex);
Lots of work so far for just a cube with vbos, but that should do it.
About the floor, if iirc you can't use GL_QUADS thats not available in the "new" opengl you have to draw to triangles to make a rectangle.
There was a great tutorial explaining all this I think it was a opengl white paper from the days that Qt was under Digia umbrella but I cant find it anymore. Also if you want have a look at a project I have, check the axis3D() function in https://github.com/joaodeus/mathgraphica/blob/master/graph3D/graph3d_opengl.cpp you should be able to try to "port it" to a cube.@johngod About the vbo for colors, i dont need the cube solid, i need only for the lines, the cube meant to be transparent. If i start the vbo, how to define color only for the lines?
Yeah, this vbo is to hard to do that i imagine.
Thanks for the explanation! Now i will research about do this shaders!
cya -
Using only one color is easier, you dont need a vbo, so please delete all that, you just have to tell your shader program what color to use. So instead of using setAttributeBuffer() we're going to use setUniformValue()
QColor someColor; // set some color m_shaderProgram.disableAttributeArray("vertexColor"); m_shaderProgram.setUniformValue("vertexColor", someColor); glDrawArrays(GL_LINES,0 ,number_of_necessary_vertex);
note that in the vertex shader we need to change "attribute vec4 vertexColor;" to "uniform vec4 vertexColor;" Basically we're just telling that we'll use one color for all vertexs.