GL_TEXTURE_GEN_S);
glEnable(GL_TEXTURE_GEN_T);
glEnable(GL_TEXTURE_GEN_R);
为了制造更加真实的反射效果,我们需要考虑照相机的方向。我们可以从照相机类中获得照相机的旋转矩阵,并进行反转,然后在应用立方体纹理贴图之前,先把它乘以纹理矩阵。没有旋转纹理坐标,立方体贴图将无法正确地反射周围的环境(反射的是固定的图像不随着照相机的旋转而变化)。因为gltDrawSphere函数并不影响模型视图矩阵,所以我们可以使矩阵模式为GL_TEXTURE(纹理模式)直到我们画完球体后再恢复到原始状态。代码如下:
效果如下(移动照相机,并旋转可以看到不同的反射面)(code):

现代的OpenGL硬件实现都支持把多个纹理应用到几何图形上。我们可以通过GL_MAX_TEXTURE_UNITS检查有多少个纹理单元是可用的:
GLint iUnits;
glGetIntergv(GL_MAX_TETURE_UNITS, &iUnits);
可用的纹理为从基础的纹理单元(GL_TEXTURE0)到最大的纹理单元(GL_TEXTUREn)(这里的n代表纹理单元的下标)。每个纹理单元有自己的纹理环境状态(即每个纹理单元都可通过glTexEnv设置自己的纹理环境),纹理坐标生成状态(glTexGen),纹理矩阵状态,纹理的启用状态和纹理过滤器等。


纹理结合的过程大致如下:
首先从图形中得到了片段的颜色值作为输入,然后和被应用到图元上的第一个纹理上对应的颜色值进行结合作为输出。把之前的输出作为输入,再与第二个纹理的颜色进行结合,如此循环到最后一个被启用的纹理单元为止。
默认情况下,第一个纹理单元是激活的纹理单元。除了glTexCoord之外的所有纹理命令,都只影响当前激活的???理单元。我们可以通过调用glActiveTexture参数为GL_TEXTUREn来激活相应的纹理单元(纹理的下标是从0开始)。例如:我们激活第二个纹理,并启用2D纹理:
glActiveTexture(GL_TEXTURE1);
glEnable(GL_TEXTURE_2D);
相反地禁用则如下:
glDisable(GL_TEXTURE_2D);
glActiveTexutre(GL_TEXTURE0);
所有的纹理函数调用glTexParameter, glTexEnv,glTexGen,glTexImage和glBindTexture都只对当前激活的纹理单元有效。当图形被渲染时,被启用的纹理单元将被应用。
当我们使用glTexCoord指定纹理坐标的时候,这个纹理坐标是针对GL_TEXTURE0设置的。如果我们想为其他的纹理单元设置纹理坐标可以通过glMultiTexCoord来设置:
glMultiTexCoord1f(GLenum texUnit, GLfloat s);
glMultiTexCoord2f(Glenum texUnit, GLfloat s, GLfloat t);
glMultiTexCoord3f(GLenum texUnit, GLfloat s, GLfloat t, GLfloat r);
其中texUnit为GL_TEXTUREn. 也有相应的不同类型的版本。当然我们也可以用自动生成纹理坐标的方式。
在之前的CUBEMAP例子的基础上做一些更改,我们把cubemap的纹理作为第二个纹理即GL_TEXTURE1。第一个纹理是有污点的纹理。然后,让立方体贴图纹理和这个污点纹理相乘,就能得到如下的效果:

完整代码示例如下:
?
?