# HG changeset patch # User John Tsiombikas # Date 1299214276 -7200 # Node ID dc1723a8bf6f1b05d429958b4d47d5e9174f5143 initial import diff -r 000000000000 -r dc1723a8bf6f Makefile --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Makefile Fri Mar 04 06:51:16 2011 +0200 @@ -0,0 +1,20 @@ +src = $(wildcard src/*.cc) +obj = $(src:.cc=.o) +bin = stereoview + +CXX = g++ +CXXFLAGS = -pedantic -Wall -g `pkg-config --cflags henge2` +LDFLAGS = `pkg-config --libs henge2` $(libgl) + +ifneq ($(shell uname -s), Darwin) + libgl = -lGL -lGLU -lglut +else + libgl = -framework OpenGL -framework GLUT +endif + +$(bin): $(obj) + $(CXX) -o $@ $(obj) $(LDFLAGS) + +.PHONY: clean +clean: + rm -f $(obj) $(bin) diff -r 000000000000 -r dc1723a8bf6f src/cam.cc --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/cam.cc Fri Mar 04 06:51:16 2011 +0200 @@ -0,0 +1,162 @@ +#include +#include "cam.h" + +/* viewing parameters */ +#define DEF_THETA 0 +#define DEF_PHI 25 +#define DEF_DIST 5 +#define DEF_X 0 +#define DEF_Y 0.25 +#define DEF_Z 0 + +static float cam_theta = DEF_THETA, cam_phi = DEF_PHI; +static float cam_dist = DEF_DIST; +static Vector3 cam_pos(DEF_X, DEF_Y, DEF_Z); + +/* projection parameters */ +#define DEF_VFOV 45.0 +#define DEF_ASPECT 1.3333333 +#define DEF_NEAR 1.0 +#define DEF_FAR 1000.0 + +static float vfov = DEF_VFOV; +static float aspect = DEF_ASPECT; +static float nearclip = DEF_NEAR, farclip = DEF_FAR; + +/* stereo parameters */ +#define DEF_EYE_SEP 0.1 +#define DEF_FOCUS_DIST 1.0 + +static float eye_sep = DEF_EYE_SEP; +static float focus_dist = DEF_FOCUS_DIST; + + +static float rot_speed = 0.5; +static float zoom_speed = 0.1; + +static float cam_speed = 1.0; + + +void cam_reset(void) +{ + cam_reset_view(); + cam_reset_proj(); + cam_reset_stereo(); +} + +void cam_reset_view(void) +{ + cam_theta = DEF_THETA; + cam_phi = DEF_PHI; + cam_dist = DEF_DIST; + cam_pos = Vector3(DEF_X, DEF_Y, DEF_Z); +} + +void cam_reset_proj(void) +{ + vfov = DEF_VFOV; + aspect = DEF_ASPECT; + nearclip = DEF_NEAR; + farclip = DEF_FAR; +} + +void cam_reset_stereo(void) +{ + eye_sep = DEF_EYE_SEP; + focus_dist = DEF_FOCUS_DIST; +} + +void cam_pan(int dx, int dy) +{ + float dxf = dx * cam_speed;// * cam_dist; + float dyf = dy * cam_speed;// * cam_dist; + float angle = -DEG_TO_RAD(cam_theta); + + cam_pos.x += cos(angle) * dxf + sin(angle) * dyf; + cam_pos.z += -sin(angle) * dxf + cos(angle) * dyf; +} + +void cam_height(int dh) +{ + cam_pos.y += dh * cam_speed;// * cam_dist; +} + +void cam_rotate(int dx, int dy) +{ + cam_theta += dx * rot_speed; + cam_phi += dy * rot_speed; + + if(cam_phi < -90) cam_phi = -90; + if(cam_phi > 90) cam_phi = 90; +} + +void cam_zoom(int dz) +{ + cam_dist += dz * zoom_speed; + if(cam_dist < 0.001) { + cam_dist = 0.001; + } +} + +void cam_clip(float n, float f) +{ + nearclip = n; + farclip = f; +} + +void cam_fov(float f) +{ + vfov = f; +} + +void cam_aspect(float a) +{ + aspect = a; +} + +void cam_separation(float s) +{ + eye_sep = s; +} + +void cam_focus_dist(float d) +{ + focus_dist = d; + + cam_separation(d / 30.0); +} + +void cam_view_matrix(void) +{ + cam_stereo_view_matrix(CAM_CENTER); +} + +void cam_stereo_view_matrix(int eye) +{ + static const float offs_sign[] = {0.0f, 0.5f, -0.5f}; /* center, left, right */ + float offs = eye_sep * offs_sign[eye]; + + glTranslatef(offs, 0, 0); + + glTranslatef(0, 0, -cam_dist); + glRotatef(cam_phi, 1, 0, 0); + glRotatef(cam_theta, 0, 1, 0); + glTranslatef(-cam_pos.x, -cam_pos.y, -cam_pos.z); +} + +void cam_proj_matrix(void) +{ + cam_stereo_proj_matrix(CAM_CENTER); +} + +void cam_stereo_proj_matrix(int eye) +{ + float vfov_rad = M_PI * vfov / 180.0; + float top = nearclip * tan(vfov_rad * 0.5); + float right = top * aspect; + + static const float offs_sign[] = {0.0f, 1.0, -1.0}; /* center, left, right */ + float frust_shift = offs_sign[eye] * (eye_sep * 0.5 * nearclip / focus_dist); + + glFrustum(-right + frust_shift, right + frust_shift, -top, top, nearclip, farclip); +} diff -r 000000000000 -r dc1723a8bf6f src/cam.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/cam.h Fri Mar 04 06:51:16 2011 +0200 @@ -0,0 +1,43 @@ +#ifndef CAM_H_ +#define CAM_H_ + +enum { + CAM_CENTER, + CAM_LEFT, + CAM_RIGHT +}; + +/* reset to the initial state */ +void cam_reset(void); /* all */ +void cam_reset_view(void); /* view parameters */ +void cam_reset_proj(void); /* projection parameters */ +void cam_reset_stereo(void); /* stereo parameters */ + +/* camera viewing parameters */ +void cam_pan(int dx, int dy); /* pan across X/Z plane */ +void cam_height(int dh); /* move verticaly */ +void cam_rotate(int dx, int dy); /* rotate around local Y and X axis */ +void cam_zoom(int dz); /* dolly the camera fwd/back */ + +/* camera projection parameters */ +void cam_clip(float n, float f); /* set clipping planes */ +void cam_fov(float f); /* vertical field of view in degrees */ +void cam_aspect(float a); /* aspect ratio (width / height) */ + +/* stereo parameters */ +void cam_separation(float s); +void cam_focus_dist(float d); + +/* multiply the camera view matrix on top of the current matrix stack + * (which should be GL_MODELVIEW) + */ +void cam_view_matrix(void); +void cam_stereo_view_matrix(int eye); + +/* multiply the camera projection matrix on top of the current matrix stack + * (which should be GL_PROJECTION) + */ +void cam_proj_matrix(void); +void cam_stereo_proj_matrix(int eye); + +#endif /* CAM_H_ */ diff -r 000000000000 -r dc1723a8bf6f src/stereoview.cc --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/stereoview.cc Fri Mar 04 06:51:16 2011 +0200 @@ -0,0 +1,268 @@ +#include +#include +#include +#include + +#ifndef __APPLE__ +#include +#else +#include +#endif + +#include "cam.h" +#include "zscn.h" + +struct Light { + float pos[4]; + float color[4]; +}; + +static void cleanup(); +static int parse_args(int argc, char **argv); +static void disp(); +static void render_scene(); +static void reshape(int x, int y); +static void keyb(unsigned char key, int x, int y); +static void mouse(int bn, int state, int x, int y); +static void motion(int x, int y); + +static bool use_stereo = false; +static bool use_zbuf = true; + +static std::list scn_fnames; +static henge::Scene *scn; + + +int main(int argc, char **argv) +{ + unsigned int init_flags = GLUT_RGB | GLUT_DOUBLE; + + atexit(cleanup); + + glutInitWindowSize(800, 600); + glutInit(&argc, argv); + + if(parse_args(argc, argv) == -1) { + return 1; + } + if(use_stereo) { + init_flags |= GLUT_STEREO; + } + if(use_zbuf) { + init_flags |= GLUT_DEPTH; + } + + glutInitDisplayMode(init_flags); + glutCreateWindow("stereoscopic scene viewer"); + + glutDisplayFunc(disp); + glutReshapeFunc(reshape); + glutKeyboardFunc(keyb); + glutMouseFunc(mouse); + glutMotionFunc(motion); + + if(use_zbuf) { + glEnable(GL_DEPTH_TEST); + } + + glEnable(GL_LIGHTING); + { + int i, num_lights; + struct Light lights[] = { + {{-0.85, 0.7, 1, 0}, {1.0, 1.0, 1.0, 1.0}}, + {{1, -0.5, 0.9, 0}, {0.75, 0.75, 0.75, 1.0}}, + {{0, 0, 1, 0}, {0.4, 0.4, 0.4, 1.0}} + }; + + num_lights = sizeof lights / sizeof *lights; + + for(i=0; i::iterator it = scn_fnames.begin(); + while(it != scn_fnames.end()) { + if(!(scn->load(it->c_str()))) { + fprintf(stderr, "failed to load scene: %s\n", it->c_str()); + return 1; + } + it++; + } + if(!scn->object_count()) { + fprintf(stderr, "didn't load any geometry, aborting\n"); + return 1; + } + + henge::Renderer *rend = henge::get_renderer(); + rend->set_render_mask(henge::REND_ALL & ~henge::REND_CAM); + + cam_reset(); + + glutMainLoop(); + return 0; +} + +static void cleanup() +{ + delete scn; +} + +static int parse_args(int argc, char **argv) +{ + for(int i=1; irender(); +} + +static void reshape(int x, int y) +{ + glViewport(0, 0, x, y); + + cam_aspect((float)x / (float)y); +} + +static void keyb(unsigned char key, int x, int y) +{ + static float focus_dist = 1.0; + + switch(key) { + case 27: + exit(0); + + case '-': + focus_dist -= 0.5; + cam_focus_dist(focus_dist); + glutPostRedisplay(); + printf("focus_dist: %f\n", focus_dist); + break; + + case '=': + focus_dist += 0.5; + cam_focus_dist(focus_dist); + glutPostRedisplay(); + printf("focus_dist: %f\n", focus_dist); + break; + + default: + break; + } +} + +static int px = -1, py; +static int bnstate[32]; + +static void mouse(int bn, int state, int x, int y) +{ + bnstate[bn] = state == GLUT_DOWN ? 1 : 0; + + if(state == GLUT_DOWN) { + px = x; + py = y; + } else { + px = -1; + } +} + +static void motion(int x, int y) +{ + int dx = x - px; + int dy = y - py; + + px = x; + py = y; + + if(bnstate[0]) { + cam_rotate(dx, dy); + glutPostRedisplay(); + } + if(bnstate[1]) { + cam_pan(dx, dy); + glutPostRedisplay(); + } + if(bnstate[2]) { + cam_zoom(dy); + glutPostRedisplay(); + } +} diff -r 000000000000 -r dc1723a8bf6f src/zscn.cc --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/zscn.cc Fri Mar 04 06:51:16 2011 +0200 @@ -0,0 +1,127 @@ +#include +#include "zscn.h" + +struct Face { + Vector3 v[3]; + Vector3 n[3]; + Vector2 t[3]; + + const henge::Material *mat; + + Face() + { + memset(this, 0, sizeof(Face)); + } +}; + +static void proc_mesh(std::list *facelist, const henge::TriMesh *mesh, + const henge::Material *mat, const Matrix4x4 &xform); +static bool operator <(const Face &a, const Face &b); + +ZScene::~ZScene() +{ +} + +void ZScene::render(unsigned int msec) const +{ + setup_lights(msec); + + glMatrixMode(GL_MODELVIEW); + + Matrix4x4 view_mat; + henge::store_matrix(&view_mat); + + std::list facelist; + + for(size_t i=0; iget_xform_matrix(msec) * view_mat; + + const henge::Material *mat = ((henge::RObject*)obj)->get_material_ptr(); + const henge::TriMesh *mesh = obj->get_mesh(); + + proc_mesh(&facelist, mesh, mat, xform); + } + + facelist.sort(); + + glPushAttrib(GL_ENABLE_BIT); + glDisable(GL_DEPTH_TEST); + + glPushMatrix(); + glLoadIdentity(); + + glBegin(GL_TRIANGLES); + + const henge::Material *cur_mat = 0; + std::list::iterator face = facelist.begin(); + while(face != facelist.end()) { + if(face->mat != cur_mat) { + glEnd(); + + face->mat->bind(); + cur_mat = face->mat; + + glBegin(GL_TRIANGLES); + } + + for(int i=0; i<3; i++) { + glNormal3f(face->n[i].x, face->n[i].y, face->n[i].z); + glTexCoord2f(face->t[i].x, face->t[i].y); + glVertex3f(face->v[i].x, face->v[i].y, face->v[i].z); + } + + face++; + } + glEnd(); + + glMatrixMode(GL_MODELVIEW); + glPopMatrix(); + glPopAttrib(); +} + +static void proc_mesh(std::list *facelist, const henge::TriMesh *mesh, + const henge::Material *mat, const Matrix4x4 &xform) +{ + Matrix3x3 norm_xform = xform; + + const Vector3 *vert = mesh->get_data_vec3(henge::EL_VERTEX); + const Vector3 *norm = mesh->get_data_vec3(henge::EL_NORMAL); + const Vector2 *tc = mesh->get_data_vec2(henge::EL_TEXCOORD); + const unsigned int *index = mesh->get_data_int(henge::EL_INDEX); + + int nvert = mesh->get_count(henge::EL_VERTEX); + int nindex = mesh->get_count(henge::EL_INDEX); + + if(!vert || !nvert) { + return; + } + + int face_count = (index ? nindex : nvert) / 3; + + for(int i=0; ipush_back(face); + } +} + +static bool operator <(const Face &a, const Face &b) +{ + return (a.v[0].z + a.v[1].z + a.v[2].z) < (b.v[0].z + b.v[1].z + b.v[2].z); +} diff -r 000000000000 -r dc1723a8bf6f src/zscn.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/zscn.h Fri Mar 04 06:51:16 2011 +0200 @@ -0,0 +1,8 @@ +#include + +class ZScene : public henge::Scene { +public: + virtual ~ZScene(); + + virtual void render(unsigned int msec = 0) const; +};