ccdemos: put the common code to header files, common_ply.h and common_sdl.h pyrit
authorRadek Brich <radek.brich@devl.cz>
Fri, 14 Dec 2007 16:51:22 +0100
branchpyrit
changeset 39 7079dcc3bd74
parent 38 5d043eeb09d9
child 40 929aad02c5f2
ccdemos: put the common code to header files, common_ply.h and common_sdl.h move all ccdemos on octree and make them all realtime (-i argument)
ccdemos/Makefile
ccdemos/common_ply.h
ccdemos/common_sdl.h
ccdemos/realtime.cc
ccdemos/realtime_bunny.cc
ccdemos/realtime_dragon.cc
ccdemos/spheres_shadow.cc
--- a/ccdemos/Makefile	Fri Dec 14 10:34:31 2007 +0100
+++ b/ccdemos/Makefile	Fri Dec 14 16:51:22 2007 +0100
@@ -5,20 +5,25 @@
 include $(ROOT)/config.mk
 
 
+### Rules ###
+%.o: %.cc
+	$(CXX) -c -o $@ $(CCFLAGS) $(SDL_CCFLAGS) $< $(DEFS) -DPYRIT_DOUBLE
+
+%: %.o
+	$(CXX) -o $@ $(ROOT)/bin/libs-double/*.o $< image.o $(LDFLAGS) $(SDL_LDFLAGS) -lpng
+
 ### Targets ###
 all: realtime realtime_dragon realtime_bunny spheres_shadow
 
-realtime: realtime.o libs-double
-	$(CXX) -o $@ $(ROOT)/bin/libs-double/*.o $< $(LDFLAGS) $(SDL_LDFLAGS)
-
-realtime_dragon: realtime_dragon.o libs-double
-	$(CXX) -o $@ $(ROOT)/bin/libs-double/*.o $< $(LDFLAGS) $(SDL_LDFLAGS)
+realtime: realtime.o libs-double image.o
+realtime_dragon: realtime_dragon.o libs-double image.o
+realtime_bunny: realtime_bunny.o libs-double image.o
+spheres_shadow: spheres_shadow.o libs-double image.o
 
-realtime_bunny: realtime_bunny.o libs-double
-	$(CXX) -o $@ $(ROOT)/bin/libs-double/*.o $< $(LDFLAGS) $(SDL_LDFLAGS)
-
-spheres_shadow: spheres_shadow.o image.o libs-float
-	$(CXX) -o $@ $(ROOT)/bin/libs-float/*.o $< image.o $(LDFLAGS) -lpng
+realtime.o: realtime.cc
+realtime_dragon.o: realtime_dragon.cc common_sdl.h common_ply.h
+realtime_bunny.o: realtime_bunny.cc common_sdl.h common_ply.h
+spheres_shadow.o: spheres_shadow.cc
 
 libs-float:
 	$(MAKE) -C ../src libs-float
@@ -26,20 +31,8 @@
 libs-double:
 	$(MAKE) -C ../src libs-double
 
-realtime.o: realtime.cc
-	$(CXX) -c -o $@ $(CCFLAGS) $(SDL_CCFLAGS) $< $(DEFS) -DPYRIT_DOUBLE
-
-realtime_dragon.o: realtime_dragon.cc
-	$(CXX) -c -o $@ $(CCFLAGS) $(SDL_CCFLAGS) $< $(DEFS) -DPYRIT_DOUBLE
-
-realtime_bunny.o: realtime_bunny.cc
-	$(CXX) -c -o $@ $(CCFLAGS) $(SDL_CCFLAGS) $< $(DEFS) -DPYRIT_DOUBLE
-
 image.o: image.c
 	$(CXX) -c -o $@ $*.c
 
-spheres_shadow.o: spheres_shadow.cc
-	$(CXX) -c -o $@ $*.cc $(CCFLAGS) $(DEFS)
-
 clean:
 	rm -f spheres_shadow realtime realtime_dragon realtime_bunny *.o
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/ccdemos/common_ply.h	Fri Dec 14 16:51:22 2007 +0100
@@ -0,0 +1,81 @@
+#include <iostream>
+#include <fstream>
+#include <iomanip>
+
+void load_ply(Raytracer &rt, const char *filename, Material *mat, Vector3 scale, Vector3 transp)
+{
+	vector<NormalVertex*> vertices;
+	vector<Vector3> normals;
+	vector<int> vertex_face_num;
+	ifstream f(filename);
+	string token = "a";
+	if (!f.is_open())
+	{
+		cout << "File not found: " << filename <<endl;
+		exit(1);
+	}
+	// read header
+	int vertex_num, face_num;
+	while (token != "end_header")
+	{
+		f >> token;
+		if (token == "element")
+		{
+			f >> token;
+			if (token == "vertex")
+				f >> vertex_num;
+			if (token == "face")
+				f >> face_num;
+		}
+		f.ignore(1000,'\n');
+	}
+
+	// read vertices
+	Vector3 P;
+	int num = vertex_num;
+	while (num--)
+	{
+		f >> P.x >> P.y >> P.z;
+		P.x = scale.x*P.x + transp.x;
+		P.y = scale.y*P.y + transp.y;
+		P.z = scale.z*P.z + transp.z;
+		vertices.push_back(new NormalVertex(P));
+		normals.push_back(Vector3());
+		vertex_face_num.push_back(0);
+		f.ignore(1000,'\n');
+	}
+
+	// read faces
+	Triangle *face;
+	int v1, v2, v3;
+	while (face_num--)
+	{
+		f >> num;
+		if (num != 3)
+		{
+			printf("ply error: faces of %d vertices not supported", num);
+			continue;
+		}
+		f >> v1 >> v2 >> v3;
+		face = new Triangle(vertices.at(v1), vertices.at(v3), vertices.at(v2), mat);
+		rt.addshape(face);
+		face->setSmooth();
+
+		normals.at(v1) += face->getNormal();
+		vertex_face_num.at(v1)++;
+		normals.at(v2) += face->getNormal();
+		vertex_face_num.at(v2)++;
+		normals.at(v3) += face->getNormal();
+		vertex_face_num.at(v3)++;
+		f.ignore(1000,'\n');
+	}
+
+	for (int i = 0; i < vertex_num; i++)
+	{
+		normals.at(i) /= vertex_face_num.at(i);
+		normals.at(i).normalize();
+		vertices.at(i)->N = normals.at(i);
+	}
+
+	f.close();
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/ccdemos/common_sdl.h	Fri Dec 14 16:51:22 2007 +0100
@@ -0,0 +1,151 @@
+#include <SDL.h>
+
+Uint32 fp10s_acc = 0;
+Uint32 fp10s_acc_samples = 0;
+
+int w = 512;
+int h = 384;
+
+void update(Raytracer &rt, SDL_Surface *screen, Float *render_buffer)
+{
+	static Uint32 t = 0;
+	Uint32 tnow = SDL_GetTicks();
+	int fp10s = 10000/(int)(tnow - t);
+	if (t != 0)
+	{
+		fp10s_acc += fp10s;
+		++fp10s_acc_samples;
+	}
+	t = tnow;
+	printf("\b\b\b\b\b\b\b\b\bfps:%3d.%1d", fp10s/10, fp10s%10);
+	fflush(stdout);
+
+	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);
+}
+
+void quit()
+{
+	Uint32 fp100s_aver = fp10s_acc*10/fp10s_acc_samples;
+	printf("\naverlage fps: %3d.%2d\n", fp100s_aver/100, fp100s_aver%100);
+	SDL_Quit();
+}
+
+void loop_sdl(Raytracer &rt, Camera &cam)
+{
+	SDL_Surface *screen;
+	Float *render_buffer;
+
+	pyrit_verbosity = 0;
+	render_buffer = (Float *) malloc(w*h*3*sizeof(Float));
+
+	if( SDL_Init(SDL_INIT_VIDEO) < 0 ) {
+		fprintf(stderr, "Couldn't initialize SDL: %s\n", SDL_GetError());
+		exit(1);
+	}
+	
+	atexit(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);
+	}
+
+	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(rt, screen, render_buffer);
+	}
+	free(render_buffer);
+}
--- a/ccdemos/realtime.cc	Fri Dec 14 10:34:31 2007 +0100
+++ b/ccdemos/realtime.cc	Fri Dec 14 16:51:22 2007 +0100
@@ -1,72 +1,15 @@
-#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;
+#include "octree.h"
 
-	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);
-}
+#include "common_sdl.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);
+	Raytracer rt;
+	Octree top;
+	Camera cam;
 
-	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));
@@ -85,80 +28,7 @@
 	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);
+	loop_sdl(rt, cam);
 }
--- a/ccdemos/realtime_bunny.cc	Fri Dec 14 10:34:31 2007 +0100
+++ b/ccdemos/realtime_bunny.cc	Fri Dec 14 16:51:22 2007 +0100
@@ -1,176 +1,16 @@
-#include <SDL.h>
-
 #include "raytracer.h"
 #include "octree.h"
-#include <iostream>
-#include <fstream>
-#include <iomanip>
 
-int w = 640;
-int h = 400;
-Float *render_buffer;
-
-Raytracer rt;
-Camera cam;
-
-Uint32 fp10s_acc = 0;
-Uint32 fp10s_acc_samples = 0;
-
-void load_ply(const char *filename, Material *mat, Float scale)
-{
-	vector<NormalVertex*> vertices;
-	vector<Vector3> normals;
-	vector<int> vertex_face_num;
-	ifstream f(filename);
-	string token = "a";
-	if (!f.is_open())
-	{
-		cout << "File not found: " << filename <<endl;
-		exit(1);
-	}
-	// read header
-	int vertex_num, face_num;
-	while (token != "end_header")
-	{
-		f >> token;
-		if (token == "element")
-		{
-			f >> token;
-			if (token == "vertex")
-				f >> vertex_num;
-			if (token == "face")
-				f >> face_num;
-		}
-		f.ignore(1000,'\n');
-	}
-
-	// read vertices
-	Vector3 P;
-	int num = vertex_num;
-	while (num--)
-	{
-		f >> P.x >> P.y >> P.z;
-		P.x = -scale*P.x - 1.0;
-		P.y = scale*P.y - 3.0;
-		P.z = scale*P.z;
-		vertices.push_back(new NormalVertex(P));
-		normals.push_back(Vector3());
-		vertex_face_num.push_back(0);
-		f.ignore(1000,'\n');
-	}
-
-	// read faces
-	Triangle *face;
-	int v1, v2, v3;
-	while (face_num--)
-	{
-		f >> num;
-		if (num != 3)
-		{
-			printf("ply error: faces of %d vertices not supported", num);
-			continue;
-		}
-		f >> v1 >> v2 >> v3;
-		face = new Triangle(vertices.at(v1), vertices.at(v3), vertices.at(v2), mat);
-		rt.addshape(face);
-		face->setSmooth();
-
-		normals.at(v1) += face->getNormal();
-		vertex_face_num.at(v1)++;
-		normals.at(v2) += face->getNormal();
-		vertex_face_num.at(v2)++;
-		normals.at(v3) += face->getNormal();
-		vertex_face_num.at(v3)++;
-		f.ignore(1000,'\n');
-	}
-
-	for (int i = 0; i < vertex_num; i++)
-	{
-		normals.at(i) /= vertex_face_num.at(i);
-		normals.at(i).normalize();
-		vertices.at(i)->N = normals.at(i);
-	}
-
-	f.close();
-}
-
-void update(SDL_Surface *screen)
-{
-	static Uint32 t = 0;
-	Uint32 tnow = SDL_GetTicks();
-	int fp10s = 10000/(int)(tnow - t);
-	if (t != 0)
-	{
-		fp10s_acc += fp10s;
-		++fp10s_acc_samples;
-	}
-	t = tnow;
-	printf("\b\b\b\b\b\b\b\b\b%3d.%1d fps", fp10s/10, fp10s%10);
-	fflush(stdout);
-
-	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);
-}
-
-void quit()
-{
-	Uint32 fp100s_aver = fp10s_acc*10/fp10s_acc_samples;
-	printf("\naverlage fps: %3d.%2d\n", fp100s_aver/100, fp100s_aver%100);
-	SDL_Quit();
-}
+#include "common_sdl.h"
+#include "common_ply.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(quit);
+	Raytracer rt;
+	Octree top;
+	Camera cam;
 
-	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 */
-	pyrit_verbosity = 0;
-	render_buffer = (Float *) malloc(w*h*3*sizeof(Float));
-
-	rt.setThreads(2);
 	rt.setMaxDepth(0);
