lunes, 12 de noviembre de 2012

fuentes de luz en pengl

Iluminación en OpenGL

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
#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