diff -r 4e0955fca797 -r f22952603f29 ccdemos/realtime.cc --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/ccdemos/realtime.cc Thu Nov 29 18:30:16 2007 +0100 @@ -0,0 +1,160 @@ +#include + +#include "raytracer.h" + +int w = 512; +int h = 200; +float *render_buffer; + +Raytracer rt; +Camera cam; + +void update(SDL_Surface *screen) +{ + rt.render(w, h, render_buffer); + + if ( SDL_MUSTLOCK(screen) ) { + if ( SDL_LockSurface(screen) < 0 ) { + return; + } + } + + Uint32 *bufp = (Uint32 *)screen->pixels; + unsigned char c[3]; + for (float *fd = render_buffer; fd != render_buffer + w*h*3; fd += 3) + { + for (int i = 0; i < 3; i++) + { + if (fd[i] > 1.0) + c[i] = 255; + else + c[i] = (unsigned char)(fd[i] * 255.0); + } + *bufp = SDL_MapRGB(screen->format, c[0], c[1], c[2]); + bufp++; + } + + if ( SDL_MUSTLOCK(screen) ) { + SDL_UnlockSurface(screen); + } + + SDL_UpdateRect(screen, 0, 0, w, h); + SDL_Flip(screen); +} + +int main() +{ + /* initialize SDL */ + SDL_Surface *screen; + + if( SDL_Init(SDL_INIT_VIDEO) < 0 ) { + fprintf(stderr, "Couldn't initialize SDL: %s\n", SDL_GetError()); + exit(1); + } + + atexit(SDL_Quit); + + screen = SDL_SetVideoMode(w, h, 32, SDL_HWSURFACE|SDL_DOUBLEBUF|SDL_RESIZABLE); + if ( screen == NULL ) { + fprintf(stderr, "Unable to set video mode: %s\n", SDL_GetError()); + exit(1); + } + + /* initialize raytracer and prepare scene */ + render_buffer = (float *) malloc(w*h*3*sizeof(float)); + + rt.setThreads(2); + + KdTree top; + rt.setTop(&top); + + Light light1(Vector3(2.0, -5.0, -5.0), Colour(0.7, 0.3, 0.6)); + rt.addlight(&light1); + + Light light2(Vector3(-2.0, 10.0, 2.0), Colour(0.4, 0.6, 0.3)); + rt.addlight(&light2); + + Material mat_sph(Colour(1.0, 1.0, 1.0)); + for (int y=0; y<20; y++) + for (int x=0; x<20; x++) + rt.addshape(new Sphere(Vector3(x-10, (float)random()/RAND_MAX*5.0, y-10), 0.45, &mat_sph)); + + rt.setCamera(&cam); + cam.setEye(Vector3(0,0,10)); + + /* build kd-tree */ + top.optimize(); + + /* loop... */ + SDL_Event event; + bool quit = false; + float roty = 0.0, rotx = 0.0, move = 0.0; + while (!quit) + { + while (SDL_PollEvent(&event)) + { + switch (event.type) { + case SDL_VIDEORESIZE: + w = event.resize.w; + h = event.resize.h; + render_buffer = (float *) realloc(render_buffer, w*h*3*sizeof(float)); + screen = SDL_SetVideoMode(w, h, 32, SDL_HWSURFACE|SDL_DOUBLEBUF|SDL_RESIZABLE); + break; + case SDL_KEYDOWN: + if (event.key.keysym.sym == SDLK_ESCAPE) { + quit = true; + break; + } + if (event.key.keysym.sym == SDLK_LEFT) { + roty = -0.01; + break; + } + if (event.key.keysym.sym == SDLK_RIGHT) { + roty = +0.01; + break; + } + if (event.key.keysym.sym == SDLK_DOWN) { + rotx = +0.01; + break; + } + if (event.key.keysym.sym == SDLK_UP) { + rotx = -0.01; + break; + } + if (event.key.keysym.sym == SDLK_w) { + move = +0.5; + break; + } + if (event.key.keysym.sym == SDLK_s) { + move = -0.5; + break; + } + break; + case SDL_KEYUP: + if (event.key.keysym.sym == SDLK_LEFT || event.key.keysym.sym == SDLK_RIGHT) { + roty = 0.0; + break; + } + if (event.key.keysym.sym == SDLK_UP || event.key.keysym.sym == SDLK_DOWN) { + rotx = 0.0; + break; + } + if (event.key.keysym.sym == SDLK_w || event.key.keysym.sym == SDLK_s) { + move = 0.0; + break; + } + break; + case SDL_QUIT: + quit = true; + } + } + cam.rotate(Quaternion(cos(roty),0,sin(roty),0).normalize()); + cam.rotate(Quaternion(cos(rotx),cam.u[0]*sin(rotx),0,cam.u[2]*sin(rotx)).normalize()); + cam.u.y = 0; + cam.u.normalize(); + cam.move(move,0,0); + update(screen); + } + + free(render_buffer); +}