Qt Forum

    • Login
    • Search
    • Categories
    • Recent
    • Tags
    • Popular
    • Users
    • Groups
    • Search
    • Unsolved

    Opengl textures with glDrawElements

    Game Development
    4
    10
    8973
    Loading More Posts
    • 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
      john_god last edited by

      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 Reply Quote 0
      • Z
        ZapB last edited by

        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 Reply Quote 0
        • J
          john_god last edited by

          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 Reply Quote 0
          • J
            john_god last edited by

            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 Reply Quote 0
            • J
              john_god last edited by

              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 Reply Quote 0
              • E
                eggsmatter last edited by

                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 Reply Quote 0
                • J
                  john_god last edited by

                  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 Reply Quote 0
                  • E
                    eggsmatter last edited by

                    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 Reply Quote 0
                    • E
                      eggsmatter last edited by

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

                      1 Reply Last reply Reply Quote 0
                      • S
                        Skyrpex last edited by

                        You can use glDrawElements for each face

                        1 Reply Last reply Reply Quote 0
                        • First post
                          Last post