# HG changeset patch # User John Tsiombikas # Date 1326925051 -7200 # Node ID 182bfd9f55c7414515d9c8fde7101ad38b2f41c4 view3d diff -r 000000000000 -r 182bfd9f55c7 .hgignore --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/.hgignore Thu Jan 19 00:17:31 2012 +0200 @@ -0,0 +1,5 @@ +\.o$ +\.d$ +\.swp$ +^view3d$ +^Makefile$ diff -r 000000000000 -r 182bfd9f55c7 Makefile.in --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Makefile.in Thu Jan 19 00:17:31 2012 +0200 @@ -0,0 +1,36 @@ +src = $(wildcard src/*.c) +obj = $(src:.c=.o) +dep = $(obj:.o=.d) +bin = view3d + +CFLAGS = -pedantic -Wall -g $(incdir) +LDFLAGS = $(libdir) $(libgl) -lassimp -lm -limago + +ifeq ($(shell uname -s), Darwin) + libgl = -framework OpenGL -framework GLUT -lGLEW + incdir = -I/opt/local/include + libdir = -L/opt/local/lib +else + libgl = -lGL -lGLU -lglut -lGLEW +endif + +$(bin): $(obj) + $(CC) -o $@ $(obj) $(LDFLAGS) + +-include $(dep) + +%.d: %.c + @$(CPP) $(CFLAGS) $< -MM -MT $(@:.d=.o) >$@ + +.PHONY: clean +clean: + rm -f $(obj) $(bin) + +.PHONY: install +install: $(bin) + mkdir -p $(INSTDIR)$(PREFIX)/bin + cp $(bin) $(INSTDIR)$(PREFIX)/bin/$(bin) + +.PHONY: uninstall +uninstall: + rm -f $(INSTDIR)$(PREFIX)/bin/$(bin) diff -r 000000000000 -r 182bfd9f55c7 configure --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/configure Thu Jan 19 00:17:31 2012 +0200 @@ -0,0 +1,33 @@ +#!/bin/sh + +prefix='/usr/local' +opt=false +dbg=true + +while [ $# -gt 0 ]; do + case $1 in + --prefix=*) + prefix=`echo $1 | sed 's/^--prefix=//'` + ;; + + --enable-opt) + opt=true + ;; + --disable-opt) + opt=false + ;; + --enable-debug) + dbg=true + ;; + --disable-debug) + dbg=false + ;; + esac + shift +done + +echo '# this file is generated by the configure script' >Makefile +echo "PREFIX = $prefix" >>Makefile +$opt && echo 'opt = -O3 -ffast-math' >>Makefile +$dbg && echo 'dbg = -g' >>Makefile +cat Makefile.in >>Makefile diff -r 000000000000 -r 182bfd9f55c7 src/main.c --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/main.c Thu Jan 19 00:17:31 2012 +0200 @@ -0,0 +1,354 @@ +#include +#include +#include + +#include +#ifndef __APPLE__ +#include +#else +#include +#endif + +#include "scene.h" + +void disp(void); +void render(unsigned int msec); +void proj_matrix(float eye); +void view_matrix(float eye); + +void reshape(int x, int y); +void keyb(unsigned char key, int x, int y); +void keyb_up(unsigned char key, int x, int y); +void mouse(int bn, int state, int x, int y); +void motion(int x, int y); +void sball_motion(int x, int y, int z); +void sball_rotate(int x, int y, int z); +void sball_button(int bn, int state); +int parse_args(int argc, char **argv); + +char *scene_fname; +int win_width, win_height; +int stereo; +int flip_winding; +int auto_rot = 1; +float cam_theta, cam_phi, cam_dist = 10; +float near_clip = 0.5; +float far_clip = 1000.0; +float fov = M_PI / 4.0; +float stereo_focus_dist = 1.0; +float stereo_eye_sep = 1.0 / 30.0; + +struct scene scn; + +int main(int argc, char **argv) +{ + float ldir[] = {1, -1, -1, 0}; + float dx, dy, dz, diag; + + glutInitWindowSize(800, 600); + glutInit(&argc, argv); + + if(parse_args(argc, argv) == -1) { + return 1; + } + + glutInitDisplayMode(GLUT_RGB | GLUT_DEPTH | GLUT_DOUBLE | (stereo ? GLUT_STEREO : 0)); + glutCreateWindow("OpenGL Logo"); + + glutDisplayFunc(disp); + glutReshapeFunc(reshape); + glutKeyboardFunc(keyb); + glutKeyboardUpFunc(keyb_up); + glutMouseFunc(mouse); + glutMotionFunc(motion); + glutSpaceballMotionFunc(sball_motion); + glutSpaceballRotateFunc(sball_rotate); + glutSpaceballButtonFunc(sball_button); + glutIdleFunc(glutPostRedisplay); + + glewInit(); + + glEnable(GL_DEPTH_TEST); + glEnable(GL_CULL_FACE); + glEnable(GL_LIGHTING); + glEnable(GL_LIGHT0); + glLightfv(GL_LIGHT0, GL_POSITION, ldir); + + if((load_scene(&scn, scene_fname)) == -1) { + fprintf(stderr, "failed to load: %s\n", scene_fname); + return 1; + } + dx = scn.bbox.max[0] - scn.bbox.min[0]; + dy = scn.bbox.max[1] - scn.bbox.min[1]; + dz = scn.bbox.max[2] - scn.bbox.min[2]; + diag = sqrt(dx * dx + dy * dy + dz * dz); + cam_dist = diag / fov; + printf("camera distance: %f\n", cam_dist); + + glutMainLoop(); + return 0; +} + + +void disp(void) +{ + unsigned int tm = glutGet(GLUT_ELAPSED_TIME); + + if(stereo) { + glDrawBuffer(GL_BACK_LEFT); + glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); + + glMatrixMode(GL_PROJECTION); + glLoadIdentity(); + proj_matrix(-1); + glMatrixMode(GL_MODELVIEW); + glLoadIdentity(); + view_matrix(-1); + + render(tm); + + glDrawBuffer(GL_BACK_RIGHT); + glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); + + glMatrixMode(GL_PROJECTION); + glLoadIdentity(); + proj_matrix(1); + glMatrixMode(GL_MODELVIEW); + glLoadIdentity(); + view_matrix(1); + + render(tm); + } else { + glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); + + glMatrixMode(GL_PROJECTION); + glLoadIdentity(); + proj_matrix(0); + glMatrixMode(GL_MODELVIEW); + glLoadIdentity(); + view_matrix(0); + + render(tm); + } + + glutSwapBuffers(); +} + +void render(unsigned int msec) +{ + if(auto_rot) { + glRotatef(msec / 10, 0, 1, 0); + } + render_scene(&scn); +} + +void proj_matrix(float eye) +{ + float vfov_rad = fov; + float top = near_clip * tan(vfov_rad * 0.5); + float right = top * (float)win_width / (float)win_height; + + float frust_shift = eye * (stereo_eye_sep * 0.5 * near_clip / stereo_focus_dist); + + glFrustum(-right + frust_shift, right + frust_shift, -top, top, near_clip, far_clip); +} + +void view_matrix(float eye) +{ + float offs = stereo_eye_sep * eye * 0.5; + glTranslatef(offs, 0, 0); + + glTranslatef(0, 0, -cam_dist); + glRotatef(cam_phi, 1, 0, 0); + glRotatef(cam_theta, 0, 1, 0); +} + +void reshape(int x, int y) +{ + glViewport(0, 0, x, y); + win_width = x; + win_height = y; +} + +static int stereo_shift_key; + +void keyb(unsigned char key, int x, int y) +{ + switch(key) { + case 'q': + case 27: + exit(0); + + case 's': + stereo_shift_key = 1; + break; + + case 'c': + { + static int flip; + glFrontFace((++flip & 1) ? GL_CW : GL_CCW); + glutPostRedisplay(); + } + break; + + case 'C': + { + static int cull = 1; + if(++cull & 1) { + glEnable(GL_CULL_FACE); + } else { + glDisable(GL_CULL_FACE); + } + glutPostRedisplay(); + } + break; + + case 'w': + { + static int wire; + glPolygonMode(GL_FRONT_AND_BACK, (++wire & 1) ? GL_LINE : GL_FILL); + glutPostRedisplay(); + } + break; + + case 'l': + { + static int lit = 1; + if(++lit & 1) { + glEnable(GL_LIGHTING); + } else { + glDisable(GL_LIGHTING); + } + glutPostRedisplay(); + } + break; + + case ' ': + auto_rot = !auto_rot; + if(auto_rot) { + glutIdleFunc(glutPostRedisplay); + } else { + glutIdleFunc(0); + } + glutPostRedisplay(); + break; + + default: + break; + } +} + +void keyb_up(unsigned char key, int x, int y) +{ + switch(key) { + case 's': + stereo_shift_key = 0; + break; + + default: + break; + } +} + + +static int bnstate[32]; +static int prev_x, prev_y; +void mouse(int bn, int state, int x, int y) +{ + prev_x = x; + prev_y = y; + bnstate[bn - GLUT_LEFT_BUTTON] = state == GLUT_DOWN ? 1 : 0; +} + +void motion(int x, int y) +{ + int dx = x - prev_x; + int dy = y - prev_y; + prev_x = x; + prev_y = y; + + if(stereo_shift_key && dy != 0) { + stereo_focus_dist += dy * 0.1; + stereo_eye_sep = stereo_focus_dist / 30.0; + glutPostRedisplay(); + return; + } + + if(bnstate[0]) { + cam_theta += dx * 0.5; + cam_phi += dy * 0.5; + + if(cam_phi < -90) + cam_phi = -90; + if(cam_phi > 90) + cam_phi = 90; + + glutPostRedisplay(); + } + if(bnstate[2]) { + cam_dist += dy * 0.1; + glutPostRedisplay(); + } +} + +void sball_motion(int x, int y, int z) +{ +} + +void sball_rotate(int x, int y, int z) +{ + cam_theta += y * 0.05; + cam_phi += x * 0.05; + + if(cam_phi < -90) + cam_phi = -90; + if(cam_phi > 90) + cam_phi = 90; + + glutPostRedisplay(); +} + +void sball_button(int bn, int state) +{ +} + +int parse_args(int argc, char **argv) +{ + int i; + + for(i=1; i