clray

view src/clray.cc @ 34:a218551293ad

blah blah blah
author John Tsiombikas <nuclear@member.fsf.org>
date Tue, 24 Aug 2010 18:35:03 +0100
parents 4cf4919c3812
children 980bc07be868
line source
1 #include <stdio.h>
2 #include <stdlib.h>
3 #include <string.h>
4 #include <ctype.h>
5 #include <errno.h>
6 #ifndef __APPLE__
7 #include <GL/glut.h>
8 #else
9 #include <GLUT/glut.h>
10 #endif
11 #include "rt.h"
12 #include "matrix.h"
13 #include "scene.h"
15 void cleanup();
16 void disp();
17 void reshape(int x, int y);
18 void keyb(unsigned char key, int x, int y);
19 void mouse(int bn, int status, int x, int y);
20 void motion(int x, int y);
21 bool write_ppm(const char *fname, float *fb, int xsz, int ysz);
23 static int xsz, ysz;
24 static bool need_update = true;
26 static float cam_theta, cam_phi = 25.0;
27 static float cam_dist = 10.0;
29 static bool dbg_glrender = false;
30 static bool dbg_show_kdtree = false;
31 static bool dbg_show_obj = true;
33 static Scene scn;
35 int main(int argc, char **argv)
36 {
37 glutInitWindowSize(800, 600);
38 glutInit(&argc, argv);
40 int loaded = 0;
41 for(int i=1; i<argc; i++) {
42 if(argv[i][0] == '-' && argv[i][2] == 0) {
43 switch(argv[i][1]) {
44 case 'i':
45 if(!argv[++i] || !isdigit(argv[i][0])) {
46 fprintf(stderr, "-i must be followed by the intersection cost\n");
47 return 1;
48 }
50 set_accel_param(ACCEL_PARAM_COST_INTERSECT, atoi(argv[i]));
51 break;
53 case 't':
54 if(!argv[++i] || !isdigit(argv[i][0])) {
55 fprintf(stderr, "-t must be followed by the traversal cost\n");
56 return 1;
57 }
59 set_accel_param(ACCEL_PARAM_COST_TRAVERSE, atoi(argv[i]));
60 break;
62 case 'c':
63 if(!argv[++i] || !isdigit(argv[i][0])) {
64 fprintf(stderr, "-c must be followed by the max number of items per leaf node\n");
65 return 1;
66 }
68 set_accel_param(ACCEL_PARAM_MAX_NODE_ITEMS, atoi(argv[i]));
69 break;
71 default:
72 fprintf(stderr, "unrecognized option: %s\n", argv[i]);
73 return 1;
74 }
75 } else {
76 if(!scn.load(argv[i])) {
77 fprintf(stderr, "failed to load scene: %s\n", argv[i]);
78 return false;
79 }
80 loaded++;
81 }
82 }
84 if(!loaded) {
85 fprintf(stderr, "you must specify a scene file to load\n");
86 return false;
87 }
88 if(!scn.get_num_faces()) {
89 fprintf(stderr, "didn't load any polygons\n");
90 return false;
91 }
93 glutInitDisplayMode(GLUT_RGB | GLUT_DEPTH | GLUT_DOUBLE);
94 glutCreateWindow("OpenCL Raytracer");
96 xsz = glutGet(GLUT_WINDOW_WIDTH);
97 ysz = glutGet(GLUT_WINDOW_HEIGHT);
99 glutDisplayFunc(disp);
100 glutReshapeFunc(reshape);
101 glutKeyboardFunc(keyb);
102 glutMouseFunc(mouse);
103 glutMotionFunc(motion);
105 if(!init_renderer(xsz, ysz, &scn)) {
106 return 1;
107 }
108 atexit(cleanup);
110 unsigned int *test_pattern = new unsigned int[xsz * ysz];
111 for(int i=0; i<ysz; i++) {
112 for(int j=0; j<xsz; j++) {
113 test_pattern[i * xsz + j] = ((i >> 4) & 1) == ((j >> 4) & 1) ? 0xff0000 : 0xff00;
114 }
115 }
117 /*glGenTextures(1, &tex);
118 glBindTexture(GL_TEXTURE_2D, tex);*/
119 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP);
120 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP);
121 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
122 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
123 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB32F_ARB, xsz, ysz, 0, GL_RGBA, GL_UNSIGNED_BYTE, test_pattern);
124 delete [] test_pattern;
126 glutMainLoop();
127 return 0;
128 }
130 void cleanup()
131 {
132 destroy_renderer();
133 }
135 static Matrix4x4 mat, inv_mat, inv_trans;
137 void disp()
138 {
139 glMatrixMode(GL_MODELVIEW);
140 glLoadIdentity();
142 if(need_update) {
143 glPushMatrix();
144 glRotatef(-cam_theta, 0, 1, 0);
145 glRotatef(-cam_phi, 1, 0, 0);
146 glTranslatef(0, 0, cam_dist);
148 glGetFloatv(GL_MODELVIEW_MATRIX, mat.m);
150 inv_mat = mat;
151 inv_mat.invert();
153 /*inv_trans = inv_mat;
154 inv_trans.transpose();*/
155 inv_trans = mat;
156 inv_trans.m[3] = inv_trans.m[7] = inv_trans.m[11] = 0.0;
157 inv_trans.m[12] = inv_trans.m[13] = inv_trans.m[14] = 0.0;
158 inv_trans.m[15] = 1.0;
160 set_xform(mat.m, inv_trans.m);
161 glPopMatrix();
163 if(!dbg_glrender) {
164 if(!render()) {
165 exit(1);
166 }
167 need_update = false;
168 }
169 }
171 if(dbg_glrender) {
172 glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
173 glLoadMatrixf(inv_mat.m);
174 dbg_render_gl(&scn, dbg_show_kdtree, dbg_show_obj);
175 } else {
176 glEnable(GL_TEXTURE_2D);
177 glDisable(GL_LIGHTING);
179 glBegin(GL_QUADS);
180 glColor3f(1, 1, 1);
181 glTexCoord2f(0, 1); glVertex2f(-1, -1);
182 glTexCoord2f(1, 1); glVertex2f(1, -1);
183 glTexCoord2f(1, 0); glVertex2f(1, 1);
184 glTexCoord2f(0, 0); glVertex2f(-1, 1);
185 glEnd();
187 glDisable(GL_TEXTURE_2D);
188 }
190 glutSwapBuffers();
191 }
193 void reshape(int x, int y)
194 {
195 glViewport(0, 0, x, y);
197 /* reallocate the framebuffer */
198 /*delete [] fb;
199 fb = new float[x * y * 4];
200 set_framebuffer(fb, x, y);*/
201 }
203 void keyb(unsigned char key, int x, int y)
204 {
205 switch(key) {
206 case 27:
207 exit(0);
209 case 'r':
210 need_update = true;
211 glutPostRedisplay();
212 break;
214 case 'd':
215 dbg_glrender = !dbg_glrender;
216 if(dbg_glrender) {
217 printf("Debug OpenGL rendering\n");
218 } else {
219 printf("Raytracing\n");
220 }
221 glutPostRedisplay();
222 break;
224 case 'k':
225 dbg_show_kdtree = !dbg_show_kdtree;
226 if(dbg_glrender) {
227 glutPostRedisplay();
228 }
229 break;
231 case 'o':
232 dbg_show_obj = !dbg_show_obj;
233 if(dbg_glrender) {
234 glutPostRedisplay();
235 }
236 break;
238 default:
239 break;
240 }
241 }
243 static bool bnstate[32];
244 static int prev_x, prev_y;
246 void mouse(int bn, int state, int x, int y)
247 {
248 if(state == GLUT_DOWN) {
249 prev_x = x;
250 prev_y = y;
251 bnstate[bn] = true;
252 } else {
253 bnstate[bn] = false;
254 }
255 }
257 #define ROT_SCALE 0.5
258 #define PAN_SCALE 0.1
260 void motion(int x, int y)
261 {
262 int dx = x - prev_x;
263 int dy = y - prev_y;
264 prev_x = x;
265 prev_y = y;
267 if(bnstate[0]) {
268 cam_theta += dx * ROT_SCALE;
269 cam_phi += dy * ROT_SCALE;
271 if(cam_phi < -89) cam_phi = -89;
272 if(cam_phi > 89) cam_phi = 89;
274 need_update = true;
275 glutPostRedisplay();
276 }
277 if(bnstate[2]) {
278 cam_dist += dy * PAN_SCALE;
279 if(cam_dist < 0) cam_dist = 0;
281 need_update = true;
282 glutPostRedisplay();
283 }
284 }
286 bool write_ppm(const char *fname, float *fb, int xsz, int ysz)
287 {
288 FILE *fp;
290 if(!(fp = fopen(fname, "wb"))) {
291 fprintf(stderr, "write_ppm: failed to open file %s for writing: %s\n", fname, strerror(errno));
292 return false;
293 }
294 fprintf(fp, "P6\n%d %d\n255\n", xsz, ysz);
296 for(int i=0; i<xsz * ysz * 4; i++) {
297 if(i % 4 == 3) continue;
299 unsigned char c = (unsigned char)(fb[i] * 255.0);
300 fputc(c, fp);
301 }
302 fclose(fp);
303 return true;
304 }