octree traversal rewritten to avoid recursion
reenabled -O3 optimizations (was accidentaly disabled, now it traces even faster! :-))
realtime_bunny: added FPS counter, fixed a bug in ply loader
min3 and max3 templates added to common.h
+ − #include <SDL.h>
+ −
+ − #include "raytracer.h"
+ − #include "kdtree.h"
+ −
+ − int w = 480;
+ − int h = 288;
+ − 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);
+ −
+ − if (screen->flags & SDL_DOUBLEBUF)
+ − SDL_Flip(screen);
+ − else
+ − SDL_UpdateRect(screen, 0, 0, w, h);
+ − }
+ −
+ − 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_SWSURFACE|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);
+ − rt.setMaxDepth(3);
+ −
+ − KdTree top;
+ − rt.setTop(&top);
+ −
+ − Light light1(Vector3(2.0, -5.0, -5.0), Colour(0.7, 0.3, 0.6));
+ − light1.castShadows(false);
+ − rt.addlight(&light1);
+ −
+ − Light light2(Vector3(-2.0, 10.0, 2.0), Colour(0.4, 0.6, 0.3));
+ − light2.castShadows(false);
+ − rt.addlight(&light2);
+ −
+ − Material mat_sph(Colour(1.0, 1.0, 1.0));
+ − for (int y=0; y<10; y++)
+ − for (int x=0; x<10; x++)
+ − rt.addshape(new Sphere(Vector3(x*2-10, (Float)random()/RAND_MAX*5.0, y*2-10), 0.45, &mat_sph));
+ −
+ − rt.setCamera(&cam);
+ − cam.setEye(Vector3(0,0,10));
+ −
+ − /* build kd-tree */
+ − top.setMaxDepth(100);
+ − 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);
+ − }