vizrays.c (7371B)
1 #include "viz.h" /* for vizrays */ 2 #include "../inc/vec3.h" /* for Vec3 */ 3 #include "../inc/scene.h" /* for Scene, Mesh, scene_load */ 4 #include "../inc/ray.h" /* for Ray */ 5 6 #include <GL/glut.h> 7 #include <stdio.h> 8 #include <stdlib.h> 9 #include <math.h> 10 #include <stdint.h> 11 #include <ctype.h> /* for tolower */ 12 13 /** 14 * Structs 15 */ 16 17 typedef struct { 18 Vec3 o, t; 19 float d; 20 float lastX, lastY; 21 float yaw, pitch, roll; 22 } Camera; 23 24 /** 25 * Globals 26 */ 27 28 Camera g_cam = { 29 {0.f, 0.f, 5.f}, 30 {0.f, 0.f, 0.f}, 31 5.f, 32 0.f, 0.f, 33 0.f, 0.f, 0.f 34 }; 35 uint8_t g_mouseDown = 0; 36 37 Ray* g_rays = NULL; 38 uint8_t *g_active = NULL; 39 Scene* g_scene = NULL; 40 41 uint32_t g_numTx = 0; 42 uint32_t g_numPaths = 0; 43 uint32_t g_numBounces = 0; 44 45 uint32_t g_bounce_cur = 0; 46 47 /** 48 * Draw functions 49 */ 50 51 void drawScene() { 52 glBegin(GL_TRIANGLES); 53 for (uint32_t i = 0; i < g_scene->num_meshes; i++) { 54 Mesh* mesh = &g_scene->meshes[i]; 55 float mesh_color = (float)i / g_scene->num_meshes; 56 glColor3f(mesh_color, 1.f - mesh_color, 0.f); 57 58 for (uint32_t j = 0; j < mesh->num_triangles; j++) { 59 uint32_t idx = mesh->is[j * 3]; 60 Vec3 v1 = mesh->vs[idx]; 61 idx = mesh->is[j * 3 + 1]; 62 Vec3 v2 = mesh->vs[idx]; 63 idx = mesh->is[j * 3 + 2]; 64 Vec3 v3 = mesh->vs[idx]; 65 glVertex3f(v1.x, v1.y, v1.z); 66 glVertex3f(v2.x, v2.y, v2.z); 67 glVertex3f(v3.x, v3.y, v3.z); 68 } 69 } 70 glEnd(); 71 } 72 73 void drawRays() { 74 float color = (float)g_bounce_cur / g_numBounces; 75 glColor3f(color, 0.0f, 1.0f - color); 76 77 uint8_t active_bit = 1; 78 uint32_t num_skipped = 0; 79 for (uint32_t tx = 0; tx < g_numTx; ++tx) { 80 glBegin(GL_LINES); 81 82 uint32_t active_byte = (tx * (g_numBounces + 1) + g_bounce_cur) * (g_numPaths / 8 + 1); 83 uint32_t ray_ind_base = (tx * (g_numBounces + 1) + g_bounce_cur) * g_numPaths; 84 85 for (uint32_t path = 0; path < g_numPaths; ++path, active_bit <<= 1) { 86 if (!active_bit) { 87 active_byte++; 88 active_bit = 1; 89 } 90 if (!(g_active[active_byte] & active_bit)) 91 { 92 num_skipped++; 93 continue; 94 } 95 96 uint32_t idx = ray_ind_base + path; 97 GLfloat x = g_rays[idx].o.x; 98 GLfloat y = g_rays[idx].o.y; 99 GLfloat z = g_rays[idx].o.z; 100 /* Origin */ 101 glVertex3f(x, y, z); 102 /* Destination */ 103 glVertex3f( 104 x + g_rays[idx].d.x, 105 y + g_rays[idx].d.y, 106 z + g_rays[idx].d.z 107 ); 108 } 109 glEnd(); 110 111 /* Draw points */ 112 glPointSize(5.0f); 113 glBegin(GL_POINTS); 114 active_byte = g_bounce_cur * (g_numTx * g_numPaths / 8 + 1); 115 active_bit = 1; 116 for (uint32_t path = 0; path < g_numPaths; ++path) { 117 if (!active_bit) { 118 active_byte++; 119 active_bit = 1; 120 } 121 if (!(g_active[active_byte] & active_bit)) 122 continue; 123 uint32_t idx = ray_ind_base + path; 124 glVertex3f(g_rays[idx].o.x, g_rays[idx].o.y, g_rays[idx].o.z); 125 } 126 glEnd(); 127 } 128 129 printf("\rSkipped %d paths", num_skipped); 130 fflush(stdout); 131 } 132 133 /** 134 * Callbacks 135 */ 136 137 void reshape(int w, int h) { 138 glViewport(0, 0, w, h); 139 glMatrixMode(GL_PROJECTION); 140 glLoadIdentity(); 141 gluPerspective(60.0f, (float)w/h, 0.1f, 1000.0f); 142 glMatrixMode(GL_MODELVIEW); 143 } 144 145 void display() { 146 glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); 147 glLoadIdentity(); 148 149 /* Look at target from camera position */ 150 gluLookAt( 151 g_cam.o.x, g_cam.o.y, g_cam.o.z, 152 g_cam.t.x, g_cam.t.y, g_cam.t.z, 153 0.0f, 1.0f, 0.0f 154 ); 155 156 if (g_scene) drawScene(); 157 drawRays(); 158 159 glutSwapBuffers(); 160 } 161 162 void updateCamera() { 163 float x = g_cam.d * cosf(g_cam.pitch) * cosf(g_cam.yaw); 164 float y = g_cam.d * sinf(g_cam.pitch); 165 float z = g_cam.d * cosf(g_cam.pitch) * sinf(g_cam.yaw); 166 167 g_cam.o.x = g_cam.t.x + x; 168 g_cam.o.y = g_cam.t.y + y; 169 g_cam.o.z = g_cam.t.z + z; 170 171 gluLookAt(g_cam.o.x, g_cam.o.y, g_cam.o.z, 172 g_cam.t.x, g_cam.t.y, g_cam.t.z, 173 0.f, 1.f, 0.f); 174 } 175 176 void keyboard(unsigned char key, int x, int y) { 177 float moveSpeed = 0.1f; 178 float tiltSpeed = 0.15f; 179 /* Speed up if SHIFT is down */ 180 if (glutGetModifiers() & GLUT_ACTIVE_SHIFT) { 181 moveSpeed *= 5; 182 key = tolower(key); 183 } 184 185 /* Calculate forward direction */ 186 Vec3 dir = { 187 g_cam.t.x - g_cam.o.x, 188 g_cam.t.y - g_cam.o.y, 189 g_cam.t.z - g_cam.o.z 190 }; 191 float norm = sqrtf(dir.x * dir.x + dir.y * dir.y + dir.z * dir.z); 192 Vec3 forward = {dir.x / norm, dir.y / norm, dir.z / norm}; 193 194 /* Calculate right vector (cross product of forward and up (0,0,1)) */ 195 norm = sqrtf(forward.z * forward.z + forward.x * forward.x); 196 Vec3 right = {forward.z / norm, 0.0f, -forward.x / norm}; 197 198 switch (key) { 199 case 'w': /* Move target forward */ 200 g_cam.t.x += forward.x * moveSpeed; 201 g_cam.t.z += forward.z * moveSpeed; 202 break; 203 case 's': /* Move target backward */ 204 g_cam.t.x -= forward.x * moveSpeed; 205 g_cam.t.z -= forward.z * moveSpeed; 206 break; 207 case 'a': /* Move target left */ 208 g_cam.t.x += right.x * moveSpeed; 209 g_cam.t.z += right.z * moveSpeed; 210 break; 211 case 'd': /* Move target right */ 212 g_cam.t.x -= right.x * moveSpeed; 213 g_cam.t.z -= right.z * moveSpeed; 214 break; 215 216 case 'q': /* Roll left */ 217 g_cam.roll += tiltSpeed; 218 break; 219 case 'e': /* Roll right */ 220 g_cam.roll -= tiltSpeed; 221 break; 222 223 case 'x': /* Increase g_curBounce */ 224 if (g_bounce_cur < g_numBounces) g_bounce_cur++; 225 break; 226 case 'z': /* Decrease g_curBounce */ 227 if (g_bounce_cur > 0) g_bounce_cur--; 228 break; 229 } 230 231 updateCamera(); 232 glutPostRedisplay(); 233 } 234 235 void mouse(int button, int state, int x, int y) { 236 if (button == GLUT_LEFT_BUTTON) { 237 g_mouseDown = (state == GLUT_DOWN); 238 g_cam.lastX = x; 239 g_cam.lastY = y; 240 } 241 /* Handle scroll wheel */ 242 else if (button == 3) { /* Scroll up */ 243 g_cam.d = fmaxf(0.1f, g_cam.d - 0.5f); /* Prevent going too close */ 244 updateCamera(); 245 glutPostRedisplay(); 246 } 247 else if (button == 4) { /* Scroll down */ 248 g_cam.d += 0.5f; 249 updateCamera(); 250 glutPostRedisplay(); 251 } 252 } 253 254 void mouseMotion(int x, int y) { 255 if (!g_mouseDown) return; 256 257 float sensitivity = 0.005f; 258 float dx = (float)(x - g_cam.lastX); 259 float dy = (float)(y - g_cam.lastY); 260 261 g_cam.yaw -= dx * sensitivity; 262 g_cam.pitch -= dy * sensitivity; 263 264 /* Clamp pitch to prevent flipping */ 265 if (g_cam.pitch > 1.5f) g_cam.pitch = 1.5f; 266 if (g_cam.pitch < -1.5f) g_cam.pitch = -1.5f; 267 268 g_cam.lastX = x; 269 g_cam.lastY = y; 270 271 updateCamera(); 272 glutPostRedisplay(); 273 } 274 275 /** 276 * vizrays 277 */ 278 279 void vizrays( 280 IN RaysInfo *raysInfo, 281 IN Scene *scene, 282 IN uint32_t numTx 283 ) 284 { 285 g_rays = raysInfo->rays; 286 g_active = raysInfo->rays_active; 287 g_scene = scene; 288 g_numTx = numTx; 289 g_numPaths = raysInfo->num_rays; 290 g_numBounces = raysInfo->num_bounces; 291 292 /* Initialize GLUT */ 293 int fake_argc = 1; 294 char *fake_argv[] = {"vizrays"}; 295 glutInit(&fake_argc, fake_argv); 296 glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGB | GLUT_DEPTH); 297 glutInitWindowSize(800, 600); 298 glutCreateWindow("Ray Visualization"); 299 300 /* Set up OpenGL */ 301 glEnable(GL_DEPTH_TEST); 302 glClearColor(0.f, 0.f, 0.f, 1.0f); 303 304 /* Register callbacks */ 305 glutDisplayFunc(display); 306 glutReshapeFunc(reshape); 307 glutKeyboardFunc(keyboard); 308 glutMouseFunc(mouse); 309 glutMotionFunc(mouseMotion); 310 311 updateCamera(); 312 glutMainLoop(); 313 }