问题
I'm developing a version of the Frogger game for a University project, and we got to the light and materials part. The problem I have is: when I set the materials for the frog, it applies them to all other objects that are drawn. How do I make it so that it only applies to the frog? If I disable GL_COLOR_MATERIAL after the draw or after the material properties have been set, everything becomes red.
void Frog::draw(void)
{
Vector3 _pos = Entity::getPosition();
glPushMatrix();
glEnable(GL_COLOR_MATERIAL);
GLfloat greenEmissiveMaterial[] = {1.0, 0.0, 0.0};
glColorMaterial(GL_FRONT, GL_AMBIENT_AND_DIFFUSE);
GLfloat mat_ambient[] = {0.7, 0.0, 0.0, 1.0};
GLfloat mat_diffuse[] = { 0.7, 0.0, 0.0, 1.0 };
GLfloat mat_specular[] = { 0.0, 0.0, 0.0, 0.0 };
GLfloat mat_shininess[] = {1.8 };
glColor3f(1.0, 0.0, 0.0);
glMaterialfv(GL_FRONT, GL_AMBIENT, mat_ambient);
glMaterialfv(GL_FRONT, GL_DIFFUSE, mat_diffuse);
glMaterialfv(GL_FRONT, GL_SPECULAR, mat_specular);
glMaterialfv(GL_FRONT, GL_SHININESS, mat_shininess);
glDisable(GL_COLOR_MATERIAL);
glScalef(0.1, 0.1, 0.1);
glTranslatef( _pos.getX()*U , _pos.getY()*U , 1 );
//CORPO
glPushMatrix();
glColor3f(0.0, 1.0, 0.0);
glutSolidSphere(0.5,50,50);
glPopMatrix();
glPushMatrix();
glColor3f(0.0, 1.0, 0.0);
glTranslatef(0.0, 0.5, 0.0);
glutSolidSphere(0.3,50,50);
glPopMatrix();
glPopMatrix();
}
回答1:
Enabling the state GL_COLOR_MATERIAL
causes the material color to track the current color for the face you specify in a call to glColorMaterial (...)
. In other words, while GL_COLOR_MATERIAL
is enabled and glColorMaterial(GL_FRONT, GL_AMBIENT_AND_DIFFUSE)
has been set, the value of GL_AMBIENT
and GL_DIFFUSE
are determined exclusively by the current color for the front-face.
Thus, the the following call:
glColor3f (1.0f, 0.0f, 0.0f);
Is effectively equivalent to this in your software:
glColor3f (1.0f, 0.0f, 0.0f); // Set the "current" color
GLfloat red [3] = { 1.0f, 0.0f, 0.0f };
glMaterialfv (GL_FRONT, GL_AMBIENT_AND_DIFFUSE, red);
You can see that you have changed the value of GL_AMBIENT
and GL_DIFFUSE
to red. And you also tried to change the ambient / diffuse material color manually while that state was enabled in your original code, which is not going to do anything.
The behavior above is described in more detail here:
Name
glColorMaterial — cause a material color to track the current color
C Specification
void glColorMaterial( GLenum face, GLenum mode);
Description
glColorMaterial
specifies which material parameters track the current color. WhenGL_COLOR_MATERIAL
is enabled, the material parameter or parameters specified by mode, of the material or materials specified by face, track the current color at all times.To enable and disable
GL_COLOR_MATERIAL
, callglEnable
andglDisable
with argumentGL_COLOR_MATERIAL
.GL_COLOR_MATERIAL
is initially disabled.
If you want to stop tracking the current color and use the values in mat_ambient
and mat_diffuse
, then you should add the following code sometime after you disable GL_COLOR_MATERIAL
:
glMaterialfv(GL_FRONT, GL_AMBIENT, mat_ambient);
glMaterialfv(GL_FRONT, GL_DIFFUSE, mat_diffuse);
来源:https://stackoverflow.com/questions/26638039/glenablegl-color-material-applying-to-all-drawn-objects