Código:
#include <windows.h> #include <C:\GLUT\include\GL\glut.h #include <stdlib.h> #include <stdio.h> #include <math.h> GLfloat angle = 0,angle2 = 0; int moving, startx, starty; int alto=512,ancho=512;//dim imagen unsigned char * textura; static GLfloat posicionLuz[] = {12, 20, 12, 0.5};//x,y,z,luz posicional/direccional static GLfloat planoPiso[4]; static GLfloat matSombra[4][4]; enum {X, Y, Z, W}; //calcular matriz enum {A, B, C, D};//plano /* Matriz de proyeccion de la sombra */ static GLfloat verticesPiso[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 }, }; /* Ecuación del plano dados 3 puntos. */ void ecPlano(GLfloat plano[4],GLfloat v0[3], GLfloat v1[3], GLfloat v2[3])//donde lo voy a guaradr y 3 puntos cualquiera { 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 */ plano[A] = vec0[Y] * vec1[Z] - vec0[Z] * vec1[Y]; plano[B] = -(vec0[X] * vec1[Z] - vec0[Z] * vec1[X]); plano[C] = vec0[X] * vec1[Y] - vec0[Y] * vec1[X]; plano[D] = -(plano[A] * v0[X] + plano[B] * v0[Y] + plano[C] * v0[Z]); } void matrizDsombra(GLfloat matrizSombra[4][4],GLfloat plano[4], GLfloat posLuz[4]) { GLfloat punto; // Producto punto entre vector light position y la normal del plano punto = plano[X] * posLuz[X] + plano[Y] * posLuz[Y] + plano[Z] * posLuz[Z] + plano[W] * posLuz[W]; matrizSombra[0][0] = punto - posLuz[X] * plano[X]; matrizSombra[1][0] = 0 - posLuz[X] * plano[Y]; matrizSombra[2][0] = 0 - posLuz[X] * plano[Z]; matrizSombra[3][0] = 0 - posLuz[X] * plano[W]; matrizSombra[X][1] = 0 - posLuz[Y] * plano[X]; matrizSombra[1][1] = punto - posLuz[Y] * plano[Y]; matrizSombra[2][1] = 0 - posLuz[Y] * plano[Z]; matrizSombra[3][1] = 0 - posLuz[Y] * plano[W]; matrizSombra[X][2] = 0 - posLuz[Z] * plano[X]; matrizSombra[1][2] = 0 - posLuz[Z] * plano[Y]; matrizSombra[2][2] = punto - posLuz[Z] * plano[Z]; matrizSombra[3][2] = 0- posLuz[Z] * plano[W]; matrizSombra[X][3] = 0 - posLuz[W] * plano[X]; matrizSombra[1][3] = 0 - posLuz[W] * plano[Y]; matrizSombra[2][3] = 0 - posLuz[W] * plano[Z]; matrizSombra[3][3] = punto - posLuz[W] * plano[W]; } void aplicarMaterialBronce(int encendido) //es color verde esmeralda { if(encendido==1) { //estos primeros son los parametros GLfloat mat_green_ambient[] = {0.2125,0.1275,0.054,0.75};//ambiente y la ultima es alfa transaparencia GLfloat mat_green_diffuse[] = { 0.714,0.4284,0.18144,0.75};//difuso GLfloat mat_specular[] = { 0.393548,0.271906,0.166721,0.5};//especular r,g,b y alfa GLfloat mat_shininess[] = { 0.2}; //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 aplicarMaterialVerde(int encendido) //es color verde esmeralda { if(encendido==1) { //estos primeros son los parametros GLfloat mat_green_ambient[] = {0.0,0.0,0.0,0.75};//ambiente y la ultima es alfa transaparencia GLfloat mat_green_diffuse[] = { 0.1,0.35,0.1,0.75};//difuso GLfloat mat_specular[] = { 0.45,0.55,0.45,0.5};//especular r,g,b y alfa GLfloat mat_shininess[] = { 0.25}; //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); } } //se crea la figura del arbol void arbol(void){ //tronco glPushMatrix(); aplicarMaterialBronce(1); glRotatef(270,1,0,0); glutSolidCone(0.7, 5.5, 100, 100); glPopMatrix(); //rama principal glPushMatrix(); aplicarMaterialVerde(1); glTranslatef(0,4.5,0); glutSolidDodecahedron(); glPopMatrix(); //tronco derecho glPushMatrix(); aplicarMaterialBronce(1); glTranslatef(0,1.2,0); glRotatef(220,1,0,0); glutSolidCone(0.5, 2.5, 100, 100); glPopMatrix(); //rama derecha glPushMatrix(); aplicarMaterialVerde(1); glTranslatef(0,2.3,-1.5); glRotatef(220,1,0,0); glScalef(0.5,0.5,0.5); glutSolidDodecahedron(); glPopMatrix(); //tronco izquierdo glPushMatrix(); aplicarMaterialBronce(1); glTranslatef(0,0.5,0); glRotatef(320,1,0,0); glutSolidCone(0.5, 2.5, 100, 100); glPopMatrix(); //rama izquierda glPushMatrix(); aplicarMaterialVerde(1); glTranslatef(0,2,1.5); glRotatef(220,1,0,0); glScalef(0.5,0.5,0.5); glutSolidDodecahedron(); glPopMatrix(); } void dibujaObjeto(void) { glPushMatrix(); //glTranslatef(0, 4, 0); lo comente para que el objeto estuviera sobre el piso 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); //se dibujan y se trasladan los arboles en todo el escenario glTranslatef(-30,0,9); arbol(); glTranslatef(10,0,15); arbol(); glTranslatef(30,0,20); arbol(); glTranslatef(15,0,-20); arbol(); glTranslatef(20,0,-3); arbol(); glTranslatef(-25,0,-18); arbol(); glTranslatef(-30,0,-25); arbol(); glPopMatrix(); } int leerImagen(){ FILE *imagen; imagen=fopen("C:/Users/migue/Dropbox/8vo Semestre/Graficación/3D/TareaSombras/Piso.raw","r"); textura=(unsigned char*)malloc(ancho*alto*3); if(imagen==NULL){ printf("Error: No imagen"); return 0; } fread(textura,ancho*alto*3,1,imagen); fclose(imagen); return 1; } void usarTextura(void) { glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, ancho, alto, 0, GL_RGB, GL_UNSIGNED_BYTE, textura); } void dibujaPiso(void) { glDisable(GL_LIGHTING); glBegin(GL_QUADS); glTexCoord2f(0.0, 0.0); //se utiliza para dibujar la textura glVertex3fv(verticesPiso[0]); glTexCoord2f(0.0, 10); glVertex3fv(verticesPiso[1]); glTexCoord2f(10, 10); glVertex3fv(verticesPiso[2]); glTexCoord2f(10, 0.0); glVertex3fv(verticesPiso[3]); glEnd(); glEnable(GL_LIGHTING); } void display(void) { glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT); 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);//posicion de laluz //glColor3f(0.1, 0.55, 0.55); se utiliza para el color del piso glEnable(GL_TEXTURE_2D); //se habilita la textura sobre el piso dibujaPiso(); glDisable(GL_TEXTURE_2D); glDisable(GL_LIGHTING);//iluminacion glDisable(GL_DEPTH_TEST); glEnable(GL_BLEND);//transparencia glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); glPushMatrix(); glColor4f(0.0, 0.0, 0.0, 1); //negro y .1 de transparencia glMultMatrixf((GLfloat *) matSombra); dibujaObjeto();//Sombra glPopMatrix(); glDisable(GL_BLEND); glEnable(GL_LIGHTING); glEnable(GL_DEPTH_TEST); dibujaObjeto(); //dibujo objeto original //si dibuja el circulo amarillo que simula el sol, es el objeto que le da iluminacion a los objetos glDisable(GL_LIGHTING); //esfera amarilla glTranslatef(posicionLuz[0], posicionLuz[1], posicionLuz[2]); glColor3f(1.0, 1.0, 0.0); glutSolidSphere(0.5, 10, 10); 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 init(void){ glMatrixMode(GL_PROJECTION); gluPerspective(25.0,2.0,20.0,150.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.0); /* altura en Y */ glEnable(GL_LIGHTING); glEnable(GL_LIGHT0); glLightf(GL_LIGHT0, GL_CONSTANT_ATTENUATION, 2.5); leerImagen(); usarTextura(); glClearColor(0.80, 0.90, 0.93, 1);//color del fondo ecPlano(planoPiso, verticesPiso[1], verticesPiso[2], verticesPiso[3]);//Plano para sombra, ecuacion del plano,se guarda en plano piso matrizDsombra(matSombra, planoPiso, posicionLuz); //matriz de la sombra recalcular?, matriz de pryexccion en matSombra } int main(int argc, char **argv) { glutInit(&argc, argv); glutInitDisplayMode(GLUT_RGB | GLUT_DOUBLE | GLUT_DEPTH | GLUT_STENCIL | GLUT_MULTISAMPLE); //Stencial glutInitWindowSize(800, 400); glutCreateWindow("Arboles"); glutDisplayFunc(display); glutMouseFunc(mouse); glutMotionFunc(mover); init(); glutMainLoop(); return 0; }
No hay comentarios.:
Publicar un comentario