-
-	Octree top;
 	rt.setTop(&top);
 
 	Light light1(Vector3(-5.0, 2.0, 8.0), Colour(0.9, 0.3, 0.6));
@@ -182,85 +22,12 @@
 	//rt.addlight(&light2);
 
 	Material mat(Colour(0.9, 0.9, 0.9));
-	load_ply("../models/bunny/bun_zipper.ply", &mat, 29);
+	load_ply(rt, "../models/bunny/bun_zipper.ply", &mat, Vector3(-29,29,29), Vector3(-1,-3,0));
 
 	rt.setCamera(&cam);
 	cam.setEye(Vector3(0,0,10));
 
-	/* build kd-tree */
-	top.setMaxDepth(8);
 	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);
+	loop_sdl(rt, cam);
 }
--- a/ccdemos/realtime_dragon.cc	Fri Dec 14 10:34:31 2007 +0100
+++ b/ccdemos/realtime_dragon.cc	Fri Dec 14 16:51:22 2007 +0100
@@ -1,148 +1,16 @@
-#include <SDL.h>
-
 #include "raytracer.h"
 #include "octree.h"
-#include <iostream>
-#include <fstream>
 
-int w = 320;
-int h = 200;
-Float *render_buffer;
-
-Raytracer rt;
-Camera cam;
-
-void load_ply(const char *filename, Material *mat, Float scale)
-{
-	vector<NormalVertex*> vertices;
-	vector<Vector3> normals;
-	vector<int> vertex_face_num;
-	ifstream f(filename);
-	string token = "a";
-	if (!f.is_open())
-	{
-		cout << "File not found: " << filename <<endl;
-		exit(1);
-	}
-	// read header
-	int vertex_num, face_num;
-	while (token != "end_header")
-	{
-		f >> token;
-		if (token == "element")
-		{
-			f >> token;
-			if (token == "vertex")
-				f >> vertex_num;
-			if (token == "face")
-				f >> face_num;
-		}
-	}
-
-	// read vertices
-	Vector3 P;
-	for (int i = 0; i < vertex_num; i++)
-	{
-		f >> P.x >> P.y >> P.z;
-		P.x = -scale*P.x;
-		P.y = scale*P.y - 3.6;
-		P.z = -scale*P.z;
-		vertices.push_back(new NormalVertex(P));
-		normals.push_back(Vector3());
-		vertex_face_num.push_back(0);
-	}
-
-	// read faces
-	Triangle *face;
-	int v1, v2, v3;
-	for (int i = 0; i < face_num; i++)
-	{
-		f >> num;
-		if (num != 3)
-		{
-			printf("ply error: faces of %d vertices not supported", num);
-			return;
-		}
-		f >> v1 >> v2 >> v3;
-		face = new Triangle(vertices.at(v1), vertices.at(v2), vertices.at(v3), mat);
-		rt.addshape(face);
-		face->setSmooth();
-
-		normals.at(v1) += face->getNormal();
-		vertex_face_num.at(v1)++;
-		normals.at(v2) += face->getNormal();
-		vertex_face_num.at(v2)++;
-		normals.at(v3) += face->getNormal();
-		vertex_face_num.at(v3)++;
-	}
-
-	for (int i = 0; i < vertex_num; i++)
-	{
-		normals.at(i) /= vertex_face_num.at(i);
-		normals.at(i).normalize();
-		vertices.at(i)->N = normals.at(i);
-	}
-
-	f.close();
-}
-
-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);
-}
+#include "common_sdl.h"
+#include "common_ply.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);
+	Raytracer rt;
+	Octree top;
+	Camera cam;
 
