summaryrefslogtreecommitdiff
path: root/source/gl_surf.c
diff options
context:
space:
mode:
Diffstat (limited to 'source/gl_surf.c')
-rw-r--r--source/gl_surf.c331
1 files changed, 155 insertions, 176 deletions
diff --git a/source/gl_surf.c b/source/gl_surf.c
index 488093c..29dafaa 100644
--- a/source/gl_surf.c
+++ b/source/gl_surf.c
@@ -28,18 +28,74 @@ lightmapBuilder_t lm;
static cvar_t *gl_coloredlightmaps;
static cvar_t *gl_brightness;
+static cvar_t *gl_modulate_mask;
-cvar_t *gl_modulate_hack;
+static float colorScale, colorAdj;
/*
=============================================================================
-LIGHTMAPS BUILDING
+LIGHTMAP COLOR ADJUSTING
=============================================================================
*/
-static float colorScale, brightness;
+void GL_AdjustColor( byte *dst, const byte *src, int what ) {
+ float r, g, b, min, max, mid;
+
+ r = src[0];
+ g = src[1];
+ b = src[2];
+
+ if( colorScale != 1.0f ) {
+ min = max = r;
+ if ( g < min ) min = g;
+ if ( b < min ) min = b;
+ if ( g > max ) max = g;
+ if ( b > max ) max = b;
+ mid = 0.5 * ( min + max );
+ r = mid + ( r - mid ) * colorScale;
+ g = mid + ( g - mid ) * colorScale;
+ b = mid + ( b - mid ) * colorScale;
+ }
+
+ if( gl_modulate_mask->integer & what ) {
+ r *= gl_modulate->value;
+ g *= gl_modulate->value;
+ b *= gl_modulate->value;
+ }
+
+ max = g;
+ if( r > max ) {
+ max = r;
+ }
+ if( b > max ) {
+ max = b;
+ }
+
+ if( max > 255 ) {
+ r *= 255.0f / max;
+ g *= 255.0f / max;
+ b *= 255.0f / max;
+ }
+
+ // atu brightness adjustments
+ r += colorAdj;
+ g += colorAdj;
+ b += colorAdj;
+
+ dst[0] = clamp( r, 0, 255 );
+ dst[1] = clamp( g, 0, 255 );
+ dst[2] = clamp( b, 0, 255 );
+}
+
+/*
+=============================================================================
+
+LIGHTMAPS BUILDING
+
+=============================================================================
+*/
static qboolean LM_AllocBlock( int w, int h, int *s, int *t ) {
int i, j;
@@ -100,7 +156,7 @@ static void LM_UploadBlock( void ) {
}
}
-static void LM_BuildSurfaceLightmap( bspSurface_t *surf, vec_t *vbo ) {
+static void LM_BuildSurfaceLightmap( mface_t *surf, vec_t *vbo ) {
byte *ptr, *dst, *src;
int i, j;
int smax, tmax, s, t;
@@ -126,63 +182,7 @@ static void LM_BuildSurfaceLightmap( bspSurface_t *surf, vec_t *vbo ) {
for( i = 0; i < tmax; i++ ) {
ptr = dst;
for( j = 0; j < smax; j++ ) {
- float r, g, b, min, max, mid;
-
- r = src[0];
- g = src[1];
- b = src[2];
-
- if( colorScale != 1.0f ) {
- min = max = r;
- if ( g < min ) min = g;
- if ( b < min ) min = b;
- if ( g > max ) max = g;
- if ( b > max ) max = b;
- mid = 0.5 * ( min + max );
- r = mid + ( r - mid ) * colorScale;
- g = mid + ( g - mid ) * colorScale;
- b = mid + ( b - mid ) * colorScale;
- }
-
- if( !gl_modulate_hack->integer ) {
- r *= gl_modulate->value;
- g *= gl_modulate->value;
- b *= gl_modulate->value;
- }
-
- max = g;
- if( r > max ) {
- max = r;
- }
- if( b > max ) {
- max = b;
- }
-
- if( max > 255 ) {
- r *= 255.0f / max;
- g *= 255.0f / max;
- b *= 255.0f / max;
- }
-
- //atu brightness adjustments
- brightness = 255.0f * gl_brightness->value;
- r += brightness;
- g += brightness;
- b += brightness;
- if ( r > 255.0f ) r = 255.0f;
- else if ( r < 0.0f ) r = 0.0f;
- if ( g > 255.0f ) g = 255.0f;
- else if ( g < 0.0f ) g = 0.0f;
- if ( b > 255.0f ) b = 255.0f;
- else if ( b < 0.0f ) b = 0.0f;
-
- src[0] = r;
- src[1] = g;
- src[2] = b;
-
- ptr[0] = src[0];
- ptr[1] = src[1];
- ptr[2] = src[2];
+ GL_AdjustColor( ptr, src, 1 );
ptr[3] = 255;
src += 3; ptr += 4;
@@ -198,7 +198,7 @@ static void LM_BuildSurfaceLightmap( bspSurface_t *surf, vec_t *vbo ) {
s -= surf->texturemins[0];
t -= surf->texturemins[1];
- for( i = 0; i < surf->numVerts; i++ ) {
+ for( i = 0; i < surf->numsurfedges; i++ ) {
vbo[5] += s;
vbo[6] += t;
vbo[5] /= LM_BLOCK_WIDTH * 16;
@@ -215,38 +215,23 @@ POLYGONS BUILDING
=============================================================================
*/
-static void GL_BuildSurfacePoly( bspSurface_t *surf, vec_t *vbo ) {
- int *src_surfedge;
- dvertex_t *src_vert;
- dedge_t *src_edge;
- bspTexinfo_t *texinfo = surf->texinfo;
- int index, vertIndex;
- int i, numEdges = surf->numSurfEdges;
+static void GL_BuildSurfacePoly( bsp_t *bsp, mface_t *surf, vec_t *vbo ) {
+ msurfedge_t *src_surfedge;
+ mvertex_t *src_vert;
+ medge_t *src_edge;
+ mtexinfo_t *texinfo = surf->texinfo;
+ int i;
vec2_t scale, tc, mins, maxs;
int bmins[2], bmaxs[2];
- surf->numVerts = numEdges;
- surf->numIndices = ( numEdges - 2 ) * 3;
surf->texnum[0] = texinfo->image->texnum;
- surf->texflags = texinfo->flags;
-
- if( texinfo->flags & SURF_WARP ) {
- if( qglProgramStringARB ) {
- surf->type = DSURF_WARP;
- surf->texnum[1] = r_warptexture->texnum;
- } else {
- surf->type = DSURF_NOLM;
- }
- } else if( !surf->lightmap || gl_fullbright->integer || ( texinfo->flags & NOLIGHT_MASK ) ) {
- surf->type = DSURF_NOLM;
- } else {
- surf->type = DSURF_POLY;
- }
// normalize texture coordinates
scale[0] = 1.0f / texinfo->image->width;
scale[1] = 1.0f / texinfo->image->height;
- if( surf->type == DSURF_WARP ) {
+
+ if( ( texinfo->c.flags & SURF_WARP ) && qglProgramStringARB ) {
+ surf->texnum[1] = r_warptexture->texnum;
scale[0] *= 0.5f;
scale[1] *= 0.5f;
}
@@ -254,22 +239,11 @@ static void GL_BuildSurfacePoly( bspSurface_t *surf, vec_t *vbo ) {
mins[0] = mins[1] = 99999;
maxs[0] = maxs[1] = -99999;
- src_surfedge = surf->firstSurfEdge;
- for( i = 0; i < numEdges; i++ ) {
- index = *src_surfedge++;
-
- vertIndex = 0;
- if( index < 0 ) {
- index = -index;
- vertIndex = 1;
- }
-
- if( index >= r_world.numEdges ) {
- Com_Error( ERR_DROP, "%s: bad edge index", __func__ );
- }
-
- src_edge = r_world.edges + index;
- src_vert = r_world.vertices + src_edge->v[vertIndex];
+ src_surfedge = surf->firstsurfedge;
+ for( i = 0; i < surf->numsurfedges; i++ ) {
+ src_edge = src_surfedge->edge;
+ src_vert = src_edge->v[src_surfedge->vert];
+ src_surfedge++;
// vertex coordinates
VectorCopy( src_vert->point, vbo );
@@ -288,7 +262,7 @@ static void GL_BuildSurfacePoly( bspSurface_t *surf, vec_t *vbo ) {
vbo[4] = tc[1] * scale[1];
// texture1 coordinates
- if( surf->type == DSURF_WARP ) {
+ if( ( texinfo->c.flags & SURF_WARP ) && qglProgramStringARB ) {
vbo[5] = vbo[3];
vbo[6] = vbo[4];
} else {
@@ -312,84 +286,84 @@ static void GL_BuildSurfacePoly( bspSurface_t *surf, vec_t *vbo ) {
surf->extents[1] = ( bmaxs[1] - bmins[1] ) << 4;
}
-static void GL_BuildSkyPoly( bspSurface_t *surf ) {
- int *src_surfedge;
- dvertex_t *src_vert;
- dedge_t *src_edge;
- bspTexinfo_t *texinfo = surf->texinfo;
- int index, vertIndex;
- int i, numEdges = surf->numSurfEdges;
- vec_t *dst_vert;
-
- surf->numVerts = numEdges;
- surf->numIndices = ( numEdges - 2 ) * 3;
- surf->texnum[0] = texinfo->image->texnum;
- surf->texflags = texinfo->flags;
- surf->type = DSURF_SKY;
+void GL_FreeWorld( void ) {
+ if( !gl_static.world.cache ) {
+ return;
+ }
- surf->vertices = sys.HunkAlloc( &r_world.pool,
- numEdges * 3 * sizeof( vec_t ) );
+ BSP_Free( gl_static.world.cache );
- src_surfedge = surf->firstSurfEdge;
- dst_vert = surf->vertices;
- for( i = 0; i < numEdges; i++ ) {
- index = *src_surfedge++;
-
- vertIndex = 0;
- if( index < 0 ) {
- index = -index;
- vertIndex = 1;
- }
+ if( gl_static.world.vertices ) {
+ Hunk_Free( &gl_static.world.pool );
+ } else if( qglDeleteBuffersARB ) {
+ GLuint buf = 1;
- if( index >= r_world.numEdges ) {
- Com_Error( ERR_DROP, "%s: bad edge index", __func__ );
- }
+ qglDeleteBuffersARB( 1, &buf );
+ }
- src_edge = r_world.edges + index;
- src_vert = r_world.vertices + src_edge->v[vertIndex];
+ lm.numMaps = 0;
+ LM_InitBlock();
+
+ memset( &gl_static.world, 0, sizeof( gl_static.world ) );
+}
+
+void GL_LoadWorld( const char *name ) {
+ char buffer[MAX_QPATH];
+ mface_t *surf;
+ int i, size, count;
+ vec_t *vbo;
+ bsp_t *bsp;
+ mtexinfo_t *info;
+ image_t *image;
+
+ if( !( bsp = BSP_Load( name ) ) ) {
+ Com_Error( ERR_DROP, "%s: couldn't load %s: %s",
+ __func__, name, BSP_GetError() );
+ }
- VectorCopy( src_vert->point, dst_vert );
+ // check if the required world model was already loaded
+ if( gl_static.world.cache == bsp ) {
+ for( i = 0; i < bsp->numtexinfo; i++ ) {
+ bsp->texinfo[i].image->registration_sequence = registration_sequence;
+ }
+ for( i = 0; i < bsp->numnodes; i++ ) {
+ bsp->nodes[i].visframe = 0;
+ }
+ for( i = 0; i < bsp->numleafs; i++ ) {
+ bsp->leafs[i].visframe = 0;
+ }
+ Com_DPrintf( "%s: reused old world model\n", __func__ );
+ bsp->refcount--;
+ return;
+ }
- dst_vert += 3;
- }
-}
+ gl_coloredlightmaps = Cvar_Get( "gl_coloredlightmaps", "1", CVAR_ARCHIVE|CVAR_FILES );
+ gl_brightness = Cvar_Get( "gl_brightness", "0", CVAR_ARCHIVE|CVAR_FILES );
+ gl_modulate_mask = Cvar_Get( "gl_modulate_mask", "3", CVAR_FILES );
-void GL_BeginPostProcessing( void ) {
- lm.numMaps = 0;
- LM_InitBlock();
+ colorScale = Cvar_ClampValue( gl_coloredlightmaps, 0, 1 );
+ colorAdj = 255 * Cvar_ClampValue( gl_brightness, -1, 1 );
- gl_coloredlightmaps = cvar.Get( "gl_coloredlightmaps", "1", CVAR_ARCHIVE|CVAR_FILES );
- gl_brightness = cvar.Get( "gl_brightness", "0", CVAR_ARCHIVE|CVAR_FILES );
- gl_modulate_hack = cvar.Get( "gl_modulate_hack", "0", CVAR_FILES );
+ // free previous model, if any
+ GL_FreeWorld();
- if( gl_coloredlightmaps->value < 0 ) {
- cvar.Set( "gl_coloredlightmaps", "0" );
- } else if( gl_coloredlightmaps->value > 1 ) {
- cvar.Set( "gl_coloredlightmaps", "1" );
- }
+ gl_static.world.cache = bsp;
- if( gl_brightness->value < -1 ) {
- cvar.Set( "gl_brightness", "-1" );
- } else if( gl_brightness->value > 1 ) {
- cvar.Set( "gl_brightness", "1" );
- }
+ // registers all texinfo
+ for( i = 0, info = bsp->texinfo; i < bsp->numtexinfo; i++, info++ ) {
+ Q_concat( buffer, sizeof( buffer ), "textures/", info->name, ".wal", NULL );
+ image = IMG_Find( buffer, it_wall );
+ info->image = image ? image : r_notexture;
+ }
- brightness = gl_brightness->value;
- colorScale = gl_coloredlightmaps->value;
-}
-
-void GL_EndPostProcessing( void ) {
- bspSurface_t *surf;
- int i, size, count;
- vec_t *vbo = NULL;
-
// calculate vertex buffer size in bytes
count = 0;
- for( i = 0, surf = r_world.surfaces; i < r_world.numSurfaces; i++, surf++ ) {
- count += surf->numSurfEdges;
+ for( i = 0, surf = bsp->faces; i < bsp->numfaces; i++, surf++ ) {
+ count += surf->numsurfedges;
}
size = count * VERTEX_SIZE * 4;
+ vbo = NULL;
if( qglBindBufferARB ) {
qglBindBufferARB( GL_ARRAY_BUFFER_ARB, 1 );
@@ -399,7 +373,7 @@ void GL_EndPostProcessing( void ) {
vbo = qglMapBufferARB( GL_ARRAY_BUFFER_ARB, GL_READ_WRITE_ARB );
if( vbo ) {
- gl_static.vertices = NULL;
+ gl_static.world.vertices = NULL;
Com_DPrintf( "%s: %d bytes of vertex data as VBO\n", __func__, size );
} else {
Com_EPrintf( "Failed to map VBO data in client memory\n" );
@@ -408,29 +382,34 @@ void GL_EndPostProcessing( void ) {
}
if( !vbo ) {
- gl_static.vertices = vbo = sys.HunkAlloc( &r_world.pool, size );
+ Hunk_Begin( &gl_static.world.pool, size );
+ vbo = Hunk_Alloc( &gl_static.world.pool, size );
+ Hunk_End( &gl_static.world.pool );
+
Com_DPrintf( "%s: %d bytes of vertex data on hunk\n", __func__, size );
+ gl_static.world.vertices = vbo;
}
// post process all surfaces
count = 0;
- for( i = 0, surf = r_world.surfaces; i < r_world.numSurfaces; i++, surf++ ) {
- if( surf->texinfo->flags & SURF_SKY ) {
- GL_BuildSkyPoly( surf );
+ for( i = 0, surf = bsp->faces; i < bsp->numfaces; i++, surf++ ) {
+ if( surf->texinfo->c.flags & SURF_SKY ) {
continue;
}
- surf->firstVert = count;
- GL_BuildSurfacePoly( surf, vbo );
+ surf->firstvert = count;
+ GL_BuildSurfacePoly( bsp, surf, vbo );
- if( surf->type == DSURF_POLY ) {
+ if( surf->lightmap && !gl_fullbright->integer &&
+ !( surf->texinfo->c.flags & SURF_NOLM_MASK ) )
+ {
LM_BuildSurfaceLightmap( surf, vbo );
}
- count += surf->numVerts;
- vbo += surf->numVerts * VERTEX_SIZE;
+ count += surf->numsurfedges;
+ vbo += surf->numsurfedges * VERTEX_SIZE;
}
- if( qglBindBufferARB && !gl_static.vertices ) {
+ if( qglBindBufferARB && !gl_static.world.vertices ) {
qglBindBufferARB( GL_ARRAY_BUFFER_ARB, 1 );
if( !qglUnmapBufferARB( GL_ARRAY_BUFFER_ARB ) ) {
Com_Error( ERR_DROP, "Failed to unmap VBO data" );