martes, 23 de mayo de 2017

Tarea sombras

Captura:

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