/* LAMPARA MOVIL SOBRE UN PISO [4]
NO SE ESPECIFICAN LAS PROPIEDADES DEL MATERIAL
USO DE <<< glColor*() >>>
{{{
definiciOn de las luces
float diffuse_light [] = {0.4f, 0.4f, 0.4f, 1.0f}; <<<gris>>>
float specular_light [] = {1.0f, 1.0f, 0.0f, 1.0f}; <<<amarillo>>>
fijar las caracterIsticas de las luces
glLightfv (GL_LIGHT0, GL_DIFFUSE, diffuse_light);
glLightfv (GL_LIGHT0, GL_SPECULAR, specular_light);
no es necesario definir materiales
glEnable (GL_COLOR_MATERIAL);
glColorMaterial (GL_FRONT, GL_DIFFUSE);
glColorMaterial (GL_FRONT, GL_SPECULAR);
glEnable(GL_LIGHT0)
dibujo de la escena
glColor3f (1.0f, 1.0f, 1.0f); auxSolidCube (5.0f);
}}}
*/
#include <GL/glut.h>
#include <unistd.h>
// ---------- [M]aterial ________ [L]uz --------------------------------------
// -------------------------- [D]ifuso ___ [E]specular ___ [A]mbiental
// ___ LUZ ___
// D ===> (color de la luz -lAmpara-)
// E ===> (luz que viene de una direcciOn y rebota en un objeto en una determinada direcciOn)
// A ===> (contribuciOn de la lAmpara a la luz del ambiente)
// LD = LE ==> Para lograr un efecto suficientemente realista
GLfloat LD[] = {0.0, 0.0, 1.0, 1.0}, LE[] = {0.0, 0.0, 1.0, 1.0}, LA[] = {0.0, 0.0, 0.1, 1.0};
// ___ MATERIAL ___ ===> se refiere a la reflexiOn del material
// D ===> color de base que reflejaría el objeto si incidiera sobre El una luz pura blanca
// E ===> "puntitos brillantes" de los objetos iluminados
// A ===> como refleja la luz que viene de la escena y no de la fuente -lAmpara-
GLfloat MD[] = {0.0, 0.0, 1.0, 1.0}, ME[] = {0.0, 0.0, 1.0, 1.0}, MA[] = {0.0, 0.0, 0.1, 1.0};
//GLfloat MD [] = {0.7,0.7,0.7,1.0}, ME [] = {1.0,1.0,1.0,1.0}, MA [] = {0.0,0.0,0.0,1.0};
// MB ===> (BRILLO) #de puntos luminosos y su concentración (con valor alto podrIa ser el metal p.e.)
GLfloat MB[] = {50}; // 0% al 120% -tamanio del punto de mAxima reflexiOn-
// M_EM color de la luz que emite el objeto
GLfloat M_EM[] = {0.0, 0.0, 1.0, 1.0}; // definido en la funciOn "Piso"
GLfloat normalTodo [] = {0.0, 0.0, 1.0};
GLfloat L0Pos [] = {-10, -10, 1, 1}; // Posicion (x=0,y=0,z=0) Tipo(w=1) ... w=1(posicional) o 2(direccional)
GLfloat L0DIR [] = {0, 0, -1}; // Direccion hacia donde apunta la luz
float Luz_Foco [] = {1.0, 1.0, 1.0, 1.0}; // Luz mOvil
float PosX = -10.0; float PosY = -10.0; float PosZ = 1; // Posicion del foco
float DIM = 10;
/*
void PintaEjes()
{
glBegin(GL_LINES);
glColor3f(1,0,0); glVertex3f(-DIM, 0, 0); glVertex3f(DIM, 0, 0); // X
glColor3f(0,1,0); glVertex3f(0, -DIM, 0); glVertex3f(0, DIM, 0); // Y
glColor3f(0,0,1); glVertex3f(0, 0, -DIM); glVertex3f(0, 0, DIM); // Z
glEnd();
glPushMatrix();glColor3f(1,0,0); glTranslatef(DIM, 0.0f, 0.0f); glutWireSphere(0.20, 20, 20);glPopMatrix();
glPushMatrix();glColor3f(0,1,0); glTranslatef(0.0f, DIM, 0.0f); glutWireSphere(0.20, 20, 20);glPopMatrix();
glPushMatrix();glColor3f(0,0,1); glTranslatef(0.0f, 0.0f, DIM); glutWireSphere(0.20, 20, 20);glPopMatrix();
}
void Gradua ( )
{
int k=0, x1,y1,x2,y2;
glBegin(GL_LINES);
glColor3f(1,0,0); for(k=1; k<DIM*2; k++) { glVertex3f(-10+k, 0.2, 0); glVertex3f(-10+k, -0.2, 0); }
glColor3f(0,1,0); for(k=1; k<DIM*2; k++) { glVertex3f(0.2, -10+k, 0); glVertex3f(-0.2, -10+k, 0); }
glColor3f(0,1,0); for(k=1; k<DIM*2; k++) { glVertex3f(0.2, 0, -10+k); glVertex3f(-0.2, 0, -10+k); }
glEnd();
}
void Rejilla()
{
int k=0;
glColor3f(1,1,1); glLineWidth(5);
for(k=0; k<DIM*2+1; k++)
{ glBegin(GL_LINES); glVertex3f(-DIM+k, -DIM, 0); glVertex3f(-DIM+k, DIM, 0); glEnd(); }
for(k=0; k<DIM*2+1; k++)
{ glBegin(GL_LINES); glVertex3f(-DIM, -DIM+k, 0); glVertex3f(DIM, -DIM+k, 0); glEnd(); }
glLineWidth(1);
}
*/
void Piso()
{
int y=0, x=0;
glColor3f(1, 1, 0);
for(y=10; y>-10; y--)
for(x=-10; x<10; x++)
{
glBegin(GL_QUADS);glNormal3fv(normalTodo);
glVertex3f(x, y, 0);
glVertex3f(x, y-1, 0);
glVertex3f(x+1, y-1, 0);
glVertex3f(x+1, y, 0);
glEnd();
}
}
void Cubo() { glColor3f(1.0, 1.0, 0.0); glutWireCube(0.5); } // el cubo es solo para saber donde está el centro
void display(void)
{
GLfloat L0Pos [] = {PosX, PosY, PosZ, 1};
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
//PintaEjes( ); Gradua( );
glPushMatrix();
Piso(); Cubo();
glPushMatrix();
glColor4fv(Luz_Foco); glTranslatef(PosX, PosY, PosZ); glutSolidCone(0.25, 1.0, 7,7);
glPopMatrix();
glLightfv(GL_LIGHT0, GL_POSITION, L0Pos);
glutSwapBuffers();
}
void Inicio(void)
{
glClearColor(0.0,0.0,0.0,0.0);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
glOrtho(-DIM-5, DIM+5, -DIM-5, DIM+5, -DIM-5, DIM+5);
glMatrixMode(GL_MODELVIEW);
gluLookAt(-1,-1,1, 2,2,-1, 0,0,1);
glDepthFunc(GL_LEQUAL); glEnable(GL_DEPTH_TEST); glClearDepth(1.0);
// PROPIEDADES DE LA LUZ
glLightfv(GL_LIGHT0, GL_AMBIENT, LA);
glLightfv(GL_LIGHT0, GL_DIFFUSE, LD);
glLightfv(GL_LIGHT0, GL_SPECULAR, LE);
//glLightfv(GL_LIGHT0, GL_POSITION, L0Pos);
glLightf (GL_LIGHT0, GL_SHININESS, 20);
// ATENUACION CON LA DISTANCIA
glLightf (GL_LIGHT0, GL_CONSTANT_ATTENUATION, 0.1); // AtenuaciOn de la luz conforme se hacerca
glLightf (GL_LIGHT0, GL_LINEAR_ATTENUATION, 0.1f);
glLightf (GL_LIGHT0, GL_QUADRATIC_ATTENUATION, 0.1f);
// AREA DE COBERTURA (Area que abarca el haz de luz que surge de la fuente)
glLightf (GL_LIGHT0, GL_SPOT_CUTOFF, 30); // Angulo en grados -0 a 90- (mitad)
glLightfv(GL_LIGHT0, GL_SPOT_DIRECTION, L0DIR); // Hacia donde apunta (propio de Posicional focal)
// pErdida de intensidad de la luz a medida que nos alejamos del centro del cono
glLightf (GL_LIGHT0, GL_SPOT_EXPONENT, 20); // entre 0 y 120
glEnable (GL_COLOR_MATERIAL); // Conservar el color de los poligonos
glColorMaterial (GL_FRONT, GL_DIFFUSE);
glColorMaterial (GL_FRONT, GL_SPECULAR);
glColorMaterial (GL_FRONT, GL_AMBIENT);
glLightModeli(GL_LIGHT_MODEL_TWO_SIDE, GL_FALSE); // Sin luz las caras traseras (al inicio)
glShadeModel( GL_SMOOTH );
glEnable(GL_SMOOTH); // Mostrar el degradado mas suave
glEnable ( GL_NORMALIZE ); // Garantiza un vector normal unitario
glEnable(GL_LIGHTING); glEnable(GL_LIGHT0); // activaciOn
}
void mouse(int Boton, int Estado, int x, int y)
{
int Ang = 0.0;
switch (Boton)
{
case GLUT_LEFT_BUTTON: if (Estado == GLUT_DOWN) PosZ += 1; break;
case GLUT_RIGHT_BUTTON: if (Estado == GLUT_DOWN) PosZ -= 1; break;
default: break;
}
if (PosZ > 10) PosZ = 10;
if (PosZ < 0) PosZ = 0;
glutPostRedisplay();
}
void Flechas(int Tecla, int x, int y)
{
switch (Tecla)
{
case GLUT_KEY_UP: { PosY += 1; if (PosY > 10) PosY= 10; break; }
case GLUT_KEY_DOWN: { PosY -= 1; if (PosY < -10) PosY=-10; break; }
case GLUT_KEY_RIGHT: { PosX += 1; if (PosX > 10) PosX= 10; break; }
case GLUT_KEY_LEFT: { PosX -= 1; if (PosX < -10) PosX=-10; break; }
}
glutPostRedisplay();
}
int main(int argc, char** argv)
{
glutInit(&argc, argv);
glutInitDisplayMode(GLUT_SINGLE | GLUT_RGB | GLUT_DEPTH);
glutInitWindowSize (800, 600);
glutInitWindowPosition (100, 100);
glutCreateWindow ("Control de las luces ... ");
Inicio();
glutDisplayFunc(display);
glutMouseFunc(mouse);
glutSpecialFunc(Flechas);
glutMainLoop();
return 0;
}