clray

annotate src/clray.cc @ 12:85fd61f374d9

fixed the bloody intersection bug
author John Tsiombikas <nuclear@member.fsf.org>
date Tue, 03 Aug 2010 13:06:59 +0100
parents deaf85acf6af
children 407935b73af3
rev   line source
nuclear@0 1 #include <stdio.h>
nuclear@3 2 #include <stdlib.h>
nuclear@2 3 #include <string.h>
nuclear@2 4 #include <errno.h>
nuclear@3 5 #ifndef __APPLE__
nuclear@3 6 #include <GL/glut.h>
nuclear@3 7 #else
nuclear@3 8 #include <GLUT/glut.h>
nuclear@3 9 #endif
nuclear@3 10 #include "rt.h"
nuclear@12 11 #include "matrix.h"
nuclear@0 12
nuclear@3 13 void cleanup();
nuclear@3 14 void disp();
nuclear@3 15 void reshape(int x, int y);
nuclear@3 16 void keyb(unsigned char key, int x, int y);
nuclear@3 17 void mouse(int bn, int status, int x, int y);
nuclear@3 18 void motion(int x, int y);
nuclear@2 19 bool write_ppm(const char *fname, float *fb, int xsz, int ysz);
nuclear@2 20
nuclear@3 21 static int xsz, ysz;
nuclear@3 22 static bool need_update = true;
nuclear@3 23
nuclear@8 24 static float cam_theta, cam_phi = 25.0;
nuclear@8 25 static float cam_dist = 10.0;
nuclear@8 26
nuclear@12 27 static bool dbg_glrender;
nuclear@12 28
nuclear@3 29 int main(int argc, char **argv)
nuclear@0 30 {
nuclear@3 31 glutInitWindowSize(800, 600);
nuclear@3 32 glutInit(&argc, argv);
nuclear@3 33 glutInitDisplayMode(GLUT_RGB | GLUT_DOUBLE);
nuclear@3 34 glutCreateWindow("OpenCL Raytracer");
nuclear@0 35
nuclear@3 36 xsz = glutGet(GLUT_WINDOW_WIDTH);
nuclear@3 37 ysz = glutGet(GLUT_WINDOW_HEIGHT);
nuclear@2 38
nuclear@3 39 glutDisplayFunc(disp);
nuclear@3 40 glutReshapeFunc(reshape);
nuclear@3 41 glutKeyboardFunc(keyb);
nuclear@3 42 glutMouseFunc(mouse);
nuclear@3 43 glutMotionFunc(motion);
nuclear@0 44
nuclear@12 45 if(!init_renderer(xsz, ysz)) {
nuclear@0 46 return 1;
nuclear@0 47 }
nuclear@3 48 atexit(cleanup);
nuclear@0 49
nuclear@3 50 /*glGenTextures(1, &tex);
nuclear@3 51 glBindTexture(GL_TEXTURE_2D, tex);*/
nuclear@3 52 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP);
nuclear@3 53 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP);
nuclear@3 54 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
nuclear@3 55 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
nuclear@3 56 glTexImage2D(GL_TEXTURE_2D, 0, 4, xsz, ysz, 0, GL_RGBA, GL_FLOAT, 0);
nuclear@2 57
nuclear@3 58 glutMainLoop();
nuclear@0 59 return 0;
nuclear@0 60 }
nuclear@2 61
nuclear@3 62 void cleanup()
nuclear@2 63 {
nuclear@3 64 destroy_renderer();
nuclear@3 65 }
nuclear@2 66
nuclear@12 67 static Matrix4x4 mat, inv_mat, inv_trans;
nuclear@12 68
nuclear@3 69 void disp()
nuclear@3 70 {
nuclear@8 71 glMatrixMode(GL_MODELVIEW);
nuclear@8 72 glLoadIdentity();
nuclear@8 73
nuclear@3 74 if(need_update) {
nuclear@12 75 glPushMatrix();
nuclear@12 76 glRotatef(-cam_theta, 0, 1, 0);
nuclear@12 77 glRotatef(-cam_phi, 1, 0, 0);
nuclear@12 78 glTranslatef(0, 0, cam_dist);
nuclear@8 79
nuclear@12 80 glGetFloatv(GL_MODELVIEW_MATRIX, mat.m);
nuclear@8 81
nuclear@12 82 inv_mat = mat;
nuclear@12 83 inv_mat.invert();
nuclear@12 84
nuclear@12 85 /*inv_trans = inv_mat;
nuclear@12 86 inv_trans.transpose();*/
nuclear@12 87 inv_trans = mat;
nuclear@12 88 inv_trans.m[3] = inv_trans.m[7] = inv_trans.m[11] = 0.0;
nuclear@12 89 inv_trans.m[12] = inv_trans.m[13] = inv_trans.m[14] = 0.0;
nuclear@12 90 inv_trans.m[15] = 1.0;
nuclear@12 91
nuclear@12 92 set_xform(mat.m, inv_trans.m);
nuclear@8 93 glPopMatrix();
nuclear@8 94
nuclear@12 95 if(!render()) {
nuclear@12 96 exit(1);
nuclear@12 97 }
nuclear@3 98 need_update = false;
nuclear@3 99 }
nuclear@2 100
nuclear@12 101 if(dbg_glrender) {
nuclear@12 102 glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
nuclear@12 103 glLoadMatrixf(inv_mat.m);
nuclear@12 104 dbg_render_gl();
nuclear@12 105 } else {
nuclear@12 106 glEnable(GL_TEXTURE_2D);
nuclear@2 107
nuclear@12 108 glBegin(GL_QUADS);
nuclear@12 109 glColor3f(1, 1, 1);
nuclear@12 110 glTexCoord2f(0, 1); glVertex2f(-1, -1);
nuclear@12 111 glTexCoord2f(1, 1); glVertex2f(1, -1);
nuclear@12 112 glTexCoord2f(1, 0); glVertex2f(1, 1);
nuclear@12 113 glTexCoord2f(0, 0); glVertex2f(-1, 1);
nuclear@12 114 glEnd();
nuclear@2 115
nuclear@12 116 glDisable(GL_TEXTURE_2D);
nuclear@12 117 }
nuclear@3 118
nuclear@3 119 glutSwapBuffers();
nuclear@3 120 }
nuclear@3 121
nuclear@3 122 void reshape(int x, int y)
nuclear@3 123 {
nuclear@3 124 glViewport(0, 0, x, y);
nuclear@3 125
nuclear@3 126 /* reallocate the framebuffer */
nuclear@3 127 /*delete [] fb;
nuclear@3 128 fb = new float[x * y * 4];
nuclear@3 129 set_framebuffer(fb, x, y);*/
nuclear@3 130 }
nuclear@3 131
nuclear@3 132 void keyb(unsigned char key, int x, int y)
nuclear@3 133 {
nuclear@3 134 switch(key) {
nuclear@3 135 case 27:
nuclear@3 136 exit(0);
nuclear@3 137
nuclear@12 138 case 'r':
nuclear@12 139 need_update = true;
nuclear@12 140 glutPostRedisplay();
nuclear@3 141 break;
nuclear@3 142
nuclear@12 143 case 'd':
nuclear@12 144 dbg_glrender = !dbg_glrender;
nuclear@12 145 if(dbg_glrender) {
nuclear@12 146 printf("DEBUG GL RENDER\n");
nuclear@12 147 }
nuclear@3 148 glutPostRedisplay();
nuclear@3 149 break;
nuclear@3 150
nuclear@3 151 default:
nuclear@3 152 break;
nuclear@3 153 }
nuclear@3 154 }
nuclear@3 155
nuclear@8 156 static bool bnstate[32];
nuclear@8 157 static int prev_x, prev_y;
nuclear@8 158
nuclear@3 159 void mouse(int bn, int state, int x, int y)
nuclear@3 160 {
nuclear@8 161 if(state == GLUT_DOWN) {
nuclear@8 162 prev_x = x;
nuclear@8 163 prev_y = y;
nuclear@8 164 bnstate[bn] = true;
nuclear@8 165 } else {
nuclear@8 166 bnstate[bn] = false;
nuclear@8 167 }
nuclear@3 168 }
nuclear@3 169
nuclear@8 170 #define ROT_SCALE 0.5
nuclear@8 171 #define PAN_SCALE 0.1
nuclear@8 172
nuclear@3 173 void motion(int x, int y)
nuclear@3 174 {
nuclear@8 175 int dx = x - prev_x;
nuclear@8 176 int dy = y - prev_y;
nuclear@8 177 prev_x = x;
nuclear@8 178 prev_y = y;
nuclear@8 179
nuclear@8 180 if(bnstate[0]) {
nuclear@8 181 cam_theta += dx * ROT_SCALE;
nuclear@8 182 cam_phi += dy * ROT_SCALE;
nuclear@8 183
nuclear@12 184 if(cam_phi < -89) cam_phi = -89;
nuclear@8 185 if(cam_phi > 89) cam_phi = 89;
nuclear@8 186
nuclear@8 187 need_update = true;
nuclear@8 188 glutPostRedisplay();
nuclear@8 189 }
nuclear@8 190 if(bnstate[2]) {
nuclear@8 191 cam_dist += dy * PAN_SCALE;
nuclear@8 192 if(cam_dist < 0) cam_dist = 0;
nuclear@8 193
nuclear@8 194 need_update = true;
nuclear@8 195 glutPostRedisplay();
nuclear@8 196 }
nuclear@2 197 }
nuclear@2 198
nuclear@2 199 bool write_ppm(const char *fname, float *fb, int xsz, int ysz)
nuclear@2 200 {
nuclear@2 201 FILE *fp;
nuclear@2 202
nuclear@2 203 if(!(fp = fopen(fname, "wb"))) {
nuclear@2 204 fprintf(stderr, "write_ppm: failed to open file %s for writing: %s\n", fname, strerror(errno));
nuclear@2 205 return false;
nuclear@2 206 }
nuclear@2 207 fprintf(fp, "P6\n%d %d\n255\n", xsz, ysz);
nuclear@2 208
nuclear@2 209 for(int i=0; i<xsz * ysz * 4; i++) {
nuclear@2 210 if(i % 4 == 3) continue;
nuclear@2 211
nuclear@2 212 unsigned char c = (unsigned char)(fb[i] * 255.0);
nuclear@2 213 fputc(c, fp);
nuclear@2 214 }
nuclear@2 215 fclose(fp);
nuclear@2 216 return true;
nuclear@2 217 }