c++ - iluminacion - primitivas opengl
¿Por qué mi color desaparece cuando habilito la iluminación en OpenGL? (2)
Cuando la iluminación está habilitada, el color de un vértice no se determina a partir del color establecido por glColor
o glColorPointer
, sino por los colores del material configurados actualmente combinados con los colores de las luces utilizando los cálculos de iluminación.
Por lo tanto, para cambiar el color de un objeto, debe cambiar la configuración del material (que por defecto es un material gris difuso) antes de renderizar, utilizando las funciones glMaterial
. Hay esencialmente un color de material correspondiente para cada uno de los diferentes colores claros ( GL_DIFFUSE
, ...) junto con algunas propiedades adicionales para aproximar los materiales emisores de luz ( GL_EMISSION
) y controlar la aspereza del material ( GL_SHININESS
). Lea algún material introductorio sobre las características de iluminación de OpenGL para comprender su funcionamiento.
Lo que puede hacer para adaptar rápidamente su código de la coloración normal a la iluminación (o para habilitar las propiedades del material por vértice) es usar material de color. Al invocar glEnable(GL_COLOR_MATERIAL)
y establecer una asignación adecuada con glColorMaterial
, puede configurar OpenGL para cambiar un color de material específico, siempre que cambie el color de vértice actual (utilizando glColor
o glColorPointer
).
Estoy desarrollando una aplicación de gráficos en C ++ con OpenGL API y GLUT.
Para agregar iluminación, hice los siguientes cambios en mi matriz de modelos de vista:
glEnable(GL_LIGHTING);
glEnable(GL_LIGHT0);
// Create light components.
GLfloat ambientLight[] = { 0.2f, 0.2f, 0.2f, 1.0f };
GLfloat diffuseLight[] = { 0.8f, 0.8f, 0.8, 1.0f };
GLfloat specularLight[] = { 0.5f, 0.5f, 0.5f, 1.0f };
GLfloat position[] = { 0.0f, 0.0f, 0.0f, 1.0f };
// Assign created components to GL_LIGHT0.
glLightfv(GL_LIGHT0, GL_AMBIENT, ambientLight);
glLightfv(GL_LIGHT0, GL_DIFFUSE, diffuseLight);
glLightfv(GL_LIGHT0, GL_SPECULAR, specularLight);
glLightfv(GL_LIGHT0, GL_POSITION, position);
La iluminación funciona en gran medida, creo, pero los colores de mis objetos desaparecen. Todo lo que veo es una silueta en blanco y negro de mi figura general.
Me preguntaba por qué es esto?
Pruebe glEnable(GL_COLOR_MATERIAL)
.
Ver Falla común de OpenGL # 14 :
- Cuidado con el material de color
La característica de material de color de OpenGL proporciona una forma menos costosa de cambiar los parámetros del material. Con el material de color habilitado, los colores del material rastrean el color actual. Esto significa que en lugar de utilizar la rutina relativamente costosa
glMaterialfv
, puede usar la rutinaglColor3f
.Aquí hay un ejemplo que utiliza la función de material de color para cambiar el color difuso de cada vértice de un triángulo:
glColorMaterial(GL_FRONT, GL_DIFFUSE); glEnable(GL_COLOR_MATERIAL); glBegin(GL_TRIANGLES); glColor3f(0.2, 0.5, 0.8); glVertex3f(1.0, 0.0, 0.0); glColor3f(0.3, 0.5, 0.6); glVertex3f(0.0, 0.0, 0.0); glColor3f(0.4, 0.2, 0.2); glVertex3f(1.0, 1.0, 0.0); glEnd();
Considere la secuencia de código más costosa que se necesita si
glMaterialfv
se usa explícitamente:
GLfloat d1[] = { 0.2, 0.5, 0.8, 1.0 }; GLfloat d2[] = { 0.3, 0.5, 0.6, 1.0 }; GLfloat d3[] = { 0.4, 0.2, 0.2, 1.0 }; glBegin(GL_TRIANGLES); glMaterialfv(GL_FRONT,GL_DIFFUSE,d1); glVertex3f(1.0, 0.0, 0.0); glMaterialfv(GL_FRONT,GL_DIFFUSE,d2); glVertex3f(0.0, 0.0, 0.0); glMaterialfv(GL_FRONT,GL_DIFFUSE,d3); glVertex3f(1.0, 1.0, 0.0); glEnd();
Si está renderizando objetos que requieren frecuentes cambios simples de material, intente utilizar el modo de material de color. Sin embargo, hay una falla común al habilitar el modo de material de color. Cuando el material de color está habilitado, OpenGL cambia inmediatamente los colores del material controlados por el estado del material de color. Considere la siguiente pieza de código para inicializar un nuevo contexto de creación de OpenGL:
GLfloat a[] = { 0.1, 0.1, 0.1, 1.0 }; glColor4f(1.0, 1.0, 1.0, 1.0); glMaterialfv(GL_FRONT, GL_AMBIENT, a); glEnable(GL_COLOR_MATERIAL); /* WARNING: Ambient and diffuse material latch immediately to the current color. */ glColorMaterial(GL_FRONT, GL_DIFFUSE); glColor3f(0.3, 0.5, 0.6);
¿Qué estado tendrán los colores del material frontal difuso y difuso después de ejecutar el fragmento de código anterior? Si bien el programador puede haber tenido la intención de que el estado del material ambiental sea
(0.1, 0.1, 0.1, 1.0)
y el estado del material difuso sea(0.3, 0.5, 0.6, 1.0)
, eso no es exactamente lo que sucede.El estado del material difuso resultante es lo que el programador pretendía, pero el estado del material ambiental resultante es bastante inesperado
(1.0, 1.0, 1.0, 1.0)
. ¿Cómo ocurrió eso? Bueno, recuerde que el modo de material de color comienza inmediatamente a rastrear el color actual cuando está habilitado. El valor inicial para la configuración del material de color esGL_FRONT_AND_BACK
yGL_AMBIENT_AND_DIFFUSE
(¡probablemente no lo que esperaba!).Como la habilitación del modo material de color comienza inmediatamente a rastrear el color actual, tanto el estado del material ambiental como el difuso se actualizan para que sean
(1.0, 1.0, 1.0, 1.0)
. Tenga en cuenta que el efecto de la inicialglMaterialfv
se pierde. A continuación, el estado del material de color se actualiza para cambiar el material difuso frontal. Por último, la invocaciónglColor3f
cambia el material difuso a(0.3, 0.5, 0.6, 1.0)
. El estado del material ambiental termina siendo(1.0, 1.0, 1.0, 1.0)
.El problema en el fragmento de código anterior es que el modo de material de color está habilitado antes de llamar a
glColorMaterial
. El modo de material de color es muy efectivo para cambios de material simples y eficientes, pero para evitar el peligro anterior, siempre tenga cuidado de configurarglColorMaterial
antes de habilitarGL_COLOR_MATERIAL
.