Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • Users
  • Groups
  • Search
  • Get Qt Extensions
  • Unsolved
Collapse
Brand Logo
  1. Home
  2. Qt Development
  3. General and Desktop
  4. Draw a cube with vbo opengl
QtWS25 Last Chance

Draw a cube with vbo opengl

Scheduled Pinned Locked Moved General and Desktop
4 Posts 2 Posters 5.1k Views
  • Oldest to Newest
  • Newest to Oldest
  • Most Votes
Reply
  • Reply as topic
Log in to reply
This topic has been deleted. Only users with topic management privileges can see it.
  • Lays147L Offline
    Lays147L Offline
    Lays147
    wrote on last edited by
    #1

    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();
    }
    
    

    Lays Rodrigues
    Newby on Qt - Learning always!
    Using QT 5.7
    ArchLinux

    1 Reply Last reply
    0
    • johngodJ Offline
      johngodJ Offline
      johngod
      wrote on last edited by
      #2

      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.

      Lays147L 1 Reply Last reply
      2
      • johngodJ johngod

        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.

        Lays147L Offline
        Lays147L Offline
        Lays147
        wrote on last edited by
        #3

        @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

        Lays Rodrigues
        Newby on Qt - Learning always!
        Using QT 5.7
        ArchLinux

        1 Reply Last reply
        0
        • johngodJ Offline
          johngodJ Offline
          johngod
          wrote on last edited by
          #4

          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.

          1 Reply Last reply
          0

          • Login

          • Login or register to search.
          • First post
            Last post
          0
          • Categories
          • Recent
          • Tags
          • Popular
          • Users
          • Groups
          • Search
          • Get Qt Extensions
          • Unsolved