/* =================== AllocateLightmaps =================== */ void AllocateLightmaps( entity_t *e ) { int i, j; mapDrawSurface_t *ds; shaderInfo_t *si; qprintf ("--- AllocateLightmaps ---\n"); // sort all surfaces by shader so common shaders will usually // be in the same lightmap numSortShaders = 0; for ( i = e->firstDrawSurf ; i < numMapDrawSurfs ; i++ ) { ds = &mapDrawSurfs[i]; if ( !ds->numVerts ) { continue; // leftover from a surface subdivision } if ( ds->miscModel ) { continue; } if ( !ds->patch ) { VectorCopy( mapplanes[ds->side->planenum].normal, ds->lightmapVecs[2] ); } // search for this shader for ( j = 0 ; j < numSortShaders ; j++ ) { if ( ds->shaderInfo == surfsOnShader[j]->shaderInfo ) { ds->nextOnShader = surfsOnShader[j]; surfsOnShader[j] = ds; break; } } if ( j == numSortShaders ) { if ( numSortShaders >= MAX_MAP_SHADERS ) { Error( "MAX_MAP_SHADERS" ); } surfsOnShader[j] = ds; numSortShaders++; } } qprintf( "%5i unique shaders\n", numSortShaders ); // for each shader, allocate lightmaps for each surface // numLightmaps = 0; // PrepareNewLightmap(); for ( i = 0 ; i < numSortShaders ; i++ ) { si = surfsOnShader[i]->shaderInfo; for ( ds = surfsOnShader[i] ; ds ; ds = ds->nextOnShader ) { // some surfaces don't need lightmaps allocated for them if ( si->surfaceFlags & SURF_NOLIGHTMAP ) { ds->lightmapNum = -1; } else if ( si->surfaceFlags & SURF_POINTLIGHT ) { ds->lightmapNum = -3; } else { AllocateLightmapForSurface( ds ); } } } qprintf( "%7i exact lightmap texels\n", c_exactLightmap ); qprintf( "%7i block lightmap texels\n", numLightmaps * LIGHTMAP_WIDTH*LIGHTMAP_HEIGHT ); }
/* =================== AllocateLightmaps =================== */ void AllocateLightmaps( entity_t *e ) { int i, j; mapDrawSurface_t *ds; shaderInfo_t *si; /* note it */ Sys_FPrintf( SYS_VRB,"--- AllocateLightmaps ---\n" ); /* sort all surfaces by shader so common shaders will usually be in the same lightmap */ /* ydnar: this is done in two passes, because of an odd bug with lightmapped terrain */ numSortShaders = 0; for( i = e->firstDrawSurf; i < numMapDrawSurfs; i++ ) { /* get surface and early out if possible */ ds = &mapDrawSurfs[ i ]; si = ds->shaderInfo; if( si->surfaceFlags & SURF_VERTEXLIT ) continue; if( ds->numVerts <= 0 ) continue; /* ydnar: handle brush faces and patches first */ if( ds->type != SURF_FACE && ds->type != SURF_PATCH ) continue; /* ydnar: this is unecessary because it should already be set */ //% VectorCopy( ds->plane.normal, ds->lightmapVecs[ 2 ] ); /* search for this shader */ for( j = 0 ; j < numSortShaders; j++ ) { if( ds->shaderInfo == surfsOnShader[ j ]->shaderInfo ) { ds->nextOnShader = surfsOnShader[ j ]; surfsOnShader[ j ] = ds; break; } } /* new shader */ if( j == numSortShaders ) { if( numSortShaders >= MAX_MAP_SHADERS ) Error( "MAX_MAP_SHADERS" ); surfsOnShader[ j ] = ds; ds->nextOnShader = NULL; numSortShaders++; } } /* second pass, to allocate lightmapped terrain last */ for( i = e->firstDrawSurf; i < numMapDrawSurfs; i++ ) { /* get surface and early out if possible */ ds = &mapDrawSurfs[ i ]; si = ds->shaderInfo; if( si->surfaceFlags & SURF_VERTEXLIT ) continue; if( ds->numVerts <= 0 ) continue; /* ydnar: this only handles metasurfaces and terrain */ if( ds->type != SURF_TERRAIN && ds->type != SURF_META ) continue; /* ydnar: a lightmap projection should be pre-stored for anything but excessively curved patches */ if( VectorLength( ds->lightmapAxis ) <= 0 ) continue; /* search for this shader */ for( j = 0; j < numSortShaders; j++ ) { if( ds->shaderInfo == surfsOnShader[ j ]->shaderInfo ) { ds->nextOnShader = surfsOnShader[ j ]; surfsOnShader[ j ] = ds; break; } } /* new shader */ if( j == numSortShaders ) { if( numSortShaders >= MAX_MAP_SHADERS ) Error( "MAX_MAP_SHADERS" ); surfsOnShader[ j ] = ds; ds->nextOnShader = NULL; numSortShaders++; } } /* tot up shader count */ Sys_FPrintf( SYS_VRB, "%9d unique shaders\n", numSortShaders ); /* for each shader, allocate lightmaps for each surface */ for( i = 0; i < numSortShaders; i++ ) { si = surfsOnShader[ i ]->shaderInfo; for( ds = surfsOnShader[ i ]; ds; ds = ds->nextOnShader ) { /* ydnar: promoting pointlight above nolightmap */ if( si->surfaceFlags & SURF_POINTLIGHT ) ds->lightmapNum = -3; else if( si->surfaceFlags & SURF_NOLIGHTMAP ) ds->lightmapNum = -1; else AllocateLightmapForSurface( ds ); } } /* emit some statistics */ Sys_FPrintf( SYS_VRB, "%9d exact lightmap texels\n", c_exactLightmap ); Sys_FPrintf( SYS_VRB, "%9d block lightmap texels\n", numLightmaps * LIGHTMAP_WIDTH * LIGHTMAP_HEIGHT ); Sys_FPrintf( SYS_VRB, "%9d non-planar or terrain lightmap texels\n", c_nonplanarLightmap ); Sys_FPrintf( SYS_VRB, "%9d planar patch lightmaps\n", c_planarPatch ); Sys_FPrintf( SYS_VRB, "%9d lightmap textures, size: %d Kbytes\n", numLightmaps, (numLightmaps * LIGHTMAP_WIDTH * LIGHTMAP_HEIGHT * 3) / 1024 ); }