En el modelo de iluminación de OpenGL, la
luz de una escena proviene de varias fuentes de luz que pueden apagarse o
encenderse individualmente. Las luces pueden iluminar la escena desde una
dirección o posición particular, o bien de forma general (luz ambiente).
En OpenGL las fuentes de luz sólo tienen
efecto cuando hay superficies que absorben o reflejan la luz. Cada superficie
se asume que está compuesta de un material con distintas propiedades. Un
material puede emitir su propia luz (como los focos de un coche), puede
reflejar la luz que le llega en todas las direcciones (reflexión difusa) o
parte de esa luz en una dirección preferente generando un brillo (reflexión
especular).
De esta forma, OpenGL divide la iluminación
en cuatro componentes independientes: emitida, ambiente, difusa y especular.
Los pasos a seguir para añadir iluminación
a una escena son los siguientes:
1. 1.
Definir los vectores normales para cada vértice de todos los objetos
2. 2.
Crear, seleccionar y colocar una o más fuentes de luz
3. 3.
Crear y seleccionar el modelo de iluminación
4. 4.
Definir las propiedades del material de todos los objetos de la escena
Definición de los vectores normales
Para aplicar un modelo de iluminación (como
se ha visto en apartados anteriores) es necesario definir los vectores normales
de los objetos que forman parte de la escena para determinar su orientación con
respecto a las fuentes de luz.
La librería
auxiliar de OpenGL define un conjunto de funciones para la definición de
primitivas básicas mediante polígonos, que ya incorporan las normales de sus
vértices. Entre estas funciones se encuentran las siguientes.
void auxSolidSphere (GLdouble radius);
void auxSolidCube (GLdouble
size);
void auxSolidBox (GLdouble
width, GLdouble heigth, GLdouble depth);
void auxSolidTorus
(GLdouble innerRadius, GLdouble outerRadius);
void auxSolidCylinder
(GLdouble radius, GLdouble heigth);
void auxSolidIcosahedron
(GLdouble radius);
void auxSolidOctahedron
(GLdouble radius);
void auxSolidTetrahedron
(GLdouble radius);
void auxSolidDodecahedron
(GLdouble radius);
void auxSolidCone (GLdouble
radius, GLdouble heigth);
Sin embargo, si no se utilizan estas
primitivas básicas, al definir el objeto será necesario especificar las
normales para los distintos vértices que lo componen. En este caso, se
utilizará la función glNormal para
definir la normal de cada vértice y posteriormente la función glVertex para asignar la normal actual a
dicho vértice. Debido a que a menudo cada vértice tiene una normal diferente,
será necesario realizar una serie de llamadas alternativas de la forma
siguiente:
glBegin (GL_POLYGON);
glNormal3fv(n0);
glVertex3fv(v0);
glNormal3fv(n1);
glVertex3fv(v1);
glNormal3fv(n2);
glVertex3fv(v2);
glNormal3fv(n3);
glVertex3fv(v3);
glEnd();
2. Creación de las
fuentes de luz
Las fuentes de luz en OpenGL tienen una
serie de propiedades tales como: el color, la posición y su dirección. La
función utilizada para especificar dichas propiedades es glLight*.
La sintaxis de este comando es la
siguiente:
void glLight{if}[v](GLenum light, GLenum pname, TYPE param);
De esta forma se crea la fuente de luz que
indica el parámetro light, el cual
puede recibir los valores GL_LIGHT0,
GL_LIGHT1, … , GL_LIGHT7 (ocho fuentes de luz como máximo en la definición
estándar de la librería). Las características de la luz se especifican en el
parámetro pname utilizando las
constantes que se muestran en la tabla adjunta. Finalmente, el argumento param indica los valores de la
característica fijada en pname.
Nombre del parámetro
|
Valor por defecto
|
Significado
|
GL_AMBIENT
|
(0.0, 0.0, 0.0, 1.0)
|
intensidad ambiente RGBA de la luz
|
GL_DIFFUSE
|
(1.0, 1.0, 1.0, 1.0)
|
intensidad difusa RGBA de la luz
|
GL_SPECULAR
|
(1.0, 1.0, 1.0, 1.0)
|
intensidad especular RGBA de la luz
|
GL_POSITION
|
(0.0, 0.0, 1.0, 0.0)
|
posición (x,y,z,w) de la luz
|
GL_SPOT_DIRECTION
|
(0.0, 0.0, -1.0)
|
dirección (x,y,z) del foco de luz
|
GL_SPOT_EXPONENT
|
0.0
|
exponente del foco de luz
|
GL_SPOT_CUTOFF
|
180.0
|
ángulo del foco de luz
|
GL_CONSTANT_ATTENUATION
|
1.0
|
factor de atenuación constante
|
GL_LINEAR_ATTENUATION
|
0.0
|
factor de atenuación lineal
|
GL_QUADRATIC_ATTENUATION
|
0.0
|
factor de atenuación cuadrático
|
Nota: Los valores por defecto de GL_DIFFUSE y GL_SPECULAR se aplican sólo a GL_LIGTH0.
Para otras fuentes de luz, los valores por defecto son (0.0, 0.0, 0.0, 1.0) para
ambos casos.
Ejemplo de utilización del comando glLight*:
GLfloat light_ambient [] = { 0.0, 0.0, 0.0, 1.0 };
GLfloat light_diffuse [] = { 1.0, 1.0, 1.0, 1.0 };
GLfloat light_specular [] = { 1.0, 1.0, 1.0, 1.0 };
GLfloat light_position [] = { 1.0, 1.0, 1.0, 0.0 };
glLightfv(GL_LIGHT0, GL_AMBIENT, light_ambient);
glLightfv(GL_LIGHT0, GL_DIFFUSE, light_diffuse);
glLightfv(GL_LIGHT0, GL_SPECULAR, light_specular);
glLightfv(GL_LIGHT0, GL_POSITION, light_position);
Una vez creada la fuente de luz es
necesario activar primero la iluminación de la escena (en caso contrario los
objetos se visualizan únicamente con el color activo, sin incluir los efectos
de luz, ni el tipo de material) y posteriormente cada una de las fuentes de luz
que la iluminan. La función encargada de realizar dicha tarea es glEnable.
glEnable(GL_LIGHTING); {Activar el modelo
de iluminación}
glEnable(GL_LIGHT0); {Activar la fuente de
luz 0}
Para desactivar la iluminación debe
utilizarse la función glDisable con
el argumento GL_LIGHTING. De igual forma apagaremos cada una de las fuentes de
luz con la misma función utilizando como argumento la luz que se desea apagar.
Color
El color de la fuente de luz se indica
mediante sus componentes ambiente, difusa y especular. El significado asociado
con cada uno de ellos es el siguiente:
· · Ambiente. Indica la aportación a la iluminación
ambiente de la escena
· · Difusa. Determina el color de la fuente de luz
· · Especular. Define el color del brillo especular que
produce la fuente de luz
Posición
En OpenGL pueden utilizarse dos tipos de
fuentes de luz, dependiendo de como se define su posición en el espacio:
· Direccionales. (x,
y, z) indica el vector de dirección y w es cero. La luz se localiza en el infinito
· Posicionales. (x,
y, z, w) indican la posición en coordenadas homogéneas. La luz se encuentra en la escena
Por tanto, la componente homogénea w
determina el tipo de luz (direccional si w=0, posicional si w=1), mientras que
las coordenadas x, y, z determinan la posición o dirección a la fuente de luz.
Hay que tener en cuenta que en OpenGL la posición o dirección de una fuente de
luz recibe el mismo tratamiento que la posición de una primitiva geométrica, es
decir, una fuente de luz esta sujeta a las mismas transformaciones que una
primitiva de acuerdo con la matriz de
modelo / vista (GL_MODELVIEW)
Atenuación
En el mundo real, la intensidad de
iluminación de las luces decrece a medida que aumenta la distancia a las
mismas. En OpenGL se puede obtener este efecto para las luces posicionales
definiendo los parámetros de atenuación
constante (Kc), lineal
(Kl) y cuadrática (Kq).
La ecuación utilizada es la siguiente:
factor de atenuación = 1 / (Kc +
Kl*d + Kq*d2)
Focos de luz
Las fuentes de luz posicionales en
principio irradian luz en todas las direcciones. Sin embargo, estas luces
pueden convertirse en focos o luces de teatro restringiendo la forma de la luz
emitida .
Para definir una luz focal es necesario
indicar la dirección a la que apunta el foco (GL_SPOT_DIRECTION), el ángulo que define el cono con respecto a la
dirección del foco (GL_SPOT_CUTTOFF)
y el grado de concentración de la luz (GL_SPOT_EXPONENT).
3. Selección del
modelo de iluminación
El modelo de iluminación de OpenGL queda
definido por tres componentes:
· La intensidad de la luz ambiente global
· La posición local o infinita del observador
· La forma de iluminar los polígonos (si se iluminan una o las dos caras
de los polígonos)
Para determinar la intensidad de la luz
ambiente que no proviene de ninguna fuente de luz en particular, sino que es
inherente a la escena, se utiliza la función glLightModel* con un parámetro GL_LIGHT_MODEL_AMBIENT:
GLfloat lmodel_ambient [] = { 0.2, 0.2,
0.2, 1.0 };
glLightModelfv(GL_LIGHT_MODEL_AMBIENT,
lmodel_ambient);
La posición del observador afecta a los
cálculos de la iluminación especular, y por defecto se sitúa en el infinito,
por lo que la dirección entre los vértices a iluminar y el observador es la
misma para todos los objetos de la escena. Por el contrario, si se establece su
posición local en la escena, las direcciones varían para los objetos de la
escena y la iluminación tiene un coste mayor. La función que permite cambiar el
observador y colocarlo local es la siguiente:
glLightModeli(GL_LIGHT_MODEL_LOCAL_VIEWER, GL_TRUE);
Esta función coloca el punto de vista para
la iluminación en (0, 0, 0). Para volver a colocar el observador en el infinito
basta con utilizar la misma función dando como segundo argumento GL_FALSE.
4. Definición de
las propiedades del material
La forma en que la luz incide sobre las
superficies de los objetos depende de las propiedades del material de los
mismos. En OpenGL se definen estas propiedades mediante la función glMaterial*, cuya sintaxis es la
siguiente:
void glMaterial{if}[v](GLenum face, GLenum pname, TYPE param);
El primer argumento determina la cara del
objeto donde se aplica el material, y puede tomar los valores GL_FRONT, GL_BACK o GL_FRONT_AND_BACK. El siguiente argumento indica la propiedad del
material que va a fijarse (sus posibles valores se muestran en la tabla
adjunta). Finalmente, el argumento param
permite asignar los valores a la característica indicada en pname.
Nombre del parámetro
|
Valor por defecto
|
Significado
|
GL_AMBIENT
|
(0.2, 0.2, 0.2, 1.0)
|
color ambiente del material
|
GL_DIFFUSE
|
(0.8, 0.8, 0.8, 1.0)
|
color difuso del material
|
GL_AMBIENT_AND_DIFFUSE
|
color ambiente y difuso del material
|
|
GL_SPECULAR
|
(0.0, 0.0, 0.0, 1.0)
|
color especular del material
|
GL_SHININESS
|
0.0
|
exponente especular
|
GL_EMISSION
|
(0.0, 0.0, 0.0, 1.0)
|
color de emisión del material
|
GL_COLOR_INDEXES
|
(0, 1, 1)
|
índices de color ambiente, difuso y especular
|
Reflexión ambiente y difusa
La reflexión difusa determina el color del
objeto, y la reflexión ambiente la forma en que el objeto redistribuye la luz
ambiente que recibe. Los objetos del mundo real suelen tener el mismo color de
reflexión ambiente y difusa.
Reflexión especular
La componente de reflexión especular define
el color de los brillos del objeto, cuyo tamaño se controla con el parámetro GL_SHININESS.
Emisión
OpenGL permite asignar a los objetos un color de
emisión para que parezca que dichos objetos emiten luz de ese color. De esta
forma se pueden simular lámparas y objetos luminosos. Se pueden conseguir
mejores efectos situando fuentes de luz en la misma posición que los.Normal en OpenGl
Una de las caracteristicas que se puede establecer de un vertice es el color, pero podemos establecer otras caracteristicas como coordenada de la textura o la normal que sirve para realizar los calculos de iluminacion resultante. No importa el orden en que se definan las caraceteristicas pero siempre se hara antes de definir el vertice.
glColor3f(1.0, 0.3, 0.4); //color del vertice
glNormal3f(1.0, 0.0, 0.0); //Normal del vertice
glTextCoord2f(0.0, 1.0); //Coordenada de la textura
glVertex3f (1.0, 3.2, 3.6); //vertice
El vector normal se utiliza para calcular la incidencia de la luz sobre el vertice, si el vector normal no es unitario el vertice estara sobreiluminado (mayor que 1) o infraluminado (menor que 1).
Es muy importante que para cada vertice se defina la normal, ya que OpenGL no asigna la normal a partir de la orientacion primitiva. De lo contrario utilizara como normal al ultima normal establecida.
ejemplos de fuentes de luz
Programa
Iluminacion
ejemplo 1
#include <GL/glut.h>
float escala=0.2;
float angX=0.0f,angY=0.0f;
int ResX=800,ResY=600;
enum{EJE=2};
float angB=0.0f,angC=0.0f,angDE=0.0f;
float aceX=0.0f,aceY=-0.0001f;
float velX=0.001f,velY=0.0f;
float posX=0.0f,posY=10.0f;
//Definición del modelo de una luz
GLfloat light_Ambient [4] = { 0.2, 0.2, 0.2, 1.0};
GLfloat light_Diffuse [4] = { 1.0, 1.0, 1.0, 1.0};
GLfloat light_Position [4] = {20.0, 15.0, 10.0, 1.0};
//Definición de las caracteristicas opticas del material: coeficientes de reflexión
GLfloat material [4] = {1.0f, 0.2f, 0.2f, 1.0f };
GLfloat RedMaterial [4] = {1.0, 0.0, 0.0, 1.0 };
GLfloat GreenMaterial [4] = {0.0, 1.0, 0.0, 1.0 };
GLfloat BlueMaterial [4] = {0.0, 0.0, 1.0, 1.0 };
GLfloat WhiteMaterial [4] = {1.0, 1.0, 1.0, 1.0 };
GLfloat BlackMaterial [4] = {0.0, 0.0, 0.0, 1.0 };
GLfloat GrayMaterial [4] = {0.6, 0.6, 0.6, 1.0 };
void luces(void){
glEnable (GL_LIGHTING);
glEnable (GL_LIGHT0);
glLightfv(GL_LIGHT0, GL_AMBIENT, light_Ambient );
glLightfv(GL_LIGHT0, GL_DIFFUSE, light_Diffuse );
glLightfv(GL_LIGHT0, GL_POSITION, light_Position );
}
void EjesReferencia()
{
glNewList(1,GL_COMPILE);
glBegin (GL_LINES);
glMaterialfv(GL_FRONT, GL_AMBIENT_AND_DIFFUSE, RedMaterial );
glVertex3f ( 0.0, 0.0, 0.0);
glVertex3f (20.0, 0.0, 0.0);
glMaterialfv(GL_FRONT, GL_AMBIENT_AND_DIFFUSE, GreenMaterial );
glVertex3f ( 0.0, 0.0, 0.0);
glVertex3f ( 0.0,20.0, 0.0);
glMaterialfv(GL_FRONT, GL_AMBIENT_AND_DIFFUSE, WhiteMaterial );
glVertex3f ( 0.0, 0.0, 0.0);
glVertex3f ( 0.0, 0.0,20.0);
glEnd();
glEndList();
}
void pEJE(){
glNewList(EJE,GL_COMPILE);
glPushMatrix();
glutSolidSphere(1.0f,50,50);
glPopMatrix();
glEndList();
}
void RenderScene(void){
glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT);
glClearColor( 0.2f, 0.6f, 0.2f, 1.0f );
//AJUSTANDO LA CÁMARA
glLoadIdentity( );
glTranslatef(0.0f,0.0f,-5.0f);
glRotatef(angY,1.0f,0.0f,0.0f);
glRotatef(angX,0.0f,1.0f,0.0f);
//EJES DE REFERENCIA
glLineWidth(5);
glCallList(1);
glPushMatrix();
glScalef(escala,escala,escala);
//glTranslatef(1.0f,1.0f,1.0f);
glMaterialfv(GL_FRONT, GL_AMBIENT_AND_DIFFUSE, RedMaterial );
glPushMatrix();
glTranslatef(posX,posY,0.0f);
glCallList(EJE);
glPopMatrix();
//glFlush();
glutSwapBuffers();
}
void raton(int x, int y){
angX=(float)x;
angY=(float)y;
}
void idle(void){
velY+=aceY; posY+=velY;
velX+=aceX; posX+=velX;
if(posY<0.0f){posY=0.0f; velY*=-0.8f;
if(velY<0.01f){velX=0.0f; velY=0.0f;}
}
glutPostRedisplay();
}
int main(int a, char *b[]){
glutInit(&a,b);
glutInitDisplayMode(GLUT_RGB | GLUT_DOUBLE | GLUT_DEPTH);
glutInitWindowSize(ResX,ResY);
glutInitWindowPosition(100,100);
glutCreateWindow("PELOTA QUE REBOTA");
glutDisplayFunc(RenderScene);
glutKeyboardFunc(teclado);
glutPassiveMotionFunc(raton);
glutIdleFunc(idle);
//OPENGL
glViewport( 0, 0, ResX, ResY );
glMatrixMode( GL_PROJECTION );
glLoadIdentity( );
glFrustum(-(float)ResX/ResY, (float)ResX/ResY, -1.0, 1.0, 2, 10000.0);
glMatrixMode( GL_MODELVIEW );
glLoadIdentity( );
glEnable(GL_DEPTH_TEST);
glEnable(GL_LIGHTING);
glEnable(GL_LIGHT0);
glShadeModel(GL_SMOOTH);
luces();
EjesReferencia();
pEJE();
glutMainLoop();
return 0;
}
ejemplo 2
ejemplo 1
#include <GL/glut.h>
float escala=0.2;
float angX=0.0f,angY=0.0f;
int ResX=800,ResY=600;
enum{EJE=2};
float angB=0.0f,angC=0.0f,angDE=0.0f;
float aceX=0.0f,aceY=-0.0001f;
float velX=0.001f,velY=0.0f;
float posX=0.0f,posY=10.0f;
//Definición del modelo de una luz
GLfloat light_Ambient [4] = { 0.2, 0.2, 0.2, 1.0};
GLfloat light_Diffuse [4] = { 1.0, 1.0, 1.0, 1.0};
GLfloat light_Position [4] = {20.0, 15.0, 10.0, 1.0};
//Definición de las caracteristicas opticas del material: coeficientes de reflexión
GLfloat material [4] = {1.0f, 0.2f, 0.2f, 1.0f };
GLfloat RedMaterial [4] = {1.0, 0.0, 0.0, 1.0 };
GLfloat GreenMaterial [4] = {0.0, 1.0, 0.0, 1.0 };
GLfloat BlueMaterial [4] = {0.0, 0.0, 1.0, 1.0 };
GLfloat WhiteMaterial [4] = {1.0, 1.0, 1.0, 1.0 };
GLfloat BlackMaterial [4] = {0.0, 0.0, 0.0, 1.0 };
GLfloat GrayMaterial [4] = {0.6, 0.6, 0.6, 1.0 };
void luces(void){
glEnable (GL_LIGHTING);
glEnable (GL_LIGHT0);
glLightfv(GL_LIGHT0, GL_AMBIENT, light_Ambient );
glLightfv(GL_LIGHT0, GL_DIFFUSE, light_Diffuse );
glLightfv(GL_LIGHT0, GL_POSITION, light_Position );
}
void EjesReferencia()
{
glNewList(1,GL_COMPILE);
glBegin (GL_LINES);
glMaterialfv(GL_FRONT, GL_AMBIENT_AND_DIFFUSE, RedMaterial );
glVertex3f ( 0.0, 0.0, 0.0);
glVertex3f (20.0, 0.0, 0.0);
glMaterialfv(GL_FRONT, GL_AMBIENT_AND_DIFFUSE, GreenMaterial );
glVertex3f ( 0.0, 0.0, 0.0);
glVertex3f ( 0.0,20.0, 0.0);
glMaterialfv(GL_FRONT, GL_AMBIENT_AND_DIFFUSE, WhiteMaterial );
glVertex3f ( 0.0, 0.0, 0.0);
glVertex3f ( 0.0, 0.0,20.0);
glEnd();
glEndList();
}
void pEJE(){
glNewList(EJE,GL_COMPILE);
glPushMatrix();
glutSolidSphere(1.0f,50,50);
glPopMatrix();
glEndList();
}
void RenderScene(void){
glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT);
glClearColor( 0.2f, 0.6f, 0.2f, 1.0f );
//AJUSTANDO LA CÁMARA
glLoadIdentity( );
glTranslatef(0.0f,0.0f,-5.0f);
glRotatef(angY,1.0f,0.0f,0.0f);
glRotatef(angX,0.0f,1.0f,0.0f);
//EJES DE REFERENCIA
glLineWidth(5);
glCallList(1);
glPushMatrix();
glScalef(escala,escala,escala);
//glTranslatef(1.0f,1.0f,1.0f);
glMaterialfv(GL_FRONT, GL_AMBIENT_AND_DIFFUSE, RedMaterial );
glPushMatrix();
glTranslatef(posX,posY,0.0f);
glCallList(EJE);
glPopMatrix();
//glFlush();
glutSwapBuffers();
}
void raton(int x, int y){
angX=(float)x;
angY=(float)y;
}
void idle(void){
velY+=aceY; posY+=velY;
velX+=aceX; posX+=velX;
if(posY<0.0f){posY=0.0f; velY*=-0.8f;
if(velY<0.01f){velX=0.0f; velY=0.0f;}
}
glutPostRedisplay();
}
int main(int a, char *b[]){
glutInit(&a,b);
glutInitDisplayMode(GLUT_RGB | GLUT_DOUBLE | GLUT_DEPTH);
glutInitWindowSize(ResX,ResY);
glutInitWindowPosition(100,100);
glutCreateWindow("PELOTA QUE REBOTA");
glutDisplayFunc(RenderScene);
glutKeyboardFunc(teclado);
glutPassiveMotionFunc(raton);
glutIdleFunc(idle);
//OPENGL
glViewport( 0, 0, ResX, ResY );
glMatrixMode( GL_PROJECTION );
glLoadIdentity( );
glFrustum(-(float)ResX/ResY, (float)ResX/ResY, -1.0, 1.0, 2, 10000.0);
glMatrixMode( GL_MODELVIEW );
glLoadIdentity( );
glEnable(GL_DEPTH_TEST);
glEnable(GL_LIGHTING);
glEnable(GL_LIGHT0);
glShadeModel(GL_SMOOTH);
luces();
EjesReferencia();
pEJE();
glutMainLoop();
return 0;
}
ejemplo 2
#include <windows.h>
#include <gl\gl.h>
#include <gl\glu.h>
#include "glut.h"
#pragma comment(lib, "opengl32.lib")
#pragma comment(lib, "glut32.lib")
#pragma comment(lib, "glu32.lib")
GLfloat angulo=0;
const GLfloat plasticoNegroAmb[4] = {0.0f,0.0f,0.0f,1.0f};
const GLfloat plasticoNegroDif[4] = {0.01f,0.01f,0.01f,1.0f};
const GLfloat plasticoNegroSpe[4] = {0.5f,0.5f,0.5f,1.0f};
GLfloat plasticoNegroShi = 32.0f;
const GLfloat oroAmb[4] = {0.24725f,0.2245f,0.0645f,1.0f};
const GLfloat oroDif[4] = {0.34615f,0.3143f,0.0903f,1.0f};
const GLfloat oroSpe[4] = {0.797357f,0.723991f,0.208006f,1.0f};
GLfloat oroShi = 128.0f;
const GLfloat esmeraldaAmb[4] = {0.0215f,0.1745f,0.0215f,0.55f};
const GLfloat esmeraldaDif[4] = {0.07568f,0.61424f,0.07568f,0.55f};
const GLfloat esmeraldaSpe[4] = {0.633f,0.727811f,0.633f,0.55};
GLfloat esmeraldaShi = 76.8f;
const GLfloat cromoAmb[4] = {0.25f,0.25f,0.25f,1.0f};
const GLfloat cromoDif[4] = {0.4f,0.4f,0.4f,1.0f};
const GLfloat cromoSpe[4] = {0.774597f,0.774597f,0.774597f,1.0f};
GLfloat cromoShi = 76.8f;
const GLfloat totalAmb[4] = {1.0f,1.0f,1.0f,1.0f};
const GLfloat totalDif[4] = {1.0f,1.0f,1.0f,1.0f};
const GLfloat totalSpe[4] = {1.0f,1.0f,1.0f,1.0f};
GLfloat totalShi = 128.0f;
const GLfloat nadaAmb[4] = {0.0f,0.0f,0.0f,1.0f};
const GLfloat nadaDif[4] = {0.0f,0.0f,0.0f,1.0f};
const GLfloat nadaSpe[4] = {0.0f,0.0f,0.0f,1.0f};
GLfloat nadaShi = 1.0f;
const GLfloat difusionAmb[4] = {0.0f,0.0f,0.0f,1.0f};
const GLfloat difusionDif[4] = {1.0f,1.0f,1.0f,1.0f};
const GLfloat difusionSpe[4] = {0.0f,0.0f,0.0f,1.0f};
GLfloat difusionShi = 1.0f;
const GLfloat ambienteAmb[4] = {1.0f,1.0f,1.0f,1.0f};
const GLfloat ambienteDif[4] = {0.0f,0.0f,0.0f,1.0f};
const GLfloat ambienteSpe[4] = {0.0f,0.0f,0.0f,1.0f};
GLfloat ambienteShi = 1.0f;
const GLfloat especularAmb[4] = {0.0f,0.0f,0.0f,1.0f};
const GLfloat especularDif[4] = {0.0f,0.0f,0.0f,1.0f};
const GLfloat especularSpe[4] = {1.0f,1.0f,1.0f,1.0f};
GLfloat especularShi = 40.0f;
void render(void)
{
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glLoadIdentity();
gluLookAt(0.0f,10.0f,40.0f, 0.0f,0.0f,0.0f, 0.0f,1.0f,0.0f);
//Plastico Negro
glMaterialfv(GL_FRONT, GL_AMBIENT, plasticoNegroAmb);
glMaterialfv(GL_FRONT, GL_DIFFUSE, plasticoNegroDif);
glMaterialfv(GL_FRONT, GL_SPECULAR, plasticoNegroSpe);
glMaterialf(GL_FRONT, GL_SHININESS, plasticoNegroShi);
glPushMatrix();
glTranslatef(-10.0f,10.0f,0.0f);
glRotatef(angulo,0.0f,1.0f,0.0f);
glRotatef(15.0f,1.0f,0.0f,0.0f);
glutSolidTeapot(3.0f);
glPopMatrix();
//Oro
glMaterialfv(GL_FRONT, GL_AMBIENT, oroAmb);
glMaterialfv(GL_FRONT, GL_DIFFUSE, oroDif);
glMaterialfv(GL_FRONT, GL_SPECULAR, oroSpe);
glMaterialf(GL_FRONT, GL_SHININESS, oroShi);
glPushMatrix();
glTranslatef(-10.0f,0.0f,0.0f);
glRotatef(angulo,0.0f,1.0f,0.0f);
glRotatef(15.0f,1.0f,0.0f,0.0f);
glutSolidTeapot(3.0f);
glPopMatrix();
//Esmeralda
glMaterialfv(GL_FRONT, GL_AMBIENT, esmeraldaAmb);
glMaterialfv(GL_FRONT, GL_DIFFUSE, esmeraldaDif);
glMaterialfv(GL_FRONT, GL_SPECULAR, esmeraldaSpe);
glMaterialf(GL_FRONT, GL_SHININESS, esmeraldaShi);
glPushMatrix();
glTranslatef(-10.0f,-10.0f,0.0f);
glRotatef(angulo,0.0f,1.0f,0.0f);
glRotatef(15.0f,1.0f,0.0f,0.0f);
glutSolidTeapot(3.0f);
glPopMatrix();
//Cromo
glMaterialfv(GL_FRONT, GL_AMBIENT, cromoAmb);
glMaterialfv(GL_FRONT, GL_DIFFUSE, cromoDif);
glMaterialfv(GL_FRONT, GL_SPECULAR, cromoSpe);
glMaterialf(GL_FRONT, GL_SHININESS, cromoShi);
glPushMatrix();
glTranslatef(0.0f,10.0f,0.0f);
glRotatef(angulo,0.0f,1.0f,0.0f);
glRotatef(15.0f,1.0f,0.0f,0.0f);
glutSolidTeapot(3.0f);
glPopMatrix();
//Total
glMaterialfv(GL_FRONT, GL_AMBIENT, totalAmb);
glMaterialfv(GL_FRONT, GL_DIFFUSE, totalDif);
glMaterialfv(GL_FRONT, GL_SPECULAR, totalSpe);
glMaterialf(GL_FRONT, GL_SHININESS, totalShi);
glPushMatrix();
glTranslatef(0.0f,0.0f,0.0f);
glRotatef(angulo,0.0f,1.0f,0.0f);
glRotatef(15.0f,1.0f,0.0f,0.0f);
glutSolidTeapot(3.0f);
glPopMatrix();
//Nada
glMaterialfv(GL_FRONT, GL_AMBIENT, nadaAmb);
glMaterialfv(GL_FRONT, GL_DIFFUSE, nadaDif);
glMaterialfv(GL_FRONT, GL_SPECULAR, nadaSpe);
glMaterialf(GL_FRONT, GL_SHININESS, nadaShi);
glPushMatrix();
glTranslatef(0.0f,-10.0f,0.0f);
glRotatef(angulo,0.0f,1.0f,0.0f);
glRotatef(15.0f,1.0f,0.0f,0.0f);
glutSolidTeapot(3.0f);
glPopMatrix();
//Solo Difusion
glMaterialfv(GL_FRONT, GL_AMBIENT, difusionAmb);
glMaterialfv(GL_FRONT, GL_DIFFUSE, difusionDif);
glMaterialfv(GL_FRONT, GL_SPECULAR, difusionSpe);
glMaterialf(GL_FRONT, GL_SHININESS, difusionShi);
glPushMatrix();
glTranslatef(10.0f,10.0f,0.0f);
glRotatef(angulo,0.0f,1.0f,0.0f);
glRotatef(15.0f,1.0f,0.0f,0.0f);
glutSolidTeapot(3.0f);
glPopMatrix();
//Solo Ambiente
glMaterialfv(GL_FRONT, GL_AMBIENT, ambienteAmb);
glMaterialfv(GL_FRONT, GL_DIFFUSE, ambienteDif);
glMaterialfv(GL_FRONT, GL_SPECULAR, ambienteSpe);
glMaterialf(GL_FRONT, GL_SHININESS, ambienteShi);
glPushMatrix();
glTranslatef(10.0f,0.0f,0.0f);
glRotatef(angulo,0.0f,1.0f,0.0f);
glRotatef(15.0f,1.0f,0.0f,0.0f);
glutSolidTeapot(3.0f);
glPopMatrix();
//Solo Especular
glMaterialfv(GL_FRONT, GL_AMBIENT, especularAmb);
glMaterialfv(GL_FRONT, GL_DIFFUSE, especularDif);
glMaterialfv(GL_FRONT, GL_SPECULAR, especularSpe);
glMaterialf(GL_FRONT, GL_SHININESS, especularShi);
glPushMatrix();
glTranslatef(10.0f,-10.0f,0.0f);
glRotatef(angulo,0.0f,1.0f,0.0f);
glRotatef(15.0f,1.0f,0.0f,0.0f);
glutSolidTeapot(3.0f);
glPopMatrix();
glutSwapBuffers(); //Se hace el cambio de
buffer
}
void Redimensionar(GLsizei ancho, GLsizei alto)
{
if(alto ==
0)
{
alto =
1;
}
glViewport(0, 0, ancho, alto);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
if(ancho>alto)
{
gluPerspective(45.0f,ancho/alto,1,150.0f);
}
else
{
gluPerspective(45.0f,alto/ancho,1,150.0f);
}
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
}
void InicializarGL(void)
{
glClearColor(0.5f,0.5f,0.5f,1.0f);
//Parametros de
la luz 0
GLfloat
ambientlight[]
= {0.5f ,0.5f ,0.5f
,1.0f};
GLfloat
difuselight[]
= {1.0f ,1.0f ,1.0f
,1.0f};
GLfloat
specularlight[]
= {1.0f ,1.0f ,1.0f
,1.0f};
GLfloat
lightposition[]
= {20.0f,100.0f,10.0f,0.0f};
//Se setean los
parametros
glLightfv(GL_LIGHT0,GL_AMBIENT,ambientlight);
glLightfv(GL_LIGHT0,GL_DIFFUSE,difuselight);
glLightfv(GL_LIGHT0,GL_SPECULAR,specularlight);
glLightfv(GL_LIGHT0,GL_POSITION,lightposition);
glEnable(GL_DEPTH_TEST); //Test
de profundidad
glEnable(GL_LIGHTING);
//se activa la iluminacion
glEnable(GL_LIGHT0);
//se activa la luz 0 que previamente se habia seteado
glEnable(GL_COLOR_MATERIAL); //Se
activa lo materiales de color
glColorMaterial(GL_BACK,GL_AMBIENT_AND_DIFFUSE);
//Se desean de tipo ambiente y difusión (tambien incluyen specular
}
void animacionGL(void)
{
angulo+=0.2f;
glutPostRedisplay();
}
void main(void)
{
glutInitWindowPosition(120,120);
glutInitWindowSize(400,400);
glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGB); //En este punto se
hace la solicitud de doble buffer
glutCreateWindow("Superficies
en OpenGL");
InicializarGL();
glutIdleFunc(animacionGL);
glutDisplayFunc(render);
glutReshapeFunc(Redimensionar);
glutMainLoop();
}
No hay comentarios:
Publicar un comentario