martes, 15 de noviembre de 2016

Ejercicio Luz y Sombras - Equipos

Trabajo en Equipo Luz y Sombras:

Este programa es para aplicar luz y sombras a un objeto en movimiento, el objeto va proyectando su sombra tanto en el piso como en las paredes.

Capturas de Pantalla:






Código:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <math.h>
//#include <GLut/gutil.h>
#include <GL/glut.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 a=0;
static GLdouble tamanio = 4.0;

static GLfloat posicionLuz[4];
static GLfloat posicionAve[3];
static GLfloat colorLuz[] = {1, 1, 1, 1.0};///x,y,z y si es posicional
static GLfloat planoPiso[4];///plano del piso
static GLfloat sombraPiso[4][4];///transformacion objeto-sombra

enum {X, Y, Z, W};
enum {A, B, C, D};

char *textura[] = {
    "..................",
    "..................",
    ".......xxxx.......",
    ".....xxxxxxxx......",
    "....xxxxxxxxxx.....",
    "....xxx....xxx.....",
    "...xxx......xxx....",
    "...xxxoo..ooxxx....",
    "...xxxoo..ooxxx....",
    "...xxx......xxx....",
    "....xxx....xxx.....",
    "....xxxxxxxxxx.....",
    ".....xxxxxxxx......",
    "..................",
    "..................",
    "..................",
};

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] = 0;
                col[1] = 250;
                col[2] = 0;
            } else if (textura[t][s] == 'o') {
                col[0] = 0;
                col[1] = 250;
                col[2] = 0;
            }else {
                col[0] =0;
                col[1] =250;
                col[2] =0;
            }
            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 sombre */
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 dibujarCastillo(GLfloat x , GLfloat y ,GLfloat ambr , GLfloat ambg, GLfloat ambb,GLfloat difr, GLfloat difg, GLfloat difb, GLfloat specr, GLfloat specg ,GLfloat specb,GLfloat brillo)
{

    float mat[4];
    //glPushMatrix();
    glTranslatef(x,y,0) ;
    mat[3] = 1 ;
    mat[0] = ambr;
    mat[1] = ambg;
    mat[2] = ambb;
    glMaterialfv(GL_FRONT, GL_AMBIENT, mat) ;
    mat[0] = difr;
    mat[1] = difg;
    mat[2] = difb;
    glMaterialfv(GL_FRONT, GL_DIFFUSE, mat) ;
    mat[0] = specr;
    mat[1] = specg;
    mat[2] = specb;
    glMaterialfv(GL_FRONT , GL_SPECULAR, mat) ;
    glMaterialf(GL_FRONT, GL_SHININESS , brillo * 128) ;
    glDisable(GL_LIGHTING);
    /*Base superior.*/
    glPushMatrix();
    glColor3f(1, 1, 1);

    glTranslatef(0.0, 0.11, 0.0);
    glScalef(1.5, 0.3, 2.0);
    glutSolidCube(0.1);
    glPopMatrix();

    /*Base media.*/
    glPushMatrix();
    glColor3f(1.0, 0.0, 0.0);
    glScalef(1.0, 2.0, 1.5);
    glutSolidCube(0.1);
    glPopMatrix();

    /*Base inferior.*/
    glPushMatrix();
    glColor3f(1, 1, 1);
    glTranslatef(0.0, -0.11, 0.0);
    glScalef(1.5, 0.3, 2.0);
    glutSolidCube(0.1);
    glPopMatrix();
//glPopMatrix();
    glPopAttrib();
    glEnable(GL_LIGHTING);
}


