我在使用 opengl 渲染纹理时遇到了一些麻烦。首先我渲染我的纹理,然后我渲染一个正方形。为了设置我的正方形的颜色,我使用glColor3f(1.0f,0.0f,0.0f);
这使正方形变成红色。但是当我的纹理再次被渲染时,它也被渲染为红色。
这里有什么问题?
当您调用时,您正在为所有未来的绘图调用glColor
设置常量颜色。如果您希望它恢复到开始时的状态,则必须在绘制正方形后将其显式设置回来。
通常(取决于纹理环境)顶点颜色和常量颜色在顶点着色期间组合,然后插值,然后在片段着色中与纹理像素颜色相乘。
如果你使用 a glColor3f(1,0,0)
,你最终会将纹理的红色通道乘以 1.0,将绿色和蓝色通道乘以 0.0——所以你只会得到纹理的红色通道。
您需要将常量颜色重置为 1,1,1 才能看到常规纹理颜色。
一般来说,您需要提前设置所有常见的 gl 状态,然后在绘制任何需要不常见更改的内容后“返回”到该状态。这有时被称为“零状态”。您还会注意到,许多性能调整文献建议将具有相似的不常见的非零状态需求的事物组合在一起——这可能会或可能不会产生影响,具体取决于图形驱动程序、硬件等。
这里的“问题”是(a)默认情况下,opengl 使用 GL_MODULATE texenv 模式,因此片段的颜色乘以纹理的颜色来产生最终颜色和(b)openGL 是一个状态机,因此,只要您设置其他颜色,红色就会保持不变。
请注意,在使用光照时,GL_MODULATE 对于将光照计算的结果与纹理颜色相结合非常有用。
如果您只想要纹理,您可以在绘制纹理对象之前指定白色,我们使用另一种纹理环境模式,如 GL_REPLACE:
glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);
查看glTexEnv的手册页以了解该功能以及可用模式和选项的说明。
如果您只想绘制纹理(甚至是光照),如果您只想绘制纹理,则在绘制纹理之前不需要白色。您只需在绘图函数中指定顶点之前的坐标,如下例所示:
void dibujarTexturaIluminacionPlana(GLuint texName){
glShadeModel(GL_FLAT); //Flat model ilumination
glEnable(GL_TEXTURE_2D);
glBindTexture(GL_TEXTURE_2D, texName);
glBegin(GL_TRIANGLES);
for(int i=0; i<caras.size(); i++){
glNormal3f(normales[i].x, normales[i].y, normales[i].z);
glTexCoord2f(cTs[caras[i]._0].x, cTs[caras[i]._0].y);
glVertex3f(vertices[caras[i]._0].x, vertices[caras[i]._0].y ,vertices[caras[i]._0].z);
glTexCoord2f(cTs[caras[i]._1].x, cTs[caras[i]._1].y);
glVertex3f(vertices[caras[i]._1].x, vertices[caras[i]._1].y ,vertices[caras[i]._1].z);
glTexCoord2f(cTs[caras[i]._2].x, cTs[caras[i]._2].y);
glVertex3f(vertices[caras[i]._2].x, vertices[caras[i]._2].y ,vertices[caras[i]._2].z);
}
glEnd();
glFlush();
glDisable(GL_TEXTURE_2D);
}
Wherein caras is "faces", normales is "normal" and vertices is "vertex".
So, if you want draw the texture, only you call the function.
glEnable(GL_LIGHTING);
figuraPerfilCompleto.dibujarTexturaIluminacionPlana2(texturas[0]);
glDisable(GL_LIGHTING);
不需要调用 glTexEnv ...