还有两种纹理生成模式未介绍,GL_REFLECTION_MAP和GL_NORMAL_MAP,这两种模式需要用到新的纹理目标:立方体贴图。一个立方体贴图被当做一个纹理来看待,它由六个正方形的2D图像(必须是正方形)来组成立方体的六个面。下图展示了cubemap示例的立方体的六个面:

这六个面分别是-X,+X,-Y,+Y,-Z,+Z.然后我们使用GL_REFLECTION_MAP的模式来生成纹理,能够制造一个真实的表面的倒影。
立方体贴图有六个新的值作为参数传给glTexImage2D:
GL_TEXTURE_CUBE_MAP_POSITIVE_X, GL_TEXTURE_CUBE_MAP_NEGATIVE_X,
GL_TEXTURE_CUBE_MAP_POSITIVE_Y,GL_TEXTURE_CUBE_MAP_NEGATIVE_Y,
GL_TEXTURE_CUBE_MAP_POSITIVE_Z,GL_TEXTURE_CUBE_MAP_NEGATIVE_Z.
例如我们要加载正X方向的贴图,如下所示:
glTexImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_X, 0, GL_RGBA, iWidth, iHeight, 0, GL_RGBA, GL_UNSIGNED_BYTE, pImage);
在cubemap示例中,我们把立方体的六个图像的路径保存到一个数组中,然后循环加载这六个面的纹理贴图:
立方体贴图的纹理坐标与一般的3D纹理坐标不同,S,T和R纹理坐标代表着一个从立方体贴图中心出发的有符号向量,这个向量会与立方体的六个面中的一个相交,然后对相交的纹理单元进行采样。
立方体贴图常用于创建一个对周围景象进行反射的物体。下面的代码创建一个天空盒,一个有效的天空盒包含了六个面,从盒子的中心出发朝六个方向看去可以看到六张图像。天空盒是有六个正方形构成的,每个面使用glTexCoord3f来手工设置纹理坐标。
glPushMatrix();
? ? //手动指定纹理坐标
? ? glBegin(GL_QUADS);
? ? ? //-x
? ? ? glTexCoord3f(-1.0f, 1.0f, -1.0f);
? ? ? glVertex3f(-fExtent, fExtent, -fExtent);
? ? ? glTexCoord3f(-1.0f, 1.0f, 1.0f);
? ? ? glVertex3f(-fExtent, fExtent, fExtent);
? ? ? glTexCoord3f(-1.0f, -1.0f, 1.0f);
? ? ? glVertex3f(-fExtent, -fExtent, fExtent);
? ? ? glTexCoord3f(-1.0f, -1.0f, -1.0f);
? ? ? glVertex3f(-fExtent, -fExtent, -fExtent);
?
? ? ? //+x
? ? ? glTexCoord3f(1.0f, -1.0f, -1.0f);
? ? ? glVertex3f(fExtent, -fExtent, -fExtent);
? ? ? glTexCoord3f(1.0f, -1.0f, 1.0f);
? ? ? glVertex3f(fExtent, -fExtent, fExtent);
? ? ? glTexCoord3f(1.0f, 1.0f, 1.0f);
? ? ? glVertex3f(fExtent, fExtent, fExtent);
? ? ? glTexCoord3f(1.0f, 1.0f, -1.0f);
? ? ? glVertex3f(fExtent, fExtent, -fExtent);
?
? ? ? //+y
? ? ? glTexCoord3f(-1.0f, 1.0f, -1.0f);
? ? ? glVertex3f(-fExtent, fExtent, -fExtent);
? ? ? glTexCoord3f(-1.0f, 1.0f, 1.0f);
? ? ? glVertex3f(-fExtent, fExtent, fExtent);
? ? ? glTexCoord3f(1.0f, 1.0f, 1.0f);
? ? ? glVertex3f(fExtent, fExtent, fExtent);
? ? ? glTexCoord3f(1.0f, 1.0f, -1.0f);
? ? ? glVertex3f(fExtent, fExtent, -fExtent);
?
? ? ? //-y
? ? ? glTexCoord3f(1.0f, -1.0f, -1.0f);
? ? ? glVertex3f(fExtent, -fExtent, -fExtent);
? ? ? glTexCoord3f(1.0f, -1.0f, 1.0f);
? ? ? glVertex3f(fExtent, -fExtent, fExtent);
? ? ? glTexCoord3f(-1.0f, -1.0f, 1.0f);
? ? ? glVertex3f(-fExtent, -fExtent, fExtent);
? ? ? glTexCoord3f(-1.0f, -1.0f, -1.0f);
? ? ? glVertex3f(-fExtent, -fExtent, -fExtent);
?
?
? ? ? //-z
? ? ? glTexCoord3f(-1.0f, -1.0f, -1.0f);
? ? ? glVertex3f(-fExtent, -fExtent, -fExtent);
? ? ? glTexCoord3f(1.0f, -1.0f, -1.0f);
? ? ? glVertex3f(fExtent, -fExtent, -fExtent);
? ? ? glTexCoord3f(1.0f, 1.0f, -1.0f);
? ? ? glVertex3f(fExtent, fExtent, -fExtent);
? ? ? glTexCoord3f(-1.0f, 1.0f, -1.0f);
? ? ? glVertex3f(-fExtent, fExtent, -fExtent);
?
? ? ? //+z
? ? ? glTexCoord3f(-1.0f, 1.0f, 1.0f);
? ? ? glVertex3f(-fExtent, fExtent, fExtent);
? ? ? glTexCoord3f(1.0f, 1.0f, 1.0f);
? ? ? glVertex3f(fExtent, fExtent, fExtent);
? ? ? glTexCoord3f(1.0f, -1.0f, 1.0f);
? ? ? glVertex3f(fExtent, -fExtent, fExtent);
? ? ? glTexCoord3f(-1.0f, -1.0f, 1.0f);
? ? ? glVertex3f(-fExtent, -fExtent, fExtent);
? ? glEnd();
? glPopMatrix();
glDisable(GL_TEXTURE_GEN_S);
glDisable(GL_TEXTURE_GEN_T);
glDisable(GL_TEXTURE_GEN_R);
DrawSkyBox();
然后画一个反射周围环境的球体,开启纹理坐标自动生成:
glTexGeni(GL_S, GL_TEXTURE_GEN_MODE, GL_REFLECTION_MAP);
glTexGeni(GL_T, GL_TEXTURE_GEN_MODE, GL_REFLECTION_MAP);
glTexGeni(GL_R, GL_TEXTURE_GEN_MODE, GL_REFLECTION_MAP);
glEnable(