🛠️🐜 Antkeeper superbuild with dependencies included https://antkeeper.com
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

277 lines
6.4 KiB

  1. #include <stdio.h>
  2. #include <stdlib.h>
  3. #include <assert.h>
  4. #include <float.h>
  5. #include <string.h>
  6. #include <string.h>
  7. #ifdef __APPLE__
  8. #include <GLUT/glut.h>
  9. #else
  10. #include <GL/glut.h>
  11. #endif
  12. #include "../../tinyexr.h"
  13. #include "trackball.h"
  14. static int mouse_x, mouse_y;
  15. static int mouse_m_pressed;
  16. static int mouse_r_pressed;
  17. static int mouse_moving;
  18. static int width = 512, height = 512;
  19. static float view_org[3], view_tgt[3];
  20. static float curr_quat[4], prev_quat[4];
  21. static float color_scale = 1.0f;
  22. DeepImage gDeepImage;
  23. //
  24. // --
  25. //
  26. static void reshape(int w, int h) {
  27. glViewport(0, 0, w, h);
  28. glMatrixMode(GL_PROJECTION);
  29. glLoadIdentity();
  30. gluPerspective(5.0, (float)w / (float)h, 0.1f, 1000.0f);
  31. glMatrixMode(GL_MODELVIEW);
  32. glLoadIdentity();
  33. width = w;
  34. height = h;
  35. }
  36. static void draw_samples() {
  37. glPointSize(1.0f);
  38. glColor3f(1.0f, 1.0f, 1.0f);
  39. glBegin(GL_POINTS);
  40. // find depth channel.
  41. // @todo { Do this only once. }
  42. int depthChan = 0;
  43. int rChan = -1;
  44. int raChan = -1;
  45. int gChan = -1;
  46. int gaChan = -1;
  47. int bChan = -1;
  48. int baChan = -1;
  49. for (int c = 0; c < gDeepImage.num_channels; c++) {
  50. if (strcmp("Z", gDeepImage.channel_names[c]) == 0) {
  51. depthChan = c;
  52. } else if (strcmp("R", gDeepImage.channel_names[c]) == 0) {
  53. rChan = c;
  54. } else if (strcmp("RA", gDeepImage.channel_names[c]) == 0) {
  55. raChan = c;
  56. } else if (strcmp("G", gDeepImage.channel_names[c]) == 0) {
  57. gChan = c;
  58. } else if (strcmp("GA", gDeepImage.channel_names[c]) == 0) {
  59. gaChan = c;
  60. } else if (strcmp("B", gDeepImage.channel_names[c]) == 0) {
  61. bChan = c;
  62. } else if (strcmp("BA", gDeepImage.channel_names[c]) == 0) {
  63. baChan = c;
  64. }
  65. }
  66. for (int y = 0; y < gDeepImage.height; y++) {
  67. float py = 2.0f * ((gDeepImage.height - y - 1) / (float)gDeepImage.height) -
  68. 1.0f; // upside down?
  69. int sampleNum = gDeepImage.offset_table[y][gDeepImage.width - 1];
  70. int s_start = 0; // First pixel data starts at 0
  71. for (int x = 0; x < gDeepImage.width; x++) {
  72. float px = 2.0f * (x / (float)gDeepImage.width) - 1.0f;
  73. int s_end = gDeepImage.offset_table[y][x];
  74. if (s_start >= sampleNum || s_end >= sampleNum) {
  75. continue;
  76. }
  77. for (int s = s_start; s < s_end; s++) {
  78. float pz = -gDeepImage.image[depthChan][y][s];
  79. float red = 1.0f;
  80. float green = 1.0f;
  81. float blue = 1.0f;
  82. float red_alpha = 1.0f;
  83. float green_alpha = 1.0f;
  84. float blue_alpha = 1.0f;
  85. if (rChan >= 0) {
  86. red = gDeepImage.image[rChan][y][s];
  87. }
  88. if (raChan >= 0) {
  89. red_alpha = gDeepImage.image[raChan][y][s];
  90. }
  91. if (gChan >= 0) {
  92. green = gDeepImage.image[gChan][y][s];
  93. }
  94. if (gaChan >= 0) {
  95. green_alpha = gDeepImage.image[gaChan][y][s];
  96. }
  97. if (bChan >= 0) {
  98. blue = gDeepImage.image[bChan][y][s];
  99. }
  100. if (baChan >= 0) {
  101. blue_alpha = gDeepImage.image[baChan][y][s];
  102. }
  103. // unmultiply and apply scaling
  104. red *= color_scale / red_alpha;
  105. green *= color_scale / green_alpha;
  106. blue *= color_scale / blue_alpha;
  107. glColor3f(red, green, blue);
  108. glVertex3f(px, py, pz);
  109. }
  110. s_start = s_end;
  111. }
  112. }
  113. glEnd();
  114. }
  115. static void display() {
  116. GLfloat mat[4][4];
  117. glClearColor(0.0f, 0.0f, 0.0f, 0.0f);
  118. glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
  119. glEnable(GL_DEPTH_TEST);
  120. glMatrixMode(GL_MODELVIEW);
  121. glLoadIdentity();
  122. // camera & rotate
  123. gluLookAt(view_org[0], view_org[1], view_org[2], view_tgt[0], view_tgt[1],
  124. view_tgt[2], 0.0, 1.0, 0.0);
  125. build_rotmatrix(mat, curr_quat);
  126. glMultMatrixf(&mat[0][0]);
  127. draw_samples();
  128. // glBegin(GL_POLYGON);
  129. // glTexCoord2f(0 , 0); glVertex2f(-0.9 , -0.9);
  130. // glTexCoord2f(0 , 1); glVertex2f(-0.9 , 0.9);
  131. // glTexCoord2f(1 , 1); glVertex2f(0.9 , 0.9);
  132. // glTexCoord2f(1 , 0); glVertex2f(0.9 , -0.9);
  133. // glEnd();
  134. glutSwapBuffers();
  135. }
  136. static void keyboard(unsigned char key, int x, int y) {
  137. switch (key) {
  138. case 'q':
  139. case 27:
  140. exit(0);
  141. break;
  142. case 'c':
  143. color_scale += 1.0f;
  144. break;
  145. case 'x':
  146. color_scale -= 1.0f;
  147. if (color_scale < 1.0f)
  148. color_scale = 1.0f;
  149. break;
  150. default:
  151. break;
  152. }
  153. glutPostRedisplay();
  154. }
  155. static void mouse(int button, int state, int x, int y) {
  156. int mod = glutGetModifiers();
  157. if (button == GLUT_LEFT_BUTTON && state == GLUT_DOWN) {
  158. if (mod == GLUT_ACTIVE_SHIFT) {
  159. mouse_m_pressed = 1;
  160. } else if (mod == GLUT_ACTIVE_CTRL) {
  161. mouse_r_pressed = 1;
  162. } else {
  163. trackball(prev_quat, 0, 0, 0, 0);
  164. }
  165. mouse_moving = 1;
  166. mouse_x = x;
  167. mouse_y = y;
  168. } else if (button == GLUT_LEFT_BUTTON && state == GLUT_UP) {
  169. mouse_m_pressed = 0;
  170. mouse_r_pressed = 0;
  171. mouse_moving = 0;
  172. }
  173. }
  174. static void motion(int x, int y) {
  175. float w = 1.0;
  176. float mw = 0.1;
  177. if (mouse_moving) {
  178. if (mouse_r_pressed) {
  179. view_org[2] += mw * (mouse_y - y);
  180. view_tgt[2] += mw * (mouse_y - y);
  181. } else if (mouse_m_pressed) {
  182. view_org[0] += mw * (mouse_x - x);
  183. view_org[1] -= mw * (mouse_y - y);
  184. view_tgt[0] += mw * (mouse_x - x);
  185. view_tgt[1] -= mw * (mouse_y - y);
  186. } else {
  187. trackball(prev_quat, w * (2.0 * mouse_x - width) / width,
  188. w * (height - 2.0 * mouse_y) / height,
  189. w * (2.0 * x - width) / width, w * (height - 2.0 * y) / height);
  190. add_quats(prev_quat, curr_quat, curr_quat);
  191. }
  192. mouse_x = x;
  193. mouse_y = y;
  194. }
  195. glutPostRedisplay();
  196. }
  197. static void init() {
  198. trackball(curr_quat, 0, 0, 0, 0);
  199. view_org[0] = 0.0f;
  200. view_org[1] = 0.0f;
  201. view_org[2] = 3.0f;
  202. view_tgt[0] = 0.0f;
  203. view_tgt[1] = 0.0f;
  204. view_tgt[2] = 0.0f;
  205. }
  206. int main(int argc, char **argv) {
  207. const char *input = "input.exr";
  208. if (argc < 2) {
  209. printf("Usage: deepview <input.exr>\n");
  210. exit(1);
  211. }
  212. input = argv[1];
  213. const char *err;
  214. int ret = LoadDeepEXR(&gDeepImage, input, &err);
  215. if (ret != 0) {
  216. if (err) {
  217. fprintf(stderr, "ERR: %s\n", err);
  218. }
  219. exit(-1);
  220. }
  221. glutInit(&argc, argv);
  222. glutInitWindowSize(512, 512);
  223. glutInitDisplayMode(GLUT_DOUBLE | GLUT_DEPTH | GLUT_RGBA);
  224. init();
  225. glutCreateWindow("deepimage viewer");
  226. glutReshapeFunc(reshape);
  227. glutDisplayFunc(display);
  228. glutKeyboardFunc(keyboard);
  229. glutMouseFunc(mouse);
  230. glutMotionFunc(motion);
  231. glutMainLoop();
  232. return 0;
  233. }