ccdemos/realtime_bunny.cc
branchpyrit
changeset 39 7079dcc3bd74
parent 38 5d043eeb09d9
child 40 929aad02c5f2
equal deleted inserted replaced
38:5d043eeb09d9 39:7079dcc3bd74
     1 #include <SDL.h>
       
     2 
       
     3 #include "raytracer.h"
     1 #include "raytracer.h"
     4 #include "octree.h"
     2 #include "octree.h"
     5 #include <iostream>
       
     6 #include <fstream>
       
     7 #include <iomanip>
       
     8 
     3 
     9 int w = 640;
     4 #include "common_sdl.h"
    10 int h = 400;
     5 #include "common_ply.h"
    11 Float *render_buffer;
       
    12 
       
    13 Raytracer rt;
       
    14 Camera cam;
       
    15 
       
    16 Uint32 fp10s_acc = 0;
       
    17 Uint32 fp10s_acc_samples = 0;
       
    18 
       
    19 void load_ply(const char *filename, Material *mat, Float scale)
       
    20 {
       
    21 	vector<NormalVertex*> vertices;
       
    22 	vector<Vector3> normals;
       
    23 	vector<int> vertex_face_num;
       
    24 	ifstream f(filename);
       
    25 	string token = "a";
       
    26 	if (!f.is_open())
       
    27 	{
       
    28 		cout << "File not found: " << filename <<endl;
       
    29 		exit(1);
       
    30 	}
       
    31 	// read header
       
    32 	int vertex_num, face_num;
       
    33 	while (token != "end_header")
       
    34 	{
       
    35 		f >> token;
       
    36 		if (token == "element")
       
    37 		{
       
    38 			f >> token;
       
    39 			if (token == "vertex")
       
    40 				f >> vertex_num;
       
    41 			if (token == "face")
       
    42 				f >> face_num;
       
    43 		}
       
    44 		f.ignore(1000,'\n');
       
    45 	}
       
    46 
       
    47 	// read vertices
       
    48 	Vector3 P;
       
    49 	int num = vertex_num;
       
    50 	while (num--)
       
    51 	{
       
    52 		f >> P.x >> P.y >> P.z;
       
    53 		P.x = -scale*P.x - 1.0;
       
    54 		P.y = scale*P.y - 3.0;
       
    55 		P.z = scale*P.z;
       
    56 		vertices.push_back(new NormalVertex(P));
       
    57 		normals.push_back(Vector3());
       
    58 		vertex_face_num.push_back(0);
       
    59 		f.ignore(1000,'\n');
       
    60 	}
       
    61 
       
    62 	// read faces
       
    63 	Triangle *face;
       
    64 	int v1, v2, v3;
       
    65 	while (face_num--)
       
    66 	{
       
    67 		f >> num;
       
    68 		if (num != 3)
       
    69 		{
       
    70 			printf("ply error: faces of %d vertices not supported", num);
       
    71 			continue;
       
    72 		}
       
    73 		f >> v1 >> v2 >> v3;
       
    74 		face = new Triangle(vertices.at(v1), vertices.at(v3), vertices.at(v2), mat);
       
    75 		rt.addshape(face);
       
    76 		face->setSmooth();
       
    77 
       
    78 		normals.at(v1) += face->getNormal();
       
    79 		vertex_face_num.at(v1)++;
       
    80 		normals.at(v2) += face->getNormal();
       
    81 		vertex_face_num.at(v2)++;
       
    82 		normals.at(v3) += face->getNormal();
       
    83 		vertex_face_num.at(v3)++;
       
    84 		f.ignore(1000,'\n');
       
    85 	}
       
    86 
       
    87 	for (int i = 0; i < vertex_num; i++)
       
    88 	{
       
    89 		normals.at(i) /= vertex_face_num.at(i);
       
    90 		normals.at(i).normalize();
       
    91 		vertices.at(i)->N = normals.at(i);
       
    92 	}
       
    93 
       
    94 	f.close();
       
    95 }
       
    96 
       
    97 void update(SDL_Surface *screen)
       
    98 {
       
    99 	static Uint32 t = 0;
       
   100 	Uint32 tnow = SDL_GetTicks();
       
   101 	int fp10s = 10000/(int)(tnow - t);
       
   102 	if (t != 0)
       
   103 	{
       
   104 		fp10s_acc += fp10s;
       
   105 		++fp10s_acc_samples;
       
   106 	}
       
   107 	t = tnow;
       
   108 	printf("\b\b\b\b\b\b\b\b\b%3d.%1d fps", fp10s/10, fp10s%10);
       
   109 	fflush(stdout);
       
   110 
       
   111 	rt.render(w, h, render_buffer);
       
   112 
       
   113 	if (SDL_MUSTLOCK(screen))
       
   114 		if (SDL_LockSurface(screen) < 0)
       
   115 			return;
       
   116 
       
   117 	Uint32 *bufp = (Uint32 *)screen->pixels;
       
   118 	unsigned char c[3];
       
   119 	for (Float *fd = render_buffer; fd != render_buffer + w*h*3; fd += 3)
       
   120 	{
       
   121 		for (int i = 0; i < 3; i++)
       
   122 		{
       
   123 			if (fd[i] > 1.0)
       
   124 				c[i] = 255;
       
   125 			else
       
   126 				c[i] = (unsigned char)(fd[i] * 255.0);
       
   127 		}
       
   128 		*bufp = SDL_MapRGB(screen->format, c[0], c[1], c[2]);
       
   129 		bufp++;
       
   130 	}
       
   131 
       
   132 	if (SDL_MUSTLOCK(screen))
       
   133 		SDL_UnlockSurface(screen);
       
   134 
       
   135 	if (screen->flags & SDL_DOUBLEBUF)
       
   136 		SDL_Flip(screen);
       
   137 	else
       
   138 		SDL_UpdateRect(screen, 0, 0, w, h);
       
   139 }
       
   140 
       
   141 void quit()
       
   142 {
       
   143 	Uint32 fp100s_aver = fp10s_acc*10/fp10s_acc_samples;
       
   144 	printf("\naverlage fps: %3d.%2d\n", fp100s_aver/100, fp100s_aver%100);
       
   145 	SDL_Quit();
       
   146 }
       
   147 
     6 
   148 int main()
     7 int main()
   149 {
     8 {
   150 	/* initialize SDL */
     9 	Raytracer rt;
   151 	SDL_Surface *screen;
    10 	Octree top;
       
    11 	Camera cam;
   152 
    12 
   153 	if( SDL_Init(SDL_INIT_VIDEO) < 0 ) {
       
   154 		fprintf(stderr, "Couldn't initialize SDL: %s\n", SDL_GetError());
       
   155 		exit(1);
       
   156 	}
       
   157 
       
   158 	atexit(quit);
       
   159 
       
   160 	screen = SDL_SetVideoMode(w, h, 32, SDL_SWSURFACE|SDL_DOUBLEBUF|SDL_RESIZABLE);
       
   161 	if ( screen == NULL ) {
       
   162 		fprintf(stderr, "Unable to set video mode: %s\n", SDL_GetError());
       
   163 		exit(1);
       
   164 	}
       
   165 
       
   166 	/* initialize raytracer and prepare scene */
       
   167 	pyrit_verbosity = 0;
       
   168 	render_buffer = (Float *) malloc(w*h*3*sizeof(Float));
       
   169 
       
   170 	rt.setThreads(2);
       
   171 	rt.setMaxDepth(0);
    13 	rt.setMaxDepth(0);
   172 
       
   173 	Octree top;
       
   174 	rt.setTop(&top);
    14 	rt.setTop(&top);
   175 
    15 
   176 	Light light1(Vector3(-5.0, 2.0, 8.0), Colour(0.9, 0.3, 0.6));
    16 	Light light1(Vector3(-5.0, 2.0, 8.0), Colour(0.9, 0.3, 0.6));
   177 	light1.castShadows(false);
    17 	light1.castShadows(false);
   178 	rt.addlight(&light1);
    18 	rt.addlight(&light1);
   180 	//Light light2(Vector3(-2.0, 10.0, 2.0), Colour(0.4, 0.6, 0.3));
    20 	//Light light2(Vector3(-2.0, 10.0, 2.0), Colour(0.4, 0.6, 0.3));
   181 	//light2.castShadows(false);
    21 	//light2.castShadows(false);
   182 	//rt.addlight(&light2);
    22 	//rt.addlight(&light2);
   183 
    23 
   184 	Material mat(Colour(0.9, 0.9, 0.9));
    24 	Material mat(Colour(0.9, 0.9, 0.9));
   185 	load_ply("../models/bunny/bun_zipper.ply", &mat, 29);
    25 	load_ply(rt, "../models/bunny/bun_zipper.ply", &mat, Vector3(-29,29,29), Vector3(-1,-3,0));
   186 
    26 
   187 	rt.setCamera(&cam);
    27 	rt.setCamera(&cam);
   188 	cam.setEye(Vector3(0,0,10));
    28 	cam.setEye(Vector3(0,0,10));
   189 
    29 
   190 	/* build kd-tree */
       
   191 	top.setMaxDepth(8);
       
   192 	top.optimize();
    30 	top.optimize();
   193 
    31 
   194 	/* loop... */
    32 	loop_sdl(rt, cam);
   195 	SDL_Event event;
       
   196 	bool quit = false;
       
   197 	Float roty = 0.0, rotx = 0.0, move = 0.0;
       
   198 	while (!quit)
       
   199 	{
       
   200 		while (SDL_PollEvent(&event))
       
   201 		{
       
   202 			switch (event.type) {
       
   203 				case SDL_VIDEORESIZE:
       
   204 					w = event.resize.w;
       
   205 					h = event.resize.h;
       
   206 					render_buffer = (Float *) realloc(render_buffer, w*h*3*sizeof(Float));
       
   207 					screen = SDL_SetVideoMode(w, h, 32, SDL_HWSURFACE|SDL_DOUBLEBUF|SDL_RESIZABLE);
       
   208 					break;
       
   209 				case SDL_KEYDOWN:
       
   210 					if (event.key.keysym.sym == SDLK_ESCAPE) {
       
   211 						quit = true;
       
   212 						break;
       
   213 					}
       
   214 					if (event.key.keysym.sym == SDLK_LEFT) {
       
   215 						roty = -0.01;
       
   216 						break;
       
   217 					}
       
   218 					if (event.key.keysym.sym == SDLK_RIGHT) {
       
   219 						roty = +0.01;
       
   220 						break;
       
   221 					}
       
   222 					if (event.key.keysym.sym == SDLK_DOWN) {
       
   223 						rotx = +0.01;
       
   224 						break;
       
   225 					}
       
   226 					if (event.key.keysym.sym == SDLK_UP) {
       
   227 						rotx = -0.01;
       
   228 						break;
       
   229 					}
       
   230 					if (event.key.keysym.sym == SDLK_w) {
       
   231 						move = +0.5;
       
   232 						break;
       
   233 					}
       
   234 					if (event.key.keysym.sym == SDLK_s) {
       
   235 						move = -0.5;
       
   236 						break;
       
   237 					}
       
   238 					break;
       
   239 				case SDL_KEYUP:
       
   240 					if (event.key.keysym.sym == SDLK_LEFT || event.key.keysym.sym == SDLK_RIGHT) {
       
   241 						roty = 0.0;
       
   242 						break;
       
   243 					}
       
   244 					if (event.key.keysym.sym == SDLK_UP || event.key.keysym.sym == SDLK_DOWN) {
       
   245 						rotx = 0.0;
       
   246 						break;
       
   247 					}
       
   248 					if (event.key.keysym.sym == SDLK_w || event.key.keysym.sym == SDLK_s) {
       
   249 							move = 0.0;
       
   250 							break;
       
   251 						}
       
   252 					break;
       
   253 				case SDL_QUIT:
       
   254 					quit = true;
       
   255 			}
       
   256 		}
       
   257 		cam.rotate(Quaternion(cos(roty),0,sin(roty),0).normalize());
       
   258 		cam.rotate(Quaternion(cos(rotx),cam.u[0]*sin(rotx),0,cam.u[2]*sin(rotx)).normalize());
       
   259 		cam.u.y = 0;
       
   260 		cam.u.normalize();
       
   261 		cam.move(move,0,0);
       
   262 		update(screen);
       
   263 	}
       
   264 
       
   265 	free(render_buffer);
       
   266 }
    33 }