void dibujarAve()
{

    /*Atributos del ave.*/
    glPushMatrix();
    glTranslatef(posicionAve[0], posicionAve[1], posicionAve[2]);
    //glRotated(a,1,1,0);
    glRotated(a,1,0,1);
    GLfloat mat_p_ambient[] = {1,0.4,0,1};
    GLfloat mat_p_diffuse[] = {1,0.4,0,1};
    GLfloat mat_pspecular[] = {0.7,0,0,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);

    //glTranslatef(15,15,5);
    /*Se declara un objeto que almacena una superficie cuadrica.*/
    GLUquadricObj *quad;
    /*Se hace la instancia del objeto.*/
    quad = gluNewQuadric();
    /*Se define el estilo de la superficie cuadrica (si se desea rellena o formada por lineas).*/
    gluQuadricDrawStyle(quad, GLU_FILL);
    glScaled(0.3, 0.3, 0.2);
    //glDisable(GL_LIGHTING);
    //glColor3f(0.4, 0.211, 0.050);
    gluCylinder(quad, 10, 10, 40, 100.0, 100.0);
    glPushMatrix();
    //glColor3f(0.0, 0.0, 1.0);
    //glRotatef(a,0.0,0.0,1.0);

    GLfloat mat_p_ambient2[] = {0,0.1,1,1};
    GLfloat mat_p_diffuse2[] = {0,0.1,1,1};
    GLfloat mat_pspecular2[] = {0,0,0.7,1};
    GLfloat mat_pshininess2[] = {18.2};
    glMaterialfv(GL_FRONT, GL_SPECULAR, mat_pspecular2);
    glMaterialfv(GL_FRONT, GL_SHININESS, mat_pshininess2);
    glMaterialfv(GL_FRONT, GL_AMBIENT, mat_p_ambient2);
    glMaterialfv(GL_FRONT, GL_DIFFUSE, mat_p_diffuse2);
    glShadeModel(GL_SMOOTH);
    glTranslatef(18, 0,20);
    glScalef(15.0, 1.5, 35.0);
    glutSolidCube(1);
    glPopMatrix();
    glPushMatrix();
    //glColor3f(0.0, 0.0, 1.0);
    //glRotatef(b,0.0,0.0,1.0);
    glTranslatef(-18, 0, 20);
    glScalef(15.0, 1.5, 35.0);
    glutSolidCube(1);
    glPopMatrix();

    //glEnable(GL_LIGHTING);
    glPopMatrix();
}
dibujabase(){
    glPushMatrix();
    //lColor3f(0.63, 0.6, 0.6);
    //   glColor3f(1, 1, 1);
    glScalef(1.5, 0.5, 1.5);
    glTranslatef(0.0, 2.0, -1.0);
    glutSolidCube(5);
    glPopMatrix();
}
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] = {
    { -30.0, 0.0,  30.0 },
    {  30.0, 0.0,  30.0 },
    {  30.0, 0.0, -30.0 },
    { -30.0, 0.0, -30.0 },
};

static GLfloat floorVertices2[4][3] = {
    { -30.0, 30.0,  30 },
    {  30.0, 30.0,  30 },
    {  30.0, -30.0, 30 },
    { -30.0, -30.0, 30 },
};
static GLfloat floorVertices3[4][3] = {
    { -30.0, 30.0,  -30 },
    {  30.0, 30.0,  -30 },
    {  30.0, -30.0, -30 },
    { -30.0, -30.0, -30 },
};
static GLfloat floorVertices4[4][3] = {
    { 30.0, 30.0,  30 },
    {  30.0, 30.0,  -30 },
    {  30.0, -30.0, -30 },
    { 30.0, -30.0, 30 },
};
static GLfloat floorVertices5[4][3] = {
    { -50.0, 50.0,  50 },
    {  -50.0, 50.0,  -50 },
    {  -50.0, -50.0, -50 },
    { -50.0, -50.0, 50 },
};
void drawFloor(void)
{
    glDisable(GL_LIGHTING);
    glEnable(GL_TEXTURE_2D);
    glBegin(GL_QUADS);
    glTexCoord2f(0.0, 0.0);
    glVertex3fv(floorVertices[0]);
    glTexCoord2f(0.0, 20.0);///dice cuantas veces se repite la textura el 20.0
    glVertex3fv(floorVertices[1]);
    glTexCoord2f(20.0, 20.0);
    glVertex3fv(floorVertices[2]);
    glTexCoord2f(20.0, 0.0);
    glVertex3fv(floorVertices[3]);
    glEnd();
    glDisable(GL_TEXTURE_2D);
    glEnable(GL_LIGHTING);
}

