Sombras
#include <GL/glut.h>
GLfloat angle = 0,angle2 = 0;
int moving, startx, starty;
static GLfloat posicionLuz[] = {12, 20, 12, 0.5};//x,y,z,luz posicional/direccional
static GLfloat planoPiso[4]; //plano donde se proyeta la sombra
static GLfloat matSombra[4][4];
static GLfloat planoPared[0]; //plano donde se proyeta la sombra
static GLfloat matSombraPared[4][4];
enum {X, Y, Z, W};
enum {A, B, C, D};
/* Matriz de proyeccion de la sombra */
void matrizDsombra(GLfloat matrizSombra[4][4],GLfloat plano[4], GLfloat posLuz[4]) //aqui se utiliza la posicion de la luz y el plano para generar la matriz de sombra
{ 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.f - posLuz[X] * plano[Y];
matrizSombra[2][0] = 0.f - posLuz[X] * plano[Z];
matrizSombra[3][0] = 0.f - posLuz[X] * plano[W];
matrizSombra[X][1] = 0.f - posLuz[Y] * plano[X];
matrizSombra[1][1] = punto - posLuz[Y] * plano[Y];
matrizSombra[2][1] = 0.f - posLuz[Y] * plano[Z];
matrizSombra[3][1] = 0.f - posLuz[Y] * plano[W];
matrizSombra[X][2] = 0.f - posLuz[Z] * plano[X];
matrizSombra[1][2] = 0.f - posLuz[Z] * plano[Y];
matrizSombra[2][2] = punto - posLuz[Z] * plano[Z];
matrizSombra[3][2] = 0.f - posLuz[Z] * plano[W];
matrizSombra[X][3] = 0.f - posLuz[W] * plano[X];
matrizSombra[1][3] = 0.f - posLuz[W] * plano[Y];
matrizSombra[2][3] = 0.f - posLuz[W] * plano[Z];
matrizSombra[3][3] = punto - posLuz[W] * plano[W];
}
void matrizDsombraPared(GLfloat matrizSombra[4][4],GLfloat plano[4], GLfloat posLuz[4]) //aqui se utiliza la posicion de la luz y el plano para generar la matriz de sombra
{ 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.f - posLuz[X] * plano[Y];
matrizSombra[2][0] = 0.f - posLuz[X] * plano[Z];
matrizSombra[3][0] = 0.f - posLuz[X] * plano[W];
matrizSombra[X][1] = 0.f - posLuz[Y] * plano[X];
matrizSombra[1][1] = punto - posLuz[Y] * plano[Y];
matrizSombra[2][1] = 0.f - posLuz[Y] * plano[Z];
matrizSombra[3][1] = 0.f - posLuz[Y] * plano[W];
matrizSombra[X][2] = 0.f - posLuz[Z] * plano[X];
matrizSombra[1][2] = 0.f - posLuz[Z] * plano[Y];
matrizSombra[2][2] = punto - posLuz[Z] * plano[Z];
matrizSombra[3][2] = 0.f - posLuz[Z] * plano[W];
matrizSombra[X][3] = 0.f - posLuz[W] * plano[X];
matrizSombra[1][3] = 0.f - posLuz[W] * plano[Y];
matrizSombra[2][3] = 0.f - posLuz[W] * plano[Z];
matrizSombra[3][3] = punto - posLuz[W] * plano[W];
}
/* Ecuación del plano dados 3 puntos. */
void ecPlano(GLfloat plano[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 (para calcular la ecuación 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 ecPlanoPared(GLfloat plano[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 (para calcular la ecuación 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 objeto(void)
{
glPushMatrix();
glTranslatef(0, 4, -4);
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); //propiedades de material
glMaterialfv(GL_FRONT, GL_SHININESS, mat_pshininess);
glMaterialfv(GL_FRONT, GL_AMBIENT, mat_p_ambient);
glMaterialfv(GL_FRONT, GL_DIFFUSE, mat_p_diffuse);
glutSolidSphere(4, 68, 68);
//glutWireSphere(4, 68, 68);
//glutSolidCube(5.5);
//glutWireCube(5.5);
//glutWireTeapot(5);
//glutSolidTorus(0.3, 3, 64, 64);
glPopMatrix();
}
static GLfloat verticesPiso[4][3] = {
{ -10.0, 0.0, 10.0 },
{ 10.0, 0.0, 10.0 },
{ 10.0, 0.0, -10.0 },
{ -10.0, 0.0, -10.0 },
};
static GLfloat verticesPared1[4][3] = {
{ 10.0, 0.0, -10.0 },
{ -10.0, 0.0, -10.0 },
{ -10.0, 10.0, -10.0 },
{ 10.0, 10.0, -10.0 },
};
void dibujaPiso(void)
{
glDisable(GL_LIGHTING);
glBegin(GL_QUADS);
glVertex3fv(verticesPiso[0]);
glVertex3fv(verticesPiso[1]);
glVertex3fv(verticesPiso[2]);
glVertex3fv(verticesPiso[3]);
glEnd();
glEnable(GL_LIGHTING);
}
void dibujaPared1(void)
{
glDisable(GL_LIGHTING);
glBegin(GL_QUADS);
glVertex3fv(verticesPared1[0]);
glVertex3fv(verticesPared1[1]);
glVertex3fv(verticesPared1[2]);
glVertex3fv(verticesPared1[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);
///////////////////////////////////////////////
glColor4f(0.1, 0.55, 0.55, 0.5);
dibujaPiso();
dibujaPared1();
///////////////////////////////////////////////
glDisable(GL_LIGHTING);
glDisable(GL_DEPTH_TEST);
glEnable(GL_BLEND); //habilita la transparencia
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
glPushMatrix();
glColor4f(0.0, 0.0, 0.0, 0.1);//color atenuacion de la sombra
glMultMatrixf((GLfloat *) matSombraPared); //para proyectar la sombra en la pared
objeto();//Sombra
glPopMatrix();
glPushMatrix();
glColor4f(0.0, 0.0, 0.0, 0.1);//color atenuacion de la sombra
glMultMatrixf((GLfloat *) matSombra); //para proyectar la sombra en el piso
objeto();//Sombra
glPopMatrix();
glDisable(GL_BLEND);
glEnable(GL_LIGHTING);
glEnable(GL_DEPTH_TEST);
////////////////////////////////////////////////
objeto(); //dibujo objeto original
////////////////////////////////////////////////
glDisable(GL_LIGHTING); //desabilitar la luz porque si no se ve del color del material
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 */
glLightf(GL_LIGHT0, GL_CONSTANT_ATTENUATION, 2.5);
glEnable(GL_LIGHT0);
glEnable(GL_LIGHTING);
glClearColor(0.93, 0.93, 0.93, 1);
ecPlano(planoPiso, verticesPiso[1], verticesPiso[2], verticesPiso[3]);//Plano para sombra se ponen los planos que sean necesarios
ecPlanoPared(planoPared, verticesPared1[0], verticesPared1[1], verticesPared1[2]);
matrizDsombra(matSombra, planoPiso, posicionLuz); //matriz de la sombra recalcular?
matrizDsombraPared(matSombraPared, planoPared, posicionLuz);
}
int main(int argc, char **argv)
{
glutInit(&argc, argv);
glutInitDisplayMode(GLUT_RGB | GLUT_DOUBLE | GLUT_DEPTH | GLUT_STENCIL | GLUT_MULTISAMPLE);
glutInitWindowSize(800, 400);
glutCreateWindow("Sombra Plana");
glutDisplayFunc(display);
glutMouseFunc(mouse);
glutMotionFunc(mover);
init();
glutMainLoop();
return 0;
}
No hay comentarios:
Publicar un comentario