🛠️🐜 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

#include <stdio.h>
#include <stdlib.h>
#include <assert.h>
#include <float.h>
#include <string.h>
#include <string.h>
#ifdef __APPLE__
#include <GLUT/glut.h>
#else
#include <GL/glut.h>
#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 <input.exr>\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;
}