From 43b1afe982fdc77aa64dfde64abdea0e61c88f6d Mon Sep 17 00:00:00 2001 From: Thomas Debesse Date: Sun, 22 Sep 2019 02:16:08 +0200 Subject: [PATCH] q3map2/light: introduce -nobouncestore when storing computed lightmap on each bounce, user can interrupt compilation and get working files, but it spends allocation time (which is slow and single-threaded with this option, user can decide to only allocate lightmaps on the very final bounce, it means it can't be interrupted, but it can save a lot of time --- tools/quake3/q3map2/help.c | 1 + tools/quake3/q3map2/light.c | 29 +- tools/quake3/q3map2/lightmaps_ydnar.c | 705 +++++++++++++------------- tools/quake3/q3map2/q3map2.h | 2 +- 4 files changed, 380 insertions(+), 357 deletions(-) diff --git a/tools/quake3/q3map2/help.c b/tools/quake3/q3map2/help.c index 28690061..0e908152 100644 --- a/tools/quake3/q3map2/help.c +++ b/tools/quake3/q3map2/help.c @@ -231,6 +231,7 @@ void HelpLight() {"-lomem", "Low memory but slower lighting mode"}, {"-lowquality", "Low quality floodlight (appears to currently break floodlight)"}, {"-minsamplesize ", "Sets minimum lightmap resolution in luxels/qu"}, + {"-nobouncestore", "Do not store BSP, lightmap and shader files between bounces"}, {"-nocollapse", "Do not collapse identical lightmaps"}, {"-nodeluxe, -nodeluxemap", "Disable deluxemapping"}, {"-nofastpoint", "Disable fast point light calculation"}, diff --git a/tools/quake3/q3map2/light.c b/tools/quake3/q3map2/light.c index dd906c1c..45546f7c 100644 --- a/tools/quake3/q3map2/light.c +++ b/tools/quake3/q3map2/light.c @@ -1890,14 +1890,13 @@ void SetupGrid( void ){ does what it says... */ -void LightWorld( const char *BSPFilePath, qboolean fastLightmapSearch ){ +void LightWorld( const char *BSPFilePath, qboolean fastLightmapSearch, qboolean noBounceStore ){ vec3_t color; float f; int b, bt; qboolean minVertex, minGrid; const char *value; - /* ydnar: smooth normals */ if ( shade ) { Sys_Printf( "--- SmoothNormals ---\n" ); @@ -2031,13 +2030,19 @@ void LightWorld( const char *BSPFilePath, qboolean fastLightmapSearch ){ /* radiosity */ b = 1; bt = bounce; + while ( bounce > 0 ) { + qboolean storeForReal = !noBounceStore; + /* store off the bsp between bounces */ - StoreSurfaceLightmaps( fastLightmapSearch ); + StoreSurfaceLightmaps( fastLightmapSearch, storeForReal ); UnparseEntities(); - Sys_Printf( "Writing %s\n", BSPFilePath ); - WriteBSPFile( BSPFilePath ); + + if ( storeForReal ) { + Sys_Printf( "Writing %s\n", BSPFilePath ); + WriteBSPFile( BSPFilePath ); + } /* note it */ Sys_Printf( "\n--- Radiosity (bounce %d of %d) ---\n", b, bt ); @@ -2055,6 +2060,9 @@ void LightWorld( const char *BSPFilePath, qboolean fastLightmapSearch ){ SetupEnvelopes( qfalse, fastbounce ); if ( numLights == 0 ) { Sys_Printf( "No diffuse light to calculate, ending radiosity.\n" ); + if ( noBounceStore ) { + break; + } return; } @@ -2098,8 +2106,9 @@ void LightWorld( const char *BSPFilePath, qboolean fastLightmapSearch ){ bounce--; b++; } + /* ydnar: store off lightmaps */ - StoreSurfaceLightmaps( fastLightmapSearch ); + StoreSurfaceLightmaps( fastLightmapSearch, qtrue ); } @@ -2140,6 +2149,7 @@ int LightMain( int argc, char **argv ){ int lightmapMergeSize = 0; qboolean lightSamplesInsist = qfalse; qboolean fastLightmapSearch = qfalse; + qboolean noBounceStore = qfalse; /* note it */ Sys_Printf( "--- Light ---\n" ); @@ -2601,6 +2611,11 @@ int LightMain( int argc, char **argv ){ Sys_Printf( "Storing bounced light (radiosity) only\n" ); } + else if ( !strcmp( argv[ i ], "-nobouncestore" ) ) { + noBounceStore = qtrue; + Sys_Printf( "Do not store BSP, lightmap and shader files between bounces\n" ); + } + else if ( !strcmp( argv[ i ], "-nocollapse" ) ) { noCollapse = qtrue; Sys_Printf( "Identical lightmap collapsing disabled\n" ); @@ -3028,7 +3043,7 @@ int LightMain( int argc, char **argv ){ SetupTraceNodes(); /* light the world */ - LightWorld( BSPFilePath, fastLightmapSearch ); + LightWorld( BSPFilePath, fastLightmapSearch, noBounceStore ); /* write out the bsp */ UnparseEntities(); diff --git a/tools/quake3/q3map2/lightmaps_ydnar.c b/tools/quake3/q3map2/lightmaps_ydnar.c index d169c21f..f578daad 100644 --- a/tools/quake3/q3map2/lightmaps_ydnar.c +++ b/tools/quake3/q3map2/lightmaps_ydnar.c @@ -1985,7 +1985,6 @@ static void FindOutLightmaps( rawLightmap_t *lm, qboolean fastLightmapSearch ){ qboolean ok; int xIncrement, yIncrement; - /* set default lightmap number (-3 = LIGHTMAP_BY_VERTEX) */ for ( lightmapNum = 0; lightmapNum < MAX_LIGHTMAPS; lightmapNum++ ) lm->outLightmapNums[ lightmapNum ] = -3; @@ -2462,7 +2461,7 @@ void FillOutLightmap( outLightmap_t *olm ){ stores the surface lightmaps into the bsp as byte rgb triplets */ -void StoreSurfaceLightmaps( qboolean fastLightmapSearch ){ +void StoreSurfaceLightmaps( qboolean fastLightmapSearch, 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; @@ -2970,7 +2969,7 @@ void StoreSurfaceLightmaps( qboolean fastLightmapSearch ){ collapse non-unique lightmaps ----------------------------------------------------------------- */ - if ( noCollapse == qfalse && deluxemap == qfalse ) { + if ( storeForReal && noCollapse == qfalse && deluxemap == qfalse ) { /* note it */ Sys_FPrintf( SYS_VRB, "collapsing..." ); @@ -3057,52 +3056,54 @@ void StoreSurfaceLightmaps( qboolean fastLightmapSearch ){ 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; - /* find output lightmap */ - for ( i = 0; i < numRawLightmaps; i++ ) - { - lm = &rawLightmaps[ sortLightmaps[ i ] ]; - FindOutLightmaps( lm, fastLightmapSearch ); - } + numLightmapShaders = 0; + numOutLightmaps = 0; + numBSPLightmaps = 0; + numExtLightmaps = 0; - /* 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, fastLightmapSearch ); + } - /* 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 ] ]; - /* find output lightmap from twin */ - lm->outLightmapNums[ lightmapNum ] = lm2->outLightmapNums[ lightmapNum2 ]; - lm->lightmapX[ lightmapNum ] = lm2->lightmapX[ lightmapNum2 ]; - lm->lightmapY[ lightmapNum ] = lm2->lightmapY[ lightmapNum2 ]; + /* 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 ]; + } } } @@ -3110,373 +3111,377 @@ void StoreSurfaceLightmaps( qboolean fastLightmapSearch ){ 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 ); - } - - /* walk the list of output lightmaps */ - for ( i = 0; i < numOutLightmaps; i++ ) - { - /* get output lightmap */ - olm = &outLightmaps[ i ]; + if ( storeForReal ) { + /* note it */ + Sys_FPrintf( SYS_VRB, "storing..." ); - /* fill output lightmap */ - if ( lightmapFill ) { - FillOutLightmap( olm ); + /* 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 ); } - /* 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 ); - /* set external lightmap number */ - olm->extLightmapNum = numExtLightmaps; + /* copy direction data */ + if ( deluxemap ) { + lb = bspLightBytes + ( ( olm->lightmapNum + 1 ) * game->lightmapSize * game->lightmapSize * 3 ); + memcpy( lb, olm->bspDirBytes, game->lightmapSize * game->lightmapSize * 3 ); + } + } + + /* 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 ) ); - /* handle unused style */ - if ( lm->styles[ lightmapNum ] == LS_NONE || lm->outLightmapNums[ lightmapNum ] < 0 ) { + /* 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 ) ); + } + + /* 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 ]; - - /* 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; - } + /* 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 ]; - /* 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 ] = 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 ] = 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 ); + /* 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 ); + + } + + /* 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 ); - } - else{ - csi = CustomShader( info->si, "q3map_styleMarker", 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" ); } - /* 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 ); + } } } @@ -3489,17 +3494,19 @@ void StoreSurfaceLightmaps( qboolean fastLightmapSearch ){ ? 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(); + } } diff --git a/tools/quake3/q3map2/q3map2.h b/tools/quake3/q3map2/q3map2.h index 4220725d..6b8a77e3 100644 --- a/tools/quake3/q3map2/q3map2.h +++ b/tools/quake3/q3map2/q3map2.h @@ -1858,7 +1858,7 @@ int ImportLightmapsMain( int argc, char **argv ); void SetupSurfaceLightmaps( void ); void StitchSurfaceLightmaps( void ); -void StoreSurfaceLightmaps( qboolean fastLightmapSearch ); +void StoreSurfaceLightmaps( qboolean fastLightmapSearch, qboolean storeForReal ); /* exportents.c */ -- 2.39.2