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