Luz_Lampara_3.c



/*   LAMPARA MOVIL SOBRE UN PISO  [3]
	SE ESPECIFICAN LAS PROPIEDADES DEL MATERIAL
	USO DE <<<   glMaterial*()   >>>
	{{{
		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>>>
		definiciOn de los materiales
			float diffuse_material [] = {1.0f, 1.0f, 1.0f, 1.0f};
			float specular_material [] = {1.0f, 1.0f, 1.0f, 1.0f};
		fijar las caracterIsticas de las luces
			glLightfv (GL_LIGHT0, GL_DIFFUSE, diffuse_light);
			glLightfv (GL_LIGHT0, GL_SPECULAR, specular_light);
		fijar las caracterIsticas del material
			glMaterialfv (GL_FRONT, GL_DIFFUSE, diffuse_material);
			glMaterialfv (GL_FRONT, GL_SPECULAR, specular_material);
		glEnable(GL_LIGHT0)
		dibujo de la escena
			auxSolidCube (5.0f);		OJO ===> NO SE USAN COLORES <<< glColor*() >>>
	}}}
	
*/

#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.1, 0.1, 0.6, 1.0};
		GLfloat LD[] = {1.0, 1.0, 0.0, 1.0}, LE[] = {1.0, 1.0, 0.0, 1.0}, LA[] = {0.1, 0.1, 0.6, 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.1, 0.1, 0.6, 1.0};
		GLfloat MD[] = {1.0, 1.0, 0.0, 1.0}, ME[] = {1.0, 1.0, 0.0, 1.0}, MA[] = {0.1, 0.1, 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-

GLfloat NPiso   [] = {0.0,  0.0, 1.0};			// Normal para el piso
GLfloat NMuro   [] = {-1.0, 0.0, 0.0};			// Normal para los muros

GLfloat L0Pos   [] = {-10, -10, 1, 1};			// Posicion (x=0,y=0,z=0) Tipo(w=1) ... w=1(posicional) o 2(direccional)
GLfloat L0DIRP  [] = {0, 0, -1};				// Direccion hacia donde apunta la luz en el piso
GLfloat L0DIRM  [] = {1, 0,  0};				// Direccion hacia donde apunta la luz en los muros

//float Luz_Foco [] = {0.0, 1.0, 1.0, 0.0};			// Luz mOvil
float PosX = -10.0; float PosY = -10.0; float PosZ = 1;	// Posicion del foco

float DIM = 10;						// N divisiones por cuadrante

void Piso()
{
	int y=0, x=0;
	
	for(y=10; y>-10; y--)
		for(x=-10; x<10; x++)
		{
			glBegin(GL_QUADS);
				glNormal3fv(NPiso);
				glVertex3f(x, y, 0);
				glVertex3f(x, y-1, 0);
				glVertex3f(x+1, y-1, 0);
				glVertex3f(x+1, y, 0);
			glEnd();
		}
}

void Cubo() { glutWireCube(0.5); }

void display(void)
{
	GLfloat L0Pos  [] = {PosX, PosY, PosZ, 1};
	glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
	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,1,0);		// amarillo
	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);

	// 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,	L0DIRP);		// 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
	glMaterialfv(GL_FRONT_AND_BACK, GL_AMBIENT, MA);
	glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, MD);
	glMaterialfv(GL_FRONT_AND_BACK, GL_SPECULAR, ME);
	glMaterialfv(GL_FRONT_AND_BACK, GL_SHININESS, MB);
	glMaterialfv(GL_FRONT_AND_BACK, GL_EMISSION, MB);
	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 ("LAmpara versiOn 3 ... ");
	Inicio();
	glutDisplayFunc(display);
	glutMouseFunc(mouse);
	glutSpecialFunc(Flechas);
	glutMainLoop();
	return 0;
}