/* dependencies */
#include "q3map2.h"
-
+#include <glib.h>
/* allocate a buffer and set it up */
buffer = safe_malloc( width * height * 3 + 18 );
+ /* we may also use safe_malloc0 on the whole instead,
+ * this would just be a bit slower */
memset( buffer, 0, 18 );
buffer[ 2 ] = 2;
buffer[ 12 ] = width & 255;
/* sanity check */
if ( bspLightBytes == NULL ) {
- Sys_Printf( "WARNING: No BSP lightmap data\n" );
+ Sys_FPrintf( SYS_WRN, "WARNING: No BSP lightmap data\n" );
return;
}
int ExportLightmapsMain( int argc, char **argv ){
/* arg checking */
- if ( argc < 1 ) {
+ if ( argc < 2 ) {
Sys_Printf( "Usage: q3map -export [-v] <mapname>\n" );
return 0;
}
/* arg checking */
- if ( argc < 1 ) {
+ if ( argc < 2 ) {
Sys_Printf( "Usage: q3map -import [-v] <mapname>\n" );
return 0;
}
buffer = NULL;
len = vfsLoadFile( filename, (void*) &buffer, -1 );
if ( len < 0 ) {
- Sys_Printf( "WARNING: Unable to load image %s\n", filename );
+ Sys_FPrintf( SYS_WRN, "WARNING: Unable to load image %s\n", filename );
continue;
}
/* sanity check it */
if ( pixels == NULL ) {
- Sys_Printf( "WARNING: Unable to load image %s\n", filename );
+ Sys_FPrintf( SYS_WRN, "WARNING: Unable to load image %s\n", filename );
continue;
}
if ( width != game->lightmapSize || height != game->lightmapSize ) {
- Sys_Printf( "WARNING: Image %s is not the right size (%d, %d) != (%d, %d)\n",
+ Sys_FPrintf( SYS_WRN, "WARNING: Image %s is not the right size (%d, %d) != (%d, %d)\n",
filename, width, height, game->lightmapSize, game->lightmapSize );
}
/* get shaders */
- asi = surfaceInfos[ *( (int*) a ) ].si;
- bsi = surfaceInfos[ *( (int*) b ) ].si;
+ asi = surfaceInfos[ *( (const int*) a ) ].si;
+ bsi = surfaceInfos[ *( (const int*) b ) ].si;
/* dummy check */
if ( asi == NULL ) {
}
memset( lm->superNormals, 0, size );
+ /* allocate floodlight map storage */
+ size = lm->sw * lm->sh * SUPER_FLOODLIGHT_SIZE * sizeof( float );
+ if ( lm->superFloodLight == NULL ) {
+ lm->superFloodLight = safe_malloc( size );
+ }
+ memset( lm->superFloodLight, 0, size );
+
/* allocate cluster map storage */
size = lm->sw * lm->sh * sizeof( int );
if ( lm->superClusters == NULL ) {
length = 0;
for ( x = 0; x < ( mesh->width - 1 ); x++ )
length += widthTable[ x ];
- lm->w = ceil( length / lm->sampleSize ) + 1;
+ lm->w = lm->sampleSize != 0 ? ceil( length / lm->sampleSize ) + 1 : 0;
if ( lm->w < ds->patchWidth ) {
lm->w = ds->patchWidth;
}
length = 0;
for ( y = 0; y < ( mesh->height - 1 ); y++ )
length += heightTable[ y ];
- lm->h = ceil( length / lm->sampleSize ) + 1;
+ lm->h = lm->sampleSize != 0 ? ceil( length / lm->sampleSize ) + 1 : 0;
if ( lm->h < ds->patchHeight ) {
lm->h = ds->patchHeight;
}
qboolean AddSurfaceToRawLightmap( int num, rawLightmap_t *lm ){
bspDrawSurface_t *ds, *ds2;
- surfaceInfo_t *info, *info2;
+ surfaceInfo_t *info;
int num2, n, i, axisNum;
float s, t, d, len, sampleSize;
- vec3_t mins, maxs, origin, faxis, size, exactSize, delta, normalized, vecs[ 2 ];
+ vec3_t mins, maxs, origin, faxis, size, delta, normalized, vecs[ 2 ];
vec4_t plane;
bspDrawVert_t *verts;
/* round to the lightmap resolution */
for ( i = 0; i < 3; i++ )
{
- exactSize[ i ] = lm->maxs[ i ] - lm->mins[ i ];
mins[ i ] = sampleSize * floor( lm->mins[ i ] / sampleSize );
maxs[ i ] = sampleSize * ceil( lm->maxs[ i ] / sampleSize );
size[ i ] = ( maxs[ i ] - mins[ i ] ) / sampleSize + 1.0f;
/* hack (god this sucks) */
- if ( size[ i ] > lm->customWidth || size[ i ] > lm->customHeight ) {
+ if ( size[ i ] > lm->customWidth || size[ i ] > lm->customHeight || ( lmLimitSize && size[i] > lmLimitSize ) ) {
i = -1;
sampleSize += 1.0f;
}
}
+ if ( sampleSize != lm->sampleSize && lmLimitSize == 0 ) {
+ Sys_FPrintf( SYS_VRB,"WARNING: surface at (%6.0f %6.0f %6.0f) (%6.0f %6.0f %6.0f) too large for desired samplesize/lightmapsize/lightmapscale combination, increased samplesize from %d to %d\n",
+ info->mins[0],
+ info->mins[1],
+ info->mins[2],
+ info->maxs[0],
+ info->maxs[1],
+ info->maxs[2],
+ lm->sampleSize,
+ (int) sampleSize );
+ }
+
/* set actual sample size */
lm->actualSampleSize = sampleSize;
/* check for bogus axis */
if ( faxis[ axisNum ] == 0.0f ) {
- Sys_Printf( "WARNING: ProjectSurfaceLightmap: Chose a 0 valued axis\n" );
+ Sys_FPrintf( SYS_WRN, "WARNING: ProjectSurfaceLightmap: Chose a 0 valued axis\n" );
lm->w = lm->h = 0;
return qfalse;
}
/* get surface */
num2 = lightSurfaces[ lm->firstLightSurface + n ];
ds2 = &bspDrawSurfaces[ num2 ];
- info2 = &surfaceInfos[ num2 ];
verts = &yDrawVerts[ ds2->firstVert ];
/* set the lightmap texture coordinates in yDrawVerts in [0, superSample * lm->customWidth] space */
/* get first drawsurface */
num2 = lightSurfaces[ lm->firstLightSurface ];
ds2 = &bspDrawSurfaces[ num2 ];
- info2 = &surfaceInfos[ num2 ];
verts = &yDrawVerts[ ds2->firstVert ];
/* calculate lightmap origin */
/* for planar surfaces, create lightmap vectors for st->xyz conversion */
if ( VectorLength( ds->lightmapVecs[ 2 ] ) || 1 ) { /* ydnar: can't remember what exactly i was thinking here... */
/* allocate space for the vectors */
- lm->vecs = safe_malloc( 3 * sizeof( vec3_t ) );
- memset( lm->vecs, 0, 3 * sizeof( vec3_t ) );
+ lm->vecs = safe_malloc0( 3 * sizeof( vec3_t ) );
VectorCopy( ds->lightmapVecs[ 2 ], lm->vecs[ 2 ] );
/* project stepped lightmap blocks and subtract to get planevecs */
/* get surface info */
- aInfo = &surfaceInfos[ *( (int*) a ) ];
- bInfo = &surfaceInfos[ *( (int*) b ) ];
+ aInfo = &surfaceInfos[ *( (const int*) a ) ];
+ bInfo = &surfaceInfos[ *( (const int*) b ) ];
/* model first */
- if ( aInfo->model < bInfo->model ) {
+ if ( aInfo->modelindex < bInfo->modelindex ) {
return 1;
}
- else if ( aInfo->model > bInfo->model ) {
+ else if ( aInfo->modelindex > bInfo->modelindex ) {
return -1;
}
return -1;
}
+ /* 27: then shader! */
+ if ( aInfo->si < bInfo->si ) {
+ return 1;
+ }
+ else if ( aInfo->si > bInfo->si ) {
+ return -1;
+ }
+
/* then lightmap sample size */
if ( aInfo->sampleSize < bInfo->sampleSize ) {
return 1;
int i, j, k, s,num, num2;
bspModel_t *model;
bspLeaf_t *leaf;
- bspDrawSurface_t *ds, *ds2;
+ bspDrawSurface_t *ds;
surfaceInfo_t *info, *info2;
rawLightmap_t *lm;
qboolean added;
superSample = 1;
}
else if ( superSample > 8 ) {
- Sys_Printf( "WARNING: Insane supersampling amount (%d) detected.\n", superSample );
+ Sys_FPrintf( SYS_WRN, "WARNING: Insane supersampling amount (%d) detected.\n", superSample );
superSample = 8;
}
/* allocate a list of surface clusters */
numSurfaceClusters = 0;
maxSurfaceClusters = numBSPLeafSurfaces;
- surfaceClusters = safe_malloc( maxSurfaceClusters * sizeof( *surfaceClusters ) );
- memset( surfaceClusters, 0, maxSurfaceClusters * sizeof( *surfaceClusters ) );
+ surfaceClusters = safe_malloc0( maxSurfaceClusters * sizeof( *surfaceClusters ) );
/* allocate a list for per-surface info */
- surfaceInfos = safe_malloc( numBSPDrawSurfaces * sizeof( *surfaceInfos ) );
- memset( surfaceInfos, 0, numBSPDrawSurfaces * sizeof( *surfaceInfos ) );
+ surfaceInfos = safe_malloc0( numBSPDrawSurfaces * sizeof( *surfaceInfos ) );
for ( i = 0; i < numBSPDrawSurfaces; i++ )
surfaceInfos[ i ].childSurfaceNum = -1;
/* allocate a list of surface indexes to be sorted */
- sortSurfaces = safe_malloc( numBSPDrawSurfaces * sizeof( int ) );
- memset( sortSurfaces, 0, numBSPDrawSurfaces * sizeof( int ) );
+ sortSurfaces = safe_malloc0( numBSPDrawSurfaces * sizeof( int ) );
/* walk each model in the bsp */
for ( i = 0; i < numBSPModels; i++ )
}
/* basic setup */
- info->model = model;
+ info->modelindex = i;
info->lm = NULL;
info->plane = NULL;
info->firstSurfaceCluster = numSurfaceClusters;
/* allocate a list of surfaces that would go into raw lightmaps */
numLightSurfaces = 0;
- lightSurfaces = safe_malloc( numSurfsLightmapped * sizeof( int ) );
- memset( lightSurfaces, 0, numSurfsLightmapped * sizeof( int ) );
+ lightSurfaces = safe_malloc0( numSurfsLightmapped * sizeof( int ) );
/* allocate a list of raw lightmaps */
numRawSuperLuxels = 0;
numRawLightmaps = 0;
- rawLightmaps = safe_malloc( numSurfsLightmapped * sizeof( *rawLightmaps ) );
- memset( rawLightmaps, 0, numSurfsLightmapped * sizeof( *rawLightmaps ) );
+ rawLightmaps = safe_malloc0( numSurfsLightmapped * sizeof( *rawLightmaps ) );
/* walk the list of sorted surfaces */
for ( i = 0; i < numBSPDrawSurfaces; i++ )
lm->splotchFix = info->si->splotchFix;
lm->firstLightSurface = numLightSurfaces;
lm->numLightSurfaces = 0;
- lm->sampleSize = info->sampleSize;
- lm->actualSampleSize = info->sampleSize;
+ /* vortex: multiply lightmap sample size by -samplescale */
+ if ( sampleScale > 0 ) {
+ lm->sampleSize = info->sampleSize * sampleScale;
+ }
+ else{
+ lm->sampleSize = info->sampleSize;
+ }
+ lm->actualSampleSize = lm->sampleSize;
lm->entityNum = info->entityNum;
lm->recvShadows = info->recvShadows;
lm->brightness = info->si->lmBrightness;
lm->filterRadius = info->si->lmFilterRadius;
+ VectorCopy( info->si->floodlightRGB, lm->floodlightRGB );
+ lm->floodlightDistance = info->si->floodlightDistance;
+ lm->floodlightIntensity = info->si->floodlightIntensity;
+ lm->floodlightDirectionScale = info->si->floodlightDirectionScale;
VectorCopy( info->axis, lm->axis );
lm->plane = info->plane;
VectorCopy( info->mins, lm->mins );
{
/* get info and attempt early out */
num2 = sortSurfaces[ j ];
- ds2 = &bspDrawSurfaces[ num2 ];
info2 = &surfaceInfos[ num2 ];
if ( info2->hasLightmap == qfalse || info2->lm != NULL ) {
continue;
/* allocate vertex luxel storage */
for ( k = 0; k < MAX_LIGHTMAPS; k++ )
{
- vertexLuxels[ k ] = safe_malloc( numBSPDrawVerts * VERTEX_LUXEL_SIZE * sizeof( float ) );
- memset( vertexLuxels[ k ], 0, numBSPDrawVerts * VERTEX_LUXEL_SIZE * sizeof( float ) );
- radVertexLuxels[ k ] = safe_malloc( numBSPDrawVerts * VERTEX_LUXEL_SIZE * sizeof( float ) );
- memset( radVertexLuxels[ k ], 0, numBSPDrawVerts * VERTEX_LUXEL_SIZE * sizeof( float ) );
+ vertexLuxels[ k ] = safe_malloc0( numBSPDrawVerts * VERTEX_LUXEL_SIZE * sizeof( float ) );
+ radVertexLuxels[ k ] = safe_malloc0( numBSPDrawVerts * VERTEX_LUXEL_SIZE * sizeof( float ) );
}
/* emit some stats */
numStitched, numCandidates, numLuxels, f, fOld, start;
rawLightmap_t *lm, *a, *b, *c[ MAX_STITCH_CANDIDATES ];
float *luxel, *luxel2, *origin, *origin2, *normal, *normal2,
- sampleSize, average[ 3 ], totalColor, ootc, *luxels[ MAX_STITCH_LUXELS ];
+ sampleSize, average[ 3 ], totalColor, ootc;
/* disabled for now */
/* add luxel */
//% VectorSet( luxel2, 255, 0, 255 );
- luxels[ numLuxels++ ] = luxel2;
VectorAdd( average, luxel2, average );
totalColor += luxel2[ 3 ];
}
olm->numShaders = 0;
/* allocate buffers */
- olm->lightBits = safe_malloc( ( olm->customWidth * olm->customHeight / 8 ) + 8 );
- memset( olm->lightBits, 0, ( olm->customWidth * olm->customHeight / 8 ) + 8 );
- olm->bspLightBytes = safe_malloc( olm->customWidth * olm->customHeight * 3 );
- memset( olm->bspLightBytes, 0, olm->customWidth * olm->customHeight * 3 );
+ olm->lightBits = safe_malloc0( ( olm->customWidth * olm->customHeight / 8 ) + 8 );
+ olm->bspLightBytes = safe_malloc0( olm->customWidth * olm->customHeight * 3 );
if ( deluxemap ) {
- olm->bspDirBytes = safe_malloc( olm->customWidth * olm->customHeight * 3 );
- memset( olm->bspDirBytes, 0, olm->customWidth * olm->customHeight * 3 );
+ olm->bspDirBytes = safe_malloc0( olm->customWidth * olm->customHeight * 3 );
}
}
for a given surface lightmap, find output lightmap pages and positions for it
*/
-static void FindOutLightmaps( rawLightmap_t *lm ){
- int i, j, lightmapNum, xMax, yMax, x, y, sx, sy, ox, oy, offset, temp;
+#define LIGHTMAP_RESERVE_COUNT 1
+static void FindOutLightmaps( rawLightmap_t *lm, qboolean fastAllocate ){
+ int i, j, k, lightmapNum, xMax, yMax, x = -1, y = -1, sx, sy, ox, oy, offset;
outLightmap_t *olm;
surfaceInfo_t *info;
float *luxel, *deluxel;
vec3_t color, direction;
byte *pixel;
qboolean ok;
-
+ int xIncrement, yIncrement;
/* set default lightmap number (-3 = LIGHTMAP_BY_VERTEX) */
for ( lightmapNum = 0; lightmapNum < MAX_LIGHTMAPS; lightmapNum++ )
y = 0;
/* walk the list of lightmap pages */
- for ( i = 0; i < numOutLightmaps; i++ )
+ if ( lightmapSearchBlockSize <= 0 || numOutLightmaps < LIGHTMAP_RESERVE_COUNT ) {
+ i = 0;
+ }
+ else{
+ i = ( ( numOutLightmaps - LIGHTMAP_RESERVE_COUNT ) / lightmapSearchBlockSize ) * lightmapSearchBlockSize;
+ }
+ for ( ; i < numOutLightmaps; i++ )
{
/* get the output lightmap */
olm = &outLightmaps[ i ];
continue;
}
+ /* if fast allocation, skip lightmap files that are more than 90% complete */
+ if ( fastAllocate == qtrue ) {
+ if (olm->freeLuxels < (olm->customWidth * olm->customHeight) / 10) {
+ continue;
+ }
+ }
+
/* don't store non-custom raw lightmaps on custom bsp lightmaps */
if ( olm->customWidth != lm->customWidth ||
olm->customHeight != lm->customHeight ) {
yMax = ( olm->customHeight - lm->h ) + 1;
}
+ /* if fast allocation, do not test allocation on every pixels, especially for large lightmaps */
+ if ( fastAllocate == qtrue ) {
+ xIncrement = MAX(1, lm->w / 15);
+ yIncrement = MAX(1, lm->h / 15);
+ }
+ else {
+ xIncrement = 1;
+ yIncrement = 1;
+ }
+
/* walk the origin around the lightmap */
- for ( y = 0; y < yMax; y++ )
+ for ( y = 0; y < yMax; y += yIncrement )
{
- for ( x = 0; x < xMax; x++ )
+ for ( x = 0; x < xMax; x += xIncrement )
{
/* find a fine tract of lauhnd */
ok = TestOutLightmapStamp( lm, lightmapNum, olm, x, y );
/* no match? */
if ( ok == qfalse ) {
- /* allocate two new output lightmaps */
- numOutLightmaps += 2;
+ /* allocate LIGHTMAP_RESERVE_COUNT new output lightmaps */
+ numOutLightmaps += LIGHTMAP_RESERVE_COUNT;
olm = safe_malloc( numOutLightmaps * sizeof( outLightmap_t ) );
- if ( outLightmaps != NULL && numOutLightmaps > 2 ) {
- memcpy( olm, outLightmaps, ( numOutLightmaps - 2 ) * sizeof( outLightmap_t ) );
+ if ( outLightmaps != NULL && numOutLightmaps > LIGHTMAP_RESERVE_COUNT ) {
+ memcpy( olm, outLightmaps, ( numOutLightmaps - LIGHTMAP_RESERVE_COUNT ) * sizeof( outLightmap_t ) );
free( outLightmaps );
}
outLightmaps = olm;
/* initialize both out lightmaps */
- SetupOutLightmap( lm, &outLightmaps[ numOutLightmaps - 2 ] );
- SetupOutLightmap( lm, &outLightmaps[ numOutLightmaps - 1 ] );
+ for ( k = numOutLightmaps - LIGHTMAP_RESERVE_COUNT; k < numOutLightmaps; ++k )
+ SetupOutLightmap( lm, &outLightmaps[ k ] );
/* set out lightmap */
- i = numOutLightmaps - 2;
+ i = numOutLightmaps - LIGHTMAP_RESERVE_COUNT;
olm = &outLightmaps[ i ];
/* set stamp xy origin to the first surface lightmap */
/* store direction */
if ( deluxemap ) {
/* normalize average light direction */
- if ( VectorNormalize( deluxel, direction ) ) {
- /* encode [-1,1] in [0,255] */
- pixel = olm->bspDirBytes + ( ( ( oy * olm->customWidth ) + ox ) * 3 );
- for ( i = 0; i < 3; i++ )
- {
- temp = ( direction[ i ] + 1.0f ) * 127.5f;
- if ( temp < 0 ) {
- pixel[ i ] = 0;
- }
- else if ( temp > 255 ) {
- pixel[ i ] = 255;
- }
- else{
- pixel[ i ] = temp;
- }
- }
- }
+ pixel = olm->bspDirBytes + ( ( ( oy * olm->customWidth ) + ox ) * 3 );
+ VectorScale( deluxel, 1000.0f, direction );
+ VectorNormalize( direction, direction );
+ VectorScale( direction, 127.5f, direction );
+ for ( i = 0; i < 3; i++ )
+ pixel[ i ] = (byte)( 127.5f + direction[ i ] );
}
}
}
/* get lightmaps */
- alm = &rawLightmaps[ *( (int*) a ) ];
- blm = &rawLightmaps[ *( (int*) b ) ];
+ alm = &rawLightmaps[ *( (const int*) a ) ];
+ blm = &rawLightmaps[ *( (const int*) b ) ];
/* get min number of surfaces */
min = ( alm->numLightSurfaces < blm->numLightSurfaces ? alm->numLightSurfaces : blm->numLightSurfaces );
+void FillOutLightmap( outLightmap_t *olm ){
+ int x, y;
+ int ofs;
+ vec3_t dir_sum, light_sum;
+ int cnt, filled;
+ byte *lightBitsNew = NULL;
+ byte *lightBytesNew = NULL;
+ byte *dirBytesNew = NULL;
+
+ lightBitsNew = safe_malloc( ( olm->customWidth * olm->customHeight + 8 ) / 8 );
+ lightBytesNew = safe_malloc( olm->customWidth * olm->customHeight * 3 );
+ if ( deluxemap ) {
+ dirBytesNew = safe_malloc( olm->customWidth * olm->customHeight * 3 );
+ }
+
+ /*
+ memset(olm->lightBits, 0, (olm->customWidth * olm->customHeight + 8) / 8);
+ olm->lightBits[0] |= 1;
+ olm->lightBits[(10 * olm->customWidth + 30) >> 3] |= 1 << ((10 * olm->customWidth + 30) & 7);
+ memset(olm->bspLightBytes, 0, olm->customWidth * olm->customHeight * 3);
+ olm->bspLightBytes[0] = 255;
+ olm->bspLightBytes[(10 * olm->customWidth + 30) * 3 + 2] = 255;
+ */
+
+ memcpy( lightBitsNew, olm->lightBits, ( olm->customWidth * olm->customHeight + 8 ) / 8 );
+ memcpy( lightBytesNew, olm->bspLightBytes, olm->customWidth * olm->customHeight * 3 );
+ if ( deluxemap ) {
+ memcpy( dirBytesNew, olm->bspDirBytes, olm->customWidth * olm->customHeight * 3 );
+ }
+
+ for (;; )
+ {
+ filled = 0;
+ for ( y = 0; y < olm->customHeight; ++y )
+ {
+ for ( x = 0; x < olm->customWidth; ++x )
+ {
+ ofs = y * olm->customWidth + x;
+ if ( olm->lightBits[ofs >> 3] & ( 1 << ( ofs & 7 ) ) ) { /* already filled */
+ continue;
+ }
+ cnt = 0;
+ VectorClear( dir_sum );
+ VectorClear( light_sum );
+
+ /* try all four neighbors */
+ ofs = ( ( y + olm->customHeight - 1 ) % olm->customHeight ) * olm->customWidth + x;
+ if ( olm->lightBits[ofs >> 3] & ( 1 << ( ofs & 7 ) ) ) { /* already filled */
+ ++cnt;
+ VectorAdd( light_sum, olm->bspLightBytes + ofs * 3, light_sum );
+ if ( deluxemap ) {
+ VectorAdd( dir_sum, olm->bspDirBytes + ofs * 3, dir_sum );
+ }
+ }
+
+ ofs = ( ( y + 1 ) % olm->customHeight ) * olm->customWidth + x;
+ if ( olm->lightBits[ofs >> 3] & ( 1 << ( ofs & 7 ) ) ) { /* already filled */
+ ++cnt;
+ VectorAdd( light_sum, olm->bspLightBytes + ofs * 3, light_sum );
+ if ( deluxemap ) {
+ VectorAdd( dir_sum, olm->bspDirBytes + ofs * 3, dir_sum );
+ }
+ }
+
+ ofs = y * olm->customWidth + ( x + olm->customWidth - 1 ) % olm->customWidth;
+ if ( olm->lightBits[ofs >> 3] & ( 1 << ( ofs & 7 ) ) ) { /* already filled */
+ ++cnt;
+ VectorAdd( light_sum, olm->bspLightBytes + ofs * 3, light_sum );
+ if ( deluxemap ) {
+ VectorAdd( dir_sum, olm->bspDirBytes + ofs * 3, dir_sum );
+ }
+ }
+
+ ofs = y * olm->customWidth + ( x + 1 ) % olm->customWidth;
+ if ( olm->lightBits[ofs >> 3] & ( 1 << ( ofs & 7 ) ) ) { /* already filled */
+ ++cnt;
+ VectorAdd( light_sum, olm->bspLightBytes + ofs * 3, light_sum );
+ if ( deluxemap ) {
+ VectorAdd( dir_sum, olm->bspDirBytes + ofs * 3, dir_sum );
+ }
+ }
+
+ if ( cnt ) {
+ ++filled;
+ ofs = y * olm->customWidth + x;
+ lightBitsNew[ofs >> 3] |= ( 1 << ( ofs & 7 ) );
+ VectorScale( light_sum, 1.0 / cnt, lightBytesNew + ofs * 3 );
+ if ( deluxemap ) {
+ VectorScale( dir_sum, 1.0 / cnt, dirBytesNew + ofs * 3 );
+ }
+ }
+ }
+ }
+
+ if ( !filled ) {
+ break;
+ }
+
+ memcpy( olm->lightBits, lightBitsNew, ( olm->customWidth * olm->customHeight + 8 ) / 8 );
+ memcpy( olm->bspLightBytes, lightBytesNew, olm->customWidth * olm->customHeight * 3 );
+ if ( deluxemap ) {
+ memcpy( olm->bspDirBytes, dirBytesNew, olm->customWidth * olm->customHeight * 3 );
+ }
+ }
+
+ free( lightBitsNew );
+ free( lightBytesNew );
+ if ( deluxemap ) {
+ free( dirBytesNew );
+ }
+}
+
+
+
/*
StoreSurfaceLightmaps()
stores the surface lightmaps into the bsp as byte rgb triplets
*/
-void StoreSurfaceLightmaps( void ){
+void StoreSurfaceLightmaps( qboolean fastAllocate, qboolean storeForReal ){
int i, j, k, x, y, lx, ly, sx, sy, *cluster, mappedSamples;
int style, size, lightmapNum, lightmapNum2;
float *normal, *luxel, *bspLuxel, *bspLuxel2, *radLuxel, samples, occludedSamples;
char dirname[ 1024 ], filename[ 1024 ];
shaderInfo_t *csi;
char lightmapName[ 128 ];
- char *rgbGenValues[ 256 ];
- char *alphaGenValues[ 256 ];
+ const char *rgbGenValues[ 256 ];
+ const char *alphaGenValues[ 256 ];
/* note it */
Sys_Printf( "--- StoreSurfaceLightmaps ---\n" );
/* setup */
- strcpy( dirname, source );
- StripExtension( dirname );
+ if ( lmCustomDir ) {
+ strcpy( dirname, lmCustomDir );
+ }
+ else
+ {
+ strcpy( dirname, source );
+ StripExtension( dirname );
+ }
memset( rgbGenValues, 0, sizeof( rgbGenValues ) );
memset( alphaGenValues, 0, sizeof( alphaGenValues ) );
/* allocate bsp luxel storage */
if ( lm->bspLuxels[ lightmapNum ] == NULL ) {
size = lm->w * lm->h * BSP_LUXEL_SIZE * sizeof( float );
- lm->bspLuxels[ lightmapNum ] = safe_malloc( size );
- memset( lm->bspLuxels[ lightmapNum ], 0, size );
+ lm->bspLuxels[ lightmapNum ] = safe_malloc0( size );
}
/* allocate radiosity lightmap storage */
}
}
+ /* -----------------------------------------------------------------
+ convert modelspace deluxemaps to tangentspace
+ ----------------------------------------------------------------- */
+ /* note it */
+ if ( !bouncing ) {
+ if ( deluxemap && deluxemode == 1 ) {
+ vec3_t worldUp, myNormal, myTangent, myBinormal;
+ float dist;
+
+ Sys_Printf( "converting..." );
+
+ for ( i = 0; i < numRawLightmaps; i++ )
+ {
+ /* get lightmap */
+ lm = &rawLightmaps[ i ];
+
+ /* walk lightmap samples */
+ for ( y = 0; y < lm->sh; y++ )
+ {
+ for ( x = 0; x < lm->sw; x++ )
+ {
+ /* get normal and deluxel */
+ normal = SUPER_NORMAL( x, y );
+ cluster = SUPER_CLUSTER( x, y );
+ bspDeluxel = BSP_DELUXEL( x, y );
+ deluxel = SUPER_DELUXEL( x, y );
+
+ /* get normal */
+ VectorSet( myNormal, normal[0], normal[1], normal[2] );
+
+ /* get tangent vectors */
+ if ( myNormal[ 0 ] == 0.0f && myNormal[ 1 ] == 0.0f ) {
+ if ( myNormal[ 2 ] == 1.0f ) {
+ VectorSet( myTangent, 1.0f, 0.0f, 0.0f );
+ VectorSet( myBinormal, 0.0f, 1.0f, 0.0f );
+ }
+ else if ( myNormal[ 2 ] == -1.0f ) {
+ VectorSet( myTangent, -1.0f, 0.0f, 0.0f );
+ VectorSet( myBinormal, 0.0f, 1.0f, 0.0f );
+ }
+ }
+ else
+ {
+ VectorSet( worldUp, 0.0f, 0.0f, 1.0f );
+ CrossProduct( myNormal, worldUp, myTangent );
+ VectorNormalize( myTangent, myTangent );
+ CrossProduct( myTangent, myNormal, myBinormal );
+ VectorNormalize( myBinormal, myBinormal );
+ }
+
+ /* project onto plane */
+ dist = -DotProduct( myTangent, myNormal );
+ VectorMA( myTangent, dist, myNormal, myTangent );
+ dist = -DotProduct( myBinormal, myNormal );
+ VectorMA( myBinormal, dist, myNormal, myBinormal );
+
+ /* renormalize */
+ VectorNormalize( myTangent, myTangent );
+ VectorNormalize( myBinormal, myBinormal );
+
+ /* convert modelspace deluxel to tangentspace */
+ dirSample[0] = bspDeluxel[0];
+ dirSample[1] = bspDeluxel[1];
+ dirSample[2] = bspDeluxel[2];
+ VectorNormalize( dirSample, dirSample );
+
+ /* fix tangents to world matrix */
+ if ( myNormal[0] > 0 || myNormal[1] < 0 || myNormal[2] < 0 ) {
+ VectorNegate( myTangent, myTangent );
+ }
+
+ /* build tangentspace vectors */
+ bspDeluxel[0] = DotProduct( dirSample, myTangent );
+ bspDeluxel[1] = DotProduct( dirSample, myBinormal );
+ bspDeluxel[2] = DotProduct( dirSample, myNormal );
+ }
+ }
+ }
+ }
+ }
+
+ /* -----------------------------------------------------------------
+ blend lightmaps
+ ----------------------------------------------------------------- */
+
+#ifdef sdfsdfwq312323
+ /* note it */
+ Sys_Printf( "blending..." );
+
+ for ( i = 0; i < numRawLightmaps; i++ )
+ {
+ vec3_t myColor;
+ float myBrightness;
+
+ /* get lightmap */
+ lm = &rawLightmaps[ i ];
+
+ /* walk individual lightmaps */
+ for ( lightmapNum = 0; lightmapNum < MAX_LIGHTMAPS; lightmapNum++ )
+ {
+ /* early outs */
+ if ( lm->superLuxels[ lightmapNum ] == NULL ) {
+ continue;
+ }
+
+ /* walk lightmap samples */
+ for ( y = 0; y < lm->sh; y++ )
+ {
+ for ( x = 0; x < lm->sw; x++ )
+ {
+ /* get luxel */
+ bspLuxel = BSP_LUXEL( lightmapNum, x, y );
+
+ /* get color */
+ VectorNormalize( bspLuxel, myColor );
+ myBrightness = VectorLength( bspLuxel );
+ myBrightness *= ( 1 / 127.0f );
+ myBrightness = myBrightness * myBrightness;
+ myBrightness *= 127.0f;
+ VectorScale( myColor, myBrightness, bspLuxel );
+ }
+ }
+ }
+ }
+#endif
+
/* -----------------------------------------------------------------
collapse non-unique lightmaps
----------------------------------------------------------------- */
- if ( noCollapse == qfalse && deluxemap == qfalse ) {
+ if ( storeForReal && noCollapse == qfalse && deluxemap == qfalse ) {
/* note it */
Sys_FPrintf( SYS_VRB, "collapsing..." );
allocate output lightmaps
----------------------------------------------------------------- */
- /* note it */
- Sys_FPrintf( SYS_VRB, "allocating..." );
+ if ( storeForReal ) {
+ /* note it */
+ Sys_FPrintf( SYS_VRB, "allocating..." );
- /* kill all existing output lightmaps */
- if ( outLightmaps != NULL ) {
- for ( i = 0; i < numOutLightmaps; i++ )
- {
- free( outLightmaps[ i ].lightBits );
- free( outLightmaps[ i ].bspLightBytes );
+ /* kill all existing output lightmaps */
+ if ( outLightmaps != NULL ) {
+ for ( i = 0; i < numOutLightmaps; i++ )
+ {
+ free( outLightmaps[ i ].lightBits );
+ free( outLightmaps[ i ].bspLightBytes );
+ }
+ free( outLightmaps );
+ outLightmaps = NULL;
}
- free( outLightmaps );
- outLightmaps = NULL;
- }
- numLightmapShaders = 0;
- numOutLightmaps = 0;
- numBSPLightmaps = 0;
- numExtLightmaps = 0;
+ numLightmapShaders = 0;
+ numOutLightmaps = 0;
+ numBSPLightmaps = 0;
+ numExtLightmaps = 0;
- /* find output lightmap */
- for ( i = 0; i < numRawLightmaps; i++ )
- {
- lm = &rawLightmaps[ sortLightmaps[ i ] ];
- FindOutLightmaps( lm );
- }
-
- /* set output numbers in twinned lightmaps */
- for ( i = 0; i < numRawLightmaps; i++ )
- {
- /* get lightmap */
- lm = &rawLightmaps[ sortLightmaps[ i ] ];
+ /* find output lightmap */
+ for ( i = 0; i < numRawLightmaps; i++ )
+ {
+ lm = &rawLightmaps[ sortLightmaps[ i ] ];
+ FindOutLightmaps( lm, fastAllocate );
+ }
- /* walk lightmaps */
- for ( lightmapNum = 0; lightmapNum < MAX_LIGHTMAPS; lightmapNum++ )
+ /* set output numbers in twinned lightmaps */
+ for ( i = 0; i < numRawLightmaps; i++ )
{
- /* get twin */
- lm2 = lm->twins[ lightmapNum ];
- if ( lm2 == NULL ) {
- continue;
- }
- lightmapNum2 = lm->twinNums[ lightmapNum ];
+ /* get lightmap */
+ lm = &rawLightmaps[ sortLightmaps[ i ] ];
+
+ /* walk lightmaps */
+ for ( lightmapNum = 0; lightmapNum < MAX_LIGHTMAPS; lightmapNum++ )
+ {
+ /* get twin */
+ lm2 = lm->twins[ lightmapNum ];
+ if ( lm2 == NULL ) {
+ continue;
+ }
+ lightmapNum2 = lm->twinNums[ lightmapNum ];
- /* find output lightmap from twin */
- lm->outLightmapNums[ lightmapNum ] = lm2->outLightmapNums[ lightmapNum2 ];
- lm->lightmapX[ lightmapNum ] = lm2->lightmapX[ lightmapNum2 ];
- lm->lightmapY[ lightmapNum ] = lm2->lightmapY[ lightmapNum2 ];
+ /* find output lightmap from twin */
+ lm->outLightmapNums[ lightmapNum ] = lm2->outLightmapNums[ lightmapNum2 ];
+ lm->lightmapX[ lightmapNum ] = lm2->lightmapX[ lightmapNum2 ];
+ lm->lightmapY[ lightmapNum ] = lm2->lightmapY[ lightmapNum2 ];
+ }
}
}
store output lightmaps
----------------------------------------------------------------- */
- /* note it */
- Sys_FPrintf( SYS_VRB, "storing..." );
-
- /* count the bsp lightmaps and allocate space */
- if ( bspLightBytes != NULL ) {
- free( bspLightBytes );
- }
- if ( numBSPLightmaps == 0 || externalLightmaps ) {
- numBSPLightBytes = 0;
- bspLightBytes = NULL;
- }
- else
- {
- numBSPLightBytes = ( numBSPLightmaps * game->lightmapSize * game->lightmapSize * 3 );
- bspLightBytes = safe_malloc( numBSPLightBytes );
- memset( bspLightBytes, 0, numBSPLightBytes );
- }
+ if ( storeForReal ) {
+ /* note it */
+ Sys_FPrintf( SYS_VRB, "storing..." );
- /* walk the list of output lightmaps */
- for ( i = 0; i < numOutLightmaps; i++ )
- {
- /* get output lightmap */
- olm = &outLightmaps[ i ];
+ /* count the bsp lightmaps and allocate space */
+ if ( bspLightBytes != NULL ) {
+ free( bspLightBytes );
+ }
+ if ( numBSPLightmaps == 0 || externalLightmaps ) {
+ numBSPLightBytes = 0;
+ bspLightBytes = NULL;
+ }
+ else
+ {
+ numBSPLightBytes = ( numBSPLightmaps * game->lightmapSize * game->lightmapSize * 3 );
+ bspLightBytes = safe_malloc0( numBSPLightBytes );
+ }
- /* is this a valid bsp lightmap? */
- if ( olm->lightmapNum >= 0 && !externalLightmaps ) {
- /* copy lighting data */
- lb = bspLightBytes + ( olm->lightmapNum * game->lightmapSize * game->lightmapSize * 3 );
- memcpy( lb, olm->bspLightBytes, game->lightmapSize * game->lightmapSize * 3 );
+ /* walk the list of output lightmaps */
+ for ( i = 0; i < numOutLightmaps; i++ )
+ {
+ /* get output lightmap */
+ olm = &outLightmaps[ i ];
- /* copy direction data */
- if ( deluxemap ) {
- lb = bspLightBytes + ( ( olm->lightmapNum + 1 ) * game->lightmapSize * game->lightmapSize * 3 );
- memcpy( lb, olm->bspDirBytes, game->lightmapSize * game->lightmapSize * 3 );
+ /* fill output lightmap */
+ if ( lightmapFill ) {
+ FillOutLightmap( olm );
}
- }
- /* external lightmap? */
- if ( olm->lightmapNum < 0 || olm->extLightmapNum >= 0 || externalLightmaps ) {
- /* make a directory for the lightmaps */
- Q_mkdir( dirname );
+ /* is this a valid bsp lightmap? */
+ if ( olm->lightmapNum >= 0 && !externalLightmaps ) {
+ /* copy lighting data */
+ lb = bspLightBytes + ( olm->lightmapNum * game->lightmapSize * game->lightmapSize * 3 );
+ memcpy( lb, olm->bspLightBytes, game->lightmapSize * game->lightmapSize * 3 );
+
+ /* copy direction data */
+ if ( deluxemap ) {
+ lb = bspLightBytes + ( ( olm->lightmapNum + 1 ) * game->lightmapSize * game->lightmapSize * 3 );
+ memcpy( lb, olm->bspDirBytes, game->lightmapSize * game->lightmapSize * 3 );
+ }
+ }
- /* set external lightmap number */
- olm->extLightmapNum = numExtLightmaps;
+ /* external lightmap? */
+ if ( olm->lightmapNum < 0 || olm->extLightmapNum >= 0 || externalLightmaps ) {
+ /* make a directory for the lightmaps */
+ Q_mkdir( dirname );
- /* write lightmap */
- sprintf( filename, "%s/" EXTERNAL_LIGHTMAP, dirname, numExtLightmaps );
- Sys_FPrintf( SYS_VRB, "\nwriting %s", filename );
- WriteTGA24( filename, olm->bspLightBytes, olm->customWidth, olm->customHeight, qtrue );
- numExtLightmaps++;
+ /* set external lightmap number */
+ olm->extLightmapNum = numExtLightmaps;
- /* write deluxemap */
- if ( deluxemap ) {
+ /* write lightmap */
sprintf( filename, "%s/" EXTERNAL_LIGHTMAP, dirname, numExtLightmaps );
Sys_FPrintf( SYS_VRB, "\nwriting %s", filename );
- WriteTGA24( filename, olm->bspDirBytes, olm->customWidth, olm->customHeight, qtrue );
+ WriteTGA24( filename, olm->bspLightBytes, olm->customWidth, olm->customHeight, qtrue );
numExtLightmaps++;
- if ( debugDeluxemap ) {
- olm->extLightmapNum++;
+ /* write deluxemap */
+ if ( deluxemap ) {
+ sprintf( filename, "%s/" EXTERNAL_LIGHTMAP, dirname, numExtLightmaps );
+ Sys_FPrintf( SYS_VRB, "\nwriting %s", filename );
+ WriteTGA24( filename, olm->bspDirBytes, olm->customWidth, olm->customHeight, qtrue );
+ numExtLightmaps++;
+
+ if ( debugDeluxemap ) {
+ olm->extLightmapNum++;
+ }
}
}
}
- }
- if ( numExtLightmaps > 0 ) {
- Sys_FPrintf( SYS_VRB, "\n" );
- }
-
- /* delete unused external lightmaps */
- for ( i = numExtLightmaps; i; i++ )
- {
- /* determine if file exists */
- sprintf( filename, "%s/" EXTERNAL_LIGHTMAP, dirname, i );
- if ( !FileExists( filename ) ) {
- break;
+ if ( numExtLightmaps > 0 ) {
+ Sys_FPrintf( SYS_VRB, "\n" );
}
- /* delete it */
- remove( filename );
+ /* delete unused external lightmaps */
+ for ( i = numExtLightmaps; i; i++ )
+ {
+ /* determine if file exists */
+ sprintf( filename, "%s/" EXTERNAL_LIGHTMAP, dirname, i );
+ if ( !FileExists( filename ) ) {
+ break;
+ }
+
+ /* delete it */
+ remove( filename );
+ }
}
/* -----------------------------------------------------------------
project the lightmaps onto the bsp surfaces
----------------------------------------------------------------- */
- /* note it */
- Sys_FPrintf( SYS_VRB, "projecting..." );
+ if ( storeForReal ) {
+ /* note it */
+ Sys_FPrintf( SYS_VRB, "projecting..." );
- /* walk the list of surfaces */
- for ( i = 0; i < numBSPDrawSurfaces; i++ )
- {
- /* get the surface and info */
- ds = &bspDrawSurfaces[ i ];
- info = &surfaceInfos[ i ];
- lm = info->lm;
- olm = NULL;
-
- /* handle surfaces with identical parent */
- if ( info->parentSurfaceNum >= 0 ) {
- /* preserve original data and get parent */
- parent = &bspDrawSurfaces[ info->parentSurfaceNum ];
- memcpy( &dsTemp, ds, sizeof( *ds ) );
-
- /* overwrite child with parent data */
- memcpy( ds, parent, sizeof( *ds ) );
-
- /* restore key parts */
- ds->fogNum = dsTemp.fogNum;
- ds->firstVert = dsTemp.firstVert;
- ds->firstIndex = dsTemp.firstIndex;
- memcpy( ds->lightmapVecs, dsTemp.lightmapVecs, sizeof( dsTemp.lightmapVecs ) );
-
- /* set vertex data */
- dv = &bspDrawVerts[ ds->firstVert ];
- dvParent = &bspDrawVerts[ parent->firstVert ];
- for ( j = 0; j < ds->numVerts; j++ )
- {
- memcpy( dv[ j ].lightmap, dvParent[ j ].lightmap, sizeof( dv[ j ].lightmap ) );
- memcpy( dv[ j ].color, dvParent[ j ].color, sizeof( dv[ j ].color ) );
- }
+ /* walk the list of surfaces */
+ for ( i = 0; i < numBSPDrawSurfaces; i++ )
+ {
+ /* get the surface and info */
+ ds = &bspDrawSurfaces[ i ];
+ info = &surfaceInfos[ i ];
+ lm = info->lm;
+ olm = NULL;
- /* skip the rest */
- continue;
- }
+ /* handle surfaces with identical parent */
+ if ( info->parentSurfaceNum >= 0 ) {
+ /* preserve original data and get parent */
+ parent = &bspDrawSurfaces[ info->parentSurfaceNum ];
+ memcpy( &dsTemp, ds, sizeof( *ds ) );
- /* handle vertex lit or approximated surfaces */
- else if ( lm == NULL || lm->outLightmapNums[ 0 ] < 0 ) {
- for ( lightmapNum = 0; lightmapNum < MAX_LIGHTMAPS; lightmapNum++ )
- {
- ds->lightmapNum[ lightmapNum ] = -3;
- ds->lightmapStyles[ lightmapNum ] = ds->vertexStyles[ lightmapNum ];
- }
- }
+ /* overwrite child with parent data */
+ memcpy( ds, parent, sizeof( *ds ) );
- /* handle lightmapped surfaces */
- else
- {
- /* walk lightmaps */
- for ( lightmapNum = 0; lightmapNum < MAX_LIGHTMAPS; lightmapNum++ )
- {
- /* set style */
- ds->lightmapStyles[ lightmapNum ] = lm->styles[ lightmapNum ];
+ /* restore key parts */
+ ds->fogNum = dsTemp.fogNum;
+ ds->firstVert = dsTemp.firstVert;
+ ds->firstIndex = dsTemp.firstIndex;
+ memcpy( ds->lightmapVecs, dsTemp.lightmapVecs, sizeof( dsTemp.lightmapVecs ) );
+
+ /* set vertex data */
+ dv = &bspDrawVerts[ ds->firstVert ];
+ dvParent = &bspDrawVerts[ parent->firstVert ];
+ for ( j = 0; j < ds->numVerts; j++ )
+ {
+ memcpy( dv[ j ].lightmap, dvParent[ j ].lightmap, sizeof( dv[ j ].lightmap ) );
+ memcpy( dv[ j ].color, dvParent[ j ].color, sizeof( dv[ j ].color ) );
+ }
- /* handle unused style */
- if ( lm->styles[ lightmapNum ] == LS_NONE || lm->outLightmapNums[ lightmapNum ] < 0 ) {
+ /* skip the rest */
+ continue;
+ }
+
+ /* handle vertex lit or approximated surfaces */
+ else if ( lm == NULL || lm->outLightmapNums[ 0 ] < 0 ) {
+ for ( lightmapNum = 0; lightmapNum < MAX_LIGHTMAPS; lightmapNum++ )
+ {
ds->lightmapNum[ lightmapNum ] = -3;
- continue;
+ ds->lightmapStyles[ lightmapNum ] = ds->vertexStyles[ lightmapNum ];
}
+ }
- /* get output lightmap */
- olm = &outLightmaps[ lm->outLightmapNums[ lightmapNum ] ];
+ /* handle lightmapped surfaces */
+ else
+ {
+ /* walk lightmaps */
+ for ( lightmapNum = 0; lightmapNum < MAX_LIGHTMAPS; lightmapNum++ )
+ {
+ /* set style */
+ ds->lightmapStyles[ lightmapNum ] = lm->styles[ lightmapNum ];
- /* set bsp lightmap number */
- ds->lightmapNum[ lightmapNum ] = olm->lightmapNum;
+ /* handle unused style */
+ if ( lm->styles[ lightmapNum ] == LS_NONE || lm->outLightmapNums[ lightmapNum ] < 0 ) {
+ ds->lightmapNum[ lightmapNum ] = -3;
+ continue;
+ }
- /* deluxemap debugging makes the deluxemap visible */
- if ( deluxemap && debugDeluxemap && lightmapNum == 0 ) {
- ds->lightmapNum[ lightmapNum ]++;
- }
+ /* get output lightmap */
+ olm = &outLightmaps[ lm->outLightmapNums[ lightmapNum ] ];
- /* calc lightmap origin in texture space */
- lmx = (float) lm->lightmapX[ lightmapNum ] / (float) olm->customWidth;
- lmy = (float) lm->lightmapY[ lightmapNum ] / (float) olm->customHeight;
+ /* set bsp lightmap number */
+ ds->lightmapNum[ lightmapNum ] = olm->lightmapNum;
- /* calc lightmap st coords */
- dv = &bspDrawVerts[ ds->firstVert ];
- ydv = &yDrawVerts[ ds->firstVert ];
- for ( j = 0; j < ds->numVerts; j++ )
- {
- if ( lm->solid[ lightmapNum ] ) {
- dv[ j ].lightmap[ lightmapNum ][ 0 ] = lmx + ( 0.5f / (float) olm->customWidth );
- dv[ j ].lightmap[ lightmapNum ][ 1 ] = lmy + ( 0.5f / (float) olm->customWidth );
+ /* deluxemap debugging makes the deluxemap visible */
+ if ( deluxemap && debugDeluxemap && lightmapNum == 0 ) {
+ ds->lightmapNum[ lightmapNum ]++;
}
- else
+
+ /* calc lightmap origin in texture space */
+ lmx = (float) lm->lightmapX[ lightmapNum ] / (float) olm->customWidth;
+ lmy = (float) lm->lightmapY[ lightmapNum ] / (float) olm->customHeight;
+
+ /* calc lightmap st coords */
+ dv = &bspDrawVerts[ ds->firstVert ];
+ ydv = &yDrawVerts[ ds->firstVert ];
+ for ( j = 0; j < ds->numVerts; j++ )
{
- dv[ j ].lightmap[ lightmapNum ][ 0 ] = lmx + ( ydv[ j ].lightmap[ 0 ][ 0 ] / ( superSample * olm->customWidth ) );
- dv[ j ].lightmap[ lightmapNum ][ 1 ] = lmy + ( ydv[ j ].lightmap[ 0 ][ 1 ] / ( superSample * olm->customHeight ) );
+ if ( lm->solid[ lightmapNum ] ) {
+ dv[ j ].lightmap[ lightmapNum ][ 0 ] = lmx + ( 0.5f / (float) olm->customWidth );
+ dv[ j ].lightmap[ lightmapNum ][ 1 ] = lmy + ( 0.5f / (float) olm->customWidth );
+ }
+ else
+ {
+ dv[ j ].lightmap[ lightmapNum ][ 0 ] = lmx + ( ydv[ j ].lightmap[ 0 ][ 0 ] / ( superSample * olm->customWidth ) );
+ dv[ j ].lightmap[ lightmapNum ][ 1 ] = lmy + ( ydv[ j ].lightmap[ 0 ][ 1 ] / ( superSample * olm->customHeight ) );
+ }
}
}
}
- }
- /* store vertex colors */
- dv = &bspDrawVerts[ ds->firstVert ];
- for ( j = 0; j < ds->numVerts; j++ )
- {
- /* walk lightmaps */
- for ( lightmapNum = 0; lightmapNum < MAX_LIGHTMAPS; lightmapNum++ )
+ /* store vertex colors */
+ dv = &bspDrawVerts[ ds->firstVert ];
+ for ( j = 0; j < ds->numVerts; j++ )
{
- /* handle unused style */
- if ( ds->vertexStyles[ lightmapNum ] == LS_NONE ) {
- VectorClear( color );
- }
- else
+ /* walk lightmaps */
+ for ( lightmapNum = 0; lightmapNum < MAX_LIGHTMAPS; lightmapNum++ )
{
- /* get vertex color */
- luxel = VERTEX_LUXEL( lightmapNum, ds->firstVert + j );
- VectorCopy( luxel, color );
+ /* handle unused style */
+ if ( ds->vertexStyles[ lightmapNum ] == LS_NONE ) {
+ VectorClear( color );
+ }
+ else
+ {
+ /* get vertex color */
+ luxel = VERTEX_LUXEL( lightmapNum, ds->firstVert + j );
+ VectorCopy( luxel, color );
- /* set minimum light */
- if ( lightmapNum == 0 ) {
- for ( k = 0; k < 3; k++ )
- if ( color[ k ] < minVertexLight[ k ] ) {
- color[ k ] = minVertexLight[ k ];
- }
+ /* set minimum light */
+ if ( lightmapNum == 0 ) {
+ for ( k = 0; k < 3; k++ )
+ if ( color[ k ] < minVertexLight[ k ] ) {
+ color[ k ] = minVertexLight[ k ];
+ }
+ }
}
- }
- /* store to bytes */
- if ( !info->si->noVertexLight ) {
- ColorToBytes( color, dv[ j ].color[ lightmapNum ], info->si->vertexScale );
+ /* store to bytes */
+ if ( !info->si->noVertexLight ) {
+ ColorToBytes( color, dv[ j ].color[ lightmapNum ], info->si->vertexScale );
+ }
}
}
- }
-
- /* surfaces with styled lightmaps and a style marker get a custom generated shader (fixme: make this work with external lightmaps) */
- if ( olm != NULL && lm != NULL && lm->styles[ 1 ] != LS_NONE && game->load != LoadRBSPFile ) { //% info->si->styleMarker > 0 )
- qboolean dfEqual;
- char key[ 32 ], styleStage[ 512 ], styleStages[ 4096 ], rgbGen[ 128 ], alphaGen[ 128 ];
+ /* surfaces with styled lightmaps and a style marker get a custom generated shader (fixme: make this work with external lightmaps) */
+ if ( olm != NULL && lm != NULL && lm->styles[ 1 ] != LS_NONE && game->load != LoadRBSPFile ) { //% info->si->styleMarker > 0 )
+ qboolean dfEqual;
+ char key[ 32 ], styleStage[ 512 ], styleStages[ 4096 ], rgbGen[ 128 ], alphaGen[ 128 ];
- /* setup */
- sprintf( styleStages, "\n\t// Q3Map2 custom lightstyle stage(s)\n" );
- dv = &bspDrawVerts[ ds->firstVert ];
-
- /* depthFunc equal? */
- if ( info->si->styleMarker == 2 || info->si->implicitMap == IM_MASKED ) {
- dfEqual = qtrue;
- }
- else{
- dfEqual = qfalse;
- }
- /* generate stages for styled lightmaps */
- for ( lightmapNum = 1; lightmapNum < MAX_LIGHTMAPS; lightmapNum++ )
- {
- /* early out */
- style = lm->styles[ lightmapNum ];
- if ( style == LS_NONE || lm->outLightmapNums[ lightmapNum ] < 0 ) {
- continue;
- }
-
- /* get output lightmap */
- olm = &outLightmaps[ lm->outLightmapNums[ lightmapNum ] ];
+ /* setup */
+ sprintf( styleStages, "\n\t// Q3Map2 custom lightstyle stage(s)\n" );
+ dv = &bspDrawVerts[ ds->firstVert ];
- /* lightmap name */
- if ( lm->outLightmapNums[ lightmapNum ] == lm->outLightmapNums[ 0 ] ) {
- strcpy( lightmapName, "$lightmap" );
+ /* depthFunc equal? */
+ if ( info->si->styleMarker == 2 || info->si->implicitMap == IM_MASKED ) {
+ dfEqual = qtrue;
}
else{
- sprintf( lightmapName, "maps/%s/" EXTERNAL_LIGHTMAP, mapName, olm->extLightmapNum );
+ dfEqual = qfalse;
}
- /* get rgbgen string */
- if ( rgbGenValues[ style ] == NULL ) {
- sprintf( key, "_style%drgbgen", style );
- rgbGenValues[ style ] = (char*) ValueForKey( &entities[ 0 ], key );
- if ( rgbGenValues[ style ][ 0 ] == '\0' ) {
- rgbGenValues[ style ] = "wave noise 0.5 1 0 5.37";
+ /* generate stages for styled lightmaps */
+ for ( lightmapNum = 1; lightmapNum < MAX_LIGHTMAPS; lightmapNum++ )
+ {
+ /* early out */
+ style = lm->styles[ lightmapNum ];
+ if ( style == LS_NONE || lm->outLightmapNums[ lightmapNum ] < 0 ) {
+ continue;
+ }
+
+ /* get output lightmap */
+ olm = &outLightmaps[ lm->outLightmapNums[ lightmapNum ] ];
+
+ /* lightmap name */
+ if ( lm->outLightmapNums[ lightmapNum ] == lm->outLightmapNums[ 0 ] ) {
+ strcpy( lightmapName, "$lightmap" );
+ }
+ else{
+ sprintf( lightmapName, "maps/%s/" EXTERNAL_LIGHTMAP, mapName, olm->extLightmapNum );
+ }
+
+ /* get rgbgen string */
+ if ( rgbGenValues[ style ] == NULL ) {
+ sprintf( key, "_style%drgbgen", style );
+ rgbGenValues[ style ] = ValueForKey( &entities[ 0 ], key );
+ if ( rgbGenValues[ style ][ 0 ] == '\0' ) {
+ rgbGenValues[ style ] = "wave noise 0.5 1 0 5.37";
+ }
}
- }
- rgbGen[ 0 ] = '\0';
- if ( rgbGenValues[ style ][ 0 ] != '\0' ) {
- sprintf( rgbGen, "\t\trgbGen %s // style %d\n", rgbGenValues[ style ], style );
- }
- else{
rgbGen[ 0 ] = '\0';
- }
+ if ( rgbGenValues[ style ][ 0 ] != '\0' ) {
+ sprintf( rgbGen, "\t\trgbGen %s // style %d\n", rgbGenValues[ style ], style );
+ }
+ else{
+ rgbGen[ 0 ] = '\0';
+ }
- /* get alphagen string */
- if ( alphaGenValues[ style ] == NULL ) {
- sprintf( key, "_style%dalphagen", style );
- alphaGenValues[ style ] = (char*) ValueForKey( &entities[ 0 ], key );
- }
- if ( alphaGenValues[ style ][ 0 ] != '\0' ) {
- sprintf( alphaGen, "\t\talphaGen %s // style %d\n", alphaGenValues[ style ], style );
- }
- else{
- alphaGen[ 0 ] = '\0';
- }
+ /* get alphagen string */
+ if ( alphaGenValues[ style ] == NULL ) {
+ sprintf( key, "_style%dalphagen", style );
+ alphaGenValues[ style ] = ValueForKey( &entities[ 0 ], key );
+ }
+ if ( alphaGenValues[ style ][ 0 ] != '\0' ) {
+ sprintf( alphaGen, "\t\talphaGen %s // style %d\n", alphaGenValues[ style ], style );
+ }
+ else{
+ alphaGen[ 0 ] = '\0';
+ }
+
+ /* calculate st offset */
+ lmx = dv[ 0 ].lightmap[ lightmapNum ][ 0 ] - dv[ 0 ].lightmap[ 0 ][ 0 ];
+ lmy = dv[ 0 ].lightmap[ lightmapNum ][ 1 ] - dv[ 0 ].lightmap[ 0 ][ 1 ];
+
+ /* create additional stage */
+ if ( lmx == 0.0f && lmy == 0.0f ) {
+ sprintf( styleStage, "\t{\n"
+ "\t\tmap %s\n" /* lightmap */
+ "\t\tblendFunc GL_SRC_ALPHA GL_ONE\n"
+ "%s" /* depthFunc equal */
+ "%s" /* rgbGen */
+ "%s" /* alphaGen */
+ "\t\ttcGen lightmap\n"
+ "\t}\n",
+ lightmapName,
+ ( dfEqual ? "\t\tdepthFunc equal\n" : "" ),
+ rgbGen,
+ alphaGen );
+ }
+ else
+ {
+ sprintf( styleStage, "\t{\n"
+ "\t\tmap %s\n" /* lightmap */
+ "\t\tblendFunc GL_SRC_ALPHA GL_ONE\n"
+ "%s" /* depthFunc equal */
+ "%s" /* rgbGen */
+ "%s" /* alphaGen */
+ "\t\ttcGen lightmap\n"
+ "\t\ttcMod transform 1 0 0 1 %1.5f %1.5f\n" /* st offset */
+ "\t}\n",
+ lightmapName,
+ ( dfEqual ? "\t\tdepthFunc equal\n" : "" ),
+ rgbGen,
+ alphaGen,
+ lmx, lmy );
- /* calculate st offset */
- lmx = dv[ 0 ].lightmap[ lightmapNum ][ 0 ] - dv[ 0 ].lightmap[ 0 ][ 0 ];
- lmy = dv[ 0 ].lightmap[ lightmapNum ][ 1 ] - dv[ 0 ].lightmap[ 0 ][ 1 ];
-
- /* create additional stage */
- if ( lmx == 0.0f && lmy == 0.0f ) {
- sprintf( styleStage, "\t{\n"
- "\t\tmap %s\n" /* lightmap */
- "\t\tblendFunc GL_SRC_ALPHA GL_ONE\n"
- "%s" /* depthFunc equal */
- "%s" /* rgbGen */
- "%s" /* alphaGen */
- "\t\ttcGen lightmap\n"
- "\t}\n",
- lightmapName,
- ( dfEqual ? "\t\tdepthFunc equal\n" : "" ),
- rgbGen,
- alphaGen );
+ }
+
+ /* concatenate */
+ strcat( styleStages, styleStage );
}
- else
- {
- sprintf( styleStage, "\t{\n"
- "\t\tmap %s\n" /* lightmap */
- "\t\tblendFunc GL_SRC_ALPHA GL_ONE\n"
- "%s" /* depthFunc equal */
- "%s" /* rgbGen */
- "%s" /* alphaGen */
- "\t\ttcGen lightmap\n"
- "\t\ttcMod transform 1 0 0 1 %1.5f %1.5f\n" /* st offset */
- "\t}\n",
- lightmapName,
- ( dfEqual ? "\t\tdepthFunc equal\n" : "" ),
- rgbGen,
- alphaGen,
- lmx, lmy );
+ /* create custom shader */
+ if ( info->si->styleMarker == 2 ) {
+ csi = CustomShader( info->si, "q3map_styleMarker2", styleStages );
+ }
+ else{
+ csi = CustomShader( info->si, "q3map_styleMarker", styleStages );
}
- /* concatenate */
- strcat( styleStages, styleStage );
- }
+ /* emit remap command */
+ //% EmitVertexRemapShader( csi->shader, info->si->shader );
- /* create custom shader */
- if ( info->si->styleMarker == 2 ) {
- csi = CustomShader( info->si, "q3map_styleMarker2", styleStages );
+ /* store it */
+ //% Sys_Printf( "Emitting: %s (%d", csi->shader, strlen( csi->shader ) );
+ ds->shaderNum = EmitShader( csi->shader, &bspShaders[ ds->shaderNum ].contentFlags, &bspShaders[ ds->shaderNum ].surfaceFlags );
+ //% Sys_Printf( ")\n" );
}
- else{
- csi = CustomShader( info->si, "q3map_styleMarker", styleStages );
- }
-
- /* emit remap command */
- //% EmitVertexRemapShader( csi->shader, info->si->shader );
- /* store it */
- //% Sys_Printf( "Emitting: %s (%d", csi->shader, strlen( csi->shader ) );
- ds->shaderNum = EmitShader( csi->shader, &bspShaders[ ds->shaderNum ].contentFlags, &bspShaders[ ds->shaderNum ].surfaceFlags );
- //% Sys_Printf( ")\n" );
- }
-
- /* devise a custom shader for this surface (fixme: make this work with light styles) */
- else if ( olm != NULL && lm != NULL && !externalLightmaps &&
- ( olm->customWidth != game->lightmapSize || olm->customHeight != game->lightmapSize ) ) {
- /* get output lightmap */
- olm = &outLightmaps[ lm->outLightmapNums[ 0 ] ];
+ /* devise a custom shader for this surface (fixme: make this work with light styles) */
+ else if ( olm != NULL && lm != NULL && !externalLightmaps &&
+ ( olm->customWidth != game->lightmapSize || olm->customHeight != game->lightmapSize ) ) {
+ /* get output lightmap */
+ olm = &outLightmaps[ lm->outLightmapNums[ 0 ] ];
- /* do some name mangling */
- sprintf( lightmapName, "maps/%s/" EXTERNAL_LIGHTMAP, mapName, olm->extLightmapNum );
+ /* do some name mangling */
+ sprintf( lightmapName, "maps/%s/" EXTERNAL_LIGHTMAP, mapName, olm->extLightmapNum );
- /* create custom shader */
- csi = CustomShader( info->si, "$lightmap", lightmapName );
+ /* create custom shader */
+ csi = CustomShader( info->si, "$lightmap", lightmapName );
- /* store it */
- //% Sys_Printf( "Emitting: %s (%d", csi->shader, strlen( csi->shader ) );
- ds->shaderNum = EmitShader( csi->shader, &bspShaders[ ds->shaderNum ].contentFlags, &bspShaders[ ds->shaderNum ].surfaceFlags );
- //% Sys_Printf( ")\n" );
- }
+ /* store it */
+ //% Sys_Printf( "Emitting: %s (%d", csi->shader, strlen( csi->shader ) );
+ ds->shaderNum = EmitShader( csi->shader, &bspShaders[ ds->shaderNum ].contentFlags, &bspShaders[ ds->shaderNum ].surfaceFlags );
+ //% Sys_Printf( ")\n" );
+ }
- /* use the normal plain-jane shader */
- else{
- ds->shaderNum = EmitShader( info->si->shader, &bspShaders[ ds->shaderNum ].contentFlags, &bspShaders[ ds->shaderNum ].surfaceFlags );
+ /* use the normal plain-jane shader */
+ else{
+ ds->shaderNum = EmitShader( info->si->shader, &bspShaders[ ds->shaderNum ].contentFlags, &bspShaders[ ds->shaderNum ].surfaceFlags );
+ }
}
}
? 0
: (float) numUsed / (float) numStored;
- /* print stats */
- Sys_Printf( "%9d luxels used\n", numUsed );
- Sys_Printf( "%9d luxels stored (%3.2f percent efficiency)\n", numStored, efficiency * 100.0f );
- Sys_Printf( "%9d solid surface lightmaps\n", numSolidLightmaps );
- Sys_Printf( "%9d identical surface lightmaps, using %d luxels\n", numTwins, numTwinLuxels );
- Sys_Printf( "%9d vertex forced surfaces\n", numSurfsVertexForced );
- Sys_Printf( "%9d vertex approximated surfaces\n", numSurfsVertexApproximated );
- Sys_Printf( "%9d BSP lightmaps\n", numBSPLightmaps );
- Sys_Printf( "%9d total lightmaps\n", numOutLightmaps );
- Sys_Printf( "%9d unique lightmap/shader combinations\n", numLightmapShaders );
-
- /* write map shader file */
- WriteMapShaderFile();
+ if ( storeForReal ) {
+ /* print stats */
+ Sys_Printf( "%9d luxels used\n", numUsed );
+ Sys_Printf( "%9d luxels stored (%3.2f percent efficiency)\n", numStored, efficiency * 100.0f );
+ Sys_Printf( "%9d solid surface lightmaps\n", numSolidLightmaps );
+ Sys_Printf( "%9d identical surface lightmaps, using %d luxels\n", numTwins, numTwinLuxels );
+ Sys_Printf( "%9d vertex forced surfaces\n", numSurfsVertexForced );
+ Sys_Printf( "%9d vertex approximated surfaces\n", numSurfsVertexApproximated );
+ Sys_Printf( "%9d BSP lightmaps\n", numBSPLightmaps );
+ Sys_Printf( "%9d total lightmaps\n", numOutLightmaps );
+ Sys_Printf( "%9d unique lightmap/shader combinations\n", numLightmapShaders );
+
+ /* write map shader file */
+ WriteMapShaderFile();
+ }
}