ld33_umonster
changeset 6:3b4460b34d43
progress
author | John Tsiombikas <nuclear@member.fsf.org> |
---|---|
date | Sun, 23 Aug 2015 05:37:09 +0300 |
parents | 1e8d90aeae34 |
children | 92d662deb66e |
files | src/dragon.cc src/dragon.h src/game.cc src/revol.cc src/revol.h src/room.cc src/room.h src/shadow.cc |
diffstat | 8 files changed, 300 insertions(+), 7 deletions(-) [+] |
line diff
1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/src/dragon.cc Sun Aug 23 05:37:09 2015 +0300 1.3 @@ -0,0 +1,120 @@ 1.4 +#include <algorithm> 1.5 +#include "opengl.h" 1.6 +#include "dragon.h" 1.7 + 1.8 +Dragon::Dragon() 1.9 + : pos(0, 0, 0), dir(0, 0, -1), head_pos(0, 0, -1), target(0, 0, -2) 1.10 +{ 1.11 + set_head_limits(-1, 1, -1, 1); 1.12 +} 1.13 + 1.14 +Dragon::~Dragon() 1.15 +{ 1.16 +} 1.17 + 1.18 +void Dragon::set_position(const Vector3 &p) 1.19 +{ 1.20 + pos = p; 1.21 +} 1.22 + 1.23 +void Dragon::set_direction(const Vector3 &dir) 1.24 +{ 1.25 + this->dir = dir.normalized(); 1.26 +} 1.27 + 1.28 +void Dragon::set_target(const Vector3 &p) 1.29 +{ 1.30 + target = p; 1.31 +} 1.32 + 1.33 +void Dragon::set_head_limits(float xmin, float xmax, float ymin, float ymax) 1.34 +{ 1.35 + head_xlim[0] = std::min(xmin, xmax); 1.36 + head_xlim[1] = std::max(xmin, xmax); 1.37 + head_ylim[0] = std::min(ymin, ymax); 1.38 + head_ylim[1] = std::max(ymin, ymax); 1.39 +} 1.40 + 1.41 +void Dragon::move_head(const Vector3 &p) 1.42 +{ 1.43 + head_pos = p; 1.44 +} 1.45 + 1.46 +static float clamp(float x, float low, float high) 1.47 +{ 1.48 + return x < low ? low : (x > high ? high : x); 1.49 +} 1.50 + 1.51 +void Dragon::move_head(float dx, float dy) 1.52 +{ 1.53 + float newx = clamp(head_pos.x + dx, head_xlim[0], head_xlim[1]); 1.54 + float newy = clamp(head_pos.y + dy, head_ylim[0], head_ylim[1]); 1.55 + 1.56 + dx = newx - head_pos.x; 1.57 + dy = newy - head_pos.y; 1.58 + head_pos.x = newx; 1.59 + head_pos.y = newy; 1.60 + 1.61 + target.x += dx * 0.7; 1.62 + target.y += dy * 0.5; 1.63 +} 1.64 + 1.65 +const Vector3 &Dragon::head_position() const 1.66 +{ 1.67 + return head_pos; 1.68 +} 1.69 + 1.70 +Vector3 Dragon::breath_dir() const 1.71 +{ 1.72 + return (target - head_pos).normalized(); 1.73 +} 1.74 + 1.75 +void Dragon::update() 1.76 +{ 1.77 +} 1.78 + 1.79 +static Vector3 bezier(const Vector3 &a, const Vector3 &b, const Vector3 &c, const Vector3 &d, float t) 1.80 +{ 1.81 + float x = bezier(a.x, b.x, c.x, d.x, t); 1.82 + float y = bezier(a.y, b.y, c.y, d.y, t); 1.83 + float z = bezier(a.z, b.z, c.z, d.z, t); 1.84 + return Vector3(x, y, z); 1.85 +} 1.86 + 1.87 +void Dragon::draw() const 1.88 +{ 1.89 + Vector3 bdir = breath_dir(); 1.90 + Vector3 bezcp[] = { pos, pos + dir * 6.0, head_pos - bdir * 8.0, head_pos }; 1.91 + 1.92 + int cur_sdr; 1.93 + glGetIntegerv(GL_CURRENT_PROGRAM, &cur_sdr); 1.94 + glUseProgram(0); 1.95 + 1.96 + glPushAttrib(GL_ENABLE_BIT); 1.97 + glDisable(GL_LIGHTING); 1.98 + 1.99 + glLineWidth(2.0); 1.100 + glColor3f(0, 0, 1); 1.101 + 1.102 + glBegin(GL_LINE_STRIP); 1.103 + for(int i=0; i<10; i++) { 1.104 + float t = (float)i / 10.0f; 1.105 + Vector3 p = bezier(bezcp[0], bezcp[1], bezcp[2], bezcp[3], t); 1.106 + glVertex3f(p.x, p.y, p.z); 1.107 + } 1.108 + glEnd(); 1.109 + glLineWidth(1); 1.110 + 1.111 + glPointSize(5.0); 1.112 + glColor3f(0, 1, 0); 1.113 + 1.114 + glBegin(GL_POINTS); 1.115 + for(int i=0; i<4; i++) { 1.116 + glVertex3f(bezcp[i].x, bezcp[i].y, bezcp[i].z); 1.117 + } 1.118 + glEnd(); 1.119 + 1.120 + glPopAttrib(); 1.121 + 1.122 + glUseProgram(cur_sdr); 1.123 +}
2.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 2.2 +++ b/src/dragon.h Sun Aug 23 05:37:09 2015 +0300 2.3 @@ -0,0 +1,30 @@ 2.4 +#ifndef DRAGON_H_ 2.5 +#define DRAGON_H_ 2.6 + 2.7 +#include "vmath/vmath.h" 2.8 + 2.9 +class Dragon { 2.10 +private: 2.11 + Vector3 pos, dir; 2.12 + Vector3 head_pos, target; 2.13 + float head_xlim[2], head_ylim[2]; 2.14 + 2.15 +public: 2.16 + Dragon(); 2.17 + ~Dragon(); 2.18 + 2.19 + void set_position(const Vector3 &p); 2.20 + void set_direction(const Vector3 &dir); 2.21 + void set_target(const Vector3 &p); 2.22 + 2.23 + void set_head_limits(float xmin, float xmax, float ymin, float ymax); 2.24 + void move_head(const Vector3 &p); 2.25 + void move_head(float dx, float dy); 2.26 + const Vector3 &head_position() const; 2.27 + Vector3 breath_dir() const; 2.28 + 2.29 + void update(); 2.30 + void draw() const; 2.31 +}; 2.32 + 2.33 +#endif // DRAGON_H_
3.1 --- a/src/game.cc Sun Aug 23 04:45:24 2015 +0300 3.2 +++ b/src/game.cc Sun Aug 23 05:37:09 2015 +0300 3.3 @@ -9,6 +9,7 @@ 3.4 #include "mesh.h" 3.5 3.6 #include "room.h" 3.7 +#include "dragon.h" 3.8 3.9 static void draw_scene(); 3.10 3.11 @@ -19,13 +20,18 @@ 3.12 3.13 unsigned int sdr_shadow, sdr_shadow_notex; 3.14 3.15 -static float cam_theta, cam_phi = 25, cam_dist = 8; 3.16 +static float cam_theta, cam_phi = 23, cam_dist = 26; 3.17 +static float cam_x, cam_y, cam_z = 9; 3.18 static bool bnstate[8]; 3.19 static int prev_x, prev_y; 3.20 +static bool gamectl = false; 3.21 3.22 static unsigned int modkeys; 3.23 3.24 3.25 +static Dragon dragon; 3.26 + 3.27 + 3.28 bool game_init() 3.29 { 3.30 if(init_opengl() == -1) { 3.31 @@ -65,6 +71,12 @@ 3.32 return false; 3.33 } 3.34 3.35 + dragon.set_position(Vector3(0, 5, 20)); 3.36 + dragon.set_direction(Vector3(0, 0, -1)); 3.37 + dragon.set_target(Vector3(0, 3, 0)); 3.38 + dragon.move_head(Vector3(0, 6, 10)); 3.39 + dragon.set_head_limits(-ROOM_WIDTH * 0.2, ROOM_WIDTH * 0.2, 1, ROOM_HEIGHT - 3); 3.40 + 3.41 Mesh::use_custom_sdr_attr = false; 3.42 3.43 assert(glGetError() == GL_NO_ERROR); 3.44 @@ -79,6 +91,8 @@ 3.45 void game_update(unsigned long time_msec) 3.46 { 3.47 cur_time = time_msec; 3.48 + 3.49 + dragon.update(); 3.50 } 3.51 3.52 void game_display() 3.53 @@ -90,12 +104,13 @@ 3.54 glTranslatef(0, 0.1, -cam_dist); 3.55 glRotatef(cam_phi, 1, 0, 0); 3.56 glRotatef(cam_theta, 0, 1, 0); 3.57 + glTranslatef(-cam_x, -cam_y, -cam_z); 3.58 3.59 - float lpos[] = {-5, 15, 10, 1}; 3.60 + float lpos[] = {0, 10, 24, 1}; 3.61 glLightfv(GL_LIGHT0, GL_POSITION, lpos); 3.62 3.63 if(opt.shadows && sdr_shadow) { 3.64 - begin_shadow_pass(Vector3(lpos[0], lpos[1], lpos[2]), Vector3(0, 0, 0), 10); 3.65 + begin_shadow_pass(Vector3(lpos[0], lpos[1], lpos[2]), Vector3(0, 0, 0), 45); 3.66 draw_scene(); 3.67 end_shadow_pass(); 3.68 3.69 @@ -142,6 +157,8 @@ 3.70 draw_teapot(); 3.71 3.72 glPopMatrix(); 3.73 + 3.74 + dragon.draw(); 3.75 } 3.76 3.77 3.78 @@ -161,6 +178,10 @@ 3.79 case 27: 3.80 quit(); 3.81 3.82 + case ' ': 3.83 + gamectl = !gamectl; 3.84 + break; 3.85 + 3.86 case 'w': 3.87 dbg_wireframe = !dbg_wireframe; 3.88 redisplay(); 3.89 @@ -170,6 +191,11 @@ 3.90 opt.shadows = !opt.shadows; 3.91 redisplay(); 3.92 break; 3.93 + 3.94 + case 'p': 3.95 + printf("camera pos(%g %g %g) rot(%g %g) d(%g)\n", 3.96 + cam_x, cam_y, cam_z, cam_theta, cam_phi, cam_dist); 3.97 + break; 3.98 } 3.99 } 3.100 } 3.101 @@ -204,6 +230,10 @@ 3.102 prev_x = x; 3.103 prev_y = y; 3.104 3.105 + if(gamectl) { 3.106 + dragon.move_head(dx * 0.1, -dy * 0.1); 3.107 + } 3.108 + 3.109 if(modkeys) { 3.110 if(bnstate[0]) { 3.111 cam_theta += dx * 0.5; 3.112 @@ -212,6 +242,19 @@ 3.113 if(cam_phi < -90) cam_phi = -90; 3.114 if(cam_phi > 90) cam_phi = 90; 3.115 } 3.116 + if(bnstate[1]) { 3.117 + float theta = DEG_TO_RAD(cam_theta); 3.118 + 3.119 + float dxp = dx * 0.1; 3.120 + float dyp = dy * 0.1; 3.121 + 3.122 + cam_x += cos(theta) * dxp - sin(theta) * dyp; 3.123 + if(modkeys & (1 << MOD_SHIFT)) { 3.124 + cam_y -= sin(theta) * dxp + cos(theta) * dyp; 3.125 + } else { 3.126 + cam_z += sin(theta) * dxp + cos(theta) * dyp; 3.127 + } 3.128 + } 3.129 if(bnstate[2]) { 3.130 cam_dist += dy * 0.1; 3.131 if(cam_dist < 0.0) cam_dist = 0.0;
4.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 4.2 +++ b/src/revol.cc Sun Aug 23 05:37:09 2015 +0300 4.3 @@ -0,0 +1,44 @@ 4.4 +#include <algorithm> 4.5 +#include "revol.h" 4.6 + 4.7 +Vector2 bezier_revol(float u, float v, void *cls) 4.8 +{ 4.9 + BezCurve *curve = (BezCurve*)cls; 4.10 + int nseg = (curve->numcp - 1) / 2; 4.11 + 4.12 + if(v >= 1.0) v = 1.0 - 1e-6; 4.13 + int cidx = std::min((int)(v * nseg), nseg - 1); 4.14 + float t = fmod(v * (float)nseg, 1.0); 4.15 + 4.16 + const vec2_t *cp = curve->cp + cidx * 2; 4.17 + 4.18 + float resx = bezier(cp[0].x, cp[1].x, cp[1].x, cp[2].x, t); 4.19 + float resy = bezier(cp[0].y, cp[1].y, cp[1].y, cp[2].y, t); 4.20 + return Vector2(resx * curve->scale, resy * curve->scale); 4.21 +} 4.22 + 4.23 +Vector2 bezier_revol_normal(float u, float v, void *cls) 4.24 +{ 4.25 + BezCurve *curve = (BezCurve*)cls; 4.26 + int nseg = (curve->numcp - 1) / 2; 4.27 + 4.28 + if(v >= 1.0) v = 1.0 - 1e-6; 4.29 + int cidx = std::min((int)(v * nseg), nseg - 1); 4.30 + float t = fmod(v * (float)nseg, 1.0); 4.31 + 4.32 + const vec2_t *cp = curve->cp + cidx * 2; 4.33 + Vector2 cp0 = cp[0]; 4.34 + Vector2 cp1 = cp[1]; 4.35 + Vector2 cp2 = cp[2]; 4.36 + 4.37 + Vector2 pprev, pnext; 4.38 + for(int i=0; i<2; i++) { 4.39 + pprev[i] = bezier(cp0[i], cp1[i], cp1[i], cp2[i], t - 0.05); 4.40 + pnext[i] = bezier(cp0[i], cp1[i], cp1[i], cp2[i], t + 0.05); 4.41 + } 4.42 + 4.43 + float tx = pnext.x - pprev.x; 4.44 + float ty = pnext.y - pprev.y; 4.45 + 4.46 + return Vector2(-ty, tx); 4.47 +}
5.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 5.2 +++ b/src/revol.h Sun Aug 23 05:37:09 2015 +0300 5.3 @@ -0,0 +1,15 @@ 5.4 +#ifndef REVOL_H_ 5.5 +#define REVOL_H_ 5.6 + 5.7 +#include "vmath/vmath.h" 5.8 + 5.9 +struct BezCurve { 5.10 + int numcp; 5.11 + vec2_t *cp; 5.12 + float scale; 5.13 +}; 5.14 + 5.15 +Vector2 bezier_revol(float u, float v, void *cls); 5.16 +Vector2 bezier_revol_normal(float u, float v, void *cls); 5.17 + 5.18 +#endif // REVOL_H_
6.1 --- a/src/room.cc Sun Aug 23 04:45:24 2015 +0300 6.2 +++ b/src/room.cc Sun Aug 23 05:37:09 2015 +0300 6.3 @@ -5,25 +5,60 @@ 6.4 #include "object.h" 6.5 #include "scene.h" 6.6 #include "meshgen.h" 6.7 +#include "revol.h" 6.8 6.9 static Scene scn; 6.10 6.11 +static const vec2_t pillar_cp[] = { 6.12 + {0.8, 10}, 6.13 + {1.2, 5.5}, 6.14 + {1, 0} 6.15 +}; 6.16 +static const BezCurve pillar_curve = { 6.17 + sizeof pillar_cp / sizeof *pillar_cp, 6.18 + (vec2_t*)pillar_cp, 1.0 6.19 +}; 6.20 + 6.21 bool init_room() 6.22 { 6.23 Matrix4x4 xform; 6.24 6.25 // generate room 6.26 Mesh *mroom = new Mesh; 6.27 - gen_box(mroom, 50, 25, 50); 6.28 - xform.set_translation(Vector3(0, 12.5, 0)); 6.29 + gen_box(mroom, ROOM_WIDTH, ROOM_HEIGHT, ROOM_LENGTH); 6.30 + xform.set_translation(Vector3(0, ROOM_HEIGHT / 2.0, 0)); 6.31 mroom->apply_xform(xform); 6.32 mroom->flip(); 6.33 6.34 Object *oroom = new Object; 6.35 oroom->set_mesh(mroom); 6.36 + oroom->mtl.diffuse = Vector3(0.5, 0.5, 0.5); 6.37 oroom->rop.cast_shadows = false; 6.38 + scn.add_object(oroom); 6.39 6.40 - scn.add_object(oroom); 6.41 + for(int i=0; i<8; i++) { 6.42 + float x = (i < 4 ? -1.0 : 1.0) * ROOM_WIDTH * 0.3; 6.43 + float z = (float)(i % 4) * 12.5 - 12.5; 6.44 + 6.45 + Mesh *mpillar = new Mesh; 6.46 + gen_revol(mpillar, 16, 3, bezier_revol, bezier_revol_normal, (void*)&pillar_curve); 6.47 + 6.48 + Mesh mtorus; 6.49 + gen_torus(&mtorus, 1.0, 0.25, 16, 8); 6.50 + Matrix4x4 xform; 6.51 + xform.set_translation(Vector3(0, 0.1, 0)); 6.52 + mtorus.apply_xform(xform, Matrix4x4::identity); 6.53 + mpillar->append(mtorus); 6.54 + 6.55 + mpillar->texcoord_gen_cylinder(); 6.56 + 6.57 + Object *opillar = new Object; 6.58 + opillar->set_mesh(mpillar); 6.59 + opillar->mtl.diffuse = Vector3(0.6, 0.6, 0.6); 6.60 + opillar->xform().set_translation(Vector3(x, 0.0, z)); 6.61 + 6.62 + scn.add_object(opillar); 6.63 + } 6.64 return true; 6.65 } 6.66
7.1 --- a/src/room.h Sun Aug 23 04:45:24 2015 +0300 7.2 +++ b/src/room.h Sun Aug 23 05:37:09 2015 +0300 7.3 @@ -1,6 +1,12 @@ 7.4 #ifndef ROOM_H_ 7.5 #define ROOM_H_ 7.6 7.7 + 7.8 +#define ROOM_WIDTH 30.0f 7.9 +#define ROOM_HEIGHT 10.0f 7.10 +#define ROOM_LENGTH 50.0f 7.11 + 7.12 + 7.13 bool init_room(); 7.14 void cleanup_room(); 7.15 void draw_room();
8.1 --- a/src/shadow.cc Sun Aug 23 04:45:24 2015 +0300 8.2 +++ b/src/shadow.cc Sun Aug 23 05:37:09 2015 +0300 8.3 @@ -90,7 +90,7 @@ 8.4 8.5 glBindFramebuffer(GL_FRAMEBUFFER, fbo); 8.6 8.7 - glPolygonOffset(1.1, 4.0); 8.8 + glPolygonOffset(2.0, 4.0); 8.9 glEnable(GL_POLYGON_OFFSET_FILL); 8.10 8.11 glClear(GL_DEPTH_BUFFER_BIT);