ultimatepp/uppdev/GLShadow/main.c
cxl 351994a6cc Adding uppdev....
git-svn-id: svn://ultimatepp.org/upp/trunk@328 f0d560ea-af0d-0410-9eb7-867de7ffcac7
2008-08-15 08:36:24 +00:00

300 lines
7.1 KiB
C
Raw Blame History

/* shadow volume demo
*
* written by Alexander Zaprjagaev
* frustum@public.tsu.ru
*/
#include <math.h>
#include <malloc.h>
#include <stdio.h>
#include <stdarg.h>
#include <GL/gl.h>
#include <GL/glu.h>
#include "SDL.h"
#include "mathlib.h"
#include "load3ds.h"
#include "sv_mesh.h"
#include "mesh.h"
#define WIDTH 800
#define HEIGHT 600
int my_pause,my_view;
float fps;
float phi = -30,psi = -90,dist = 10;
float camera[3],dir[3];
float light[4] = { 0, 0, 0, 1 },light_speed = 5,light_rot = 180;
float shadow[4] = { 0, 0, 0, 0.5 };
mesh_t *room;
sv_mesh_t *staircase,*motor,*cooler,*box,*barrel,*shelf,*mesh;
sv_mesh_t *computer,*lcd,*door,*big_wire;
float staircase_pos[3] = { 0,0,0 };
float motor_pos[3] = { 0, 5.856, 2.549 };
float cooler_pos[3] = { 0, 4.024, 2.542 },cooler_speed = -30,cooler_rot;
float box_pos[3] = { -4.268, 1.343, 3.349 };
float barrel_pos[3] = { -4.301, 3.587, -0.018 };
float shelf_pos[3] = { 4.744, 1.680, 0.215 };
float mesh_pos[3] = { 0, 0, 2.000 },mesh_speed = 20,mesh_rot;
float computer_pos[3] = { 4.693, 3.367, 0.654 };
float big_wire_pos[4][3] = {{ 1.004, 0.983, 1.576 }, { 1.004,-1.041, 1.576 },
{-1.004,-1.041, 1.576 }, {-1.004, 0.983, 1.576 }};
float big_wire_rot[4] = { 45, -45, -135, 135 };
/*
*/
void load_mesh(char *name,float *pos,mesh_t **mesh) {
float m[16];
*mesh = mesh_load_3ds(name);
if(pos) {
m_translate(pos,m);
mesh_set_matrix(*mesh,m);
}
}
void load_sv_mesh(char *name,float *pos,sv_mesh_t **mesh) {
float m[16];
*mesh = sv_mesh_load_3ds(name);
if(pos) {
m_translate(pos,m);
sv_mesh_set_matrix(*mesh,m);
}
}
/* init
*/
int init(void) {
glClearDepth(1);
glClearColor(0,0,0,0);
glEnable(GL_LIGHT0);
glEnable(GL_CULL_FACE);
glEnable(GL_DEPTH_TEST);
glDepthFunc(GL_LEQUAL);
glPointSize(4);
load_mesh("data/room.3ds",NULL,&room);
load_sv_mesh("data/staircase.3ds",staircase_pos,&staircase);
load_sv_mesh("data/motor.3ds",motor_pos,&motor);
load_sv_mesh("data/cooler.3ds",NULL,&cooler);
load_sv_mesh("data/box.3ds",box_pos,&box);
load_sv_mesh("data/barrel.3ds",barrel_pos,&barrel);
load_sv_mesh("data/shelf.3ds",shelf_pos,&shelf);
load_sv_mesh("data/mesh.3ds",NULL,&mesh);
load_sv_mesh("data/computer.3ds",computer_pos,&computer);
load_sv_mesh("data/lcd.3ds",computer_pos,&lcd);
load_sv_mesh("data/big_wire.3ds",NULL,&big_wire);
return 0;
}
/* get fps
*/
float getfps(void) {
static float fps = 60;
static int starttime,endtime,counter;
if(counter == 10) {
endtime = starttime;
starttime = SDL_GetTicks();
fps = counter * 1000.0 / (float)(starttime - endtime);
counter = 0;
}
counter++;
return fps;
}
/*
*/
void render(void) {
int i;
float m0[16],m1[16],m2[16];
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
gluPerspective(45,WIDTH / HEIGHT,1,500);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
gluLookAt(camera[0],camera[1],camera[2], dir[0],dir[1],dir[2], 0,0,1);
glLightfv(GL_LIGHT0,GL_POSITION,light);
glColor3f(1,1,1);
/* <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> */
glBegin(GL_POINTS);
glVertex3fv(light);
glEnd();
/* <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> */
glEnable(GL_LIGHTING);
mesh_render(room);
sv_mesh_render(staircase);
sv_mesh_render(motor);
sv_mesh_render(cooler);
sv_mesh_render(box);
sv_mesh_render(barrel);
sv_mesh_render(shelf);
sv_mesh_render(mesh);
sv_mesh_render(computer);
sv_mesh_render(lcd);
for(i = 0; i < 4; i++) {
m_translate(big_wire_pos[i],m0);
m_rotation_z(big_wire_rot[i],m1);
m_multiply(m0,m1,m2);
sv_mesh_set_matrix(big_wire,m2);
sv_mesh_render(big_wire);
}
glDisable(GL_LIGHTING);
/* <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD> <20><><EFBFBD><EFBFBD> <20> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> */
sv_mesh_render_to_stencil(staircase,light);
sv_mesh_render_to_stencil(motor,light);
sv_mesh_render_to_stencil(cooler,light);
sv_mesh_render_to_stencil(box,light);
sv_mesh_render_to_stencil(barrel,light);
sv_mesh_render_to_stencil(shelf,light);
sv_mesh_render_to_stencil(mesh,light);
sv_mesh_render_to_stencil(computer,light);
sv_mesh_render_to_stencil(lcd,light);
for(i = 0; i < 4; i++) {
m_translate(big_wire_pos[i],m0);
m_rotation_z(big_wire_rot[i],m1);
m_multiply(m0,m1,m2);
sv_mesh_set_matrix(big_wire,m2);
sv_mesh_render_to_stencil(big_wire,light);
}
/* <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD> */
sv_mesh_render_shadow(shadow);
SDL_GL_SwapBuffers();
}
/*
*/
void idle(void) {
float ifps,rad,v[3],q0[4],q1[4],q2[3],m0[16],m1[16],m2[16];
fps = getfps();
ifps = 1.0 / fps;
if(my_pause != 2) cooler_rot += ifps * 360.0 * cooler_speed / 60.0;
m_translate(cooler_pos,m0);
m_rotation_y(cooler_rot,m1);
m_multiply(m0,m1,m2);
sv_mesh_set_matrix(cooler,m2);
if(my_pause != 2) mesh_rot += ifps * 360.0 * mesh_speed / 60.0;
m_translate(mesh_pos,m0);
m_rotation_z(mesh_rot,m1);
m_multiply(m0,m1,m2);
m_rotation_x(mesh_rot / 1.5,m0);
m_multiply(m2,m0,m1);
sv_mesh_set_matrix(mesh,m1);
if(my_pause == 0) light_rot += ifps * 360 * light_speed / 60.0;
rad = light_rot * DEG2RAD;
v_set(sin(rad) * 3,cos(rad) * 3,0,v);
v_set(0,0,2.5,light);
v_add(light,v,light);
v_set(0,0,1,v);
q_set(v,psi,q0);
v_set(0,1,0,v);
q_set(v,phi,q1);
q_multiply(q0,q1,q2);
q_to_matrix(q2,m0);
v_set(dist,0,0,camera);
v_transform(camera,m0,camera);
if(my_view == 0) v_copy(mesh_pos,dir)
else v_copy(light,dir)
v_add(camera,dir,camera);
}
/*
*/
void keyboard(int key) {
static int wareframe;
switch(key) {
case SDLK_ESCAPE:
SDL_Quit();
exit(0);
break;
case SDLK_SPACE:
my_pause++;
if(my_pause == 3) my_pause = 0;
break;
case SDLK_w:
wareframe = !wareframe;
glPolygonMode(GL_FRONT_AND_BACK,wareframe ? GL_LINE : GL_FILL);
break;
case SDLK_v:
my_view = !my_view;
break;
case SDLK_l:
light[3] = !light[3];
break;
}
}
/*
*/
void mouse(int button,int state,int x,int y) {
if(button == 4) dist -= 1;
if(button == 5) dist += 1;
if(dist < 1) dist = 1;
if(dist > 100) dist = 100;
psi += (x - WIDTH / 2) * 0.2;
phi += (y - HEIGHT / 2) * 0.2;
if(phi < -89) phi = -89;
if(phi > 89) phi = 89;
}
/*
*/
int main(int argc,char **argv) {
SDL_Surface *screen;
int done;
SDL_Init(SDL_INIT_VIDEO);
screen = SDL_SetVideoMode(WIDTH,HEIGHT,32,SDL_OPENGL | SDL_FULLSCREEN);
if(!screen) {
printf("couldn`t set video mode: %s\n",SDL_GetError());
SDL_Quit();
exit(1);
}
init();
SDL_ShowCursor(SDL_DISABLE);
SDL_WarpMouse(WIDTH / 2,HEIGHT / 2);
done = 0;
while(!done) {
SDL_Event event;
while(SDL_PollEvent(&event)) {
switch(event.type) {
case SDL_QUIT:
done = 1;
break;
case SDL_KEYDOWN:
keyboard(event.key.keysym.sym);
break;
case SDL_MOUSEMOTION:
mouse(0,0,event.motion.x,event.motion.y);
break;
case SDL_MOUSEBUTTONDOWN:
case SDL_MOUSEBUTTONUP:
mouse(event.button.button,event.button.state,
event.button.x,event.button.y);
break;
}
}
SDL_WarpMouse(WIDTH / 2,HEIGHT / 2);
idle();
render();
}
SDL_Quit();
return 0;
}