前言:我们知道在OpenGL中,图形都是通过一个或多个三角形来绘制的,所以给图形贴纹理,我们就需要把图形拆分为多个三角形,通过三角形的各个顶点位置来算出纹理坐标,有了纹理坐标,我们就可以给图形贴纹理了。
金字塔图形的解析,我们可以分为两部分:
- 底部四边形 = 三角形X + 三角形Y
- 顶点坐标 vApex, 如图所示:
image.png
金字塔每个点的坐标如下:
顶点坐标:
vApex(0.0, 1.0, 0.0)
vBackLeft(-1.0,-1.0,-1.0)
vBackRight(1.0,-1.0,-1.0)
vFrontLeft(-1.0,-1.0,1.0)
vFrontRight(1.0,-1.0,1.0)
三角形X的坐标:
vBackLeft(-1.0,-1.0,-1.0)
vBackRight(1.0,-1.0,-1.0)
vFrontRight(1.0,-1.0,1.0)
三角形Y的坐标:
vFrontLeft(-1.0,-1.0,1.0)
vBackLeft(-1.0,-1.0,-1.0)
vFrontRight(1.0,-1.0,1.0)
纹理坐标:
vApex(0.5, 1.0)
vBackLeft(0.0, 0.0)
vBackRight(1.0, 0.0)
vFrontLeft(0.0, 1.0)
vFrontRight(1.0, 1.0)
给图形设置Mip贴图的方法:
//设置mip贴图基层
glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_BASE_LEVEL,0);
//设置mip贴图最⼤层
glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_BASE_LEVEL,0);
经过Mip贴图的纹理过滤如下图:
image.png
通过以上对图形顶点坐标的理解,我们用隧道案例代码来加以解释:
- 地板floorBatch几何坐标的计算:
image.png
GLfloat z;
floorBatch.Begin(GL_TRIANGLE_STRIP, 28, 1);
//Z表示深度,隧道的深度
for(z = 60.0f; z >= 0.0f; z -=10.0f)
{
floorBatch.MultiTexCoord2f(0, 0.0f, 0.0f);
floorBatch.Vertex3f(-10.0f, -10.0f, z);
floorBatch.MultiTexCoord2f(0, 1.0f, 0.0f);
floorBatch.Vertex3f(10.0f, -10.0f, z);
floorBatch.MultiTexCoord2f(0, 0.0f, 1.0f);
floorBatch.Vertex3f(-10.0f, -10.0f, z - 10.0f);
floorBatch.MultiTexCoord2f(0, 1.0f, 1.0f);
floorBatch.Vertex3f(10.0f, -10.0f, z - 10.0f);
}
floorBatch.End();
- 天花板 ceilingBatch的几何坐标计算:
image.png
ceilingBatch.Begin(GL_TRIANGLE_STRIP, 28, 1);
for(z = 60.0f; z >= 0.0f; z -=10.0f)
{
ceilingBatch.MultiTexCoord2f(0, 0.0f, 1.0f);
ceilingBatch.Vertex3f(-10.0f, 10.0f, z - 10.0f);
ceilingBatch.MultiTexCoord2f(0, 1.0f, 1.0f);
ceilingBatch.Vertex3f(10.0f, 10.0f, z - 10.0f);
ceilingBatch.MultiTexCoord2f(0, 0.0f, 0.0f);
ceilingBatch.Vertex3f(-10.0f, 10.0f, z);
ceilingBatch.MultiTexCoord2f(0, 1.0f, 0.0f);
ceilingBatch.Vertex3f(10.0f, 10.0f, z);
}
ceilingBatch.End();
- 左边墙壁leftWallBatch的几何坐标计算:
image.png
leftWallBatch.Begin(GL_TRIANGLE_STRIP, 28, 1);
for(z = 60.0f; z >= 0.0f; z -=10.0f)
{
leftWallBatch.MultiTexCoord2f(0, 0.0f, 0.0f);
leftWallBatch.Vertex3f(-10.0f, -10.0f, z);
leftWallBatch.MultiTexCoord2f(0, 0.0f, 1.0f);
leftWallBatch.Vertex3f(-10.0f, 10.0f, z);
leftWallBatch.MultiTexCoord2f(0, 1.0f, 0.0f);
leftWallBatch.Vertex3f(-10.0f, -10.0f, z - 10.0f);
leftWallBatch.MultiTexCoord2f(0, 1.0f, 1.0f);
leftWallBatch.Vertex3f(-10.0f, 10.0f, z - 10.0f);
}
leftWallBatch.End();
- 右边rightWallBatch的几何坐标计算:
image.png
rightWallBatch.Begin(GL_TRIANGLE_STRIP, 28, 1);
for(z = 60.0f; z >= 0.0f; z -=10.0f)
{
rightWallBatch.MultiTexCoord2f(0, 0.0f, 0.0f);
rightWallBatch.Vertex3f(10.0f, -10.0f, z);
rightWallBatch.MultiTexCoord2f(0, 0.0f, 1.0f);
rightWallBatch.Vertex3f(10.0f, 10.0f, z);
rightWallBatch.MultiTexCoord2f(0, 1.0f, 0.0f);
rightWallBatch.Vertex3f(10.0f, -10.0f, z - 10.0f);
rightWallBatch.MultiTexCoord2f(0, 1.0f, 1.0f);
rightWallBatch.Vertex3f(10.0f, 10.0f, z - 10.0f);
}
rightWallBatch.End();
总结,通过上面对图形拆解为多个三角形,计算每个顶点的坐标和纹理坐标,我们就可以对图形进行贴纹理,具体代码实现请点这里隧道