/* shadow.c */
/*
* Use the stencil buffer to generate shadows. This demo inspired by
* an article in IRIS Universe Magazine, No. 18. This program is in
* the public domain.
*
* Brian Paul
*/
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#include <GL/glut.h>
#include <GL/gl.h>
#include <GL/glu.h>
#include "ModuleCouleurs.h"
#include "ModuleManipulateur.h"
#include "ModuleMenus.h"
#include "ModuleReshape.h"
float light_pos[] = { 0.0F,10.0F,0.0F,1.0F } ;
float ground_xrot ;
float ground_yrot ;
float ground_zrot ;
float ground_y ;
int num_tri = 4 ;
float triangle[] = {
0.5F,4.0F,0.5F,-0.5F,4.0F,0.5F,0.0F,4.0F,2.0F,0.5F,4.0F,0.5F,0.5F,4.0F,-0.5F,2.0F,4.0F,0.0F,
0.5F,4.0F,-0.5F,-0.5F,4.0F,-0.5F,0.0F,4.0F,-2.0F,-0.5F,4.0F,-0.5F,-0.5F,4.0F,0.5F,-2.0F,4.0F,0.0F };
void draw_shadow_volumes() {
int tri;
int i,j;
float v0[3] ;
float v1[3] ;
float p0[3] ;
float p1[3] ;
float p2[3] ;
float p3[3] ;
for (tri=0;tri<num_tri;tri++) {
for (i=0;i<3;i++) {
j = (i+1) % 3;
v0[0] = triangle[tri*9+i*3+0] - light_pos[0];
v0[1] = triangle[tri*9+i*3+1] - light_pos[1];
v0[2] = triangle[tri*9+i*3+2] - light_pos[2];
v1[0] = triangle[tri*9+j*3+0] - light_pos[0];
v1[1] = triangle[tri*9+j*3+1] - light_pos[1];
v1[2] = triangle[tri*9+j*3+2] - light_pos[2];
p0[0] = triangle[tri*9+i*3+0];
p0[1] = triangle[tri*9+i*3+1];
p0[2] = triangle[tri*9+i*3+2];
p1[0] = triangle[tri*9+j*3+0];
p1[1] = triangle[tri*9+j*3+1];
p1[2] = triangle[tri*9+j*3+2];
p2[0] = p1[0] + v1[0] * 10.0F;
p2[1] = p1[1] + v1[1] * 10.0F;
p2[2] = p1[2] + v1[2] * 10.0F;
p3[0] = p0[0] + v0[0] * 10.0F;
p3[1] = p0[1] + v0[1] * 10.0F;
p3[2] = p0[2] + v0[2] * 10.0F;
glBegin(GL_POLYGON);
glVertex3fv(p0);
glVertex3fv(p1);
glVertex3fv(p2);
glVertex3fv(p3);
glEnd(); } }
}
void drawScene() {
int ground = -1;
int i,j;
float x,y,z;
glPushMatrix();
glRotatef(ground_xrot,1.0F,0.0F,0.0F);
glRotatef(ground_yrot,0.0F,1.0F,0.0F);
glRotatef(ground_zrot,0.0F,0.0F,1.0F);
glTranslatef(0.0F,ground_y,0.0F);
if ( ground == -1 ) {
ground = glGenLists(1);
glNewList(ground,GL_COMPILE_AND_EXECUTE);
for ( i=0 ; i<5 ; i++ ) {
for ( j=0 ; j<5 ; j++ ) {
if ( (i+j)%2 != 0 ) {
glColor4fv(couleurVert()); }
else {
glColor4fv(couleurBleu()); }
glNormal3f(0.0F,1.0F,0.0F);
x =(float) (i*2.0 - 5.0);
y = 0.0F;
z =(float) (j*2.0 - 5.0);
glBegin(GL_POLYGON);
glVertex3f(x,y,z+2.0F);
glVertex3f(x+2.0F,y,z+2.0F);
glVertex3f(x+2.0F,y,z);
glVertex3f(x,y,z);
glEnd(); } }
glEndList(); }
else {
glCallList(ground); }
glPopMatrix();
glColor4fv(couleurRouge());
glNormal3f(0.0F,1.0F,0.0F);
glBegin(GL_TRIANGLES);
for (i=0;i<num_tri;i++) {
glVertex3f(triangle[(i*3)*3],triangle[(i*3)*3+1],triangle[(i*3)*3+2]);
glVertex3f(triangle[(i*3+1)*3],triangle[(i*3+1)*3+1],triangle[(i*3+1)*3+2]);
glVertex3f(triangle[(i*3+2)*3],triangle[(i*3+2)*3+1],triangle[(i*3+2)*3+2]); }
glEnd();
}
void display() {
glClear(GL_DEPTH_BUFFER_BIT|GL_COLOR_BUFFER_BIT|GL_STENCIL_BUFFER_BIT);
glPushMatrix();
manipulateurSouris();
manipulateurClavier();
glLightfv(GL_LIGHT0,GL_POSITION,light_pos);
glEnable(GL_LIGHTING);
glDisable(GL_LIGHT0);
glColorMaterial(GL_FRONT_AND_BACK,GL_AMBIENT);
glEnable(GL_COLOR_MATERIAL);
drawScene();
glDisable(GL_LIGHTING);
glStencilFunc(GL_ALWAYS,0,0xffffffff);
glStencilOp(GL_KEEP,GL_KEEP,GL_INVERT);
glEnable(GL_STENCIL_TEST);
glColorMask(GL_FALSE,GL_FALSE,GL_FALSE,GL_FALSE);
glDepthMask(GL_FALSE);
draw_shadow_volumes();
glColorMask(GL_TRUE,GL_TRUE,GL_TRUE,GL_TRUE);
glDepthMask(GL_TRUE);
glEnable(GL_LIGHT0);
glEnable(GL_LIGHTING);
glColorMaterial(GL_FRONT_AND_BACK,GL_AMBIENT_AND_DIFFUSE);
glEnable(GL_COLOR_MATERIAL);
glStencilFunc(GL_EQUAL,0,0xffffffff);
glStencilOp(GL_KEEP,GL_KEEP,GL_KEEP);
drawScene();
glDisable(GL_STENCIL_TEST);
glDisable(GL_LIGHT0);
glPopMatrix();
glFlush();
glutSwapBuffers();
}
void idle() {
ground_yrot -= 2.0F;
ground_xrot =(float) (sin(ground_yrot*0.1) * 10.0);
ground_zrot =(float) (cos(ground_yrot*0.1) * 10.0);
ground_y =(float) (sin(ground_yrot*0.15) * 2.0);
glutPostRedisplay() ;
}
void myinit() {
ground_xrot = ground_yrot = ground_zrot = 0.0F;
ground_y = 0.0F;
glEnable(GL_DEPTH_TEST);
glDepthFunc(GL_LEQUAL);
glShadeModel(GL_FLAT);
glLightModelfv(GL_LIGHT_MODEL_AMBIENT,couleurGrisFonce());
glLightfv(GL_LIGHT0,GL_AMBIENT,couleurGrisFonce());
}
int main(int argc,char **argv) {
glutInit(&argc,argv);
glutInitDisplayMode(GLUT_RGBA|GLUT_DEPTH|GLUT_DOUBLE);
glutInitWindowSize(300,300);
glutInitWindowPosition(50,50);
glutCreateWindow("Shadows");
myinit();
creationMenuBasique();
setParametresFrustumBasique(-1.0F,1.0F,-1.0,1.0F,5.0F,50.0F,0.0F,0.0F,-35.0F);
setManipulateurDistance(35.0F);
glutReshapeFunc(reshapeFrustumBasique);
glutKeyboardFunc(keyBasique);
glutSpecialFunc(specialBasique);
glutMotionFunc(motionBasique);
glutMouseFunc(sourisBasique);
glutIdleFunc(idle);
glutDisplayFunc(display);
glutMainLoop();
return(0);
}