【问题标题】:What are the texture coordinates for a cube in OpenGL?OpenGL中立方体的纹理坐标是什么?
【发布时间】:2011-06-26 09:27:01
【问题描述】:

我有一个立方体定义为:

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


               };  

我不确定是否需要索引数组来查找 tex 坐标。请注意,我给出的立方体顶点数组是使用索引数组最有效的立方体表示。立方体绘制完美,但纹理不完美。只有一面显示正确的图片,但其他面都搞砸了。我使用了各种在线纹理教程中描述的方法,但它不起作用。

【问题讨论】:

  • 你应该也发布你的绘图代码......
  • 根据上述信息,我们需要多少技术上正确的 tex 坐标? tex 坐标是指 tex 坐标数组中的 2d 点,例如 1,0。

标签: opengl


【解决方案1】:

您正在寻找的是cube map。在 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;等等

【讨论】:

  • 立方体贴图纹理坐标不需要归一化。
【解决方案2】:
  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),现在因为有 4 个正深度的 8 个点,你的正面face 是 4,5,6,7,这是从 -x,-y 逆时针到 -x,y。

    好的,所以你的背面都是负深度或 -z 所以它只是 0,1,2,3。

    看到图片了吗?你的左脸都是负宽度或 -x 所以 0,3,4,7 而你的右脸是正 x 所以 1,2,5,6。

    我会让你弄清楚立方体的顶部和底部。

    【讨论】:

    • 这些是纹理坐标还是只是顶点的索引?
    • 这些是顶点坐标,在他大量编辑后我没有更新问题。 tex 坐标相当微不足道,因为他在每张脸上使用 128x128 图像,所以对于每张脸,您正在映射整个图像,即每张脸 tex 坐标 (0,0), (0,128), (128, 128), (128 ,0)
    【解决方案4】:

    您的顶点数组仅描述了立方体的 2 个面,但为了论证,假设 vertices[0] - vertices[3] 描述 1 个面,那么您的纹理坐标可能是:

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

    您可以使用这些坐标为每个后续边使用整个纹理进行纹理化。

    【讨论】:

      【解决方案5】:

      要渲染天空盒(立方体贴图),下面的着色器适用于我:

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

      希望有用...

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2020-08-19
        • 1970-01-01
        • 2013-02-10
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多