aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authortaw27 <taw27@84d2e878-0bd5-11dd-ad15-13eda11d74c5>2008-05-16 16:54:55 +0000
committertaw27 <taw27@84d2e878-0bd5-11dd-ad15-13eda11d74c5>2008-05-16 16:54:55 +0000
commit0f5e2c1f67d6f9b7d6ee3dd55b8c7cd903881bd6 (patch)
tree4615062f7f0a4268d04c00196aa64381ae0f3e50 /src
parent096e588e4f2e93e51a2791258f3e6c4a7f7a78ae (diff)
Reshuffle lots of things
Basic environment mapping stuff Remove OBJ file stuff git-svn-id: svn://cook.msm.cam.ac.uk:745/thrust3d/thrust3d@19 84d2e878-0bd5-11dd-ad15-13eda11d74c5
Diffstat (limited to 'src')
-rw-r--r--src/game.c5
-rw-r--r--src/main.c31
-rw-r--r--src/model.c168
-rw-r--r--src/physics.c5
-rw-r--r--src/physics.h2
-rw-r--r--src/render.c170
-rw-r--r--src/render.h2
-rw-r--r--src/types.h15
8 files changed, 160 insertions, 238 deletions
diff --git a/src/game.c b/src/game.c
index 1e1da2d..a70b17b 100644
--- a/src/game.c
+++ b/src/game.c
@@ -241,7 +241,10 @@ Game *game_new(int width, int height) {
g->pause_rel = 1;
g->frame_delay = 8000;
g->frame_delay_fiddled = 0;
-
+ g->frames = 0;
+ g->t_fps = SDL_GetTicks();
+ g->fps = 0;
+
/* Renderer setup */
g->render = render_setup(width, height);
if ( g->render == NULL ) {
diff --git a/src/main.c b/src/main.c
index af5e97b..b3a84e5 100644
--- a/src/main.c
+++ b/src/main.c
@@ -45,6 +45,7 @@ int main(int argc, char *argv[]) {
int c;
Uint32 video_flags;
ScreenResolution res;
+ Uint32 t;
res = RES_VGA;
video_flags = SDL_OPENGL;
@@ -113,7 +114,14 @@ int main(int argc, char *argv[]) {
/* Main loop */
finished = 0;
+ t = SDL_GetTicks();
while ( !finished ) {
+
+ /* Timer advances only when game is not paused */
+ if ( !game->paused ) {
+ t = SDL_GetTicks();
+ }
+
SDL_PollEvent(&event);
switch ( event.type ) {
case SDL_KEYDOWN :
@@ -139,29 +147,38 @@ int main(int argc, char *argv[]) {
break;
case SDL_VIDEOEXPOSE :
/* Don't bother redrawing if not paused - not long to wait! */
- if ( game->paused ) render_draw(game);
+ if ( game->paused ) render_draw(game, t);
break;
case SDL_QUIT :
finished = 1;
break;
}
if ( !game->paused ) {
- physics_step(game);
- render_draw(game);
+ physics_step(game, t);
+ render_draw(game, t);
}
- printf("%+7.4f %+7.4f %+7.4f %+5.1f deg %+7.5f %+7.5f %+7.5f %2i %2i %2i %3i %3i fps\r",
+ printf("%+7.4f %+7.4f %+7.4f %+5.1f deg %+7.5f %+7.5f %+7.5f %2i %2i %2i %3i fps\r",
game->lander->x, game->lander->y, game->lander->z,
rad2deg(game->lander->yaw), game->lander->vx, game->lander->vy, game->lander->vz,
- game->cur_room_x, game->cur_room_y, game->cur_room_z, game->num_rooms, game->render->fps);
+ game->cur_room_x, game->cur_room_y, game->cur_room_z, game->fps);
fflush(stdout);
+ /* Calculate FPS every half a second */
+ game->frames++;
+ if ( t - game->t_fps > 500 ) {
+ game->fps = (500*game->frames) / (t - game->t_fps);
+ game->t_fps = t;
+ game->frames = 0;
+ game->frame_delay_fiddled = 0;
+ }
+
/* Attempt to hold output FPS close to some target value */
- if ( (!game->frame_delay_fiddled) && (game->render->fps < 30) ) {
+ if ( (!game->frame_delay_fiddled) && (game->fps < 30) ) {
game->frame_delay -= game->frame_delay/20;
game->frame_delay_fiddled = 1;
}
- if ( (!game->frame_delay_fiddled) && (game->render->fps > 50) ) {
+ if ( (!game->frame_delay_fiddled) && (game->fps > 50) ) {
game->frame_delay += game->frame_delay/20;
game->frame_delay_fiddled = 1;
}
diff --git a/src/model.c b/src/model.c
index b0275fe..2f768f5 100644
--- a/src/model.c
+++ b/src/model.c
@@ -149,165 +149,6 @@ static void model_calculate_normals(GLfloat *vertices, GLfloat *normals, int fir
}
-static int model_load_obj(ModelContext *ctx, const char *name, RenderContext *render) {
-
- FILE *fh;
- char tmp[64];
- Model *model;
- int num_vertices;
- GLfloat *vertices;
- GLfloat *normals;
- GLfloat *texcoords;
- GLfloat vtmp[3*MAX_VERTICES];
- GLfloat vntmp[3*MAX_VERTICES];
- int n_vtmp, n_vntmp;
- char *texture;
-
- snprintf(tmp, 63, "%s/models/%s.obj", DATADIR, name);
- fh = fopen(tmp, "r");
- if ( fh == NULL ) {
- return -1;
- }
-
- /* Zip through and find all the vertices */
- n_vtmp = 0;
- n_vntmp = 0;
- while ( !feof(fh) ) {
-
- char line[1024];
- GLfloat x, y, z;
- GLfloat texx, texy;
- size_t s;
-
- texx = 0.0; texy = 0.0; /* Default texture coordinates */
-
- fgets(line, 1023, fh);
- s = 0;
- for ( ; s<strlen(line); s++ ) {
- if ( line[s] != ' ' ) break;
- }
-
- if ( line[s] == '#' ) {
- continue;
- }
-
- if ( sscanf(line+s, "v %f %f %f\n", &x, &y, &z) == 3 ) {
- vtmp[3*n_vtmp+0] = x;
- vtmp[3*n_vtmp+1] = y;
- vtmp[3*n_vtmp+2] = z;
- n_vtmp++;
- continue;
- }
-
- if ( sscanf(line+s, "vn %f %f %f\n", &x, &y, &z) == 3 ) {
- vntmp[3*n_vntmp+0] = x;
- vntmp[3*n_vntmp+1] = y;
- vntmp[3*n_vntmp+2] = z;
- n_vntmp++;
- continue;
- }
-
- }
-
- /* Go through again and look for faces */
- model = model_new(name);
- vertices = malloc(MAX_VERTICES*3*sizeof(GLfloat));
- normals = malloc(MAX_VERTICES*3*sizeof(GLfloat));
- texcoords = malloc(MAX_VERTICES*2*sizeof(GLfloat));
- texture = NULL;
- num_vertices = 0;
- rewind(fh);
- while ( !feof(fh) ) {
-
- char line[1024];
- char **bits;
- int n, i;
-
- fgets(line, 1023, fh);
- n = assplode(line, " \t\r\n", &bits, ASSPLODE_NONE);
-
- /* Read in a face */
- if ( strcmp(bits[0], "f") == 0 ) {
-
- for ( i=1; i<n; i++ ) {
-
- char **sp;
- int np, vnum, nnum, j, nslash;
-
- nslash = 0;
- for ( j=0; j<strlen(bits[i]); j++ ) {
- if ( bits[i][j] == '/' ) nslash++;
- }
- if ( nslash == 2 ) {
-
- np = assplode(bits[i], "/", &sp, ASSPLODE_DUPS);
- if ( np != 3 ) {
- continue;
- }
- vnum = atoi(sp[0])-1;
- nnum = atoi(sp[2])-1;
- if ( vnum >= n_vtmp ) {
- fprintf(stderr, "Vertex index is too high (%i/%i)\n", vnum, n_vtmp);
- continue;
- }
- if ( nnum >= n_vntmp ) {
- fprintf(stderr, "Normal index is too high (%i/%i)\n", nnum, n_vntmp);
- continue;
- }
- if ( num_vertices < MAX_VERTICES ) {
- vertices[3*num_vertices+0] = vtmp[3*vnum+0];
- vertices[3*num_vertices+1] = vtmp[3*vnum+1];
- vertices[3*num_vertices+2] = vtmp[3*vnum+2];
- normals[3*num_vertices+0] = vntmp[3*nnum+0];
- normals[3*num_vertices+1] = vntmp[3*nnum+1];
- normals[3*num_vertices+2] = vntmp[3*nnum+2];
- texcoords[2*num_vertices+0] = 0.0;
- texcoords[2*num_vertices+1] = 0.0;
- num_vertices++;
- } else {
- fprintf(stderr, "Too many vertices\n");
- }
- free(sp[0]);
- free(sp[1]);
- free(sp[2]);
- free(sp);
-
- } else if ( nslash == 0 ) {
-
- vnum = atoi(bits[i]);
- if ( num_vertices < MAX_VERTICES ) {
- vertices[3*num_vertices+0] = vtmp[3*vnum+0];
- vertices[3*num_vertices+1] = vtmp[3*vnum+1];
- vertices[3*num_vertices+2] = vtmp[3*vnum+2];
- normals[3*num_vertices+0] = 1.0;
- normals[3*num_vertices+1] = 0.0;
- normals[3*num_vertices+2] = 0.0;
- num_vertices++;
- } else {
- fprintf(stderr, "Too many vertices\n");
- }
-
- }
-
- }
-
- model_add_primitive(model, GL_POLYGON, vertices, normals, texcoords, num_vertices,
- ATTRIB_NONE, 1.0, 1.0, 1.0, texture);
- num_vertices = 0;
-
- }
-
- for ( i=0; i<n; i++ ) free(bits[i]);
- free(bits);
-
- }
-
- fclose(fh);
-
- return model_add(ctx, model);
-
-}
-
static int model_load(ModelContext *ctx, const char *name, RenderContext *render) {
FILE *fh;
@@ -458,15 +299,6 @@ ModelInstance *model_instance_new(ModelContext *ctx, const char *name, RenderCon
/* Couldn't find model, so try to load it */
model_load(ctx, name, render);
instance->model = model_lookup(ctx, name);
- if ( instance->model == NULL ) {
- model_load_obj(ctx, name, render);
- instance->model = model_lookup(ctx, name);
- if ( instance->model == NULL ) {
- free(instance);
- printf("Couldn't find model %s\n", name);
- return NULL;
- }
- }
}
instance->vx = 0.0;
diff --git a/src/physics.c b/src/physics.c
index 3d860df..9fa77da 100644
--- a/src/physics.c
+++ b/src/physics.c
@@ -88,12 +88,11 @@ static void physics_process(ModelInstance *obj, Uint32 dt) {
}
-void physics_step(Game *game) {
+void physics_step(Game *game, Uint32 t) {
int i, j;
- Uint32 dt, t;
+ Uint32 dt;
- t = SDL_GetTicks();
dt = t - game->tlast;
/* Handle things specific to the lander craft */
diff --git a/src/physics.h b/src/physics.h
index c1ead94..b6db660 100644
--- a/src/physics.h
+++ b/src/physics.h
@@ -18,7 +18,7 @@
#include "types.h"
-extern void physics_step(Game *game);
+extern void physics_step(Game *game, Uint32 t);
#endif /* PHYSICS_H */
diff --git a/src/render.c b/src/render.c
index 23fde64..b765e63 100644
--- a/src/render.c
+++ b/src/render.c
@@ -79,19 +79,17 @@ static void render_delete_shaders(RenderContext *ctx) {
}
/* OpenGL initial setup */
-RenderContext *render_setup(width, height) {
+RenderContext *render_setup(int width, int height) {
RenderContext *ctx;
ctx = malloc(sizeof(RenderContext));
if ( ctx == NULL ) return NULL;
- glClearColor(0.0, 0.0, 0.0, 1.0);
- glViewport(0, 0, width, height);
+ ctx->width = width;
+ ctx->height = height;
- glMatrixMode(GL_PROJECTION);
- glLoadIdentity();
- gluPerspective(50.0, (GLfloat)width/(GLfloat)height, 0.1, 100.0); /* Depth buffer 10cm to 100m */
+ glClearColor(0.0, 0.0, 0.0, 1.0);
glEnable(GL_COLOR_MATERIAL);
glColorMaterial(GL_FRONT, GL_AMBIENT_AND_DIFFUSE);
@@ -104,18 +102,28 @@ RenderContext *render_setup(width, height) {
glEnable(GL_BLEND);
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
- glEnableClientState(GL_VERTEX_ARRAY);
- glEnableClientState(GL_NORMAL_ARRAY);
- glEnableClientState(GL_TEXTURE_COORD_ARRAY);
+ /* Create a small FBO for rendering reflections with */
+ glGenFramebuffersEXT(1, &ctx->fbo);
+ glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, ctx->fbo);
+ /* Add a (texture) colour buffer to the FBO */
+ glGenTextures(1, &ctx->fbotex);
+ glBindTexture(GL_TEXTURE_2D, ctx->fbotex);
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
+ glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, 256, 256, 0, GL_RGBA, GL_UNSIGNED_BYTE, 0);
+ glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT, GL_TEXTURE_2D, ctx->fbotex, 0);
+ /* Add a depth buffer to the FBO */
+ glGenRenderbuffersEXT(1, &ctx->fbodepth);
+ glBindRenderbufferEXT(GL_RENDERBUFFER_EXT, ctx->fbodepth);
+ glRenderbufferStorageEXT(GL_RENDERBUFFER_EXT, GL_DEPTH_STENCIL_EXT, 256, 256);
+ glFramebufferRenderbufferEXT(GL_FRAMEBUFFER_EXT, GL_DEPTH_ATTACHMENT_EXT, GL_RENDERBUFFER_EXT, ctx->fbodepth);
+ glFramebufferRenderbufferEXT(GL_FRAMEBUFFER_EXT, GL_STENCIL_ATTACHMENT_EXT, GL_RENDERBUFFER_EXT, ctx->fbodepth);
+ glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0);
render_load_shaders(ctx);
ctx->num_textures = 0;
- ctx->frames = 0;
- ctx->t_fps = SDL_GetTicks();
- ctx->fps = 0;
-
return ctx;
}
@@ -206,38 +214,15 @@ static void render_draw_line(GLfloat x1, GLfloat y1, GLfloat z1, GLfloat x2, GLf
}
-void render_draw(Game *game) {
-
- int i;
- Uint32 t;
-
- t = SDL_GetTicks();
+static void render_draw_stuff(Game *game, Uint32 t) {
- glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
-
- glMatrixMode(GL_MODELVIEW);
- glLoadIdentity();
- gluLookAt(game->lander->x-(game->view_dist*sinf(game->lander->yaw)*cosf(game->view_angle)),
- game->lander->y-(game->view_dist*cosf(game->lander->yaw)*cosf(game->view_angle)),
- game->lander->z+(game->view_dist*sinf(game->view_angle)),
- game->lander->x, game->lander->y, game->lander->z,
- sqrtf(2.0)*sinf(game->lander->yaw)*sinf(game->view_angle),
- sqrtf(2.0)*cosf(game->lander->yaw)*sinf(game->view_angle), sqrtf(2.0)*cosf(game->view_angle));
+ int i;
- GLfloat pos[] = {-1.0, -0.8, 1.3, 0.0};
- GLfloat ambient[4];
- GLfloat diffuse[] = {0.8, 0.8, 0.8, 1.0};
- GLfloat specular[] = {0.8, 0.8, 0.8, 1.0};
- ambient[0] = 0.3; ambient[1] = 0.3; ambient[2] = 0.3; ambient[3] = 1.0;
- glLightModelfv(GL_LIGHT_MODEL_AMBIENT, ambient);
- glLightfv(GL_LIGHT0, GL_POSITION, pos);
- glLightfv(GL_LIGHT0, GL_DIFFUSE, diffuse);
- glLightfv(GL_LIGHT0, GL_SPECULAR, specular);
- glEnable(GL_LIGHT0);
+ glPushClientAttrib(GL_CLIENT_VERTEX_ARRAY_BIT);
+ glEnableClientState(GL_VERTEX_ARRAY);
+ glEnableClientState(GL_NORMAL_ARRAY);
+ glEnableClientState(GL_TEXTURE_COORD_ARRAY);
- /* Draw the objects */
- //glUniform1iARB(glGetUniformLocationARB(game->render->lighting_program, "texture"), 0);
- //glUseProgramObjectARB(game->render->lighting_program);
for ( i=0; i<game->num_rooms; i++ ) {
Room *room;
@@ -261,21 +246,100 @@ void render_draw(Game *game) {
}
}
- /* Finally, the lander */
+
+ glPopClientAttrib();
+
+}
+
+static void render_setup_lighting(Game *game) {
+
+ GLfloat pos[] = {-1.0, -0.8, 1.3, 0.0};
+ GLfloat ambient[4];
+ GLfloat diffuse[] = {0.8, 0.8, 0.8, 1.0};
+ GLfloat specular[] = {0.8, 0.8, 0.8, 1.0};
+
+ glEnable(GL_LIGHTING);
+
+ ambient[0] = 0.3; ambient[1] = 0.3; ambient[2] = 0.3; ambient[3] = 1.0;
+ glLightModelfv(GL_LIGHT_MODEL_AMBIENT, ambient);
+ glLightfv(GL_LIGHT0, GL_POSITION, pos);
+ glLightfv(GL_LIGHT0, GL_DIFFUSE, diffuse);
+ glLightfv(GL_LIGHT0, GL_SPECULAR, specular);
+ glEnable(GL_LIGHT0);
+
+}
+
+void render_draw(Game *game, Uint32 t) {
+
+ /* First pass: Looking upwards */
+ glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, game->render->fbo);
+ glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
+ glViewport(0, 0, 256, 256);
+ glMatrixMode(GL_PROJECTION);
+ glLoadIdentity();
+ gluPerspective(70.0, 1.0, 0.1, 100.0);
+ glMatrixMode(GL_MODELVIEW);
+ glLoadIdentity();
+ gluLookAt(game->lander->x, game->lander->y, game->lander->z,
+ game->lander->x, game->lander->y, game->lander->z+10.0,
+ sqrtf(2.0)*sinf(game->lander->yaw), sqrtf(2.0)*cosf(game->lander->yaw), 0.0);
+ render_setup_lighting(game);
+ render_draw_stuff(game, t);
+
+ /* Second pass: Main view */
+ glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0);
+ glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
+ glViewport(0, 0, game->render->width, game->render->height);
+ glMatrixMode(GL_PROJECTION);
+ glLoadIdentity();
+ gluPerspective(50.0, (GLfloat)game->render->width/(GLfloat)game->render->height, 0.1, 100.0); /* Depth buffer 10cm to 100m */
+ glMatrixMode(GL_MODELVIEW);
+ glLoadIdentity();
+ gluLookAt(game->lander->x-(game->view_dist*sinf(game->lander->yaw)*cosf(game->view_angle)),
+ game->lander->y-(game->view_dist*cosf(game->lander->yaw)*cosf(game->view_angle)),
+ game->lander->z+(game->view_dist*sinf(game->view_angle)),
+ game->lander->x, game->lander->y, game->lander->z,
+ sqrtf(2.0)*sinf(game->lander->yaw)*sinf(game->view_angle),
+ sqrtf(2.0)*cosf(game->lander->yaw)*sinf(game->view_angle), sqrtf(2.0)*cosf(game->view_angle));
+ render_setup_lighting(game);
+ render_draw_stuff(game, t);
+
+ /* Finally, draw the lander */
+ glPushClientAttrib(GL_CLIENT_VERTEX_ARRAY_BIT);
+ glEnableClientState(GL_VERTEX_ARRAY);
+ glEnableClientState(GL_NORMAL_ARRAY);
+ glEnable(GL_TEXTURE_GEN_S);
+ glEnable(GL_TEXTURE_GEN_T);
+ glTexGeni(GL_S, GL_TEXTURE_GEN_MODE, GL_SPHERE_MAP);
+ glTexGeni(GL_T, GL_TEXTURE_GEN_MODE, GL_SPHERE_MAP);
render_model_instance_draw(game->lander, t, game->render);
+ glPopClientAttrib();
render_draw_line(game->lander->x, game->lander->y, game->lander->z, game->lander->x, game->lander->y, game->lander->z-200.0);
- //glUseProgramObjectARB(0);
+ glDisable(GL_TEXTURE_GEN_S);
+ glDisable(GL_TEXTURE_GEN_T);
- SDL_GL_SwapBuffers();
+ glClear(GL_DEPTH_BUFFER_BIT);
+ glMatrixMode(GL_PROJECTION);
+ glLoadIdentity();
+ glMatrixMode(GL_MODELVIEW);
+ glLoadIdentity();
+ glBindTexture(GL_TEXTURE_2D, game->render->fbotex);
+ glEnable(GL_TEXTURE_2D);
+ glDisable(GL_LIGHTING);
+ glColor3f(1.0, 1.0, 1.0);
+ glBegin(GL_QUADS);
+ glTexCoord2f(0.0, 0.0);
+ glVertex2f(-1.0, -1.0);
+ glTexCoord2f(1.0, 0.0);
+ glVertex2f(-0.5, -1.0);
+ glTexCoord2f(1.0, 1.0);
+ glVertex2f(-0.5, -0.5);
+ glTexCoord2f(0.0, 1.0);
+ glVertex2f(-1.0, -0.5);
+ glEnd();
+ glDisable(GL_TEXTURE_2D);
- /* Calculate FPS every half a second */
- game->render->frames++;
- if ( t - game->render->t_fps > 500 ) {
- game->render->fps = (500*game->render->frames) / (t - game->render->t_fps);
- game->render->t_fps = t;
- game->render->frames = 0;
- game->frame_delay_fiddled = 0;
- }
+ SDL_GL_SwapBuffers();
}
diff --git a/src/render.h b/src/render.h
index 8b89374..2093fe4 100644
--- a/src/render.h
+++ b/src/render.h
@@ -20,7 +20,7 @@
extern RenderContext *render_setup(int width, int height);
extern void render_shutdown(RenderContext *ctx);
-extern void render_draw(Game *game);
+extern void render_draw(Game *game, Uint32 t);
#endif /* RENDER_H */
diff --git a/src/types.h b/src/types.h
index 5c1ba53..3177028 100644
--- a/src/types.h
+++ b/src/types.h
@@ -106,10 +106,13 @@ typedef struct {
Texture textures[MAX_TEXTURES];
unsigned int num_textures;
- int frames;
- Uint32 t_fps;
- int fps;
-
+ GLuint fbo;
+ GLuint fbotex;
+ GLuint fbodepth;
+ GLfloat aspect;
+ int width;
+ int height;
+
} RenderContext;
typedef struct {
@@ -171,6 +174,10 @@ typedef struct {
int paused;
int pause_rel;
+ int frames;
+ Uint32 t_fps;
+ int fps;
+
} Game;
#endif /* TYPES_H */