diff options
author | taw27 <taw27@84d2e878-0bd5-11dd-ad15-13eda11d74c5> | 2008-05-16 16:54:55 +0000 |
---|---|---|
committer | taw27 <taw27@84d2e878-0bd5-11dd-ad15-13eda11d74c5> | 2008-05-16 16:54:55 +0000 |
commit | 0f5e2c1f67d6f9b7d6ee3dd55b8c7cd903881bd6 (patch) | |
tree | 4615062f7f0a4268d04c00196aa64381ae0f3e50 /src | |
parent | 096e588e4f2e93e51a2791258f3e6c4a7f7a78ae (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.c | 5 | ||||
-rw-r--r-- | src/main.c | 31 | ||||
-rw-r--r-- | src/model.c | 168 | ||||
-rw-r--r-- | src/physics.c | 5 | ||||
-rw-r--r-- | src/physics.h | 2 | ||||
-rw-r--r-- | src/render.c | 170 | ||||
-rw-r--r-- | src/render.h | 2 | ||||
-rw-r--r-- | src/types.h | 15 |
8 files changed, 160 insertions, 238 deletions
@@ -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 ) { @@ -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 */ |