//------------------------------------------------------------------------------- /// /// \author Cem Yuksel (www.cemyuksel.com) /// \date December 1, 2015 /// /// \brief Photon map visualization tool /// //------------------------------------------------------------------------------- #include <stdlib.h> #include <stdio.h> #include <GL/glut.h> #define WINDOW_SIZE 800 float viewAngle1=-60, viewAngle2=-120, viewTransZ=-200; int mouseMode; int mouseX, mouseY; bool showPhotonColor = false; enum MouseModes { MOUSE_MODE_NONE, MOUSE_MODE_VIEW_ROTATE, MOUSE_MODE_VIEW_ZOOM, }; //------------------------------------------------------------------------------- struct Photon { float pos[3]; float power; unsigned char color[3]; unsigned char planeAndDirZ; // splitting plane for kd-tree and one bit for determining the z direction short dirX, dirY; // photon direction }; int numPhotons = 0; Photon *photons = NULL; //------------------------------------------------------------------------------- void Display() { glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT ); glPushMatrix(); // Set view glTranslatef( 0, 0, viewTransZ ); glRotatef( viewAngle1, 1, 0, 0 ); glRotatef( viewAngle2, 0, 0, 1 ); // Draw photons glColor3f(1,1,1); glDrawArrays(GL_POINTS,0,numPhotons); const float lineSize = 100; glBegin(GL_LINES); glColor3f(1,0,0); glVertex3f(0,0,0); glVertex3f(lineSize,0,0); glColor3f(0,1,0); glVertex3f(0,0,0); glVertex3f(0,lineSize,0); glColor3f(0,0,1); glVertex3f(0,0,0); glVertex3f(0,0,lineSize); glEnd(); glPopMatrix(); glutSwapBuffers(); } //------------------------------------------------------------------------------- void Reshape(int w, int h) { glViewport( 0, 0, w, h ); glMatrixMode( GL_PROJECTION ); glLoadIdentity(); float r = (float) w / float (h); gluPerspective( 60, r, 0.02, 1000.0); glMatrixMode( GL_MODELVIEW ); glLoadIdentity(); } //------------------------------------------------------------------------------- void Mouse(int button, int state, int x, int y) { mouseX = x; mouseY = y; if ( state == GLUT_DOWN ) { switch( button ) { case GLUT_LEFT_BUTTON: mouseMode = MOUSE_MODE_VIEW_ROTATE; break; case GLUT_RIGHT_BUTTON: mouseMode = MOUSE_MODE_VIEW_ZOOM; break; } } else { mouseMode = MOUSE_MODE_NONE; } glutPostRedisplay(); } //------------------------------------------------------------------------------- #define VIEW_ROTATE_INC 0.2f #define VIEW_ZOOM_INC 0.5f void MouseMove(int x, int y) { switch ( mouseMode ) { case MOUSE_MODE_VIEW_ROTATE: viewAngle1 -= VIEW_ROTATE_INC * ( mouseY - y ); viewAngle2 -= VIEW_ROTATE_INC * ( mouseX - x ); break; case MOUSE_MODE_VIEW_ZOOM: viewTransZ += VIEW_ZOOM_INC * ( mouseY - y ); break; } mouseX = x; mouseY = y; glutPostRedisplay(); } //------------------------------------------------------------------------------- void Keyboard(unsigned char key, int x, int y) { switch ( key ) { case 27: // ESC exit(0); break; case ' ': showPhotonColor = ! showPhotonColor; if ( showPhotonColor ) { glEnableClientState(GL_COLOR_ARRAY); } else { glDisableClientState(GL_COLOR_ARRAY); } glutPostRedisplay(); break; } } //------------------------------------------------------------------------------- int main(int argc, char **argv) { glutInit(&argc,argv); char defaultFileName[] = "photonmap.dat"; char *fname = defaultFileName; if ( argc > 1 ) { fname = argv[1]; } ///////////////////////////////////////////////////////////////////////////////// // Read the photon map ///////////////////////////////////////////////////////////////////////////////// FILE *fp = fopen(fname,"rb"); if ( fp == NULL ) { printf("ERROR: Cannot open file \"%s\".\n", fname); return -1; } int n = 0; Photon buffer; for ( ; !feof(fp); n++ ) { fread(&buffer,sizeof(Photon),1,fp); } n--; if ( n <= 0 ) { printf("ERROR: No photons found.\n"); } else { photons = new Photon[n]; rewind(fp); int np = fread(photons,sizeof(Photon),n,fp); numPhotons = np; printf("%d photons read.\n",np); } fclose(fp); if ( n <= 0 ) return -2; ///////////////////////////////////////////////////////////////////////////////// glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGBA | GLUT_DEPTH ); if (glutGet(GLUT_SCREEN_WIDTH) > 0 && glutGet(GLUT_SCREEN_HEIGHT) > 0){ glutInitWindowPosition( (glutGet(GLUT_SCREEN_WIDTH) - WINDOW_SIZE)/2, (glutGet(GLUT_SCREEN_HEIGHT) - WINDOW_SIZE)/2 ); } else glutInitWindowPosition( 50, 50 ); glutInitWindowSize(WINDOW_SIZE, WINDOW_SIZE); glutCreateWindow("Photon Map Viz"); glutDisplayFunc(Display); glutReshapeFunc(Reshape); glutMouseFunc(Mouse); glutMotionFunc(MouseMove); glutKeyboardFunc(Keyboard); glClearColor(0,0,0,0); glPointSize(1.0); glEnable( GL_DEPTH_TEST ); glDisable( GL_LIGHTING ); glEnableClientState(GL_VERTEX_ARRAY); glVertexPointer(3, GL_FLOAT, sizeof(Photon), photons[0].pos); if ( showPhotonColor ) glEnableClientState(GL_COLOR_ARRAY); glColorPointer(3, GL_UNSIGNED_BYTE, sizeof(Photon), photons[0].color); glutMainLoop(); delete [] photons; return 0; } //-------------------------------------------------------------------------------