view3d
changeset 0:182bfd9f55c7
view3d
author | John Tsiombikas <nuclear@mutantstargoat.com> |
---|---|
date | Thu, 19 Jan 2012 00:17:31 +0200 |
parents | |
children | 7650e941805c |
files | .hgignore Makefile.in configure src/main.c |
diffstat | 4 files changed, 428 insertions(+), 0 deletions(-) [+] |
line diff
1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/.hgignore Thu Jan 19 00:17:31 2012 +0200 1.3 @@ -0,0 +1,5 @@ 1.4 +\.o$ 1.5 +\.d$ 1.6 +\.swp$ 1.7 +^view3d$ 1.8 +^Makefile$
2.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 2.2 +++ b/Makefile.in Thu Jan 19 00:17:31 2012 +0200 2.3 @@ -0,0 +1,36 @@ 2.4 +src = $(wildcard src/*.c) 2.5 +obj = $(src:.c=.o) 2.6 +dep = $(obj:.o=.d) 2.7 +bin = view3d 2.8 + 2.9 +CFLAGS = -pedantic -Wall -g $(incdir) 2.10 +LDFLAGS = $(libdir) $(libgl) -lassimp -lm -limago 2.11 + 2.12 +ifeq ($(shell uname -s), Darwin) 2.13 + libgl = -framework OpenGL -framework GLUT -lGLEW 2.14 + incdir = -I/opt/local/include 2.15 + libdir = -L/opt/local/lib 2.16 +else 2.17 + libgl = -lGL -lGLU -lglut -lGLEW 2.18 +endif 2.19 + 2.20 +$(bin): $(obj) 2.21 + $(CC) -o $@ $(obj) $(LDFLAGS) 2.22 + 2.23 +-include $(dep) 2.24 + 2.25 +%.d: %.c 2.26 + @$(CPP) $(CFLAGS) $< -MM -MT $(@:.d=.o) >$@ 2.27 + 2.28 +.PHONY: clean 2.29 +clean: 2.30 + rm -f $(obj) $(bin) 2.31 + 2.32 +.PHONY: install 2.33 +install: $(bin) 2.34 + mkdir -p $(INSTDIR)$(PREFIX)/bin 2.35 + cp $(bin) $(INSTDIR)$(PREFIX)/bin/$(bin) 2.36 + 2.37 +.PHONY: uninstall 2.38 +uninstall: 2.39 + rm -f $(INSTDIR)$(PREFIX)/bin/$(bin)
3.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 3.2 +++ b/configure Thu Jan 19 00:17:31 2012 +0200 3.3 @@ -0,0 +1,33 @@ 3.4 +#!/bin/sh 3.5 + 3.6 +prefix='/usr/local' 3.7 +opt=false 3.8 +dbg=true 3.9 + 3.10 +while [ $# -gt 0 ]; do 3.11 + case $1 in 3.12 + --prefix=*) 3.13 + prefix=`echo $1 | sed 's/^--prefix=//'` 3.14 + ;; 3.15 + 3.16 + --enable-opt) 3.17 + opt=true 3.18 + ;; 3.19 + --disable-opt) 3.20 + opt=false 3.21 + ;; 3.22 + --enable-debug) 3.23 + dbg=true 3.24 + ;; 3.25 + --disable-debug) 3.26 + dbg=false 3.27 + ;; 3.28 + esac 3.29 + shift 3.30 +done 3.31 + 3.32 +echo '# this file is generated by the configure script' >Makefile 3.33 +echo "PREFIX = $prefix" >>Makefile 3.34 +$opt && echo 'opt = -O3 -ffast-math' >>Makefile 3.35 +$dbg && echo 'dbg = -g' >>Makefile 3.36 +cat Makefile.in >>Makefile
4.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 4.2 +++ b/src/main.c Thu Jan 19 00:17:31 2012 +0200 4.3 @@ -0,0 +1,354 @@ 4.4 +#include <stdio.h> 4.5 +#include <stdlib.h> 4.6 +#include <math.h> 4.7 + 4.8 +#include <GL/glew.h> 4.9 +#ifndef __APPLE__ 4.10 +#include <GL/glut.h> 4.11 +#else 4.12 +#include <GLUT/glut.h> 4.13 +#endif 4.14 + 4.15 +#include "scene.h" 4.16 + 4.17 +void disp(void); 4.18 +void render(unsigned int msec); 4.19 +void proj_matrix(float eye); 4.20 +void view_matrix(float eye); 4.21 + 4.22 +void reshape(int x, int y); 4.23 +void keyb(unsigned char key, int x, int y); 4.24 +void keyb_up(unsigned char key, int x, int y); 4.25 +void mouse(int bn, int state, int x, int y); 4.26 +void motion(int x, int y); 4.27 +void sball_motion(int x, int y, int z); 4.28 +void sball_rotate(int x, int y, int z); 4.29 +void sball_button(int bn, int state); 4.30 +int parse_args(int argc, char **argv); 4.31 + 4.32 +char *scene_fname; 4.33 +int win_width, win_height; 4.34 +int stereo; 4.35 +int flip_winding; 4.36 +int auto_rot = 1; 4.37 +float cam_theta, cam_phi, cam_dist = 10; 4.38 +float near_clip = 0.5; 4.39 +float far_clip = 1000.0; 4.40 +float fov = M_PI / 4.0; 4.41 +float stereo_focus_dist = 1.0; 4.42 +float stereo_eye_sep = 1.0 / 30.0; 4.43 + 4.44 +struct scene scn; 4.45 + 4.46 +int main(int argc, char **argv) 4.47 +{ 4.48 + float ldir[] = {1, -1, -1, 0}; 4.49 + float dx, dy, dz, diag; 4.50 + 4.51 + glutInitWindowSize(800, 600); 4.52 + glutInit(&argc, argv); 4.53 + 4.54 + if(parse_args(argc, argv) == -1) { 4.55 + return 1; 4.56 + } 4.57 + 4.58 + glutInitDisplayMode(GLUT_RGB | GLUT_DEPTH | GLUT_DOUBLE | (stereo ? GLUT_STEREO : 0)); 4.59 + glutCreateWindow("OpenGL Logo"); 4.60 + 4.61 + glutDisplayFunc(disp); 4.62 + glutReshapeFunc(reshape); 4.63 + glutKeyboardFunc(keyb); 4.64 + glutKeyboardUpFunc(keyb_up); 4.65 + glutMouseFunc(mouse); 4.66 + glutMotionFunc(motion); 4.67 + glutSpaceballMotionFunc(sball_motion); 4.68 + glutSpaceballRotateFunc(sball_rotate); 4.69 + glutSpaceballButtonFunc(sball_button); 4.70 + glutIdleFunc(glutPostRedisplay); 4.71 + 4.72 + glewInit(); 4.73 + 4.74 + glEnable(GL_DEPTH_TEST); 4.75 + glEnable(GL_CULL_FACE); 4.76 + glEnable(GL_LIGHTING); 4.77 + glEnable(GL_LIGHT0); 4.78 + glLightfv(GL_LIGHT0, GL_POSITION, ldir); 4.79 + 4.80 + if((load_scene(&scn, scene_fname)) == -1) { 4.81 + fprintf(stderr, "failed to load: %s\n", scene_fname); 4.82 + return 1; 4.83 + } 4.84 + dx = scn.bbox.max[0] - scn.bbox.min[0]; 4.85 + dy = scn.bbox.max[1] - scn.bbox.min[1]; 4.86 + dz = scn.bbox.max[2] - scn.bbox.min[2]; 4.87 + diag = sqrt(dx * dx + dy * dy + dz * dz); 4.88 + cam_dist = diag / fov; 4.89 + printf("camera distance: %f\n", cam_dist); 4.90 + 4.91 + glutMainLoop(); 4.92 + return 0; 4.93 +} 4.94 + 4.95 + 4.96 +void disp(void) 4.97 +{ 4.98 + unsigned int tm = glutGet(GLUT_ELAPSED_TIME); 4.99 + 4.100 + if(stereo) { 4.101 + glDrawBuffer(GL_BACK_LEFT); 4.102 + glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); 4.103 + 4.104 + glMatrixMode(GL_PROJECTION); 4.105 + glLoadIdentity(); 4.106 + proj_matrix(-1); 4.107 + glMatrixMode(GL_MODELVIEW); 4.108 + glLoadIdentity(); 4.109 + view_matrix(-1); 4.110 + 4.111 + render(tm); 4.112 + 4.113 + glDrawBuffer(GL_BACK_RIGHT); 4.114 + glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); 4.115 + 4.116 + glMatrixMode(GL_PROJECTION); 4.117 + glLoadIdentity(); 4.118 + proj_matrix(1); 4.119 + glMatrixMode(GL_MODELVIEW); 4.120 + glLoadIdentity(); 4.121 + view_matrix(1); 4.122 + 4.123 + render(tm); 4.124 + } else { 4.125 + glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); 4.126 + 4.127 + glMatrixMode(GL_PROJECTION); 4.128 + glLoadIdentity(); 4.129 + proj_matrix(0); 4.130 + glMatrixMode(GL_MODELVIEW); 4.131 + glLoadIdentity(); 4.132 + view_matrix(0); 4.133 + 4.134 + render(tm); 4.135 + } 4.136 + 4.137 + glutSwapBuffers(); 4.138 +} 4.139 + 4.140 +void render(unsigned int msec) 4.141 +{ 4.142 + if(auto_rot) { 4.143 + glRotatef(msec / 10, 0, 1, 0); 4.144 + } 4.145 + render_scene(&scn); 4.146 +} 4.147 + 4.148 +void proj_matrix(float eye) 4.149 +{ 4.150 + float vfov_rad = fov; 4.151 + float top = near_clip * tan(vfov_rad * 0.5); 4.152 + float right = top * (float)win_width / (float)win_height; 4.153 + 4.154 + float frust_shift = eye * (stereo_eye_sep * 0.5 * near_clip / stereo_focus_dist); 4.155 + 4.156 + glFrustum(-right + frust_shift, right + frust_shift, -top, top, near_clip, far_clip); 4.157 +} 4.158 + 4.159 +void view_matrix(float eye) 4.160 +{ 4.161 + float offs = stereo_eye_sep * eye * 0.5; 4.162 + glTranslatef(offs, 0, 0); 4.163 + 4.164 + glTranslatef(0, 0, -cam_dist); 4.165 + glRotatef(cam_phi, 1, 0, 0); 4.166 + glRotatef(cam_theta, 0, 1, 0); 4.167 +} 4.168 + 4.169 +void reshape(int x, int y) 4.170 +{ 4.171 + glViewport(0, 0, x, y); 4.172 + win_width = x; 4.173 + win_height = y; 4.174 +} 4.175 + 4.176 +static int stereo_shift_key; 4.177 + 4.178 +void keyb(unsigned char key, int x, int y) 4.179 +{ 4.180 + switch(key) { 4.181 + case 'q': 4.182 + case 27: 4.183 + exit(0); 4.184 + 4.185 + case 's': 4.186 + stereo_shift_key = 1; 4.187 + break; 4.188 + 4.189 + case 'c': 4.190 + { 4.191 + static int flip; 4.192 + glFrontFace((++flip & 1) ? GL_CW : GL_CCW); 4.193 + glutPostRedisplay(); 4.194 + } 4.195 + break; 4.196 + 4.197 + case 'C': 4.198 + { 4.199 + static int cull = 1; 4.200 + if(++cull & 1) { 4.201 + glEnable(GL_CULL_FACE); 4.202 + } else { 4.203 + glDisable(GL_CULL_FACE); 4.204 + } 4.205 + glutPostRedisplay(); 4.206 + } 4.207 + break; 4.208 + 4.209 + case 'w': 4.210 + { 4.211 + static int wire; 4.212 + glPolygonMode(GL_FRONT_AND_BACK, (++wire & 1) ? GL_LINE : GL_FILL); 4.213 + glutPostRedisplay(); 4.214 + } 4.215 + break; 4.216 + 4.217 + case 'l': 4.218 + { 4.219 + static int lit = 1; 4.220 + if(++lit & 1) { 4.221 + glEnable(GL_LIGHTING); 4.222 + } else { 4.223 + glDisable(GL_LIGHTING); 4.224 + } 4.225 + glutPostRedisplay(); 4.226 + } 4.227 + break; 4.228 + 4.229 + case ' ': 4.230 + auto_rot = !auto_rot; 4.231 + if(auto_rot) { 4.232 + glutIdleFunc(glutPostRedisplay); 4.233 + } else { 4.234 + glutIdleFunc(0); 4.235 + } 4.236 + glutPostRedisplay(); 4.237 + break; 4.238 + 4.239 + default: 4.240 + break; 4.241 + } 4.242 +} 4.243 + 4.244 +void keyb_up(unsigned char key, int x, int y) 4.245 +{ 4.246 + switch(key) { 4.247 + case 's': 4.248 + stereo_shift_key = 0; 4.249 + break; 4.250 + 4.251 + default: 4.252 + break; 4.253 + } 4.254 +} 4.255 + 4.256 + 4.257 +static int bnstate[32]; 4.258 +static int prev_x, prev_y; 4.259 +void mouse(int bn, int state, int x, int y) 4.260 +{ 4.261 + prev_x = x; 4.262 + prev_y = y; 4.263 + bnstate[bn - GLUT_LEFT_BUTTON] = state == GLUT_DOWN ? 1 : 0; 4.264 +} 4.265 + 4.266 +void motion(int x, int y) 4.267 +{ 4.268 + int dx = x - prev_x; 4.269 + int dy = y - prev_y; 4.270 + prev_x = x; 4.271 + prev_y = y; 4.272 + 4.273 + if(stereo_shift_key && dy != 0) { 4.274 + stereo_focus_dist += dy * 0.1; 4.275 + stereo_eye_sep = stereo_focus_dist / 30.0; 4.276 + glutPostRedisplay(); 4.277 + return; 4.278 + } 4.279 + 4.280 + if(bnstate[0]) { 4.281 + cam_theta += dx * 0.5; 4.282 + cam_phi += dy * 0.5; 4.283 + 4.284 + if(cam_phi < -90) 4.285 + cam_phi = -90; 4.286 + if(cam_phi > 90) 4.287 + cam_phi = 90; 4.288 + 4.289 + glutPostRedisplay(); 4.290 + } 4.291 + if(bnstate[2]) { 4.292 + cam_dist += dy * 0.1; 4.293 + glutPostRedisplay(); 4.294 + } 4.295 +} 4.296 + 4.297 +void sball_motion(int x, int y, int z) 4.298 +{ 4.299 +} 4.300 + 4.301 +void sball_rotate(int x, int y, int z) 4.302 +{ 4.303 + cam_theta += y * 0.05; 4.304 + cam_phi += x * 0.05; 4.305 + 4.306 + if(cam_phi < -90) 4.307 + cam_phi = -90; 4.308 + if(cam_phi > 90) 4.309 + cam_phi = 90; 4.310 + 4.311 + glutPostRedisplay(); 4.312 +} 4.313 + 4.314 +void sball_button(int bn, int state) 4.315 +{ 4.316 +} 4.317 + 4.318 +int parse_args(int argc, char **argv) 4.319 +{ 4.320 + int i; 4.321 + 4.322 + for(i=1; i<argc; i++) { 4.323 + if(argv[i][0] == '-') { 4.324 + if(argv[i][2] != 0) 4.325 + goto inval; 4.326 + switch(argv[i][1]) { 4.327 + case 's': 4.328 + stereo = 1; 4.329 + break; 4.330 + 4.331 + case 'c': 4.332 + flip_winding = 1; 4.333 + break; 4.334 + 4.335 + default: 4.336 + goto inval; 4.337 + } 4.338 + } else { 4.339 + if(scene_fname) { 4.340 + fprintf(stderr, "unexpected argument: %s\n", argv[i]); 4.341 + return -1; 4.342 + } 4.343 + scene_fname = argv[i]; 4.344 + } 4.345 + } 4.346 + 4.347 + if(!scene_fname) { 4.348 + fprintf(stderr, "you must pass the filename of a scene to open\n"); 4.349 + return -1; 4.350 + } 4.351 + 4.352 + return 0; 4.353 + 4.354 +inval: 4.355 + fprintf(stderr, "invalid argument: %s\n", argv[i]); 4.356 + return -1; 4.357 +}