-	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(0);
-
-	Octree top;
 	rt.setTop(&top);
 
 	Light light1(Vector3(-5.0, 2.0, 8.0), Colour(0.9, 0.3, 0.6));
@@ -154,83 +22,12 @@
 	//rt.addlight(&light2);
 
 	Material mat(Colour(0.9, 0.9, 0.9));
-	load_ply("../models/dragon/dragon_vrip.ply", &mat, 29);
+	load_ply(rt, "../models/dragon/dragon_vrip.ply", &mat, Vector3(-29,29,-29), Vector3(0,-3.6,0));
 
 	rt.setCamera(&cam);
 	cam.setEye(Vector3(0,0,10));
 
 	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);
+	loop_sdl(rt, cam);
 }
--- a/ccdemos/spheres_shadow.cc	Fri Dec 14 10:34:31 2007 +0100
+++ b/ccdemos/spheres_shadow.cc	Fri Dec 14 16:51:22 2007 +0100
@@ -1,15 +1,16 @@
 #include "raytracer.h"
-#include "kdtree.h"
+#include "octree.h"
+
 #include "image.h"
+#include "common_sdl.h"
 
-int main()
+int main(int argc, char **argv)
 {
 	Raytracer rt;
-	rt.setThreads(2);
 	rt.setOversample(0);
 	rt.setSubsample(8);
 
-	KdTree top;
+	Octree top;
 	rt.setTop(&top);
 
 	Light light1(Vector3(0.0, 5.0, -5.0), Colour(0.7, 0.3, 0.6));
@@ -41,22 +42,28 @@
 	cam.setEye(Vector3(0,0,15));
 	rt.setCamera(&cam);
 
-	int w = 800;
-	int h = 600;
-	Float *fdata = (Float *) malloc(w*h*3*sizeof(Float));
-	rt.render(w, h, fdata);
-
-	struct image *img;
-	new_image(&img, w, h, 3);
+	w = 800;
+	h = 600;
 
-	Float *fd = fdata;
-	for (char *cd = img->data; cd != img->data + w*h*3; cd++, fd++) {
-		if (*fd > 1.0)
-			*cd = 255;
-		else
-			*cd = (unsigned char)(*fd * 255.0);
+	if (argc == 2 && !strcmp(argv[1], "-i"))
+		loop_sdl(rt, cam);
+	else
+	{
+		Float *fdata = (Float *) malloc(w*h*3*sizeof(Float));
+		rt.render(w, h, fdata);
+	
+		struct image *img;
+		new_image(&img, w, h, 3);
+	
+		Float *fd = fdata;
+		for (char *cd = img->data; cd != img->data + w*h*3; cd++, fd++) {
+			if (*fd > 1.0)
+				*cd = 255;
+			else
+				*cd = (unsigned char)(*fd * 255.0);
+		}
+		free(fdata);
+		save_png("spheres_shadow.png", img);
+		destroy_image(&img);
 	}
-	free(fdata);
-	save_png("spheres_shadow.png", img);
-	destroy_image(&img);
 }