aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--data/models/floor1
-rw-r--r--data/models/tiledfloor2
-rw-r--r--data/models/walle2
-rw-r--r--data/models/walln2
-rw-r--r--data/models/walls2
-rw-r--r--data/models/wallw2
-rw-r--r--src/game.c2
-rw-r--r--src/main.c4
-rw-r--r--src/model.c10
-rw-r--r--src/physics.c129
-rw-r--r--src/render.c63
-rw-r--r--src/render.h1
12 files changed, 195 insertions, 25 deletions
diff --git a/data/models/floor b/data/models/floor
index 0eb18b1..f55c79f 100644
--- a/data/models/floor
+++ b/data/models/floor
@@ -6,4 +6,5 @@ texture floor1
5.0 -5.0 0.0 1.0 0.0
5.0 5.0 0.0 1.0 1.0
-5.0 5.0 0.0 0.0 1.0
+subdivide 40 40
diff --git a/data/models/tiledfloor b/data/models/tiledfloor
index 573e38e..3a26877 100644
--- a/data/models/tiledfloor
+++ b/data/models/tiledfloor
@@ -6,5 +6,5 @@ texture tiledwall
5.0 -5.0 0.0 1.0 0.0
5.0 5.0 0.0 1.0 1.0
-5.0 5.0 0.0 0.0 1.0
-subdivide 20 20
+subdivide 40 40
diff --git a/data/models/walle b/data/models/walle
index b3c361e..04867e0 100644
--- a/data/models/walle
+++ b/data/models/walle
@@ -6,5 +6,5 @@ texture tiledwall
0.00 5.00 5.00 0.0 1.0
0.00 5.00 -5.00 0.0 0.0
0.00 -5.00 -5.00 1.0 0.0
-subdivide 20 20
+subdivide 40 40
diff --git a/data/models/walln b/data/models/walln
index 9882976..327cd4c 100644
--- a/data/models/walln
+++ b/data/models/walln
@@ -6,5 +6,5 @@ texture tiledwall
5.00 0.00 -5.00 1.0 0.0
5.00 0.00 5.00 1.0 1.0
-5.00 0.00 5.00 0.0 1.0
-subdivide 50 50
+subdivide 40 40
diff --git a/data/models/walls b/data/models/walls
index 81396fb..bffe21a 100644
--- a/data/models/walls
+++ b/data/models/walls
@@ -6,5 +6,5 @@ texture tiledwall
-5.00 0.00 5.00 1.0 1.0
5.00 0.00 5.00 0.0 1.0
5.00 0.00 -5.00 0.0 0.0
-subdivide 20 20
+subdivide 40 40
diff --git a/data/models/wallw b/data/models/wallw
index b5f3017..e017593 100644
--- a/data/models/wallw
+++ b/data/models/wallw
@@ -6,5 +6,5 @@ texture tiledwall
0.00 5.00 -5.00 1.0 0.0
0.00 5.00 5.00 1.0 1.0
0.00 -5.00 5.00 0.0 1.0
-subdivide 20 20
+subdivide 40 40
diff --git a/src/game.c b/src/game.c
index 57749a3..c7c2c68 100644
--- a/src/game.c
+++ b/src/game.c
@@ -279,7 +279,7 @@ Game *game_new(int width, int height) {
g->lander = model_instance_new(g->models, "lander", g->render);
g->lander->x = 0.0;
g->lander->y = 0.0;
- g->lander->z = -4.95;
+ g->lander->z = -0.90;
g->lander->yaw = deg2rad(30.0);
g->lander->attribs = OBJ_GRAVITY;
diff --git a/src/main.c b/src/main.c
index 0b65c09..f0016d1 100644
--- a/src/main.c
+++ b/src/main.c
@@ -81,7 +81,7 @@ int main(int argc, char *argv[]) {
}
case 'h' : {
- printf("Syntax: %s [-h] [-r <res>] [-f]\n\n", argv[0]);
+ printf("Syntax: %s [-hvf] [-r <res>]\n\n", argv[0]);
printf("Post-apocalyptic Jet Set Willy, set in a 3D nuclear power station.\n\n");
printf(" -h Display this help message and exit.\n");
printf(" -v Display version number and exit.\n");
@@ -159,6 +159,8 @@ int main(int argc, char *argv[]) {
if ( event.key.keysym.sym == SDLK_RIGHT ) game->turn_right = 1;
if ( event.key.keysym.sym == SDLK_UP ) game->forward = 1;
if ( event.key.keysym.sym == SDLK_DOWN ) game->reverse = 1;
+ if ( event.key.keysym.sym == SDLK_w ) render_set_wireframe(1);
+ if ( event.key.keysym.sym == SDLK_e ) render_set_wireframe(0);
}
if ( event.key.keysym.sym == SDLK_p ) game_pause(game);
if ( event.key.keysym.sym == SDLK_q ) finished = 1;
diff --git a/src/model.c b/src/model.c
index bd5ea5f..291bd04 100644
--- a/src/model.c
+++ b/src/model.c
@@ -26,7 +26,7 @@
#include "render.h"
/* Maximum number of vertices per primitive */
-#define MAX_VERTICES 8192*5
+#define MAX_VERTICES 100000
ModelContext *model_init() {
@@ -348,8 +348,8 @@ static int model_load(ModelContext *ctx, const char *name, RenderContext *render
vertices[3*num_vertices+0] = l3x + (v+1)*(l4x-l3x)/y;
vertices[3*num_vertices+1] = l3y + (v+1)*(l4y-l3y)/y;
vertices[3*num_vertices+2] = l3z + (v+1)*(l4z-l3z)/y;
- texcoords[2*num_vertices+0] = tl3x + v*(tl4x-tl3x)/y;
- texcoords[2*num_vertices+1] = tl3y + v*(tl4y-tl3y)/y;
+ texcoords[2*num_vertices+0] = tl3x + (v+1)*(tl4x-tl3x)/y;
+ texcoords[2*num_vertices+1] = tl3y + (v+1)*(tl4y-tl3y)/y;
normals[3*num_vertices+0] = nx;
normals[3*num_vertices+1] = ny;
normals[3*num_vertices+2] = nz;
@@ -357,8 +357,8 @@ static int model_load(ModelContext *ctx, const char *name, RenderContext *render
vertices[3*num_vertices+0] = l1x + (v+1)*(l2x-l1x)/y;
vertices[3*num_vertices+1] = l1y + (v+1)*(l2y-l1y)/y;
vertices[3*num_vertices+2] = l1z + (v+1)*(l2z-l1z)/y;
- texcoords[2*num_vertices+0] = tl1x + v*(tl2x-tl1x)/y;
- texcoords[2*num_vertices+1] = tl1y + v*(tl2y-tl1y)/y;
+ texcoords[2*num_vertices+0] = tl1x + (v+1)*(tl2x-tl1x)/y;
+ texcoords[2*num_vertices+1] = tl1y + (v+1)*(tl2y-tl1y)/y;
normals[3*num_vertices+0] = nx;
normals[3*num_vertices+1] = ny;
normals[3*num_vertices+2] = nz;
diff --git a/src/physics.c b/src/physics.c
index 0bcbae7..0c33e63 100644
--- a/src/physics.c
+++ b/src/physics.c
@@ -39,8 +39,130 @@
/* Conversion factor between friction and 'yawthrust' */
#define TORQUE 3
+static int physics_will_collide_face(GLfloat sx, GLfloat sy, GLfloat sz, GLfloat vx, GLfloat vy, GLfloat vz,
+ GLfloat nx, GLfloat ny, GLfloat nz, GLfloat *fvert, int nfvert, Uint32 dt) {
+
+ GLfloat px, py, pz;
+ GLfloat t1, t2, b;
+ int t;
+
+ /* Range test */
+ px = fvert[3*0 + 0];
+ py = fvert[3*0 + 1];
+ pz = fvert[3*0 + 2];
+
+ t1 = px*nx + py*ny + pz*nz;
+ t2 = sx*nx + sy*ny + sz*nz;
+ b = vx*nx + vy*ny + vz*nz;
+ if ( b == 0 ) return 0; /* Collision happens infinitely far in the future */
+ t = (t1 - t2) / b;
+
+// printf("Testing vertex %8f %8f %8f, velocity %8f %8f %8f against face %8f %8f %8f\n",
+// sx, sy, sz, vx, vy, vz, px, py, pz);
+// printf("Collision happens at t + %i\n", t);
+// exit(0);
+
+ /* If the vertex is exactly on the plane, then moving away from the plane is OK */
+ if ( (t == 0) && (b > 0) ) return 0;
+
+ if ( t < 0 ) return 0; /* Collided in the past */
+ if ( t > dt ) return 0; /* Not going to collide this step */
+
+ /* Boundary test */
+
+
+ return 1;
+
+}
+
+/* Return non-zero if 'obj' will collide with 'other' with 'dt' milliseconds */
+static int physics_will_collide(ModelInstance *obj, ModelInstance *other, Uint32 dt) {
+
+ int i;
+
+ const GLfloat vx = obj->vx;
+ const GLfloat vy = obj->vy;
+ const GLfloat vz = obj->vz;
+
+ /* Consider all the primitives in 'obj' */
+ for ( i=0; i<obj->model->num_primitives; i++ ) {
+
+ int j;
+
+ /* Consider all the vertices in this primitive */
+ for ( j=0; j<obj->model->primitives[i]->num_vertices; j++ ) {
+
+ int a;
+ const GLfloat sx = obj->x + obj->model->primitives[i]->vertices[3*j+0];
+ const GLfloat sy = obj->y + obj->model->primitives[i]->vertices[3*j+1];
+ const GLfloat sz = obj->z + obj->model->primitives[i]->vertices[3*j+2];
+
+ /* Consider all the primitives in 'other' */
+ for ( a=0; a<other->model->num_primitives; a++ ) {
+
+ const GLfloat nx = other->model->primitives[a]->normals[0];
+ const GLfloat ny = other->model->primitives[a]->normals[1];
+ const GLfloat nz = other->model->primitives[a]->normals[2];
+
+ switch ( other->model->primitives[a]->type ) {
+
+ case PRIMITIVE_QUADS : {
+
+ int f;
+
+ /* Faces are quads */
+ for ( f=0; f<other->model->primitives[a]->num_vertices/4; f++ ) {
+
+ GLfloat face[3*4];
+ int q;
+
+ for ( q=0; q<4; q++ ) {
+ face[3*q + 0] = other->x + other->model->primitives[a]->vertices[4*(f+q) + 0];
+ face[3*q + 1] = other->y + other->model->primitives[a]->vertices[4*(f+q) + 1];
+ face[3*q + 2] = other->z + other->model->primitives[a]->vertices[4*(f+q) + 2];
+ }
+
+ if ( physics_will_collide_face(sx, sy, sz, vx, vy, vz, nx, ny, nz,
+ face, 4, dt) != 0 ) {
+ return 1; /* Don't waste time looking anywhere else */
+ }
+ }
+ break;
+ }
+
+ }
+
+ }
+
+ }
+ }
+
+ return 0;
+
+}
+
/* Called once for each object which isn't just "scenery" */
-static void physics_process(ModelInstance *obj, Uint32 dt) {
+static void physics_process(ModelInstance *obj, Uint32 dt, Room **rooms, int num_rooms) {
+
+ int i;
+
+ #if 0
+ /* Consider all the currently relevant rooms */
+ for ( i=0; i<num_rooms; i++ ) {
+ int j;
+ /* Consider all the objects in this room */
+ for ( j=0; j<rooms[i]->num_objects; j++ ) {
+ if ( physics_will_collide(obj, rooms[i]->objects[j], dt) ) {
+ /* Stop the object in its tracks and return */
+ obj->vx = 0.0;
+ obj->vy = 0.0;
+ obj->vz = 0.0;
+ obj->yawspeed = 0.0;
+ return;
+ }
+ }
+ }
+ #endif
/* Air friction */
if ( obj->vx > 0.0 ) {
@@ -115,7 +237,10 @@ void physics_step(Game *game, Uint32 t) {
if ( game->turn_right ) {
game->lander->yawspeed += YAWTHRUST *dt; /* +ve yaw is "right" */
}
- physics_process(game->lander, dt);
+
+ /* The number of rooms to consider for physics purposes can probably be further reduced */
+ physics_process(game->lander, dt, game->rooms, game->num_rooms);
+
game_check_handoff(game);
game->tlast = t;
diff --git a/src/render.c b/src/render.c
index 4f2ba97..328301b 100644
--- a/src/render.c
+++ b/src/render.c
@@ -219,7 +219,7 @@ static int render_model_instance_draw(ModelInstance *instance, Uint32 t, RenderC
if ( p->attribs & ATTRIB_PULSE ) {
float s;
- s = fabsf(cosf(t * 0.001));
+ s = fabsf(0.4*cosf(t * 0.001));
GLfloat c[] = {s*p->col_r, s*p->col_g, s*p->col_b};
glMaterialfv(GL_FRONT, GL_EMISSION, c);
glColor3f(0.3, 0.3, 0.3);
@@ -296,9 +296,9 @@ static int render_model_instance_draw(ModelInstance *instance, Uint32 t, RenderC
static void render_draw_line(GLfloat x1, GLfloat y1, GLfloat z1, GLfloat x2, GLfloat y2, GLfloat z2) {
- GLfloat red[] = {1.0, 0.0, 0.0, 1.0};
+ GLfloat col[] = {0.0, 0.3, 0.0, 1.0};
- glMaterialfv(GL_FRONT, GL_EMISSION, red);
+ glMaterialfv(GL_FRONT, GL_EMISSION, col);
glColor3f(0.0, 0.0, 0.0);
glBegin(GL_LINES);
@@ -347,24 +347,67 @@ static void render_draw_stuff(Game *game, Uint32 t) {
static void render_setup_lighting(Game *game) {
- GLfloat pos[] = {0.0, 0.0, 0.0, 1.0};
- GLfloat dir[] = {0.0, 1.0, 0.0};
+ GLfloat pos[4];
+ GLfloat dir[3];
GLfloat ambient[4];
- GLfloat diffuse[] = {1.0, 1.0, 1.0, 1.0};
- GLfloat specular[] = {1.0, 1.0, 1.0, 1.0};
+ GLfloat diffuse[4];
+ GLfloat specular[4];
glEnable(GL_LIGHTING);
- ambient[0] = 0.3; ambient[1] = 0.3; ambient[2] = 0.3; ambient[3] = 1.0;
+ ambient[0] = 0.01; ambient[1] = 0.01; ambient[2] = 0.01; ambient[3] = 1.0;
glLightModelfv(GL_LIGHT_MODEL_AMBIENT, ambient);
+ pos[0] = game->lander->x;
+ pos[1] = game->lander->y;
+ pos[2] = game->lander->z+0.3;
+ pos[3] = 1.0;
+ dir[0] = sinf(game->lander->yaw);
+ dir[1] = cosf(game->lander->yaw);
+ dir[2] = 0.0;
+ diffuse[0] = 1.0;
+ diffuse[1] = 1.0;
+ diffuse[2] = 1.0;
+ diffuse[3] = 1.0;
+ specular[0] = 1.0;
+ specular[1] = 1.0;
+ specular[2] = 1.0;
+ specular[3] = 1.0;
glLightfv(GL_LIGHT0, GL_POSITION, pos);
glLightfv(GL_LIGHT0, GL_DIFFUSE, diffuse);
glLightfv(GL_LIGHT0, GL_SPECULAR, specular);
glLightfv(GL_LIGHT0, GL_SPOT_DIRECTION, dir);
- glLightf(GL_LIGHT0, GL_SPOT_CUTOFF, 30.0);
+ glLightf(GL_LIGHT0, GL_SPOT_CUTOFF, 45.0);
+ glLightf(GL_LIGHT0, GL_SPOT_EXPONENT, 20.0);
glEnable(GL_LIGHT0);
+ pos[0] = -1.0;
+ pos[1] = 0.8;
+ pos[2] = 4.0;
+ pos[3] = 0.0;
+ diffuse[0] = 0.1;
+ diffuse[1] = 0.1;
+ diffuse[2] = 0.1;
+ diffuse[3] = 1.0;
+ specular[0] = 0.01;
+ specular[1] = 0.01;
+ specular[2] = 0.01;
+ specular[3] = 1.0;
+ glLightfv(GL_LIGHT1, GL_POSITION, pos);
+ glLightfv(GL_LIGHT1, GL_DIFFUSE, diffuse);
+ glLightfv(GL_LIGHT1, GL_SPECULAR, specular);
+ glEnable(GL_LIGHT1);
+
+}
+
+void render_set_wireframe(int wireframe) {
+
+ if ( wireframe != 0 ) {
+ glPolygonMode(GL_FRONT, GL_LINE);
+ } else {
+ glPolygonMode(GL_FRONT, GL_FILL);
+ }
+
}
static void render_draw_2d(RenderContext *r, Game *game) {
@@ -453,8 +496,6 @@ void render_draw(Game *game, Uint32 t) {
r = game->render;
- //glPolygonMode(GL_FRONT, GL_LINE);
-
/* First pass: Looking upwards */
glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, r->fbo);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
diff --git a/src/render.h b/src/render.h
index 2093fe4..b480da2 100644
--- a/src/render.h
+++ b/src/render.h
@@ -21,6 +21,7 @@
extern RenderContext *render_setup(int width, int height);
extern void render_shutdown(RenderContext *ctx);
extern void render_draw(Game *game, Uint32 t);
+extern void render_set_wireframe(int wireframe);
#endif /* RENDER_H */