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);