aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authortaw27 <taw27@84d2e878-0bd5-11dd-ad15-13eda11d74c5>2008-06-01 19:11:41 +0000
committertaw27 <taw27@84d2e878-0bd5-11dd-ad15-13eda11d74c5>2008-06-01 19:11:41 +0000
commit04bd71265a51eb3c842c45b332a45575a8660e60 (patch)
tree7c0baf34c197b31f6b14229caa0d35aa4918b65c
parent214df94a1478591f737d5a41c65af0b26e8fa35b (diff)
Multiple portability fixes
git-svn-id: svn://cook.msm.cam.ac.uk:745/thrust3d/thrust3d@57 84d2e878-0bd5-11dd-ad15-13eda11d74c5
-rwxr-xr-xautogen.sh6
-rw-r--r--configure.ac7
-rw-r--r--data/models/platform1
-rw-r--r--src/Makefile.am2
-rw-r--r--src/game.c1
-rw-r--r--src/main.c23
-rw-r--r--src/model.c19
-rw-r--r--src/physics.c2
-rw-r--r--src/render.c114
-rw-r--r--src/texture.c4
-rw-r--r--src/types.h4
11 files changed, 103 insertions, 80 deletions
diff --git a/autogen.sh b/autogen.sh
new file mode 100755
index 0000000..5090c23
--- /dev/null
+++ b/autogen.sh
@@ -0,0 +1,6 @@
+#!/bin/sh
+
+aclocal \
+ && autoheader \
+ && automake --add-missing --foreign --copy \
+ && autoconf
diff --git a/configure.ac b/configure.ac
index 58653d4..ad9b536 100644
--- a/configure.ac
+++ b/configure.ac
@@ -1,6 +1,6 @@
dnl Process this file with autoconf to produce a configure script.
-AC_INIT(thrust3d, 0.0.2, taw27@cam.ac.uk)
+AC_INIT(thrust3d, 0.0.3, taw27@cam.ac.uk)
VERSION=AC_PACKAGE_VERSION
AM_CONFIG_HEADER(config.h)
@@ -43,6 +43,9 @@ OPENGL_LIBS=-lGL], AC_MSG_ERROR([
AC_CHECK_LIB(GLU, main, [GLU_LIBS=-lGLU], AC_MSG_ERROR([
*** GLU not found. Do you have 'libglu-dev' or similar installed?]))
+AC_CHECK_LIB(GLEW, main, [GLEW_LIBS=-lGLEW], AC_MSG_ERROR([
+*** GLEW not found. Do you have 'libglew-dev' or similar installed?]))
+
AC_MSG_CHECKING([libpng])
if $PKG_CONFIG --atleast-version 1.2.0 libpng ; then
LIBPNG_VERSION=`$PKG_CONFIG --modversion libpng`
@@ -56,7 +59,7 @@ else
fi
CFLAGS="$CFLAGS $LIBSDL_CFLAGS $OPENGL_CFLAGS $LIBPNG_CFLAGS"
-LIBS="$LIBS $LIBSDL_LIBS $OPENGL_LIBS $GLU_LIBS $LIBPNG_LIBS"
+LIBS="$LIBS $LIBSDL_LIBS $OPENGL_LIBS $GLU_LIBS $GLEW_LIBS $LIBPNG_LIBS"
AC_OUTPUT(Makefile src/Makefile data/Makefile)
diff --git a/data/models/platform b/data/models/platform
index c4e612a..fdfdf30 100644
--- a/data/models/platform
+++ b/data/models/platform
@@ -27,4 +27,5 @@ QUADS
-1.00 1.00 0.07 1.0 0.0
#
swirly
+colour 0.8 0.0 0.0
diff --git a/src/Makefile.am b/src/Makefile.am
index 6c89359..d3ccec8 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -1,6 +1,6 @@
bin_PROGRAMS = thrust3d
thrust3d_SOURCES = main.c model.c render.c physics.c game.c texture.c utils.c audio.c
-thrust3d_LDADD = @LIBS@ -lGLEW
+thrust3d_LDADD = @LIBS@
AM_CFLAGS = -Wall -g
AM_CPPFLAGS = -DDATADIR=\""$(datadir)"/thrust3d\"
diff --git a/src/game.c b/src/game.c
index 221ba23..1e262a9 100644
--- a/src/game.c
+++ b/src/game.c
@@ -253,6 +253,7 @@ Game *game_new(int width, int height) {
free(g);
return NULL;
}
+ /* Note: render_setup() initialises GLEW, which must be done before loading models. */
/* Audio setup */
g->audio = audio_setup();
diff --git a/src/main.c b/src/main.c
index 65fa217..80e5862 100644
--- a/src/main.c
+++ b/src/main.c
@@ -17,8 +17,6 @@
#include <stdarg.h>
#include <unistd.h>
#include <SDL.h>
-#include <gl.h>
-#include <glu.h>
#include <assert.h>
#include "types.h"
@@ -42,11 +40,6 @@ static void main_version() {
printf("Thrust3D version "PACKAGE_VERSION", (c) 2008 Thomas White <taw27@srcf.ucam.org>\n");
}
-extern 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,
- ModelInstance *obj);
-extern int physics_point_is_inside_hull(GLfloat cx, GLfloat cy, GLfloat cz, GLfloat *fvert, int nfvert, GLfloat nx, GLfloat ny, GLfloat nz);
-
int main(int argc, char *argv[]) {
SDL_Event event;
@@ -62,20 +55,6 @@ int main(int argc, char *argv[]) {
width = 800; height = 600;
video_flags = SDL_OPENGL;
-#if 0
- /* FIXME: Testing */
- GLfloat testv[3*4];
- int ts;
- testv[3*0+0] = 0.0; testv[3*0+1] = 0.0; testv[3*0+2] = 0.0;
- testv[3*1+0] = 1.0; testv[3*1+1] = 0.0; testv[3*1+2] = 0.0;
- testv[3*2+0] = 1.0; testv[3*2+1] = 1.0; testv[3*2+2] = 0.0;
- testv[3*3+0] = 0.0; testv[3*3+1] = 1.0; testv[3*3+2] = 0.0;
- ts = physics_point_is_inside_hull(-0.5, 0.5, 1.0, testv, 4, 0.0, 0.0, 1.0);
- printf("Boundary test: %i\n", ts);
- ts = physics_will_collide_face(-0.5, 0.5, 1.0, 0.0, 0.0, -0.02, 0.0, 0.0, 1.0, testv, 4, 100, NULL);
- printf("Will collide: %i\n", ts);
-#endif
-
while ((c = getopt(argc, argv, "hvr:f")) != -1) {
switch ( c ) {
@@ -231,7 +210,7 @@ int main(int argc, char *argv[]) {
/* Sleep for a bit to avoid hogging the CPU.
* This is a fudge - ideally this delay would adapt so that the CPU is not hogged when the GPU is the
- * limiting factor, and be zero when the CPU is limiting. I don't know a sensible way to tell which
+ * limiting factor, and be zero when the CPU is limiting. I don't know of a sensible way to tell which
* is the case. */
usleep(25000);
diff --git a/src/model.c b/src/model.c
index d182f32..2c3c895 100644
--- a/src/model.c
+++ b/src/model.c
@@ -13,8 +13,7 @@
#include <config.h>
#endif
-#define GL_GLEXT_PROTOTYPES 1
-#include <gl.h>
+#include <glew.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
@@ -75,8 +74,8 @@ static Model *model_new(const char *name) {
static Primitive *model_add_primitive(Model *model, GLenum type, GLfloat *vertices, GLfloat *normals, GLfloat *texcoords,
int n, PrimitiveAttrib attribs, GLfloat r, GLfloat g, GLfloat b, char *texture,
- GLfloat radius, GLfloat shininess) {
-
+ GLfloat radius, GLfloat shininess, int vbos) {
+#include <glew.h>
Primitive *p;
/* Sanity check */
@@ -125,9 +124,10 @@ static Primitive *model_add_primitive(Model *model, GLenum type, GLfloat *vertic
p->radius = radius;
p->shininess = shininess;
- if ( type != PRIMITIVE_HEMISPHERE ) {
+ if ( vbos && ( type != PRIMITIVE_HEMISPHERE ) ) {
- /* Buffer object stuff */
+ /* FIXME: Move this snippet to render.c is some tidy way */
+
glGenBuffersARB(1, &p->vertices_buffer);
glBindBufferARB(GL_ARRAY_BUFFER, p->vertices_buffer);
glBufferDataARB(GL_ARRAY_BUFFER, 3*p->num_vertices*sizeof(GLfloat), p->vertices, GL_STATIC_DRAW);
@@ -142,11 +142,6 @@ static Primitive *model_add_primitive(Model *model, GLenum type, GLfloat *vertic
glBindBufferARB(GL_ARRAY_BUFFER, 0);
- // free(p->vertices);
- // free(p->normals);
- // free(p->texcoords);
- /* End buffer object stuff */
-
}
model->attrib_total = model->attrib_total | attribs;
@@ -235,7 +230,7 @@ static int model_load(ModelContext *ctx, const char *name, RenderContext *render
if ( line[0] == '\n' ) {
if ( num_vertices > 0 ) {
model_add_primitive(model, type, vertices, normals, texcoords, num_vertices,
- attribs, col_r, col_g, col_b, texture, radius, shininess);
+ attribs, col_r, col_g, col_b, texture, radius, shininess, render->vbos);
num_vertices = 0;
type = PRIMITIVE_TRIANGLES;
attribs = ATTRIB_NONE;
diff --git a/src/physics.c b/src/physics.c
index 120caff..c9f89f1 100644
--- a/src/physics.c
+++ b/src/physics.c
@@ -189,7 +189,7 @@ static int physics_check_collide(ModelInstance *obj, ModelInstance *other, Uint3
if ( physics_will_collide_face(sx, sy, sz, vx, vy, vz, nx, ny, nz,
face, 4, dt, other) != 0 ) {
- //printf("collides with %s/%p\n", other->model->name, other);
+ printf("collides with %s/%p\n", other->model->name, other);
if ( (nx == 0.0) && (ny == 0.0) && ( nz == 1.0) ) {
obj->vz = 0.0;
obj->landed = 1;
diff --git a/src/render.c b/src/render.c
index d8ca276..e92abf5 100644
--- a/src/render.c
+++ b/src/render.c
@@ -114,7 +114,7 @@ static void render_delete_shaders(RenderContext *r) {
glDeleteShader(r->lighting_vert);
glDeleteShader(r->lighting_frag);
glDeleteProgram(r->lighting_program);
-
+
}
#define HEMI_ROUND_BITS 16
@@ -141,6 +141,33 @@ RenderContext *render_setup(int width, int height) {
glewInit();
+ if ( GLEW_VERSION_1_5 || GLEW_ARB_vertex_buffer_object ) {
+ r->vbos = 1;
+ } else {
+ r->vbos = 0;
+ fprintf(stderr, "Vertex buffer objects are not supported by your graphics card (or maybe just by its driver).\n");
+ fprintf(stderr, "Geometry performance may be less than optimal.\n");
+ }
+
+ if ( GLEW_EXT_framebuffer_object ) {
+ r->fbos = 1;
+ } else {
+ r->fbos = 0;
+ fprintf(stderr, "Framebuffer objects are not supported by your graphics card (or maybe just by its driver).\n");
+ fprintf(stderr, "Reflections and GPU dynamic textures disabled.\n");
+ }
+
+ if ( ( GLEW_ARB_vertex_shader && GLEW_ARB_fragment_shader && GLEW_ARB_shader_objects && GLEW_ARB_shading_language_100 ) || GLEW_VERSION_2_0 ) {
+ r->shaders = 1;
+ } else {
+ r->shaders = 0;
+ fprintf(stderr, "Shaders are not supported by your graphics card (or maybe just by its driver).\n");
+ fprintf(stderr, "Per-fragment lighting and GPU dynamic textures disabled.\n");
+ }
+ if ( !r->fbos && !r->shaders ) {
+ fprintf(stderr, "This REALLY isn't going to be as pretty as it should be. Sorry.\n");
+ }
+
r->width = width;
r->height = height;
r->aspect = (GLfloat)width/(GLfloat)height;
@@ -158,7 +185,7 @@ RenderContext *render_setup(int width, int height) {
glEnable(GL_BLEND);
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
- if ( GLEW_EXT_framebuffer_object ) {
+ if ( r->fbos ) {
/* Create a small FBO for rendering reflections with */
glGenFramebuffersEXT(1, &r->fbo);
@@ -190,10 +217,8 @@ RenderContext *render_setup(int width, int height) {
glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT, GL_TEXTURE_2D, r->swirly_texture, 0);
glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0);
- } else {
- fprintf(stderr, "EXT_framebuffer_object not supported\n");
}
-
+
/* Create coordinates for a hemisphere to reuse later */
r->hemisphere_v = malloc(3*HEMI_NUM_VERTICES*sizeof(GLfloat));
r->hemisphere_n = malloc(3*HEMI_NUM_VERTICES*sizeof(GLfloat));
@@ -236,7 +261,7 @@ RenderContext *render_setup(int width, int height) {
}
}
- render_load_shaders(r);
+ if ( r->shaders ) render_load_shaders(r);
r->num_textures = 0;
@@ -249,7 +274,7 @@ RenderContext *render_setup(int width, int height) {
}
void render_shutdown(RenderContext *r) {
- render_delete_shaders(r);
+ if ( r->shaders ) render_delete_shaders(r);
texture_free_all(r);
}
@@ -287,7 +312,7 @@ static int render_model_instance_draw(ModelInstance *instance, Uint32 t, RenderC
p = m->primitives[j];
- if ( p->attribs & ATTRIB_PULSE ) {
+ if ( ((p->attribs & ATTRIB_PULSE) && !(p->attribs & ATTRIB_SWIRLY)) || ((p->attribs & ATTRIB_SWIRLY) && !r->fbos) ) {
float s;
s = fabsf(0.4*cosf(t * 0.001));
GLfloat c[] = {s*p->col_r, s*p->col_g, s*p->col_b, 1.0};
@@ -303,7 +328,7 @@ static int render_model_instance_draw(ModelInstance *instance, Uint32 t, RenderC
if ( p->attribs & ATTRIB_SHINY ) {
GLfloat white[] = {1.0, 1.0, 1.0, 1.0};
glMaterialfv(GL_FRONT, GL_SPECULAR, white);
- glMaterialf(GL_FRONT, GL_SHININESS, p->shininess);
+ glMaterialf(GL_FRONT, GL_SHININESS, p->shininess); /* FIXME: Shader ignores this value */
} else {
glMaterialfv(GL_FRONT, GL_SPECULAR, black);
}
@@ -317,39 +342,48 @@ static int render_model_instance_draw(ModelInstance *instance, Uint32 t, RenderC
/* Texture */
if ( p->attribs & ATTRIB_SWIRLY ) {
- glBindTexture(GL_TEXTURE_2D, r->swirly_texture);
- glEnable(GL_TEXTURE_2D);
- glUniform1iARB(glGetUniformLocationARB(r->lighting_program, "texture_emits"), 1);
+ if ( r->fbos && r->shaders ) {
+ glBindTexture(GL_TEXTURE_2D, r->swirly_texture);
+ glEnable(GL_TEXTURE_2D);
+ glUniform1i(glGetUniformLocation(r->lighting_program, "texture_emits"), 1);
+ } else {
+ if ( r->shaders ) {
+ glUniform1i(glGetUniformLocation(r->lighting_program, "texture_enabled"), 0);
+ } /* else don't enable texturing */
+ }
} else if ( p->texture != NULL ) {
Texture *texture;
texture = texture_lookup(r, p->texture);
if ( texture != NULL ) {
glBindTexture(GL_TEXTURE_2D, texture->texname);
glEnable(GL_TEXTURE_2D);
- glUniform1iARB(glGetUniformLocationARB(r->lighting_program, "texture_enabled"), 1);
+ if ( r->shaders ) glUniform1i(glGetUniformLocation(r->lighting_program, "texture_enabled"), 1);
} else {
- glUniform1iARB(glGetUniformLocationARB(r->lighting_program, "texture_enabled"), 0);
+ if ( r->shaders ) glUniform1i(glGetUniformLocation(r->lighting_program, "texture_enabled"), 0);
}
} else {
- glUniform1iARB(glGetUniformLocationARB(r->lighting_program, "texture_enabled"), 0);
+ if ( r->shaders ) glUniform1i(glGetUniformLocation(r->lighting_program, "texture_enabled"), 0);
+ }
+ if ( r->vbos ) {
+ glBindBuffer(GL_ARRAY_BUFFER, p->vertices_buffer);
+ glVertexPointer(3, GL_FLOAT, 0, NULL);
+ glBindBuffer(GL_ARRAY_BUFFER, p->normals_buffer);
+ glNormalPointer(GL_FLOAT, 0, NULL);
+ glBindBuffer(GL_ARRAY_BUFFER, p->texcoords_buffer);
+ glTexCoordPointer(2, GL_FLOAT, 0, NULL);
+ glBindBuffer(GL_ARRAY_BUFFER, 0);
+ } else {
+ glVertexPointer(3, GL_FLOAT, 0, p->vertices);
+ glNormalPointer(GL_FLOAT, 0, p->normals);
+ glTexCoordPointer(2, GL_FLOAT, 0, p->texcoords);
}
-
- glBindBufferARB(GL_ARRAY_BUFFER, p->vertices_buffer);
- glVertexPointer(3, GL_FLOAT, 0, NULL);
- glBindBufferARB(GL_ARRAY_BUFFER, p->normals_buffer);
- glNormalPointer(GL_FLOAT, 0, NULL);
- glBindBufferARB(GL_ARRAY_BUFFER, p->texcoords_buffer);
- glTexCoordPointer(2, GL_FLOAT, 0, NULL);
glDrawArrays(render_gltype(p->type), 0, p->num_vertices);
*nvert += p->num_vertices;
- glBindBufferARB(GL_ARRAY_BUFFER, 0);
-
glDisable(GL_TEXTURE_2D);
-
glPopMatrix();
if ( p->attribs & ATTRIB_SWIRLY ) {
- glUniform1iARB(glGetUniformLocationARB(r->lighting_program, "texture_emits"), 0);
+ if ( r->shaders ) glUniform1i(glGetUniformLocation(r->lighting_program, "texture_emits"), 0);
}
} else {
@@ -365,17 +399,17 @@ static int render_model_instance_draw(ModelInstance *instance, Uint32 t, RenderC
glNormalPointer(GL_FLOAT, 0, r->hemisphere_n);
glTexCoordPointer(2, GL_FLOAT, 0, r->hemisphere_t);
- if ( GLEW_EXT_framebuffer_object ) {
+ if ( r->fbos ) {
glBindTexture(GL_TEXTURE_2D, r->fbotex);
glEnable(GL_TEXTURE_2D);
glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
- glUniform1iARB(glGetUniformLocationARB(r->lighting_program, "texture_enabled"), 1);
- glUniform1iARB(glGetUniformLocationARB(r->lighting_program, "texture_emits"), 1);
+ if ( r->shaders ) glUniform1i(glGetUniformLocation(r->lighting_program, "texture_enabled"), 1);
+ if ( r->shaders ) glUniform1i(glGetUniformLocation(r->lighting_program, "texture_emits"), 1);
}
glDrawArrays(GL_QUADS, 0, HEMI_NUM_VERTICES);
*nvert += HEMI_NUM_VERTICES;
- glUniform1iARB(glGetUniformLocationARB(r->lighting_program, "texture_emits"), 0);
+ if ( r->shaders ) glUniform1i(glGetUniformLocation(r->lighting_program, "texture_emits"), 0);
glDisable(GL_TEXTURE_2D);
@@ -598,7 +632,7 @@ void render_draw(Game *game, Uint32 t) {
r = game->render;
- if ( GLEW_EXT_framebuffer_object ) {
+ if ( r->fbos ) {
/* First pass: Looking upwards */
glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, r->fbo);
@@ -621,8 +655,8 @@ void render_draw(Game *game, Uint32 t) {
glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, r->swirly_fbo);
glClear(GL_COLOR_BUFFER_BIT);
glViewport(0, 0, 128, 128);
- glUseProgramObjectARB(r->swirly_program);
- glUniform1fARB(glGetUniformLocationARB(game->render->swirly_program, "time"), t);
+ if ( r->shaders ) glUseProgram(r->swirly_program);
+ if ( r->shaders ) glUniform1f(glGetUniformLocation(game->render->swirly_program, "time"), t);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
glMatrixMode(GL_MODELVIEW);
@@ -652,11 +686,11 @@ void render_draw(Game *game, Uint32 t) {
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));
- glUseProgramObjectARB(r->lighting_program);
- glUniform1iARB(glGetUniformLocationARB(game->render->lighting_program, "texture"), 0);
- glUniform1iARB(glGetUniformLocationARB(game->render->lighting_program, "texture_only"), 0);
- glUniform1iARB(glGetUniformLocationARB(game->render->lighting_program, "texture_enabled"), 1);
- glUniform1iARB(glGetUniformLocationARB(game->render->lighting_program, "fill_light_enabled"), 0);
+ if ( r->shaders ) glUseProgram(r->lighting_program);
+ if ( r->shaders ) glUniform1i(glGetUniformLocation(game->render->lighting_program, "texture"), 0);
+ if ( r->shaders ) glUniform1i(glGetUniformLocation(game->render->lighting_program, "texture_only"), 0);
+ if ( r->shaders ) glUniform1i(glGetUniformLocation(game->render->lighting_program, "texture_enabled"), 1);
+ if ( r->shaders ) glUniform1i(glGetUniformLocation(game->render->lighting_program, "fill_light_enabled"), 0);
render_setup_lighting(game);
render_draw_stuff(game, t);
@@ -674,10 +708,10 @@ void render_draw(Game *game, Uint32 t) {
glEnableClientState(GL_TEXTURE_COORD_ARRAY);
render_model_instance_draw(game->lander, t, r, NULL);
glPopClientAttrib();
- glUniform1iARB(glGetUniformLocationARB(game->render->lighting_program, "texture_enabled"), 0);
+ if ( r->shaders ) glUniform1i(glGetUniformLocation(game->render->lighting_program, "texture_enabled"), 0);
render_draw_line(game->lander->x, game->lander->y, game->lander->z, game->lander->x, game->lander->y, game->lander->z-200.0);
glDisable(GL_LIGHT2);
- glUseProgramObjectARB(0);
+ if ( r->shaders ) glUseProgram(0);
render_draw_2d(r, game);
diff --git a/src/texture.c b/src/texture.c
index b2aba03..36f6a8b 100644
--- a/src/texture.c
+++ b/src/texture.c
@@ -34,11 +34,11 @@ void texture_load(RenderContext *ctx, char *name) {
png_bytep *row_pointers;
unsigned int x;
unsigned int y;
- char tmp[64];
+ char tmp[128];
uint8_t *texels;
/* Open file */
- snprintf(tmp, 63, "%s/textures/%s.png", DATADIR, name);
+ snprintf(tmp, 127, "%s/textures/%s.png", DATADIR, name);
fh = fopen(tmp, "rb");
if ( !fh ) {
fprintf(stderr, "Couldn't open texture file '%s'\n", tmp);
diff --git a/src/types.h b/src/types.h
index 2059cbb..39238fd 100644
--- a/src/types.h
+++ b/src/types.h
@@ -113,6 +113,10 @@ typedef struct {
typedef struct {
+ int shaders;
+ int vbos;
+ int fbos;
+
/* Lighting shaders */
GLuint lighting_vert;
GLuint lighting_frag;