Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

What are the texture coordinates for a cube in OpenGL?

Tags:

opengl

I have a cube defined as:

float vertices[] = { -width, -height, -depth, // 0
                              width, -height, -depth, // 1
                              width,  height, -depth, // 2
                             -width,  height, -depth, // 3
                             -width, -height,  depth, // 4
                              width, -height,  depth, // 5
                              width,  height,  depth, // 6
                             -width,  height,  depth // 7
        };  

and I have image 128x128 which I simply want to be painted on each of the 6 faces of the cube and nothing else. So what are the texture cooridinates? I need the actual values.

This is the drawing code:

// Counter-clockwise winding.
        gl.glFrontFace(GL10.GL_CCW);
        // Enable face culling.
        gl.glEnable(GL10.GL_CULL_FACE);
        // What faces to remove with the face culling.
        gl.glCullFace(GL10.GL_BACK);
        // Enabled the vertices buffer for writing and to be used during
        // rendering.
        gl.glEnableClientState(GL10.GL_VERTEX_ARRAY);

        // Specifies the location and data format of an array of vertex
        // coordinates to use when rendering.
        gl.glVertexPointer(3, GL10.GL_FLOAT, 0, mVerticesBuffer);


            // Bind the texture according to the set texture filter
            gl.glBindTexture(GL10.GL_TEXTURE_2D, textures[filter]);
            gl.glEnable(GL10.GL_TEXTURE_2D);



            // Enable the texture state
            gl.glEnableClientState(GL10.GL_TEXTURE_COORD_ARRAY);

            // Point to our buffers
            gl.glTexCoordPointer(2, GL10.GL_FLOAT, 0, mTextureBuffer);



        // Set flat color
        gl.glColor4f(red, green, blue, alpha);


        gl.glDrawElements(GL10.GL_TRIANGLES, mNumOfIndices,
                GL10.GL_UNSIGNED_SHORT, mIndicesBuffer);

        // ALL the DRAWING IS DONE NOW

        // Disable the vertices buffer.
        gl.glDisableClientState(GL10.GL_VERTEX_ARRAY);


            gl.glDisableClientState(GL10.GL_TEXTURE_COORD_ARRAY);


        // Disable face culling.
        gl.glDisable(GL10.GL_CULL_FACE);

This is the index array:

short indices[] = { 0, 2, 1,
                0, 3, 2,

                1,2,6,
                6,5,1,

                4,5,6,
                6,7,4,

                2,3,6,
                6,3,7,

                0,7,3,
                0,4,7,

                0,1,5,
                0,5,4


               };  

I am not sure if index array is needed to find tex coordinates. Note that the cube vertex array I gave is the most efficient representation of a cube using the index array. The cube draws perfectly but not the textures. Only one side shows correct picture but other sides are messed up. I used the methods described in various online tutorials on textures but it does not work.

like image 499
ace Avatar asked Feb 13 '11 09:02

ace


People also ask

What are texture coordinates used for in OpenGL?

Texture coordinates specify the point in the texture image that will correspond to the vertex you are specifying them for. Think of a rectangular rubber sheet with your texture image printed on it, where the length of each side is normalized to the range 0-1.

How do you make a cube in OpenGL?

The general idea behind your cube is to draw all six sides individually and place them in the appropriate position. Conceptually, each side is going to be drawn by defining the four corners and letting OpenGL connect the lines and fill it in with a color that you define.


4 Answers

What you are looking for is a cube map. In OpenGL, you can define six textures at once (representing the size sides of a cube) and map them using 3D texture coordinates instead of the common 2D texture coordinates. For a simple cube, the texture coordinates would be the same as the vertices' respective normals. (If you will only be texturing plane cubes in this manner, you can consolidate normals and texture coordinates in your vertex shader, too!) Cube maps are much simpler than trying to apply the same texture to repeating quads (extra unnecessary drawing steps).

GLuint mHandle;
glGenTextures(1, &mHandle); // create your texture normally

