intravenous
changeset 1:3ea290d35984
it's never going to finish but wth :)
author | John Tsiombikas <nuclear@member.fsf.org> |
---|---|
date | Sat, 21 Apr 2012 22:42:43 +0300 |
parents | 2b30f261f641 |
children | 472c28b8b875 |
files | src/camera.cc src/camera.h src/game.cc src/game.h src/geom.cc src/geom.h src/main.cc src/ship.cc src/ship.h src/vein.cc src/vein.h |
diffstat | 11 files changed, 652 insertions(+), 10 deletions(-) [+] |
line diff
1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/src/camera.cc Sat Apr 21 22:42:43 2012 +0300 1.3 @@ -0,0 +1,190 @@ 1.4 +#include "opengl.h" 1.5 +#include "camera.h" 1.6 + 1.7 +Camera::Camera() 1.8 +{ 1.9 + inval_cache(); 1.10 +} 1.11 + 1.12 +Camera::~Camera() 1.13 +{ 1.14 +} 1.15 + 1.16 +void Camera::calc_inv_matrix(Matrix4x4 *mat) const 1.17 +{ 1.18 + *mat = matrix().inverse(); 1.19 +} 1.20 + 1.21 +void Camera::set_glmat(const Matrix4x4 &mat) const 1.22 +{ 1.23 +#ifdef SINGLE_PRECISION_MATH 1.24 + if(glLoadTransposeMatrixfARB) { 1.25 + glLoadTransposeMatrixfARB((float*)&mat); 1.26 + } else { 1.27 + Matrix4x4 tmat = mat.transposed(); 1.28 + glLoadMatrixf((float*)&tmat); 1.29 + } 1.30 +#else 1.31 + if(glLoadTransposeMatrixdARB) { 1.32 + glLoadTransposeMatrixdARB((double*)&mat); 1.33 + } else { 1.34 + Matrix4x4 tmat = mat.transposed(); 1.35 + glLoadMatrixd((double*)&tmat); 1.36 + } 1.37 +#endif 1.38 +} 1.39 + 1.40 +const Matrix4x4 &Camera::matrix() const 1.41 +{ 1.42 + if(!mcache.valid) { 1.43 + calc_matrix(&mcache.mat); 1.44 + mcache.valid = true; 1.45 + } 1.46 + return mcache.mat; 1.47 +} 1.48 + 1.49 +const Matrix4x4 &Camera::inv_matrix() const 1.50 +{ 1.51 + if(!mcache_inv.valid) { 1.52 + calc_inv_matrix(&mcache_inv.mat); 1.53 + mcache_inv.valid = true; 1.54 + } 1.55 + return mcache_inv.mat; 1.56 +} 1.57 + 1.58 +void Camera::use() const 1.59 +{ 1.60 + set_glmat(matrix()); 1.61 +} 1.62 + 1.63 +void Camera::use_inverse() const 1.64 +{ 1.65 + set_glmat(inv_matrix()); 1.66 +} 1.67 + 1.68 +void Camera::input_move(float x, float y, float z) 1.69 +{ 1.70 +} 1.71 + 1.72 +void Camera::input_rotate(float x, float y, float z) 1.73 +{ 1.74 +} 1.75 + 1.76 +void Camera::input_zoom(float factor) 1.77 +{ 1.78 +} 1.79 + 1.80 + 1.81 +// ---- orbit camera ---- 1.82 + 1.83 +OrbitCamera::OrbitCamera() 1.84 +{ 1.85 + theta = 0.0; 1.86 + phi = 0.0; 1.87 + rad = 10.0; 1.88 +} 1.89 + 1.90 +OrbitCamera::~OrbitCamera() 1.91 +{ 1.92 +} 1.93 + 1.94 +void OrbitCamera::calc_matrix(Matrix4x4 *mat) const 1.95 +{ 1.96 + mat->reset_identity(); 1.97 + mat->translate(Vector3(0, 0, -rad)); 1.98 + mat->rotate(Vector3(phi, 0, 0)); 1.99 + mat->rotate(Vector3(0, theta, 0)); 1.100 +} 1.101 + 1.102 +void OrbitCamera::calc_inv_matrix(Matrix4x4 *mat) const 1.103 +{ 1.104 + mat->reset_identity(); 1.105 + mat->rotate(Vector3(0, theta, 0)); 1.106 + mat->rotate(Vector3(phi, 0, 0)); 1.107 + mat->translate(Vector3(0, 0, -rad)); 1.108 +} 1.109 + 1.110 +void OrbitCamera::input_rotate(float x, float y, float z) 1.111 +{ 1.112 + theta += x; 1.113 + phi += y; 1.114 + 1.115 + if(phi < -M_PI / 2) 1.116 + phi = -M_PI / 2; 1.117 + if(phi > M_PI) 1.118 + phi = M_PI; 1.119 + 1.120 + inval_cache(); 1.121 +} 1.122 + 1.123 +void OrbitCamera::input_zoom(float factor) 1.124 +{ 1.125 + rad += factor; 1.126 + if(rad < 0.0) 1.127 + rad = 0.0; 1.128 + 1.129 + inval_cache(); 1.130 +} 1.131 + 1.132 + 1.133 +FlyCamera::FlyCamera() 1.134 +{ 1.135 + pos.z = 10.0f; 1.136 +} 1.137 + 1.138 +void FlyCamera::calc_matrix(Matrix4x4 *mat) const 1.139 +{ 1.140 + /*mat->reset_identity(); 1.141 + mat->translate(-pos); 1.142 + *mat = *mat * Matrix4x4(rot.get_rotation_matrix()); 1.143 + mat->translate(pos);*/ 1.144 + //mat->translate(-pos.transformed(rot)); 1.145 + 1.146 + Matrix3x3 qmat = rot.get_rotation_matrix(); 1.147 + 1.148 + Vector3 ivec = qmat.get_row_vector(0); 1.149 + Vector3 jvec = qmat.get_row_vector(1); 1.150 + Vector3 kvec = qmat.get_row_vector(2); 1.151 + 1.152 + *mat = Matrix4x4(qmat); 1.153 + /*Vector3 trans_x = ivec * pos; 1.154 + Vector3 trans_y = jvec * pos; 1.155 + Vector3 trans_z = kvec * pos; 1.156 + Vector3 trans = trans_x + trans_y + trans_z;*/ 1.157 + Vector3 trans; 1.158 + trans.x = dot_product(ivec, pos); 1.159 + trans.y = dot_product(jvec, pos); 1.160 + trans.z = dot_product(kvec, pos); 1.161 + mat->set_column_vector(-trans, 3); 1.162 +} 1.163 + 1.164 +/*void FlyCamera::calc_inv_matrix(Matrix4x4 *mat) const 1.165 +{ 1.166 + mat->set_translation(pos); 1.167 + *mat = *mat * Matrix4x4(rot.get_rotation_matrix()); 1.168 +}*/ 1.169 + 1.170 +const Vector3 &FlyCamera::get_position() const 1.171 +{ 1.172 + return pos; 1.173 +} 1.174 + 1.175 +const Quaternion &FlyCamera::get_rotation() const 1.176 +{ 1.177 + return rot; 1.178 +} 1.179 + 1.180 +void FlyCamera::input_move(float x, float y, float z) 1.181 +{ 1.182 + pos += Vector3(x, y, z); 1.183 + inval_cache(); 1.184 +} 1.185 + 1.186 +void FlyCamera::input_rotate(float x, float y, float z) 1.187 +{ 1.188 + Vector3 axis(x, y, z); 1.189 + float axis_len = axis.length(); 1.190 + rot.rotate(axis / axis_len, axis_len); 1.191 + rot.normalize(); 1.192 + inval_cache(); 1.193 +}
2.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 2.2 +++ b/src/camera.h Sat Apr 21 22:42:43 2012 +0300 2.3 @@ -0,0 +1,69 @@ 2.4 +#ifndef CAMERA_H_ 2.5 +#define CAMERA_H_ 2.6 + 2.7 +#include "vmath/vmath.h" 2.8 + 2.9 +class Camera { 2.10 +protected: 2.11 + mutable struct { 2.12 + bool valid; 2.13 + Matrix4x4 mat; 2.14 + } mcache, mcache_inv; 2.15 + 2.16 + virtual void calc_matrix(Matrix4x4 *mat) const = 0; 2.17 + virtual void calc_inv_matrix(Matrix4x4 *mat) const; 2.18 + 2.19 + void inval_cache() { mcache.valid = mcache_inv.valid = false; } 2.20 + void set_glmat(const Matrix4x4 &m) const; 2.21 + 2.22 +public: 2.23 + Camera(); 2.24 + virtual ~Camera(); 2.25 + 2.26 + const Matrix4x4 &matrix() const; 2.27 + const Matrix4x4 &inv_matrix() const; 2.28 + 2.29 + void use() const; 2.30 + void use_inverse() const; 2.31 + 2.32 + // these do nothing, override to provide input handling 2.33 + virtual void input_move(float x, float y, float z); 2.34 + virtual void input_rotate(float x, float y, float z); 2.35 + virtual void input_zoom(float factor); 2.36 +}; 2.37 + 2.38 +class OrbitCamera : public Camera { 2.39 +private: 2.40 + float theta, phi, rad; 2.41 + 2.42 + void calc_matrix(Matrix4x4 *mat) const; 2.43 + void calc_inv_matrix(Matrix4x4 *mat) const; 2.44 + 2.45 +public: 2.46 + OrbitCamera(); 2.47 + virtual ~OrbitCamera(); 2.48 + 2.49 + void input_rotate(float x, float y, float z); 2.50 + void input_zoom(float factor); 2.51 +}; 2.52 + 2.53 +class FlyCamera : public Camera { 2.54 +private: 2.55 + Vector3 pos; 2.56 + Quaternion rot; 2.57 + 2.58 + void calc_matrix(Matrix4x4 *mat) const; 2.59 + //void calc_inv_matrix(Matrix4x4 *mat) const; 2.60 + 2.61 +public: 2.62 + FlyCamera(); 2.63 + 2.64 + const Vector3 &get_position() const; 2.65 + const Quaternion &get_rotation() const; 2.66 + 2.67 + void input_move(float x, float y, float z); 2.68 + void input_rotate(float x, float y, float z); 2.69 +}; 2.70 + 2.71 + 2.72 +#endif // CAMERA_H_
3.1 --- a/src/game.cc Sat Apr 21 06:56:33 2012 +0300 3.2 +++ b/src/game.cc Sat Apr 21 22:42:43 2012 +0300 3.3 @@ -1,8 +1,18 @@ 3.4 #include <stdlib.h> 3.5 #include "opengl.h" 3.6 #include "game.h" 3.7 +#include "vein.h" 3.8 +#include "ship.h" 3.9 +#include "camera.h" 3.10 3.11 -static unsigned long tmsec, start_time = -1; 3.12 +static Vein *vein; 3.13 +static Ship ship; 3.14 + 3.15 +static int keystate[256]; 3.16 + 3.17 +static OrbitCamera dbgcam; 3.18 + 3.19 +static unsigned long msec, start_time = -1; 3.20 3.21 bool game_init() 3.22 { 3.23 @@ -14,6 +24,9 @@ 3.24 float lpos[] = {-1, 1, 1, 0}; 3.25 glLightfv(GL_LIGHT0, GL_POSITION, lpos); 3.26 3.27 + // initialize the only level (vein) 3.28 + vein = new Vein; 3.29 + 3.30 return true; 3.31 } 3.32 3.33 @@ -22,24 +35,51 @@ 3.34 exit(0); 3.35 } 3.36 3.37 -void game_update(unsigned long msec) 3.38 +void game_update(unsigned long ms) 3.39 { 3.40 + static unsigned long last_upd; 3.41 + 3.42 if(start_time == 0) { 3.43 - start_time = msec; 3.44 + start_time = ms; 3.45 } 3.46 - tmsec = msec - start_time; 3.47 + msec = ms - start_time; 3.48 + 3.49 + time_sec_t dt = (msec - last_upd) / 1000.0; 3.50 + 3.51 + // handle key input 3.52 + if(keystate['w'] || keystate['W']) { 3.53 + ship.accelerate(1.0 * dt); 3.54 + } 3.55 + if(keystate['s'] || keystate['S']) { 3.56 + ship.accelerate(-1.0 * dt); 3.57 + } 3.58 + // XXX change to mouselook 3.59 + if(keystate['d'] || keystate['D']) { 3.60 + ship.turn(-1.0 * dt, 0.0); 3.61 + } 3.62 + if(keystate['a'] || keystate['A']) { 3.63 + ship.turn(1.0 * dt, 0.0); 3.64 + } 3.65 + if(keystate['e'] || keystate['E']) { 3.66 + ship.turn(0.0, -1.0 * dt); 3.67 + } 3.68 + if(keystate['c'] || keystate['C']) { 3.69 + ship.turn(0.0, 1.0 * dt); 3.70 + } 3.71 + 3.72 + ship.update(dt); 3.73 + 3.74 + last_upd = msec; 3.75 } 3.76 3.77 void game_draw() 3.78 { 3.79 glMatrixMode(GL_MODELVIEW); 3.80 - glLoadIdentity(); 3.81 - glTranslatef(0, 0, -8); 3.82 - glRotatef(20, 1, 0, 0); 3.83 + dbgcam.use(); 3.84 3.85 - glFrontFace(GL_CW); 3.86 - glutSolidTeapot(1.0); 3.87 - glFrontFace(GL_CCW); 3.88 + vein->draw(ship.get_position()); 3.89 + 3.90 + ship.dbg_draw(); 3.91 } 3.92 3.93 void game_input_keyb(int key, int state) 3.94 @@ -48,9 +88,41 @@ 3.95 switch(key) { 3.96 case 27: 3.97 game_shutdown(); 3.98 + break; 3.99 3.100 default: 3.101 break; 3.102 } 3.103 } 3.104 + 3.105 + if(key < 256) { 3.106 + keystate[key] = state; 3.107 + } 3.108 } 3.109 + 3.110 +static int bnstate[16]; 3.111 +static int prev_x, prev_y; 3.112 + 3.113 +void game_input_mbutton(int bn, int state, int x, int y) 3.114 +{ 3.115 + if(bn < 16) { 3.116 + bnstate[bn] = state; 3.117 + } 3.118 + prev_x = x; 3.119 + prev_y = y; 3.120 +} 3.121 + 3.122 +void game_input_mmotion(int x, int y) 3.123 +{ 3.124 + int dx = x - prev_x; 3.125 + int dy = y - prev_y; 3.126 + prev_x = x; 3.127 + prev_y = y; 3.128 + 3.129 + if(bnstate[0]) { 3.130 + dbgcam.input_rotate(10.0 * dx / win_xsz, 10.0 * dy / win_ysz, 0); 3.131 + } 3.132 + if(bnstate[2]) { 3.133 + dbgcam.input_zoom(10.0 * dy / win_ysz); 3.134 + } 3.135 +}
4.1 --- a/src/game.h Sat Apr 21 06:56:33 2012 +0300 4.2 +++ b/src/game.h Sat Apr 21 22:42:43 2012 +0300 4.3 @@ -1,6 +1,10 @@ 4.4 #ifndef GAME_H_ 4.5 #define GAME_H_ 4.6 4.7 +typedef double time_sec_t; 4.8 + 4.9 +extern int win_xsz, win_ysz; 4.10 + 4.11 bool game_init(); 4.12 void game_shutdown(); 4.13 4.14 @@ -8,5 +12,7 @@ 4.15 void game_draw(); 4.16 4.17 void game_input_keyb(int key, int state); 4.18 +void game_input_mbutton(int bn, int state, int x, int y); 4.19 +void game_input_mmotion(int x, int y); 4.20 4.21 #endif // GAME_H_
5.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 5.2 +++ b/src/geom.cc Sat Apr 21 22:42:43 2012 +0300 5.3 @@ -0,0 +1,41 @@ 5.4 +#include "opengl.h" 5.5 +#include "geom.h" 5.6 + 5.7 +#ifdef SINGLE_PRECISION_MATH 5.8 +#define ELEM_TYPE GL_FLOAT 5.9 +#else 5.10 +#define ELEM_TYPE GL_DOUBLE 5.11 +#endif 5.12 + 5.13 +void draw_mesh(unsigned int prim, int num_verts, const Vertex *vbuf, const unsigned int *ibuf) 5.14 +{ 5.15 + glEnableClientState(GL_VERTEX_ARRAY); 5.16 + glVertexPointer(3, ELEM_TYPE, sizeof *vbuf, &vbuf->pos); 5.17 + 5.18 + glEnableClientState(GL_NORMAL_ARRAY); 5.19 + glNormalPointer(ELEM_TYPE, sizeof *vbuf, &vbuf->norm); 5.20 + 5.21 + glEnableClientState(GL_TEXTURE_COORD_ARRAY); 5.22 + glTexCoordPointer(2, ELEM_TYPE, sizeof *vbuf, &vbuf->tc); 5.23 + 5.24 + if(ibuf) { 5.25 + glDrawElements(prim, num_verts, GL_UNSIGNED_INT, ibuf); 5.26 + } else { 5.27 + glDrawArrays(prim, 0, num_verts); 5.28 + } 5.29 + 5.30 + glDisableClientState(GL_VERTEX_ARRAY); 5.31 + glDisableClientState(GL_NORMAL_ARRAY); 5.32 + glDisableClientState(GL_TEXTURE_COORD_ARRAY); 5.33 +#if 0 5.34 + glBegin(GL_QUADS); 5.35 + for(int i=0; i<count; i++) { 5.36 + for(int j=0; j<4; j++) { 5.37 + const Vertex *v = vbuf + ibuf[i * 4 + j]; 5.38 + glNormal3f(v->norm.x, v->norm.y, v->norm.z); 5.39 + glVertex3f(v->pos.x, v->pos.y, v->pos.z); 5.40 + } 5.41 + } 5.42 + glEnd(); 5.43 +#endif 5.44 +}
6.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 6.2 +++ b/src/geom.h Sat Apr 21 22:42:43 2012 +0300 6.3 @@ -0,0 +1,14 @@ 6.4 +#ifndef GEOM_H_ 6.5 +#define GEOM_H_ 6.6 + 6.7 +#include "opengl.h" 6.8 +#include <vmath/vmath.h> 6.9 + 6.10 +struct Vertex { 6.11 + Vector3 pos, norm, tang; 6.12 + Vector2 tc; 6.13 +}; 6.14 + 6.15 +void draw_mesh(unsigned int prim, int count, const Vertex *vbuf, const unsigned int *ibuf); 6.16 + 6.17 +#endif // GEOM_H_
7.1 --- a/src/main.cc Sat Apr 21 06:56:33 2012 +0300 7.2 +++ b/src/main.cc Sat Apr 21 22:42:43 2012 +0300 7.3 @@ -10,6 +10,8 @@ 7.4 void reshape(int x, int y); 7.5 void key_press(unsigned char key, int x, int y); 7.6 void key_release(unsigned char key, int x, int y); 7.7 +void mouse(int bn, int state, int x, int y); 7.8 +void motion(int x, int y); 7.9 7.10 int win_xsz, win_ysz; 7.11 7.12 @@ -25,6 +27,8 @@ 7.13 glutReshapeFunc(reshape); 7.14 glutKeyboardFunc(key_press); 7.15 glutKeyboardUpFunc(key_release); 7.16 + glutMouseFunc(mouse); 7.17 + glutMotionFunc(motion); 7.18 7.19 if(!game_init()) { 7.20 return 1; 7.21 @@ -45,6 +49,7 @@ 7.22 // update any game logic 7.23 game_update(msec); 7.24 7.25 + glClearColor(0.05, 0.05, 0.05, 1.0); 7.26 glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); 7.27 7.28 // render stuff 7.29 @@ -75,3 +80,13 @@ 7.30 { 7.31 game_input_keyb(key, 0); 7.32 } 7.33 + 7.34 +void mouse(int bn, int state, int x, int y) 7.35 +{ 7.36 + game_input_mbutton(bn - GLUT_LEFT_BUTTON, state == GLUT_DOWN, x, y); 7.37 +} 7.38 + 7.39 +void motion(int x, int y) 7.40 +{ 7.41 + game_input_mmotion(x, y); 7.42 +}
8.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 8.2 +++ b/src/ship.cc Sat Apr 21 22:42:43 2012 +0300 8.3 @@ -0,0 +1,74 @@ 8.4 +#include "opengl.h" 8.5 +#include "ship.h" 8.6 + 8.7 +Ship::Ship() 8.8 +{ 8.9 + friction = 0.2; 8.10 + //theta = phi = 0.0; 8.11 +} 8.12 + 8.13 +void Ship::accelerate(double a) 8.14 +{ 8.15 + velocity += get_direction() * a; 8.16 +} 8.17 + 8.18 +void Ship::turn(double yaw, double pitch) 8.19 +{ 8.20 + Quaternion qyaw(Vector3(0, 1, 0), yaw); 8.21 + Quaternion qpitch(Vector3(1, 0, 0), pitch); 8.22 + 8.23 + rot *= qpitch; 8.24 + rot *= qyaw; 8.25 + /*theta += yaw; 8.26 + phi += pitch;*/ 8.27 +} 8.28 + 8.29 +void Ship::update(time_sec_t dt) 8.30 +{ 8.31 + pos += velocity * dt; 8.32 + velocity -= velocity * friction * dt; 8.33 +} 8.34 + 8.35 +const Vector3 &Ship::get_position() const 8.36 +{ 8.37 + return pos; 8.38 +} 8.39 + 8.40 +Vector3 Ship::get_direction() const 8.41 +{ 8.42 + static const Vector3 dir{0, 0, 1}; 8.43 + return dir.transformed(rot); 8.44 + /*Vector3 dir; 8.45 + dir.x = sin(theta) * sin(phi); 8.46 + dir.z = cos(phi); 8.47 + dir.y = cos(theta) * sin(phi); 8.48 + return dir;*/ 8.49 +} 8.50 + 8.51 +Matrix4x4 Ship::get_matrix() const 8.52 +{ 8.53 + return Matrix4x4::identity; 8.54 +} 8.55 + 8.56 +void Ship::dbg_draw() const 8.57 +{ 8.58 + glPushAttrib(GL_POINT_BIT | GL_ENABLE_BIT); 8.59 + 8.60 + glPointSize(3.0); 8.61 + glDisable(GL_LIGHTING); 8.62 + 8.63 + glBegin(GL_LINES); 8.64 + glColor3f(0, 0, 1); 8.65 + glVertex3f(pos.x, pos.y, pos.z); 8.66 + 8.67 + Vector3 end = pos + get_direction(); 8.68 + glVertex3f(end.x, end.y, end.z); 8.69 + glEnd(); 8.70 + 8.71 + glBegin(GL_POINTS); 8.72 + glColor3f(1, 0, 0); 8.73 + glVertex3f(pos.x, pos.y, pos.z); 8.74 + glEnd(); 8.75 + 8.76 + glPopAttrib(); 8.77 +}
9.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 9.2 +++ b/src/ship.h Sat Apr 21 22:42:43 2012 +0300 9.3 @@ -0,0 +1,31 @@ 9.4 +#ifndef SHIP_H_ 9.5 +#define SHIP_H_ 9.6 + 9.7 +#include <vmath/vmath.h> 9.8 +#include "game.h" 9.9 + 9.10 +class Ship { 9.11 +private: 9.12 + Vector3 pos, velocity; 9.13 + Quaternion rot; 9.14 + //double theta, phi; 9.15 + double friction; 9.16 + 9.17 +public: 9.18 + Ship(); 9.19 + 9.20 + void accelerate(double a); 9.21 + void turn(double yaw, double pitch); 9.22 + 9.23 + void update(time_sec_t dt); 9.24 + 9.25 + const Vector3 &get_position() const; 9.26 + Vector3 get_direction() const; 9.27 + 9.28 + Matrix4x4 get_matrix() const; 9.29 + 9.30 + void dbg_draw() const; 9.31 +}; 9.32 + 9.33 + 9.34 +#endif // SHIP_H_
10.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 10.2 +++ b/src/vein.cc Sat Apr 21 22:42:43 2012 +0300 10.3 @@ -0,0 +1,104 @@ 10.4 +#ifndef _MSC_VER 10.5 +#include <alloca.h> 10.6 +#else 10.7 +#include <malloc.h> 10.8 +#endif 10.9 +#include "vein.h" 10.10 +#include "geom.h" 10.11 + 10.12 +Vein::Vein() 10.13 +{ 10.14 + gen_dist = 8.0; 10.15 + subdiv = 8; 10.16 + ring_subdiv = 16; 10.17 + rad = 1.0; 10.18 + 10.19 + idxbuf = 0; 10.20 +} 10.21 + 10.22 +Vein::~Vein() 10.23 +{ 10.24 + delete [] idxbuf; 10.25 +} 10.26 + 10.27 +Vector3 Vein::calc_center(const Vector3 &ppos) const 10.28 +{ 10.29 + // TODO add variation 10.30 + return Vector3(0.0, 0.0, ppos.z); 10.31 +} 10.32 + 10.33 +Vector3 Vein::calc_dir(const Vector3 &ppos) const 10.34 +{ 10.35 + // TODO add variation 10.36 + return Vector3(0, 0, 1); 10.37 +} 10.38 + 10.39 +void Vein::build_idxbuf() 10.40 +{ 10.41 + delete [] idxbuf; 10.42 + 10.43 + int nfaces = subdiv * ring_subdiv; 10.44 + int nidx = nfaces * 4; 10.45 + idxbuf = new unsigned int[nidx]; 10.46 + unsigned int *idxptr = idxbuf; 10.47 + 10.48 + for(int i=0; i<subdiv; i++) { 10.49 + for(int j=0; j<ring_subdiv; j++) { 10.50 + idxptr[0] = i * ring_subdiv + j; 10.51 + idxptr[1] = i * ring_subdiv + ((j + 1) % ring_subdiv); 10.52 + idxptr[2] = idxptr[1] + ring_subdiv; 10.53 + idxptr[3] = idxptr[0] + ring_subdiv; 10.54 + idxptr += 4; 10.55 + } 10.56 + } 10.57 +} 10.58 + 10.59 +void Vein::draw(const Vector3 &ppos) const 10.60 +{ 10.61 + float start_z = ppos.z - gen_dist / 2.0; 10.62 + float dz = gen_dist / subdiv; 10.63 + 10.64 + int nslices = subdiv + 1; 10.65 + int nverts = nslices * ring_subdiv; 10.66 + int nfaces = subdiv * ring_subdiv; 10.67 + Vertex *vbuf = (Vertex*)alloca(nverts * sizeof *vbuf); 10.68 + Vertex *vptr = vbuf; 10.69 + 10.70 + Vector3 pt = ppos; 10.71 + pt.z = start_z; 10.72 + 10.73 + for(int i=0; i<nslices; i++) { 10.74 + Vector3 cent = calc_center(pt); 10.75 + Vector3 dir = calc_dir(pt); 10.76 + Vector3 up(0, 1, 0); 10.77 + Vector3 right = cross_product(up, dir); 10.78 + up = cross_product(dir, right); 10.79 + 10.80 + Matrix3x3 vrot{right, up, dir}; 10.81 + //Quaternion vrot(dri, dtheta); 10.82 + 10.83 + float theta = 0.0, dtheta = 2.0 * M_PI / ring_subdiv; 10.84 + for(int j=0; j<ring_subdiv; j++) { 10.85 + Vector3 vec = Vector3{-cos(theta) * rad, sin(theta) * rad, 0.0} + cent; 10.86 + vec.transform(vrot); 10.87 + 10.88 + vptr->pos = vec; 10.89 + vptr->norm = cent - vec; 10.90 + vptr->tang = Vector3(); // TODO 10.91 + vptr->tc = Vector2(); // TODO 10.92 + vptr++; 10.93 + 10.94 + theta += dtheta; 10.95 + } 10.96 + 10.97 + pt.z += dz; 10.98 + } 10.99 + 10.100 + // also create the index buffer if it's not valid 10.101 + if(!idxbuf) { 10.102 + ((Vein*)this)->build_idxbuf(); 10.103 + } 10.104 + 10.105 + // awesome, now draw it 10.106 + draw_mesh(GL_QUADS, nfaces * 4, vbuf, idxbuf); 10.107 +}
11.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 11.2 +++ b/src/vein.h Sat Apr 21 22:42:43 2012 +0300 11.3 @@ -0,0 +1,26 @@ 11.4 +#ifndef VEIN_H_ 11.5 +#define VEIN_H_ 11.6 + 11.7 +#include <vmath/vmath.h> 11.8 + 11.9 +class Vein { 11.10 +private: 11.11 + float gen_dist; 11.12 + float rad; 11.13 + int subdiv, ring_subdiv; 11.14 + 11.15 + unsigned int *idxbuf; 11.16 + 11.17 + Vector3 calc_center(const Vector3 &ppos) const; 11.18 + Vector3 calc_dir(const Vector3 &ppos) const; 11.19 + 11.20 + void build_idxbuf(); 11.21 + 11.22 +public: 11.23 + Vein(); 11.24 + ~Vein(); 11.25 + 11.26 + void draw(const Vector3 &player_pos) const; 11.27 +}; 11.28 + 11.29 +#endif // VEIN_H_