void drawWall(void)
{
    glEnable(GL_TEXTURE_2D);
    glBegin(GL_QUADS);
    glTexCoord2f(0.0, 0.0);
    glVertex3fv(floorVertices2[0]);
    glTexCoord2f(0.0, 20.0);///dice cuantas veces se repite la textura el 20.0
    glVertex3fv(floorVertices2[1]);
    glTexCoord2f(20.0, 20.0);
    glVertex3fv(floorVertices2[2]);
    glTexCoord2f(20.0, 0.0);
    glVertex3fv(floorVertices2[3]);
    glEnd();
    glDisable(GL_TEXTURE_2D);


    glEnable(GL_TEXTURE_2D);
    glBegin(GL_QUADS);
    glTexCoord2f(0.0, 0.0);
    glVertex3fv(floorVertices3[0]);
    glTexCoord2f(0.0, 20.0);///dice cuantas veces se repite la textura el 20.0
    glVertex3fv(floorVertices3[1]);
    glTexCoord2f(20.0, 20.0);
    glVertex3fv(floorVertices3[2]);
    glTexCoord2f(20.0, 0.0);
    glVertex3fv(floorVertices3[3]);
    glEnd();
    glDisable(GL_TEXTURE_2D);

    glEnable(GL_TEXTURE_2D);
    glBegin(GL_QUADS);
    glTexCoord2f(0.0, 0.0);
    glVertex3fv(floorVertices4[0]);
    glTexCoord2f(0.0, 20.0);///dice cuantas veces se repite la textura el 20.0
    glVertex3fv(floorVertices4[1]);
    glTexCoord2f(20.0, 20.0);
    glVertex3fv(floorVertices4[2]);
    glTexCoord2f(20.0, 0.0);
    glVertex3fv(floorVertices4[3]);
    glEnd();
    glDisable(GL_TEXTURE_2D);

}

void dibujarMuro()
{

    glDisable(GL_LIGHTING);
    glColor3f(1, 1, 1);
    glutSolidCube(0.1);
    glEnable(GL_LIGHTING);
}

void drawPared(){
    /*Se dibujan las paredes.*/
    /*Pared izquierda.*/
    glPushMatrix();
    glTranslatef(10, 12, 25);
    glScalef(150.1, 202.0, 25);
    glRotatef(70.0, 0.0, 1.0, 0.0);
    dibujarMuro();
    glPopMatrix();
    /*Pared derecha.*/
    glPushMatrix();
    glTranslatef(10, 12, -25);
    glScalef(150.1, 202.0, 25);
    glRotatef(-70.0, 0.0, 1.0, 0.0);
    dibujarMuro();
    glPopMatrix();
}

