Código:
#include <windows.h>
#include <C:\GLUT\include\GL\glut.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <math.h>
//#include <GLut/gutil.h>
//#include <Opengl/gl.h>
static float salto = 0.0, rotar=0;
static float lightAngle = 0.0, lightHeight = 15;
GLfloat angle = -150;
GLfloat angle2 = 30;
int moving, startx, starty;
float c= 0.5;
static GLdouble tamanio = 4.0;
static GLfloat posicionLuz[4];
static GLfloat colorLuz[] = {1, 1, 1, 1.0};
static GLfloat planoPiso[4];
static GLfloat sombraPiso[4][4];
enum {X, Y, Z, W};
enum {A, B, C, D};
char *textura[] = {
"oooooooooooooooo",
"o...............",
"o..xxxxxxxxxxxx.",
"o..xxxxxxxxxxxx.",
"o..xxxxxxxxxxxx.",
"o..xxx..oo..xxx.",
"o..xxx..oo..xxx.",
"o..xxxooooooxxx.",
"o..xxxooooooxxx.",
"o..xxx..oo..xxx.",
"o..xxx..oo..xxx.",
"o..xxxxxxxxxxxx.",
"o..xxxxxxxxxxxx.",
"o..xxxxxxxxxxxx.",
"o...............",
"o...............",
};
void texturaPiso(void)
{
GLubyte floorTexture[16][16][3];
GLubyte *col;
int s, t;
// Crear RGB para textura
col = (GLubyte*) floorTexture;
for (t = 0; t < 16; t++) {
for (s = 0; s < 16; s++) {
if (textura[t][s] == 'x') {
col[0] = 128;
col[1] = 128;
col[2] = 128;
} else if (textura[t][s] == 'o') {
col[0] = 64;
col[1] = 64;
col[2] = 64;
}else {
col[0] =215;
col[1] =215;
col[2] =255;
}
col += 3;
}
}
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
glTexImage2D(GL_TEXTURE_2D, 0, 3, 16, 16, 0,
GL_RGB, GL_UNSIGNED_BYTE, floorTexture);
}
/* Matriz de proyeccion de la sombra */
void shadowMatrix(GLfloat shadowMat[4][4],
GLfloat groundplane[4],
GLfloat lightpos[4])
{
GLfloat dot;
// Producto punto entre vector light position y la normal de ground plane
dot = groundplane[X] * lightpos[X] +
groundplane[Y] * lightpos[Y] +
groundplane[Z] * lightpos[Z] +
groundplane[W] * lightpos[W];
shadowMat[0][0] = dot - lightpos[X] * groundplane[X];
shadowMat[1][0] = 0.f - lightpos[X] * groundplane[Y];
shadowMat[2][0] = 0.f - lightpos[X] * groundplane[Z];
shadowMat[3][0] = 0.f - lightpos[X] * groundplane[W];
shadowMat[X][1] = 0.f - lightpos[Y] * groundplane[X];
shadowMat[1][1] = dot - lightpos[Y] * groundplane[Y];
shadowMat[2][1] = 0.f - lightpos[Y] * groundplane[Z];
shadowMat[3][1] = 0.f - lightpos[Y] * groundplane[W];
shadowMat[X][2] = 0.f - lightpos[Z] * groundplane[X];
shadowMat[1][2] = 0.f - lightpos[Z] * groundplane[Y];
shadowMat[2][2] = dot - lightpos[Z] * groundplane[Z];
shadowMat[3][2] = 0.f - lightpos[Z] * groundplane[W];
shadowMat[X][3] = 0.f - lightpos[W] * groundplane[X];
shadowMat[1][3] = 0.f - lightpos[W] * groundplane[Y];
shadowMat[2][3] = 0.f - lightpos[W] * groundplane[Z];
shadowMat[3][3] = dot - lightpos[W] * groundplane[W];
}
/* Ecuación del plano dados 3 puntos. */
void defPlano(GLfloat plane[4],GLfloat v0[3], GLfloat v1[3], GLfloat v2[3])
{
GLfloat vec0[3], vec1[3];
/* Producto cruz entre 2 vectores. */
vec0[X] = v1[X] - v0[X];
vec0[Y] = v1[Y] - v0[Y];
vec0[Z] = v1[Z] - v0[Z];
vec1[X] = v2[X] - v0[X];
vec1[Y] = v2[Y] - v0[Y];
vec1[Z] = v2[Z] - v0[Z];
/* Encontrar producto cruz para A, B, y C en la ec. del plano */
plane[A] = vec0[Y] * vec1[Z] - vec0[Z] * vec1[Y];
plane[B] = -(vec0[X] * vec1[Z] - vec0[Z] * vec1[X]);
plane[C] = vec0[X] * vec1[Y] - vec0[Y] * vec1[X];
plane[D] = -(plane[A] * v0[X] + plane[B] * v0[Y] + plane[C] * v0[Z]);
}
/**
* Establece el tipo de material a usar, oro en este caso
* @param encendido Para activar/desactivar el uso del material
*/
void aplicarMaterialOro(int encendido)
{
if( encendido == 1 ) {
GLfloat mat_green_ambient[] = { 0.24725,0.1995,0.0745,0.75};//ambiente y la ultima es alfa transaparencia
GLfloat mat_green_diffuse[] = { 0.75164,0.60648,0.22648,0.75};//difuso
GLfloat mat_specular[] = { 0.628281,0.555802,0.366065,0.5};//especular r,g,b y alfa
GLfloat mat_shininess[] = { 0.4*128}; //128 mucho brillo y 0 poco brillo
glMaterialfv(GL_FRONT, GL_SPECULAR, mat_specular); //se aplica solo en la cara frontal gl_front and back
glMaterialfv(GL_FRONT, GL_SHININESS, mat_shininess);
glMaterialfv(GL_FRONT, GL_AMBIENT, mat_green_ambient);
glMaterialfv(GL_FRONT, GL_DIFFUSE, mat_green_diffuse);
}
}
/**
* Establece el tipo de material a usar, latón en este caso
* @param encendido Para activar/desactivar el uso del material
*/
void aplicarMaterialLaton(int encendido) //es color verde esmeralda
{
if(encendido==1) {
//estos primeros son los parametros
GLfloat mat_green_ambient[] = { 0.329412, 0.223529, 0,027451, 0.75};//ambiente y la ultima es alfa transaparencia
GLfloat mat_green_diffuse[] = { 0.780392, 0.568627, 0.113725, 0.75};//difuso
GLfloat mat_specular[] = { 0.992157, 0.941176, 0.807843, 0.5};//especular r,g,b y alfa
GLfloat mat_shininess[] = { 0.21794872*128}; //128 mucho brillo y 0 poco brillo
glMaterialfv(GL_FRONT, GL_SPECULAR, mat_specular); //se aplica solo en la cara frontal gl_front and back
glMaterialfv(GL_FRONT, GL_SHININESS, mat_shininess);
glMaterialfv(GL_FRONT, GL_AMBIENT, mat_green_ambient);
glMaterialfv(GL_FRONT, GL_DIFFUSE, mat_green_diffuse);
}
}
void dibujaObjeto(void)
{
glPushMatrix();
//glRotatef(-rotar, 0, 1,0);
glTranslatef(0.0, salto, 0.0);
glScalef(2,2,2);
glTranslatef( 0, 3.4, -2);
// Cabeza
glPushMatrix();
aplicarMaterialOro(1);
glTranslatef( 0, 2.1, 0);
glScalef( 1, 1.2, 1 );
glutSolidSphere( 0.6, 28, 28 );
glPopMatrix();
// Cuerpo
glPushMatrix();
glTranslatef( 0, 0.2, 0);
glScalef( 1.2, 2.3, 0.8 );
glutSolidSphere( 0.6, 28, 28 );
glPopMatrix();
// Hombro derecho
glPushMatrix();
glTranslatef( 0.55, 1.2, 0);
glutSolidSphere( 0.21, 28, 28 );
glPopMatrix();
// Brazo derecho, vista usuario
glPushMatrix();
aplicarMaterialLaton(1);
glTranslatef( 0.75, 0.73, 0);
glRotatef( -75, 0, 0, 1 );
glScalef( 4, 0.7, 0.7 );
glutSolidCube( 0.28 );
glPopMatrix();
// Union con antebrazo derecho
glPushMatrix();
aplicarMaterialOro(1);
glTranslatef( 0.86, 0.32, 0);
glutSolidSphere( 0.21, 28, 28 );
glPopMatrix();
// Antebrazo derecho
glPushMatrix();
aplicarMaterialLaton(1);
glTranslatef( 0.86, 0.0, 0);
glScalef( 0.65, 2.8, 0.65 );
glutSolidCube( 0.28 );
glPopMatrix();
// Mano derecha
glPushMatrix();
aplicarMaterialOro(1);
glTranslatef( 0.86, -0.38, 0);
glScalef( 1, 2, 1 );
glutSolidSphere( 0.15, 28, 28 );
glPopMatrix();
// Hombro izquierdo ///////////////////////////
glPushMatrix();
glTranslatef( -0.55, 1.2, 0);
glutSolidSphere( 0.21, 28, 28 );
glPopMatrix();
// Brazo izquierdo, vista usuario
glPushMatrix();
aplicarMaterialLaton(1);
glTranslatef( -0.75, 0.73, 0);
glRotatef( 75, 0, 0, 1 );
glScalef( 4, 0.7, 0.7 );
glutSolidCube( 0.28 );
glPopMatrix();
// Union con antebrazo izquierdo
glPushMatrix();
aplicarMaterialOro(1);
glTranslatef( -0.86, 0.32, 0);
glutSolidSphere( 0.21, 28, 28 );
glPopMatrix();
// Antebrazo izquierdo
glPushMatrix();
aplicarMaterialLaton(1);
glTranslatef( -0.86, 0.0, 0);
glScalef( 0.65, 2.8, 0.65 );
glutSolidCube( 0.28 );
glPopMatrix();
// Mano izquierda
glPushMatrix();
aplicarMaterialOro(1);
glTranslatef( -0.86, -0.38, 0);
glScalef( 1, 2, 1 );
glutSolidSphere( 0.15, 28, 28 );
glPopMatrix();
// Pierna izquierda /////////////////////////////
glPushMatrix();
glTranslatef( -0.45, -1, 0);
glutSolidSphere( 0.26, 28, 28 );
glPopMatrix();
// Muslo izquierdo
glPushMatrix();
aplicarMaterialLaton(1);
glTranslatef( -0.56, -1.6, 0);
glRotatef( -6, 0, 0, 1);
glScalef( 0.9, 3.2, 0.9);
glutSolidCube( 0.32 );
glPopMatrix();
// Rodilla
glPushMatrix();
aplicarMaterialOro(1);
glTranslatef( -0.62, -2.2, 0);
glutSolidSphere( 0.23, 28, 28 );
glPopMatrix();
// Pantorrilla izquierda
glPushMatrix();
aplicarMaterialLaton(1);
glTranslatef( -0.62, -2.6, 0);
glScalef( 0.9, 3, 0.9);
glutSolidCube( 0.32 );
glPopMatrix();
// Pie izquierdo
glPushMatrix();
aplicarMaterialOro(1);
glTranslatef( -0.62, -3.35, 0);
glRotatef( 90, 0, 1, 0 );
glRotatef( -90, 1, 0, 0 );
glutSolidCone( 0.32, 0.6, 28, 28 );
glPopMatrix();
// Pierna derecha /////////////////////////////
glPushMatrix();
glTranslatef( 0.45, -1, 0);
glutSolidSphere( 0.26, 28, 28 );
glPopMatrix();
// Muslo derecho
glPushMatrix();
aplicarMaterialLaton(1);
glTranslatef( 0.56, -1.6, 0);
glRotatef( 6, 0, 0, 1);
glScalef( 0.9, 3.2, 0.9);
glutSolidCube( 0.32 );
glPopMatrix();
// Rodilla derecha
glPushMatrix();
aplicarMaterialOro(1);
glTranslatef( 0.62, -2.2, 0);
glutSolidSphere( 0.23, 28, 28 );
glPopMatrix();
// Pantorrilla derecha
glPushMatrix();
aplicarMaterialLaton(1);
glTranslatef( 0.62, -2.6, 0);
glScalef( 0.9, 3, 0.9);
glutSolidCube( 0.32 );
glPopMatrix();
// Pie derecho
glPushMatrix();
aplicarMaterialOro(1);
glTranslatef( 0.62, -3.35, 0);
glRotatef( 90, 0, 1, 0 );
glRotatef( -90, 1, 0, 0 );
glutSolidCone( 0.32, 0.6, 28, 28 );
glPopMatrix();
glPopMatrix();
}
static GLfloat floorVertices[4][3] = {
{ -50.0, 0.0, 50.0 },
{ 50.0, 0.0, 50.0 },
{ 50.0, 0.0, -50.0 },
{ -50.0, 0.0, -50.0 },
};
void drawFloor(void)
{
glDisable(GL_LIGHTING);
glEnable(GL_TEXTURE_2D);
glBegin(GL_QUADS);
glTexCoord2f(0.0, 0.0);
glVertex3fv(floorVertices[0]);
glTexCoord2f(0.0, 16.0);
glVertex3fv(floorVertices[1]);
glTexCoord2f(16.0, 16.0);
glVertex3fv(floorVertices[2]);
glTexCoord2f(16.0, 0.0);
glVertex3fv(floorVertices[3]);
glEnd();
glDisable(GL_TEXTURE_2D);
glEnable(GL_LIGHTING);
}
void display(void)
{
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);
glClearColor(c, c, c+0, 1);
posicionLuz[0] = 12*cos(lightAngle);
posicionLuz[1] = lightHeight;
posicionLuz[2] = 12*sin(lightAngle);
posicionLuz[3] = 0.8;//luz posicional o direccional
shadowMatrix(sombraPiso, planoPiso, posicionLuz);
glPushMatrix();
glRotatef(angle2, 1.0, 0.0, 0.0);/* mover mouse */
glRotatef(angle, 0.0, 1.0, 0.0);
glLightfv(GL_LIGHT0, GL_POSITION, posicionLuz); /*light position. */
//*************************************************************
glEnable(GL_BLEND);
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
glPushMatrix();
glScalef(1,-1,1);
dibujaObjeto();
glPopMatrix();
glColor4f(1.0, 1.0, 1.0, 0.5 );
drawFloor();
glDisable(GL_LIGHTING);
glDisable(GL_DEPTH_TEST);
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
glPushMatrix();
glColor4f(0.0, 0.0, 0.0, 1.0 );
glMultMatrixf((GLfloat *) sombraPiso);
dibujaObjeto();//Sombra
glPopMatrix();
glDisable(GL_BLEND);
glEnable(GL_LIGHTING);
glEnable(GL_DEPTH_TEST);
dibujaObjeto(); //dibujo objeto solito
glDisable(GL_LIGHTING);
glColor3f(1.0, 1.0, 0.5);
glTranslatef(posicionLuz[0], posicionLuz[1], posicionLuz[2]);
glutSolidSphere(0.8, 20, 20); //simulo la pos. de la luz con una esfera
glEnable(GL_LIGHTING);
glPopMatrix();
glutSwapBuffers();
}
void mouse(int button, int state, int x, int y)
{
if (button == GLUT_LEFT_BUTTON) {
if (state == GLUT_DOWN) {
moving = 1;
startx = x;
starty = y;
}
if (state == GLUT_UP) {
moving = 0;
}
}
}
void mover(int x, int y)
{
if (moving) {
angle = angle + (x - startx);
angle2 = angle2 + (y - starty);
startx = x;
starty = y;
glutPostRedisplay();
}
}
void idle(void)
{
static float time = 0.0;
time = glutGet(GLUT_ELAPSED_TIME) / 500.0;
salto =7.0 * fabs(sin(time)*0.7);
lightAngle += 0.001;
rotar=rotar+0.1;
glutPostRedisplay();
}
static void
key(unsigned char c, int x, int y)
{
if (c == 27) {
exit(0);
}
glutPostRedisplay();
}
void init(void){
glEnable(GL_DEPTH_TEST);
glEnable(GL_TEXTURE_2D);
glMatrixMode(GL_PROJECTION);
gluPerspective(40.0, 1024.0/800.0, 20.0,500.0);
glMatrixMode(GL_MODELVIEW);
gluLookAt(0.0, 8.0, 60.0, /* vista en (0,8,60) */
0.0, 8.0, 0.0, /* centro en (0,8,0) */
0.0, 1.0, 0.); /* altura en Y */
glLightfv(GL_LIGHT0, GL_DIFFUSE, colorLuz);
glLightf(GL_LIGHT0, GL_CONSTANT_ATTENUATION, 0.1);
glLightf(GL_LIGHT0, GL_LINEAR_ATTENUATION, 0.05);
glEnable(GL_LIGHT0);
glEnable(GL_LIGHTING);
texturaPiso();
defPlano(planoPiso, floorVertices[1], floorVertices[2], floorVertices[3]);//Plano para sombra}
}
int main(int argc, char **argv)
{
glutInit(&argc, argv);
glutInitDisplayMode(GLUT_RGB | GLUT_DOUBLE | GLUT_DEPTH | GLUT_STENCIL | GLUT_MULTISAMPLE);
glutInitWindowSize(1024, 800);
glutCreateWindow("LUZ,SOMBRA,REFLEXION Y TEXTURA");
glutDisplayFunc(display);
glutMouseFunc(mouse);
glutMotionFunc(mover);
glutIdleFunc(idle);
glutKeyboardFunc(key);
init();
glutMainLoop();
return 0;
}









