#include #include #include #include #include #include #ifdef __APPLE__ #include #else #include #endif #include "../../tinyexr.h" #include "trackball.h" static int mouse_x, mouse_y; static int mouse_m_pressed; static int mouse_r_pressed; static int mouse_moving; static int width = 512, height = 512; static float view_org[3], view_tgt[3]; static float curr_quat[4], prev_quat[4]; static float color_scale = 1.0f; DeepImage gDeepImage; // // -- // static void reshape(int w, int h) { glViewport(0, 0, w, h); glMatrixMode(GL_PROJECTION); glLoadIdentity(); gluPerspective(5.0, (float)w / (float)h, 0.1f, 1000.0f); glMatrixMode(GL_MODELVIEW); glLoadIdentity(); width = w; height = h; } static void draw_samples() { glPointSize(1.0f); glColor3f(1.0f, 1.0f, 1.0f); glBegin(GL_POINTS); // find depth channel. // @todo { Do this only once. } int depthChan = 0; int rChan = -1; int raChan = -1; int gChan = -1; int gaChan = -1; int bChan = -1; int baChan = -1; for (int c = 0; c < gDeepImage.num_channels; c++) { if (strcmp("Z", gDeepImage.channel_names[c]) == 0) { depthChan = c; } else if (strcmp("R", gDeepImage.channel_names[c]) == 0) { rChan = c; } else if (strcmp("RA", gDeepImage.channel_names[c]) == 0) { raChan = c; } else if (strcmp("G", gDeepImage.channel_names[c]) == 0) { gChan = c; } else if (strcmp("GA", gDeepImage.channel_names[c]) == 0) { gaChan = c; } else if (strcmp("B", gDeepImage.channel_names[c]) == 0) { bChan = c; } else if (strcmp("BA", gDeepImage.channel_names[c]) == 0) { baChan = c; } } for (int y = 0; y < gDeepImage.height; y++) { float py = 2.0f * ((gDeepImage.height - y - 1) / (float)gDeepImage.height) - 1.0f; // upside down? int sampleNum = gDeepImage.offset_table[y][gDeepImage.width - 1]; int s_start = 0; // First pixel data starts at 0 for (int x = 0; x < gDeepImage.width; x++) { float px = 2.0f * (x / (float)gDeepImage.width) - 1.0f; int s_end = gDeepImage.offset_table[y][x]; if (s_start >= sampleNum || s_end >= sampleNum) { continue; } for (int s = s_start; s < s_end; s++) { float pz = -gDeepImage.image[depthChan][y][s]; float red = 1.0f; float green = 1.0f; float blue = 1.0f; float red_alpha = 1.0f; float green_alpha = 1.0f; float blue_alpha = 1.0f; if (rChan >= 0) { red = gDeepImage.image[rChan][y][s]; } if (raChan >= 0) { red_alpha = gDeepImage.image[raChan][y][s]; } if (gChan >= 0) { green = gDeepImage.image[gChan][y][s]; } if (gaChan >= 0) { green_alpha = gDeepImage.image[gaChan][y][s]; } if (bChan >= 0) { blue = gDeepImage.image[bChan][y][s]; } if (baChan >= 0) { blue_alpha = gDeepImage.image[baChan][y][s]; } // unmultiply and apply scaling red *= color_scale / red_alpha; green *= color_scale / green_alpha; blue *= color_scale / blue_alpha; glColor3f(red, green, blue); glVertex3f(px, py, pz); } s_start = s_end; } } glEnd(); } static void display() { GLfloat mat[4][4]; glClearColor(0.0f, 0.0f, 0.0f, 0.0f); glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); glEnable(GL_DEPTH_TEST); glMatrixMode(GL_MODELVIEW); glLoadIdentity(); // camera & rotate gluLookAt(view_org[0], view_org[1], view_org[2], view_tgt[0], view_tgt[1], view_tgt[2], 0.0, 1.0, 0.0); build_rotmatrix(mat, curr_quat); glMultMatrixf(&mat[0][0]); draw_samples(); // glBegin(GL_POLYGON); // glTexCoord2f(0 , 0); glVertex2f(-0.9 , -0.9); // glTexCoord2f(0 , 1); glVertex2f(-0.9 , 0.9); // glTexCoord2f(1 , 1); glVertex2f(0.9 , 0.9); // glTexCoord2f(1 , 0); glVertex2f(0.9 , -0.9); // glEnd(); glutSwapBuffers(); } static void keyboard(unsigned char key, int x, int y) { switch (key) { case 'q': case 27: exit(0); break; case 'c': color_scale += 1.0f; break; case 'x': color_scale -= 1.0f; if (color_scale < 1.0f) color_scale = 1.0f; break; default: break; } glutPostRedisplay(); } static void mouse(int button, int state, int x, int y) { int mod = glutGetModifiers(); if (button == GLUT_LEFT_BUTTON && state == GLUT_DOWN) { if (mod == GLUT_ACTIVE_SHIFT) { mouse_m_pressed = 1; } else if (mod == GLUT_ACTIVE_CTRL) { mouse_r_pressed = 1; } else { trackball(prev_quat, 0, 0, 0, 0); } mouse_moving = 1; mouse_x = x; mouse_y = y; } else if (button == GLUT_LEFT_BUTTON && state == GLUT_UP) { mouse_m_pressed = 0; mouse_r_pressed = 0; mouse_moving = 0; } } static void motion(int x, int y) { float w = 1.0; float mw = 0.1; if (mouse_moving) { if (mouse_r_pressed) { view_org[2] += mw * (mouse_y - y); view_tgt[2] += mw * (mouse_y - y); } else if (mouse_m_pressed) { view_org[0] += mw * (mouse_x - x); view_org[1] -= mw * (mouse_y - y); view_tgt[0] += mw * (mouse_x - x); view_tgt[1] -= mw * (mouse_y - y); } else { trackball(prev_quat, w * (2.0 * mouse_x - width) / width, w * (height - 2.0 * mouse_y) / height, w * (2.0 * x - width) / width, w * (height - 2.0 * y) / height); add_quats(prev_quat, curr_quat, curr_quat); } mouse_x = x; mouse_y = y; } glutPostRedisplay(); } static void init() { trackball(curr_quat, 0, 0, 0, 0); view_org[0] = 0.0f; view_org[1] = 0.0f; view_org[2] = 3.0f; view_tgt[0] = 0.0f; view_tgt[1] = 0.0f; view_tgt[2] = 0.0f; } int main(int argc, char **argv) { const char *input = "input.exr"; if (argc < 2) { printf("Usage: deepview \n"); exit(1); } input = argv[1]; const char *err; int ret = LoadDeepEXR(&gDeepImage, input, &err); if (ret != 0) { if (err) { fprintf(stderr, "ERR: %s\n", err); } exit(-1); } glutInit(&argc, argv); glutInitWindowSize(512, 512); glutInitDisplayMode(GLUT_DOUBLE | GLUT_DEPTH | GLUT_RGBA); init(); glutCreateWindow("deepimage viewer"); glutReshapeFunc(reshape); glutDisplayFunc(display); glutKeyboardFunc(keyboard); glutMouseFunc(mouse); glutMotionFunc(motion); glutMainLoop(); return 0; }