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]); } void dibujaObjeto(void) { glPushMatrix(); glTranslatef(0, 4, 0); glRotatef(rotar, 0, 1,0); glTranslatef(0.0, salto, 0.0); GLfloat mat_p_ambient[] = {0.4725,0.4245,0.8645,1}; GLfloat mat_p_diffuse[] = {0.34615,0.5143,0.8903,1}; GLfloat mat_pspecular[] = {1.797357,1.723991,1.708006,1}; GLfloat mat_pshininess[] = {18.2}; glMaterialfv(GL_FRONT, GL_SPECULAR, mat_pspecular); glMaterialfv(GL_FRONT, GL_SHININESS, mat_pshininess); glMaterialfv(GL_FRONT, GL_AMBIENT, mat_p_ambient); glMaterialfv(GL_FRONT, GL_DIFFUSE, mat_p_diffuse); glShadeModel(GL_SMOOTH); glutSolidSphere(tamanio, 68, 68); 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; }
No hay comentarios.:
Publicar un comentario