mirror of
https://github.com/ultimatepp/ultimatepp.git
synced 2026-05-15 22:02:49 -06:00
300 lines
7.1 KiB
C
300 lines
7.1 KiB
C
/* 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;
|
||
}
|