OpenGL中立方体的纹理坐标是什么?

5

我有一个定义为:

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

我有一个大小为128x128的图片,我想要它被简单地绘制在立方体的6个面上,除此之外不需要其他内容。那么纹理坐标是什么?我需要实际的数值。

这是绘制代码:

// 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);

这是索引数组:
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


               };  

我不确定是否需要使用索引数组来查找纹理坐标。请注意,我提供的立方体顶点数组是使用索引数组表示立方体的最有效方法。立方体可以完美绘制,但纹理不能。只有一面显示正确的图片,其他面则混乱不堪。我使用了在各种在线教程中描述的关于纹理的方法,但它并没有起作用。


1
你可能也应该发布你的绘图代码... - ltjax
在上述信息的基础上,我们需要多少个纹理坐标才是技术上正确的?所谓纹理坐标是指纹理坐标数组中类似1,0这样的二维点。 - ace
5个回答

9
你需要的是一个立方体贴图。在OpenGL中,你可以同时定义六个纹理(分别代表立方体的六个面),并使用3D纹理坐标来映射它们,而不是通常的2D纹理坐标。对于一个简单的立方体,纹理坐标将与顶点的法向量相同。(如果你只会以这种方式给平面立方体贴图,你也可以在顶点着色器中合并法向量和纹理坐标!)立方体贴图比尝试将相同的纹理应用于重复的四边形更为简单(额外的不必要的绘制步骤)。
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);

在指定纹理坐标时,您将使用一组3个坐标而不是一组2个坐标。在简单的立方体中,您可以使用规范化向量来指向8个角落。如果N = 1.0 / sqrt(3.0),则一个角落将是N,N,N;另一个角落将是N,N,-N;以此类推。


立方体贴图纹理坐标不需要被标准化。 - Tara

4
  1. 您需要定义每个面的方向(这将更改放置在每个顶点上的纹理坐标)。
  2. 您需要复制顶点位置,因为同一立方体角落会根据其所属的面而具有不同的纹理坐标。
  3. 如果您想在每个面上使用完整的纹理,则纹理坐标为(0,0)(0,1)(1,1)(1,0)。如何将它们映射到特定的顶点(24个,每个面4个)取决于您想要的方向。

3

对我来说,更容易将你的顶点视为宽度 = x,高度 = y和深度 = z。然后只需获取6个面即可。

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

例如,你的立方体前面的深度值为正数(这个立方体的中心点在0,0,0,基于你所给定的顶点),由于有8个点的深度值为正,因此你的前面是4、5、6、7这四个点,从-x,-y逆时针排列到-x,y。
好的,那么你的后面则是所有深度值为负数或者-z轴,因此它就是0、1、2、3这四个点。
看到图片了吗?你的左面是所有宽度值为负数或者-x,所以它是0、3、4、7这四个点,而右面则是正的x,因此它是1、2、5、6这四个点。
剩下的顶部和底部就留给你自己去思考了。

这些是纹理坐标还是顶点的索引? - sdasdadas
这些是顶点坐标,他在大量编辑后没有更新问题。纹理坐标相当简单,因为他在每个面上使用了128x128的图像,所以对于每个面,您都在映射整个图像,即每个面的纹理坐标为(0,0),(0,128),(128,128),(128,0)。 - Joe

2

您的顶点数组只描述了一个立方体的两个面,但是为了论证,假设vertices[0] - vertices[3]描述了一个面,则您的纹理坐标可能如下:

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     "    "
                    };

您可以使用这些坐标,将每个后续的侧面与整个纹理进行贴图。

0
为了渲染一个天空盒(立方体贴图),下面的着色器对我很有效:
Cubemap vertexshader::
        attribute vec4 a_position;             
        varying vec3 v_cubemapTexture;          
        vec3 texture_pos;                           
        uniform vec3 u_cubeCenterPt;            
        uniform mat4 mvp;                       
        void main(void)                     
        {                                       
         gl_Position = mvp * a_position;        
         texture_pos = vec3(a_position.x - u_cubeCenterPt.x, a_position.y - u_cubeCenterPt.y, a_position.z - u_cubeCenterPt.z);
         v_cubemapTexture = normalize(texture_pos.xyz); 
        }                                       

Cubemap fragmentshader::
        precision highp float;                                              
        varying vec3 v_cubemapTexture;                                      
        uniform samplerCube cubeMapTextureSample;                           
        void main(void)                                                 
        {                                                                   
          gl_FragColor = textureCube(cubeMapTextureSample, v_cubemapTexture);  
        }

希望它有用...


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接