Para usar la luz en OpengGL es necesario activarla.
Ademas de ello OpenGL estable poder usar ocho luces y hay que activar la que vayamos a usar.
Pero ademas luz cuenta con distintas propiedades. Hablemos un poco acerca la luz y sus tres componentes que son: ambiental, difusa y especular. En OpenGL estas cuentan con tres componentes de color (RGB) y un valor alpha (trasparencias)
Esta luz no proviene de ningún punto en especifico, si no que incide y rebota desde varios puntos.
Esta es el brillo o reflejo que produce el objeto al ser visto por una persona desde el punto de refracción.
Ademas de los componentes de la luz también existen tres formas en que los rayos de luz se emiten.
La luz se emite desde un punto en todas direcciones, ejemplo una fogata.
La luz sale desde un punto y crea una cono de iluminación, esta puede necesitar algunos parámetros extra como: un angulo y una distancia de atenuación. Ejemplo una lampara de mano.
La funcion encargada de definir la luces es:
glLightFv(GLenum luz, GLenum, Parametros, GLfloat Color[4]);
Luz: Desde GL_LIGHT0 hasta GL_LIGHT7
Parametros:
GL_AMBIENT //Color del ambiente
GL_DIFUSSE //Color de la luz reflejada
GL_SPECULAR //Color del brillo
GL_POSITION //Posición de la luz, puede ser de dos tipos
-w = 0.0f //Luz Direccional
-w = 1.0f //Luz Puntual o focal
GL_SPOT_CUTOFF //Angulo de abertura desde 0 hasta 90 grados
GL_SPOT_EXPONENT //Perdida de intensidad al centro desde 0 hasta 128
GL_CONSTANTA_ATTENUATION //Por defecto 1. (0.0 - 1.0)
GL_LINEAR_ATTENUATION //Por defecto 1. (0.0 - 1.0)
GL_QUADRATIC_ATTENUATION //Por defecto 1. (0.0 - 1.0)
Retomare el código de la lección 03. Vamos a agregar una luz direccional. No cambia mucho con respecto a la puntual o focal. Primero agregar algunas variables que servirán para incrementar los parámetros de la luz y mover la posición de esta.
//Definimos algunas variables
GLfloat ambiente = 0.7f;
GLfloat difusa = 0.7f;
GLfloat especular = 1.0f;
GLfloat luzPos_x = 1.0f;
GLfloat luzPos_y = 1.0f;
GLfloat luzPos_z = 1.0f;
//Inicia los Valores de OPengl
void iniciar(){
glClearColor(0.0f, 0.0f, 0.0f, 0.0f);
//Activar parametor del Buffer de Profundidad
glClearDepth(1.0);
glDepthFunc(GL_LEQUAL);
glEnable(GL_DEPTH_TEST);
//Activar cortado de caras
glFrontFace(GL_CW);
glCullFace(GL_BACK);
glEnable(GL_CULL_FACE);
//Activamos la luz
glEnable(GL_LIGHTING);
glEnable(GL_LIGHT0);
//Tipo de Sombredo
glShadeModel(GL_SMOOTH);
}
En la funcion iniciar() lo unico que hacemos es activar el modo de iluminación y la luz 1.
//Se encarga de dibuja las primitivas y volcar el buffer
void dibuja(){
//Limpia los buffers de color y profundidad
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glLoadIdentity();
gluLookAt(0.0, 3.0, 10.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0);
//Definimos los parametro de la luz
GLfloat luzDifusa[4] = {difusa, difusa, difusa, 1.0f};
GLfloat luzAmbiental[4] = {ambiente, ambiente, ambiente, 1.0f};
GLfloat luzEspecular[4] = {especular, especular, especular, 1.0f};
GLfloat luzPosicion[4] = {luzPos_x, luzPos_y, luzPos_z, 0.0f};
//Luz numero 0
glLightfv(GL_LIGHT0, GL_AMBIENT, luzAmbiental);
glLightfv(GL_LIGHT0, GL_DIFFUSE, luzDifusa);
glLightfv(GL_LIGHT0, GL_SPECULAR, luzEspecular);
glLightfv(GL_LIGHT0, GL_POSITION, luzPosicion);
//Guardamos la matriz
glPushMatrix();
glTranslatef(0.0f, 0.0f, 0.0f);
glutSolidTeapot(1.0f); //Dibujamos la tetera solida
glTranslatef(-3.0f, 0.0f, 0.0f);
.
.
.
glPopMatrix();
//Intercambiamos los buffers
glutSwapBuffers();
}
Por el momento dentro de dibuja() definiré el arreglo que contendrá las variables para las tres propiedades de la luz y una arreglo para la posición de la luz. Notar que el ultimo parámetro de la posición de la luz es 0.0f. Luz direccional.
Luego hay que asignar los arreglos a cada una las distintas propiedades de la luz 0 y la posición de esta.
Por ultimo agregare algunas teteras que serviran de modelo, hay que notar que ahora tiene caras con glutSolidTeapot en vez de glutWireTeapot.
void mostrarValores(){
printf("Luz Ambiental: %f\n", ambiente);
printf("Luz Difusa: %f\n", difusa);
printf("Luz Especular: %f\n\n", especular);
}
void posicionLuzValores(){
printf("Luz Posicion en x: %f\n", luzPos_x);
printf("Luz Posicion en y: %f\n", luzPos_y);
printf("Luz Posicion en z: %f\n\n", luzPos_z);
}
Luego tenemos estas dos funciones que lo único que haces es mostrar los valores actuales de la luz y su posición.
Igual que la vez anterior agregamos algunos eventos de teclado para cambiar los valores de la luz y su posición.
//Incrementa y drecementa los valores para hacer transformacion al presionar las teclas
void teclado(unsigned char tecla, int x, int y){
//Luz ambiente
if(tecla == 'q' || tecla == 'Q'){
ambiente += 0.1f;
mostrarValores();
glutPostRedisplay();
}
else if(tecla == 'w' || tecla == 'W'){
ambiente -= 0.1f;
mostrarValores();
glutPostRedisplay();
}
.
.
.
}
Eso seria todos los cambios dentro del código para esta lección.
(Ejemplo de una luz puntual)
Ahora bien aun falta agregar los materiales al objeto para poder ver los reflejos, pero eso sera el siguiente paso.
Teclas:
q/w: Luz Ambiente
a/s: Lus Difusa
z/x: Luz Especular
e/r: Mover la luz en x
d/f: Mover la luz en y
c/v: Mover la luz en z