// Note the target being used instead of GL_TEXTURE_2D!
glTextParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTextParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_R, GL_CLAMP_TO_EDGE);
glTextParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
glTextParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);

glBindTexture(GL_TEXTURE_CUBE_MAP, mHandle);

// Now, load in your six distinct images. They need to be the same dimensions!
// Notice the targets being specified: the six sides of the cube map.
glTexImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_X, 0, GL_RGBA, width, height, 0,
    format, GL_UNSIGNED_BYTE, data1);
glTexImage2D(GL_TEXTURE_CUBE_MAP_NEGATIVE_X, 0, GL_RGBA, width, height, 0,
    format, GL_UNSIGNED_BYTE, data2);
glTexImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_Y, 0, GL_RGBA, width, height, 0,
    format, GL_UNSIGNED_BYTE, data3);
glTexImage2D(GL_TEXTURE_CUBE_MAP_NEGATIVE_Y, 0, GL_RGBA, width, height, 0,
    format, GL_UNSIGNED_BYTE, data4);
glTexImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_Z, 0, GL_RGBA, width, height, 0,
    format, GL_UNSIGNED_BYTE, data5);
glTexImage2D(GL_TEXTURE_CUBE_MAP_NEGATIVE_Z, 0, GL_RGBA, width, height, 0,
    format, GL_UNSIGNED_BYTE, data6);

glGenerateMipmap(GL_TEXTURE_CUBE_MAP);
glTextParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR);

// And of course, after you are all done using the textures...
glDeleteTextures(1, &mHandle);

When specifying your texture coordinates, you will then use sets of 3 coordinates instead of sets of 2. In a simple cube, you point to the 8 corners using normalized vectors. If N = 1.0 / sqrt(3.0) then one corner would be N, N, N; another would be N, N, -N; etc.

like image 137
TheBuzzSaw Avatar answered Nov 03 '22 00:11

TheBuzzSaw


  1. You need to define which orientation you want on each face (and that will change which texture coordinates are put on each vertex)
  2. You need to duplicate the vertex positions as the same cube corner will have different texture coordinates depending on which face it is part of
  3. if you want the full texture on each face, then the texture coordinates are (0, 0) (0, 1) (1, 1) (1, 0). How you map them to the specific vertices (the 24 of them, 4 per face) depends on the orientation you want.
like image 31
Bahbar Avatar answered Nov 02 '22 23:11

Bahbar


For me, it's easier to consider your verticies as width = x, height = y and depth = z. Then it's a simple matter of getting the 6 faces.

float vertices[] = { -x, -y, -z, // 0
                              x, -y, -z, // 1
                              x,  y, -z, // 2
                             -x,  y, -z, // 3
                             -x, -y,  z, // 4
                              x, -y,  z, // 5
                              x,  y,  z, // 6
                             -x,  y,  z// 7
        };  

For example the front face of your cube will have a positive depth (this cube's center is at 0,0,0 from the verticies that you've given), now since there are 8 points with 4 positive depths, your front face is 4,5,6,7, this is going from -x,-y anti clockwise to -x,y.

Ok, so your back face is all negative depth or -z so it's simply 0,1,2,3.

See the picture? Your left face is all negative width or -x so 0,3,4,7 and your right face is positive x so 1,2,5,6.

I'll let you figure out the top and bottom of the cube.

like image 21
Joe Avatar answered Nov 02 '22 22:11

Joe


Your vertex array only describes 2 sides of a cube, but for arguments sake, say vertices[0] - vertices[3] describe 1 side then your texture coordinates may be:

float texCoords[] = { 0.0, 0.0,  //bottom left of texture
                      1.0, 0.0,  //bottom right "    "
                      1.0, 1.0,  //top right    "    "
                      0.0, 1.0   //top left     "    "
                    };

You can use those coordinates for texturing each subsequent side with the entire texture.

like image 27
Brett Avatar answered Nov 02 '22 22:11

Brett