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