]> de.git.xonotic.org Git - xonotic/netradiant.git/commitdiff
new light option -fill to improve lossy compression of lightmaps (should have no...
authorRudolf Polzer <divverent@alientrap.org>
Sun, 31 Oct 2010 11:38:58 +0000 (12:38 +0100)
committerRudolf Polzer <divverent@alientrap.org>
Sun, 31 Oct 2010 11:38:58 +0000 (12:38 +0100)
tools/quake3/q3map2/light.c
tools/quake3/q3map2/lightmaps_ydnar.c
tools/quake3/q3map2/q3map2.h

index 99a5a47b4436b4b4893287908f385e26ab4e996f..a703faacf53e8fff145e897ef42351055e3e62af 100644 (file)
@@ -2754,6 +2754,11 @@ int LightMain( int argc, char **argv )
                {
                        lightmapExtraVisClusterNudge = qtrue;
                }
+               else if( !strcmp( argv[ i ], "-fill" ) )
+               {
+                       lightmapFill = qtrue;
+                       Sys_Printf( "Filling lightmap colors from surrounding pixels to improve JPEG compression\n" );
+               }
                /* unhandled args */
                else
                {
index d315a7825f875198ef489d039932126d5712f8f4..080f26ec5002441991c97388ecb5028fc577fa08 100644 (file)
@@ -2255,7 +2255,112 @@ static int CompareRawLightmap( const void *a, const void *b )
        return 0;
 }
 
+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()
@@ -2937,6 +3042,10 @@ void StoreSurfaceLightmaps( void )
        {
                /* get output lightmap */
                olm = &outLightmaps[ i ];
+
+               /* fill output lightmap */
+               if(lightmapFill)
+                       FillOutLightmap(olm);
                
                /* is this a valid bsp lightmap? */
                if( olm->lightmapNum >= 0 && !externalLightmaps )
index 99a2469a04de6fb03767f3bfac78e47955afe4e4..baa29c7c31b15f32937e2cf1de37e65afa129db9 100644 (file)
@@ -2022,6 +2022,7 @@ Q_EXTERN qboolean                 debugInset Q_ASSIGN( qfalse );
 Q_EXTERN qboolean                      debugPortals Q_ASSIGN( qfalse );
 Q_EXTERN qboolean           lightmapTriangleCheck Q_ASSIGN(qfalse);
 Q_EXTERN qboolean           lightmapExtraVisClusterNudge Q_ASSIGN(qfalse);
+Q_EXTERN qboolean           lightmapFill Q_ASSIGN(qfalse);
 Q_EXTERN double                                normalEpsilon Q_ASSIGN( 0.00001 );
 Q_EXTERN double                                distanceEpsilon Q_ASSIGN( 0.01 );