Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • Users
  • Groups
  • Search
  • Get Qt Extensions
  • Unsolved
Collapse
Brand Logo
  1. Home
  2. Qt Development
  3. Game Development
  4. Opengl textures with glDrawElements
QtWS25 Last Chance

Opengl textures with glDrawElements

Scheduled Pinned Locked Moved Game Development
10 Posts 4 Posters 9.8k 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.
  • J Offline
    J Offline
    john_god
    wrote on last edited by
    #1

    I'm drawing a cube with textures, works fine when using calls to glBindTexture() and glDrawArrays() for each face.
    Can I use glDrawElements() ? If so, I'm not sure how to call glBindTexture() and how to tell wich texture should go with each face.

    1 Reply Last reply
    0
    • Z Offline
      Z Offline
      ZapB
      wrote on last edited by
      #2

      There are a number of ways to do this but glDrawElements is not a magic bullet. It is just like glDrawArrays except that you have an index buffer that tells OpenGL which order to draw the vertices in.

      Although the corners of a cube share the vertex positions they do not share normals or texture coordinates so you need to decide if using an index buffer is worth it here.

      To get a different texture on each face you could use a 2D array texture and pass in an additional vertex attribute that is an index to which texture layer to use. Then in the fragment shader you use this index to sample from the correct texture for that face.

      Nokia Certified Qt Specialist
      Interested in hearing about Qt related work

      1 Reply Last reply
      0
      • J Offline
        J Offline
        john_god
        wrote on last edited by
        #3

        Thanks for your fast replay ZapB. Since I got it working with glDrawArrays(), not sure it will be worth the trouble trying with elements. Performance should not be very different since I wil be only drawing one or two cubes.

        1 Reply Last reply
        0
        • J Offline
          J Offline
          john_god
          wrote on last edited by
          #4

          Hello again. This is what I've done so far:

          @class Car
          {
          public:
          Car();
          ...........
          void draw(QGLShaderProgram &m_carShader, const QMatrix4x4 &projection, QMatrix4x4 orientation);
          ................
          //car dimensions
          qreal width_lower; //largura
          qreal width_upper;
          qreal length_lower; //comprimento
          qreal length_upper;
          qreal height; //altura

          //car construction
          QVector3D car_geometry[18];
          GLint car_geometry_elements[30];
          
          QVector3D car_glass_geometry[8];
          QVector3D car_glass_left_lower;
          QVector3D car_glass_left_upper;
          QVector3D car_glass_right_lower;
          QVector3D car_glass_right_upper;
          
          QVector3D car_face_right_back_upper; //0
          QVector3D car_face_right_back_lower; //1
          QVector3D car_face_right_front_upper;//2
          QVector3D car_face_right_front_lower;//3
          QVector3D car_face_left_front_upper; //4
          QVector3D car_face_left_front_lower; //5
          QVector3D car_face_left_back_upper;  //6
          QVector3D car_face_left_back_lower;  //7
          

          ...................
          // texture
          GLuint textures[6];
          QVector<QVector2D> texCoords;
          QList<QString> imageTexList;
          };@

          constructor:

          @//car dimensions
          width_lower = 0.8; //largura
          width_upper = 0.6;
          length_lower = 1.8; //comprimento
          length_upper = 1.0;
          height = 1.2; //altura

          //car construction
          car_face_right_back_upper.setX(width_upper);car_face_right_back_upper.setY(-length_lower);car_face_right_back_upper.setZ(height);//0
          car_face_right_back_lower.setX(width_lower);car_face_right_back_lower.setY(-length_lower);car_face_right_back_lower.setZ(0); //1
          
          car_face_right_front_upper.setX(width_upper);car_face_right_front_upper.setY(length_upper);car_face_right_front_upper.setZ(height); //2
          car_face_right_front_lower.setX(width_lower);car_face_right_front_lower.setY(length_lower); car_face_right_front_lower.setZ(0); //3
          
          car_face_left_front_upper.setX(-width_upper);car_face_left_front_upper.setY(length_upper);car_face_left_front_upper.setZ(height);  //4
          car_face_left_front_lower.setX(-width_lower);car_face_left_front_lower.setY(length_lower);car_face_left_front_lower.setZ(0);//5
          
          car_face_left_back_upper.setX(-width_upper);car_face_left_back_upper.setY(-length_lower);car_face_left_back_upper.setZ(height); //6
          car_face_left_back_lower.setX(-width_lower);car_face_left_back_lower.setY(-length_lower);car_face_left_back_lower.setZ(0); //7
          
          
          car_geometry[0] = car_face_right_back_upper;
          car_geometry[1] = car_face_right_back_lower;
          car_geometry[2] = car_face_right_front_upper;
          car_geometry[3] = car_face_right_front_lower;
          car_geometry[4] = car_face_left_front_upper;
          car_geometry[5] = car_face_left_front_lower;
          car_geometry[6] = car_face_left_back_upper;
          car_geometry[7] = car_face_left_back_lower;
          
          
          car_geometry[8] = car_face_right_back_upper;
          car_geometry[9] = car_face_right_back_lower;
          
          //car up
          car_geometry[10] = car_face_left_back_upper;
          car_geometry[11] = car_face_right_back_upper;
          car_geometry[12] = car_face_left_front_upper;
          car_geometry[13] = car_face_right_front_upper;
          
          //car bottom
          car_geometry[14] = car_face_right_back_lower;
          car_geometry[15] = car_face_left_back_lower;
          car_geometry[16] = car_face_right_front_lower;
          car_geometry[17] = car_face_left_front_lower;
          
          
          car_geometry_elements[ 0] = 0;
          car_geometry_elements[ 1] = 1;
          car_geometry_elements[ 2] = 2;
          car_geometry_elements[ 3] = 3;
          car_geometry_elements[ 4] = 4;
          car_geometry_elements[ 5] = 5;
          car_geometry_elements[ 6] = 6;
          car_geometry_elements[ 7] = 7;
          
          car_geometry_elements[ 8] = 0;
          car_geometry_elements[ 9] = 1;
          car_geometry_elements[10] = 0;
          car_geometry_elements[11] = 0;
          car_geometry_elements[12] = 6;
          car_geometry_elements[13] = 2;
          car_geometry_elements[14] = 4;
          
          // car texture images
          imageTexList.clear();
          imageTexList.append(":/images/supercar_right.png");
          imageTexList.append(":/images/supercar_front.png");
          imageTexList.append(":/images/supercar_left.png");
          imageTexList.append(":/images/supercar_back.png");
          imageTexList.append(":/images/supercar_up.png");
          imageTexList.append(":/images/supercar_down.png");
          
          //car textures for: right, front, left, back, up, bottom
          for (int i=0;i<6;i++)
          {
              texCoords.append(QVector2D(0,1));
              texCoords.append(QVector2D(0,0));
              texCoords.append(QVector2D(1,1));
              texCoords.append(QVector2D(1,0));
          }@
          
          1 Reply Last reply
          0
          • J Offline
            J Offline
            john_god
            wrote on last edited by
            #5

            Drawing the car:

            @void Car::draw(QGLShaderProgram &m_carShader, const QMatrix4x4 &projection, QMatrix4x4 orientation)
            {
            orientation.translate(position);
            orientation.rotate(rotation.x(), 1.0f, 0.0f, 0.0f );
            orientation.rotate(rotation.y(), 0.0f, 1.0f, 0.0f );
            orientation.rotate(rotation.z(), 0.0f, 0.0f, 1.0f );

            QGLWidget g;
            for (int j=0; j < 6; ++j)
            {
                textures[j] = g.bindTexture(QPixmap(imageTexList.at(j)), GL_TEXTURE_2D);
            }
            
            
            GLint matrixAttr        = m_carShader.uniformLocation("matrix_shader");
            GLint projAttr          = m_carShader.uniformLocation("projection_shader");
            GLint vertexAttr        = m_carShader.attributeLocation("vertex_shader");
            GLint color             = m_carShader.uniformLocation("uColor");
            GLint textureCoordAttr  = m_carShader.attributeLocation("texCoord");
            

            // GLint texElementAttr = m_carShader.attributeLocation("texElements"); // ????

            m_carShader.setUniformValue( projAttr, projection );
            m_carShader.setUniformValue( matrixAttr, orientation );
            m_carShader.setAttributeArray(vertexAttr, car_geometry, 0);
            m_carShader.setUniformValue(color,car_color);
            m_carShader.setAttributeArray(textureCoordAttr, texCoords.constData());
            //m_carShader.setAttributeArray(texElementAttr,textures); //error
            
            
            glBindTexture(GL_TEXTURE_2D, textures[0]);
            glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
            
            glBindTexture(GL_TEXTURE_2D, textures[1]);
            glDrawArrays(GL_TRIANGLE_STRIP, 2, 4);
            
            glBindTexture(GL_TEXTURE_2D, textures[2]);
            glDrawArrays(GL_TRIANGLE_STRIP, 4, 4);
            
            glBindTexture(GL_TEXTURE_2D, textures[3]);
            glDrawArrays(GL_TRIANGLE_STRIP, 6, 4);
            
            glBindTexture(GL_TEXTURE_2D, textures[4]);
            glDrawArrays(GL_TRIANGLE_STRIP, 10, 4);
            
            glBindTexture(GL_TEXTURE_2D, textures[5]);
            glDrawArrays(GL_TRIANGLE_STRIP, 14, 4);
            

            // glDrawElements(GL_TRIANGLE_STRIP, 15, GL_UNSIGNED_INT, car_geometry_elements);@

            The shaders:

            @attribute highp vec4 vertex_shader;
            uniform mediump mat4 matrix_shader;
            uniform mediump mat4 projection_shader;

            //variables for the car texture
            //attribute mediump vec4 texElements; // ???
            //varying mediump vec4 texElements_v; // ???
            attribute mediump vec4 texCoord;
            varying mediump vec4 texc;

            uniform mediump vec4 uColor;
            varying highp vec4 Color;

            void main(void)
            {
            // texElements_v = texElements; //?????
            texc = texCoord; // car texture
            Color = uColor;
            gl_Position = projection_shader * matrix_shader * vertex_shader;
            }
            @

            @//uniform highp vec4 Color;
            varying highp vec4 Color;

            // car texture
            //varying mediump vec4 texElements_v; // ???
            varying mediump vec4 texc;
            uniform sampler2D texture;

            void main(void)
            {
            gl_FragColor = texture2D(texture, texc.st);
            //gl_FragColor = Color;
            }@

            I tried passing the index textures to the shaders, but in line 27 from draw(), it fails because I cannot bind a GLint[] to a vec4 in the shader.

            bq. To get a different texture on each face you could use a 2D array texture and pass in an additional vertex attribute that is an index to which texture layer to use. Then in the fragment shader you use this index to sample from the correct texture for that face.

            I don't have clue how to select the texture in the fragment shader.

            1 Reply Last reply
            0
            • E Offline
              E Offline
              eggsmatter
              wrote on last edited by
              #6

              Bump on this. I am trying to accomplish a very similar task. Nor do I have a clue how to select the texture in the fragment shader. Online resources are quite disparate and I get a lot of conflicting data. Let me know if you've figured it out, or I will post my findings here

              1 Reply Last reply
              0
              • J Offline
                J Offline
                john_god
                wrote on last edited by
                #7

                Still havent figured this out.
                Only thing I can think of is to use several calls to glBindTexture() and glDrawElements() in a loop, with diferent geometry elements in each call, drawing only one texture per loop, but this would not bring any benefits over glDrawArrays(). Also it would be in client side, not in the shader.

                1 Reply Last reply
                0
                • E Offline
                  E Offline
                  eggsmatter
                  wrote on last edited by
                  #8

                  My thoughs exactly. I posted a similar question relegated to my project. Hopefully something will come out of it. I'm going to dig deeper into the graphics pipeline and let you know if I uncover anything

                  1 Reply Last reply
                  0
                  • E Offline
                    E Offline
                    eggsmatter
                    wrote on last edited by
                    #9

                    Here is probably the best resource on GLSL I can find:
                    http://www.lighthouse3d.com/tutorials/glsl-tutorial/pipeline-overview/

                    1 Reply Last reply
                    0
                    • S Offline
                      S Offline
                      Skyrpex
                      wrote on last edited by
                      #10

                      You can use glDrawElements for each face

                      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