--- /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 <SDL.h>
+
+#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);
+}