# HG changeset patch # User John Tsiombikas # Date 1335037363 -10800 # Node ID 3ea290d359840c53d476349d6b4f77bb507d0800 # Parent 2b30f261f6419af5596dce19a6e3aa89995951b5 it's never going to finish but wth :) diff -r 2b30f261f641 -r 3ea290d35984 src/camera.cc --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/camera.cc Sat Apr 21 22:42:43 2012 +0300 @@ -0,0 +1,190 @@ +#include "opengl.h" +#include "camera.h" + +Camera::Camera() +{ + inval_cache(); +} + +Camera::~Camera() +{ +} + +void Camera::calc_inv_matrix(Matrix4x4 *mat) const +{ + *mat = matrix().inverse(); +} + +void Camera::set_glmat(const Matrix4x4 &mat) const +{ +#ifdef SINGLE_PRECISION_MATH + if(glLoadTransposeMatrixfARB) { + glLoadTransposeMatrixfARB((float*)&mat); + } else { + Matrix4x4 tmat = mat.transposed(); + glLoadMatrixf((float*)&tmat); + } +#else + if(glLoadTransposeMatrixdARB) { + glLoadTransposeMatrixdARB((double*)&mat); + } else { + Matrix4x4 tmat = mat.transposed(); + glLoadMatrixd((double*)&tmat); + } +#endif +} + +const Matrix4x4 &Camera::matrix() const +{ + if(!mcache.valid) { + calc_matrix(&mcache.mat); + mcache.valid = true; + } + return mcache.mat; +} + +const Matrix4x4 &Camera::inv_matrix() const +{ + if(!mcache_inv.valid) { + calc_inv_matrix(&mcache_inv.mat); + mcache_inv.valid = true; + } + return mcache_inv.mat; +} + +void Camera::use() const +{ + set_glmat(matrix()); +} + +void Camera::use_inverse() const +{ + set_glmat(inv_matrix()); +} + +void Camera::input_move(float x, float y, float z) +{ +} + +void Camera::input_rotate(float x, float y, float z) +{ +} + +void Camera::input_zoom(float factor) +{ +} + + +// ---- orbit camera ---- + +OrbitCamera::OrbitCamera() +{ + theta = 0.0; + phi = 0.0; + rad = 10.0; +} + +OrbitCamera::~OrbitCamera() +{ +} + +void OrbitCamera::calc_matrix(Matrix4x4 *mat) const +{ + mat->reset_identity(); + mat->translate(Vector3(0, 0, -rad)); + mat->rotate(Vector3(phi, 0, 0)); + mat->rotate(Vector3(0, theta, 0)); +} + +void OrbitCamera::calc_inv_matrix(Matrix4x4 *mat) const +{ + mat->reset_identity(); + mat->rotate(Vector3(0, theta, 0)); + mat->rotate(Vector3(phi, 0, 0)); + mat->translate(Vector3(0, 0, -rad)); +} + +void OrbitCamera::input_rotate(float x, float y, float z) +{ + theta += x; + phi += y; + + if(phi < -M_PI / 2) + phi = -M_PI / 2; + if(phi > M_PI) + phi = M_PI; + + inval_cache(); +} + +void OrbitCamera::input_zoom(float factor) +{ + rad += factor; + if(rad < 0.0) + rad = 0.0; + + inval_cache(); +} + + +FlyCamera::FlyCamera() +{ + pos.z = 10.0f; +} + +void FlyCamera::calc_matrix(Matrix4x4 *mat) const +{ + /*mat->reset_identity(); + mat->translate(-pos); + *mat = *mat * Matrix4x4(rot.get_rotation_matrix()); + mat->translate(pos);*/ + //mat->translate(-pos.transformed(rot)); + + Matrix3x3 qmat = rot.get_rotation_matrix(); + + Vector3 ivec = qmat.get_row_vector(0); + Vector3 jvec = qmat.get_row_vector(1); + Vector3 kvec = qmat.get_row_vector(2); + + *mat = Matrix4x4(qmat); + /*Vector3 trans_x = ivec * pos; + Vector3 trans_y = jvec * pos; + Vector3 trans_z = kvec * pos; + Vector3 trans = trans_x + trans_y + trans_z;*/ + Vector3 trans; + trans.x = dot_product(ivec, pos); + trans.y = dot_product(jvec, pos); + trans.z = dot_product(kvec, pos); + mat->set_column_vector(-trans, 3); +} + +/*void FlyCamera::calc_inv_matrix(Matrix4x4 *mat) const +{ + mat->set_translation(pos); + *mat = *mat * Matrix4x4(rot.get_rotation_matrix()); +}*/ + +const Vector3 &FlyCamera::get_position() const +{ + return pos; +} + +const Quaternion &FlyCamera::get_rotation() const +{ + return rot; +} + +void FlyCamera::input_move(float x, float y, float z) +{ + pos += Vector3(x, y, z); + inval_cache(); +} + +void FlyCamera::input_rotate(float x, float y, float z) +{ + Vector3 axis(x, y, z); + float axis_len = axis.length(); + rot.rotate(axis / axis_len, axis_len); + rot.normalize(); + inval_cache(); +} diff -r 2b30f261f641 -r 3ea290d35984 src/camera.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/camera.h Sat Apr 21 22:42:43 2012 +0300 @@ -0,0 +1,69 @@ +#ifndef CAMERA_H_ +#define CAMERA_H_ + +#include "vmath/vmath.h" + +class Camera { +protected: + mutable struct { + bool valid; + Matrix4x4 mat; + } mcache, mcache_inv; + + virtual void calc_matrix(Matrix4x4 *mat) const = 0; + virtual void calc_inv_matrix(Matrix4x4 *mat) const; + + void inval_cache() { mcache.valid = mcache_inv.valid = false; } + void set_glmat(const Matrix4x4 &m) const; + +public: + Camera(); + virtual ~Camera(); + + const Matrix4x4 &matrix() const; + const Matrix4x4 &inv_matrix() const; + + void use() const; + void use_inverse() const; + + // these do nothing, override to provide input handling + virtual void input_move(float x, float y, float z); + virtual void input_rotate(float x, float y, float z); + virtual void input_zoom(float factor); +}; + +class OrbitCamera : public Camera { +private: + float theta, phi, rad; + + void calc_matrix(Matrix4x4 *mat) const; + void calc_inv_matrix(Matrix4x4 *mat) const; + +public: + OrbitCamera(); + virtual ~OrbitCamera(); + + void input_rotate(float x, float y, float z); + void input_zoom(float factor); +}; + +class FlyCamera : public Camera { +private: + Vector3 pos; + Quaternion rot; + + void calc_matrix(Matrix4x4 *mat) const; + //void calc_inv_matrix(Matrix4x4 *mat) const; + +public: + FlyCamera(); + + const Vector3 &get_position() const; + const Quaternion &get_rotation() const; + + void input_move(float x, float y, float z); + void input_rotate(float x, float y, float z); +}; + + +#endif // CAMERA_H_ diff -r 2b30f261f641 -r 3ea290d35984 src/game.cc --- a/src/game.cc Sat Apr 21 06:56:33 2012 +0300 +++ b/src/game.cc Sat Apr 21 22:42:43 2012 +0300 @@ -1,8 +1,18 @@ #include #include "opengl.h" #include "game.h" +#include "vein.h" +#include "ship.h" +#include "camera.h" -static unsigned long tmsec, start_time = -1; +static Vein *vein; +static Ship ship; + +static int keystate[256]; + +static OrbitCamera dbgcam; + +static unsigned long msec, start_time = -1; bool game_init() { @@ -14,6 +24,9 @@ float lpos[] = {-1, 1, 1, 0}; glLightfv(GL_LIGHT0, GL_POSITION, lpos); + // initialize the only level (vein) + vein = new Vein; + return true; } @@ -22,24 +35,51 @@ exit(0); } -void game_update(unsigned long msec) +void game_update(unsigned long ms) { + static unsigned long last_upd; + if(start_time == 0) { - start_time = msec; + start_time = ms; } - tmsec = msec - start_time; + msec = ms - start_time; + + time_sec_t dt = (msec - last_upd) / 1000.0; + + // handle key input + if(keystate['w'] || keystate['W']) { + ship.accelerate(1.0 * dt); + } + if(keystate['s'] || keystate['S']) { + ship.accelerate(-1.0 * dt); + } + // XXX change to mouselook + if(keystate['d'] || keystate['D']) { + ship.turn(-1.0 * dt, 0.0); + } + if(keystate['a'] || keystate['A']) { + ship.turn(1.0 * dt, 0.0); + } + if(keystate['e'] || keystate['E']) { + ship.turn(0.0, -1.0 * dt); + } + if(keystate['c'] || keystate['C']) { + ship.turn(0.0, 1.0 * dt); + } + + ship.update(dt); + + last_upd = msec; } void game_draw() { glMatrixMode(GL_MODELVIEW); - glLoadIdentity(); - glTranslatef(0, 0, -8); - glRotatef(20, 1, 0, 0); + dbgcam.use(); - glFrontFace(GL_CW); - glutSolidTeapot(1.0); - glFrontFace(GL_CCW); + vein->draw(ship.get_position()); + + ship.dbg_draw(); } void game_input_keyb(int key, int state) @@ -48,9 +88,41 @@ switch(key) { case 27: game_shutdown(); + break; default: break; } } + + if(key < 256) { + keystate[key] = state; + } } + +static int bnstate[16]; +static int prev_x, prev_y; + +void game_input_mbutton(int bn, int state, int x, int y) +{ + if(bn < 16) { + bnstate[bn] = state; + } + prev_x = x; + prev_y = y; +} + +void game_input_mmotion(int x, int y) +{ + int dx = x - prev_x; + int dy = y - prev_y; + prev_x = x; + prev_y = y; + + if(bnstate[0]) { + dbgcam.input_rotate(10.0 * dx / win_xsz, 10.0 * dy / win_ysz, 0); + } + if(bnstate[2]) { + dbgcam.input_zoom(10.0 * dy / win_ysz); + } +} diff -r 2b30f261f641 -r 3ea290d35984 src/game.h --- a/src/game.h Sat Apr 21 06:56:33 2012 +0300 +++ b/src/game.h Sat Apr 21 22:42:43 2012 +0300 @@ -1,6 +1,10 @@ #ifndef GAME_H_ #define GAME_H_ +typedef double time_sec_t; + +extern int win_xsz, win_ysz; + bool game_init(); void game_shutdown(); @@ -8,5 +12,7 @@ void game_draw(); void game_input_keyb(int key, int state); +void game_input_mbutton(int bn, int state, int x, int y); +void game_input_mmotion(int x, int y); #endif // GAME_H_ diff -r 2b30f261f641 -r 3ea290d35984 src/geom.cc --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/geom.cc Sat Apr 21 22:42:43 2012 +0300 @@ -0,0 +1,41 @@ +#include "opengl.h" +#include "geom.h" + +#ifdef SINGLE_PRECISION_MATH +#define ELEM_TYPE GL_FLOAT +#else +#define ELEM_TYPE GL_DOUBLE +#endif + +void draw_mesh(unsigned int prim, int num_verts, const Vertex *vbuf, const unsigned int *ibuf) +{ + glEnableClientState(GL_VERTEX_ARRAY); + glVertexPointer(3, ELEM_TYPE, sizeof *vbuf, &vbuf->pos); + + glEnableClientState(GL_NORMAL_ARRAY); + glNormalPointer(ELEM_TYPE, sizeof *vbuf, &vbuf->norm); + + glEnableClientState(GL_TEXTURE_COORD_ARRAY); + glTexCoordPointer(2, ELEM_TYPE, sizeof *vbuf, &vbuf->tc); + + if(ibuf) { + glDrawElements(prim, num_verts, GL_UNSIGNED_INT, ibuf); + } else { + glDrawArrays(prim, 0, num_verts); + } + + glDisableClientState(GL_VERTEX_ARRAY); + glDisableClientState(GL_NORMAL_ARRAY); + glDisableClientState(GL_TEXTURE_COORD_ARRAY); +#if 0 + glBegin(GL_QUADS); + for(int i=0; inorm.x, v->norm.y, v->norm.z); + glVertex3f(v->pos.x, v->pos.y, v->pos.z); + } + } + glEnd(); +#endif +} diff -r 2b30f261f641 -r 3ea290d35984 src/geom.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/geom.h Sat Apr 21 22:42:43 2012 +0300 @@ -0,0 +1,14 @@ +#ifndef GEOM_H_ +#define GEOM_H_ + +#include "opengl.h" +#include + +struct Vertex { + Vector3 pos, norm, tang; + Vector2 tc; +}; + +void draw_mesh(unsigned int prim, int count, const Vertex *vbuf, const unsigned int *ibuf); + +#endif // GEOM_H_ diff -r 2b30f261f641 -r 3ea290d35984 src/main.cc --- a/src/main.cc Sat Apr 21 06:56:33 2012 +0300 +++ b/src/main.cc Sat Apr 21 22:42:43 2012 +0300 @@ -10,6 +10,8 @@ void reshape(int x, int y); void key_press(unsigned char key, int x, int y); void key_release(unsigned char key, int x, int y); +void mouse(int bn, int state, int x, int y); +void motion(int x, int y); int win_xsz, win_ysz; @@ -25,6 +27,8 @@ glutReshapeFunc(reshape); glutKeyboardFunc(key_press); glutKeyboardUpFunc(key_release); + glutMouseFunc(mouse); + glutMotionFunc(motion); if(!game_init()) { return 1; @@ -45,6 +49,7 @@ // update any game logic game_update(msec); + glClearColor(0.05, 0.05, 0.05, 1.0); glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); // render stuff @@ -75,3 +80,13 @@ { game_input_keyb(key, 0); } + +void mouse(int bn, int state, int x, int y) +{ + game_input_mbutton(bn - GLUT_LEFT_BUTTON, state == GLUT_DOWN, x, y); +} + +void motion(int x, int y) +{ + game_input_mmotion(x, y); +} diff -r 2b30f261f641 -r 3ea290d35984 src/ship.cc --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/ship.cc Sat Apr 21 22:42:43 2012 +0300 @@ -0,0 +1,74 @@ +#include "opengl.h" +#include "ship.h" + +Ship::Ship() +{ + friction = 0.2; + //theta = phi = 0.0; +} + +void Ship::accelerate(double a) +{ + velocity += get_direction() * a; +} + +void Ship::turn(double yaw, double pitch) +{ + Quaternion qyaw(Vector3(0, 1, 0), yaw); + Quaternion qpitch(Vector3(1, 0, 0), pitch); + + rot *= qpitch; + rot *= qyaw; + /*theta += yaw; + phi += pitch;*/ +} + +void Ship::update(time_sec_t dt) +{ + pos += velocity * dt; + velocity -= velocity * friction * dt; +} + +const Vector3 &Ship::get_position() const +{ + return pos; +} + +Vector3 Ship::get_direction() const +{ + static const Vector3 dir{0, 0, 1}; + return dir.transformed(rot); + /*Vector3 dir; + dir.x = sin(theta) * sin(phi); + dir.z = cos(phi); + dir.y = cos(theta) * sin(phi); + return dir;*/ +} + +Matrix4x4 Ship::get_matrix() const +{ + return Matrix4x4::identity; +} + +void Ship::dbg_draw() const +{ + glPushAttrib(GL_POINT_BIT | GL_ENABLE_BIT); + + glPointSize(3.0); + glDisable(GL_LIGHTING); + + glBegin(GL_LINES); + glColor3f(0, 0, 1); + glVertex3f(pos.x, pos.y, pos.z); + + Vector3 end = pos + get_direction(); + glVertex3f(end.x, end.y, end.z); + glEnd(); + + glBegin(GL_POINTS); + glColor3f(1, 0, 0); + glVertex3f(pos.x, pos.y, pos.z); + glEnd(); + + glPopAttrib(); +} diff -r 2b30f261f641 -r 3ea290d35984 src/ship.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/ship.h Sat Apr 21 22:42:43 2012 +0300 @@ -0,0 +1,31 @@ +#ifndef SHIP_H_ +#define SHIP_H_ + +#include +#include "game.h" + +class Ship { +private: + Vector3 pos, velocity; + Quaternion rot; + //double theta, phi; + double friction; + +public: + Ship(); + + void accelerate(double a); + void turn(double yaw, double pitch); + + void update(time_sec_t dt); + + const Vector3 &get_position() const; + Vector3 get_direction() const; + + Matrix4x4 get_matrix() const; + + void dbg_draw() const; +}; + + +#endif // SHIP_H_ diff -r 2b30f261f641 -r 3ea290d35984 src/vein.cc --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/vein.cc Sat Apr 21 22:42:43 2012 +0300 @@ -0,0 +1,104 @@ +#ifndef _MSC_VER +#include +#else +#include +#endif +#include "vein.h" +#include "geom.h" + +Vein::Vein() +{ + gen_dist = 8.0; + subdiv = 8; + ring_subdiv = 16; + rad = 1.0; + + idxbuf = 0; +} + +Vein::~Vein() +{ + delete [] idxbuf; +} + +Vector3 Vein::calc_center(const Vector3 &ppos) const +{ + // TODO add variation + return Vector3(0.0, 0.0, ppos.z); +} + +Vector3 Vein::calc_dir(const Vector3 &ppos) const +{ + // TODO add variation + return Vector3(0, 0, 1); +} + +void Vein::build_idxbuf() +{ + delete [] idxbuf; + + int nfaces = subdiv * ring_subdiv; + int nidx = nfaces * 4; + idxbuf = new unsigned int[nidx]; + unsigned int *idxptr = idxbuf; + + for(int i=0; ipos = vec; + vptr->norm = cent - vec; + vptr->tang = Vector3(); // TODO + vptr->tc = Vector2(); // TODO + vptr++; + + theta += dtheta; + } + + pt.z += dz; + } + + // also create the index buffer if it's not valid + if(!idxbuf) { + ((Vein*)this)->build_idxbuf(); + } + + // awesome, now draw it + draw_mesh(GL_QUADS, nfaces * 4, vbuf, idxbuf); +} diff -r 2b30f261f641 -r 3ea290d35984 src/vein.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/vein.h Sat Apr 21 22:42:43 2012 +0300 @@ -0,0 +1,26 @@ +#ifndef VEIN_H_ +#define VEIN_H_ + +#include + +class Vein { +private: + float gen_dist; + float rad; + int subdiv, ring_subdiv; + + unsigned int *idxbuf; + + Vector3 calc_center(const Vector3 &ppos) const; + Vector3 calc_dir(const Vector3 &ppos) const; + + void build_idxbuf(); + +public: + Vein(); + ~Vein(); + + void draw(const Vector3 &player_pos) const; +}; + +#endif // VEIN_H_