diff options
-rw-r--r-- | data/models/floor | 1 | ||||
-rw-r--r-- | data/models/tiledfloor | 2 | ||||
-rw-r--r-- | data/models/walle | 2 | ||||
-rw-r--r-- | data/models/walln | 2 | ||||
-rw-r--r-- | data/models/walls | 2 | ||||
-rw-r--r-- | data/models/wallw | 2 | ||||
-rw-r--r-- | src/game.c | 2 | ||||
-rw-r--r-- | src/main.c | 4 | ||||
-rw-r--r-- | src/model.c | 10 | ||||
-rw-r--r-- | src/physics.c | 129 | ||||
-rw-r--r-- | src/render.c | 63 | ||||
-rw-r--r-- | src/render.h | 1 |
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 @@ -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; @@ -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 */ |