void dibujapilares(){
    glPushMatrix();
    glTranslatef(30, 12.0, 10.0);
    glScalef(42.0, 103.0, 42.0);
    dibujarCastillo(0,0,0.0215,0.1745,0.55,0.7568,0.61424,0.55,0.633,0.727811,0.55,76.8);
    glPopMatrix();
    /*Primer muro trasero.*/
    glPushMatrix();
    glTranslatef(30, 12.0, -10.0);
    glScalef(42.0, 103.0, 42.0);
    dibujarCastillo(0,0,0.0215,0.1745,0.55,0.7568,0.61424,0.55,0.633,0.727811,0.55,76.8);
    glPopMatrix();
    /*Tercer muro trasero.*/
    glPushMatrix();
    glTranslatef(30, 12, -28);
    glScalef(42.0, 103.0, 42.0);
    dibujarCastillo(0,0,0.0215,0.1745,0.55,0.7568,0.61424,0.55,0.633,0.727811,0.55,76.8);
    glPopMatrix();
    /*Cuarto muro trasero.*/
    glPushMatrix();
    glTranslatef(30, 12, 28);
    glScalef(42.0, 103.0, 42.0);
    dibujarCastillo(0,0,0.0215,0.1745,0.55,0.7568,0.61424,0.55,0.633,0.727811,0.55,76.8);
    glPopMatrix();
    /*Muro izquierdo medio.*/
    glPushMatrix();
    glTranslatef(0, 12, 25);
    glScalef(42.0, 103.0, 42.0);
    dibujarCastillo(0,0,0.0215,0.1745,0.55,0.7568,0.61424,0.55,0.633,0.727811,0.55,76.8);
    glPopMatrix();
    /*Muro derecho medio.*/
    glPushMatrix();
    glTranslatef(0, 12, -25);
    glScalef(42.0, 103.0, 42.0);
    dibujarCastillo(0,0,0.0215,0.1745,0.55,0.7568,0.61424,0.55,0.633,0.727811,0.55,76.8);
    glPopMatrix();
    /*Muro izquierdo frontal.*/
    glPushMatrix();
    glTranslatef(-30, 15, 18);
    glScalef(42.0, 103.0, 42.0);
    dibujarCastillo(0,0,0.0215,0.1745,0.55,0.7568,0.61424,0.55,0.633,0.727811,0.55,76.8);
    glPopMatrix();
    /*Muro derecho frontal.*/
    glPushMatrix();
    glTranslatef(-30, 15, -18);
    glScalef(42.0, 103.0, 42.0);
    dibujarCastillo(0,0,0.0215,0.1745,0.55,0.7568,0.61424,0.55,0.633,0.727811,0.55,76.8);
    glPopMatrix();
}
void display(void)
{

    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);

    posicionAve[0] = 20*cos(lightAngle);
    posicionAve[1] = lightHeight;///rota en y
    posicionAve[2] = 20*sin(lightAngle);
    posicionLuz[0] = 0;
    posicionLuz[1] = 20;///rota en y
    posicionLuz[2] = -1;
    posicionLuz[3] = 0.7;///luz posicional (0) o direccional(1) ilumina a todo

    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. */
        ///cambia la posicion de la luz mientras va girando


        glLightfv(GL_LIGHT0, GL_POSITION, posicionLuz);//Reacomodar la luz
        ///se reacomoda

        glEnable(GL_BLEND);///transparencia
        glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
        glColor4f(1.0, 1.0, 1.0, 0.5);///a la mitad la transparencia
        drawFloor();
        drawPared();
        dibujapilares();
        glDisable(GL_BLEND);

        glDisable(GL_DEPTH_TEST);///deshabilitamos profundidad
        glDisable(GL_LIGHTING);///deshabilitamos luz
        glEnable(GL_BLEND);
        glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);

            glPushMatrix();
                glColor4f(0.0, 0.0, 0.0, 0.5);///le ponemos transparencia para que se vea la textura
                glMultMatrixf((GLfloat *) sombraPiso);
                ///es una matriz de sombra al piso
                //dibujaObjeto();///Sombra
                dibujarAve();
                dibujabase();
            glPopMatrix();

        glDisable(GL_BLEND);
        glEnable(GL_DEPTH_TEST);
        glEnable(GL_LIGHTING);

///----------------------------------------------------------------
        dibujarAve();
        //dibujaObjeto();     ///dibujo objeto solito
    dibujabase();

///----------------------------------------------------------------
        glDisable(GL_LIGHTING);///Simulamos la luz en la esfera
            glColor3f(1.0, 1.0, 0.5);
            glPushMatrix();
            glTranslatef(posicionLuz[0], posicionLuz[1], posicionLuz[2]);
            glutSolidSphere(0.8, 20, 20);  //simulo la pos. de la luz con una esfera
            glColor3f(1, 0.9, 0.4);
            glutSolidSphere(3, 30, 30);
            glPopMatrix();
            glPushMatrix();
            /*Se declara un objeto que almacena una superficie cuadrica.*/
            GLUquadricObj *quad;
            /*Se hace la instancia del objeto.*/
            quad = gluNewQuadric();
            /*Se define el estilo de la superficie cuadrica (si se desea rellena o formada por lineas).*/
            gluQuadricDrawStyle(quad, GLU_FILL);
            glTranslated(0.0, 20, -1.0);
            glRotatef(90, 1.0, 0.0, 0.0);
            glScaled(0.25, 0.25, 2);
            glDisable(GL_LIGHTING);
            glColor3f(0.4, 0.211, 0.050);
            gluCylinder(quad, 4, 4, 10.0, 30.0, 60.0);
            glEnable(GL_LIGHTING);
            glPopMatrix();
            /*Atributos de la base del poste.*/
        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)///REposo
{
    static float time = 0.0;
    time = glutGet(GLUT_ELAPSED_TIME) / 500.0;///inicializamos e incrementamos medio segundo
    //salto =20.0 * fabs(sin(time)*0.7);
    lightAngle -= 0.01;
    rotar=rotar+0.1;
    a=a+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,1.0,20.0,500.0);
    glMatrixMode(GL_MODELVIEW);
    gluLookAt(0.0, 8.0, 70.0,  /* vista en (0,8,60) */
              0.0, 10.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);
    glClearColor(0, 0, 0, 1);
    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;
}

Descarga:

Link de descarga (Pulse aquí)

No hay comentarios:

Publicar un comentario