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 +}