Main Page | Class Hierarchy | Alphabetical List | Data Structures | Directories | File List | Data Fields | Globals

lightmaps.c File Reference

#include "qbsp.h"

Include dependency graph for lightmaps.c:

Include dependency graph

Go to the source code of this file.

Functions

void AllocateLightmapForPatch (mapDrawSurface_t *ds)
void AllocateLightmapForSurface (mapDrawSurface_t *ds)
void AllocateLightmaps (entity_t *e)
qboolean AllocLMBlock (int w, int h, int *x, int *y)
void PrepareNewLightmap (void)

Variables

int allocated [LIGHTMAP_WIDTH]
int c_exactLightmap
int numLightmaps = 1
int numSortShaders
mapDrawSurface_tsurfsOnShader [MAX_MAP_SHADERS]


Function Documentation

void AllocateLightmapForPatch mapDrawSurface_t ds  ) 
 

Definition at line 97 of file lightmaps.c.

References AllocLMBlock(), bspbrush_s::brushnum, c_exactLightmap, bspbrush_s::entitynum, Error(), FreeMesh(), h(), mesh_t::height, i, j, k, drawVert_t::lightmap, LIGHTMAP_WIDTH, drawsurf_s::lightmapHeight, drawsurf_s::lightmapNum, shaderInfo_s::lightmapSampleSize, drawsurf_s::lightmapWidth, drawsurf_s::lightmapX, drawsurf_s::lightmapY, drawsurf_s::mapBrush, mapDrawSurface_t, numLightmaps, originalHeights, originalWidths, drawsurf_s::patchHeight, drawsurf_s::patchWidth, PrepareNewLightmap(), PutMeshOnCurve(), RemoveLinearMeshColumnsRows(), s, drawsurf_s::shaderInfo, SubdivideMesh(), SubdivideMeshQuads(), t, mesh_t::verts, drawsurf_s::verts, w, mesh_t::width, x, and y.

Referenced by AllocateLightmapForSurface().

00097                                                       {
00098     int         i, j, k;
00099     drawVert_t  *verts;
00100     int         w, h;
00101     int         x, y;
00102     float       s, t;
00103     mesh_t      mesh, *subdividedMesh, *tempMesh, *newmesh;
00104     int         widthtable[LIGHTMAP_WIDTH], heighttable[LIGHTMAP_HEIGHT], ssize;
00105 
00106     verts = ds->verts;
00107 
00108     mesh.width = ds->patchWidth;
00109     mesh.height = ds->patchHeight;
00110     mesh.verts = verts;
00111     newmesh = SubdivideMesh( mesh, 8, 999 );
00112 
00113     PutMeshOnCurve( *newmesh );
00114     tempMesh = RemoveLinearMeshColumnsRows( newmesh );
00115     FreeMesh(newmesh);
00116 
00117     ssize = samplesize;
00118     if (ds->shaderInfo->lightmapSampleSize)
00119         ssize = ds->shaderInfo->lightmapSampleSize;
00120 
00121 #ifdef LIGHTMAP_PATCHSHIFT
00122     subdividedMesh = SubdivideMeshQuads( tempMesh, ssize, LIGHTMAP_WIDTH-1, widthtable, heighttable);
00123 #else
00124     subdividedMesh = SubdivideMeshQuads( tempMesh, ssize, LIGHTMAP_WIDTH, widthtable, heighttable);
00125 #endif
00126 
00127     w = subdividedMesh->width;
00128     h = subdividedMesh->height;
00129 
00130 #ifdef LIGHTMAP_PATCHSHIFT
00131     w++;
00132     h++;
00133 #endif
00134 
00135     FreeMesh(subdividedMesh);
00136 
00137     // allocate the lightmap
00138     c_exactLightmap += w * h;
00139 
00140     if ( !AllocLMBlock( w, h, &x, &y ) ) {
00141         PrepareNewLightmap();
00142         if ( !AllocLMBlock( w, h, &x, &y ) ) {
00143             Error("Entity %i, brush %i: Lightmap allocation failed", 
00144                 ds->mapBrush->entitynum, ds->mapBrush->brushnum );
00145         }
00146     }
00147 
00148 #ifdef LIGHTMAP_PATCHSHIFT
00149     w--;
00150     h--;
00151 #endif
00152 
00153     // set the lightmap texture coordinates in the drawVerts
00154     ds->lightmapNum = numLightmaps - 1;
00155     ds->lightmapWidth = w;
00156     ds->lightmapHeight = h;
00157     ds->lightmapX = x;
00158     ds->lightmapY = y;
00159 
00160     for ( i = 0 ; i < ds->patchWidth ; i++ ) {
00161         for ( k = 0 ; k < w ; k++ ) {
00162             if ( originalWidths[k] >= i ) {
00163                 break;
00164             }
00165         }
00166         if (k >= w)
00167             k = w-1;
00168         s = x + k;
00169         for ( j = 0 ; j < ds->patchHeight ; j++ ) {
00170             for ( k = 0 ; k < h ; k++ ) {
00171                 if ( originalHeights[k] >= j ) {
00172                     break;
00173                 }
00174             }
00175             if (k >= h)
00176                 k = h-1;
00177             t = y + k;
00178             verts[i + j * ds->patchWidth].lightmap[0] = ( s + 0.5 ) / LIGHTMAP_WIDTH;
00179             verts[i + j * ds->patchWidth].lightmap[1] = ( t + 0.5 ) / LIGHTMAP_HEIGHT;
00180         }
00181     }
00182 }

Here is the call graph for this function:

void AllocateLightmapForSurface mapDrawSurface_t ds  ) 
 

Definition at line 191 of file lightmaps.c.

References AddPointToBounds(), AllocateLightmapForPatch(), AllocLMBlock(), bspbrush_s::brushnum, c_exactLightmap, ceil(), ClearBounds(), d, plane_t::dist, DotProduct, bspbrush_s::entitynum, Error(), fabs(), floor(), h(), i, drawVert_t::lightmap, LIGHTMAP_HEIGHT, LIGHTMAP_WIDTH, drawsurf_s::lightmapHeight, drawsurf_s::lightmapNum, drawsurf_s::lightmapOrigin, shaderInfo_s::lightmapSampleSize, drawsurf_s::lightmapVecs, drawsurf_s::lightmapWidth, drawsurf_s::lightmapX, drawsurf_s::lightmapY, drawsurf_s::mapBrush, mapDrawSurface_t, mapplanes, memset(), plane_t::normal, numLightmaps, drawsurf_s::numVerts, drawsurf_s::patch, side_s::planenum, PrepareNewLightmap(), s, drawsurf_s::shaderInfo, drawsurf_s::side, t, vec3_t, vecs, VectorCopy, VectorNormalize(), VectorScale, VectorSubtract, drawsurf_s::verts, w, x, and y.

Referenced by AllocateLightmaps().

00191                                                         {
00192     vec3_t      mins, maxs, size, exactSize, delta;
00193     int         i;
00194     drawVert_t  *verts;
00195     int         w, h;
00196     int         x, y, ssize;
00197     int         axis;
00198     vec3_t      vecs[2];
00199     float       s, t;
00200     vec3_t      origin;
00201     plane_t     *plane;
00202     float       d;
00203     vec3_t      planeNormal;
00204 
00205     if ( ds->patch ) {
00206         AllocateLightmapForPatch( ds );
00207         return;
00208     }
00209 
00210     ssize = samplesize;
00211     if (ds->shaderInfo->lightmapSampleSize)
00212         ssize = ds->shaderInfo->lightmapSampleSize;
00213 
00214     plane = &mapplanes[ ds->side->planenum ];
00215 
00216     // bound the surface
00217     ClearBounds( mins, maxs );
00218     verts = ds->verts;
00219     for ( i = 0 ; i < ds->numVerts ; i++ ) {
00220         AddPointToBounds( verts[i].xyz, mins, maxs );
00221     }
00222 
00223     // round to the lightmap resolution
00224     for ( i = 0 ; i < 3 ; i++ ) {
00225         exactSize[i] = maxs[i] - mins[i];
00226         mins[i] = ssize * floor( mins[i] / ssize );
00227         maxs[i] = ssize * ceil( maxs[i] / ssize );
00228         size[i] = (maxs[i] - mins[i]) / ssize + 1;
00229     }
00230 
00231     // the two largest axis will be the lightmap size
00232     memset( vecs, 0, sizeof( vecs ) );
00233 
00234     planeNormal[0] = fabs( plane->normal[0] );
00235     planeNormal[1] = fabs( plane->normal[1] );
00236     planeNormal[2] = fabs( plane->normal[2] );
00237 
00238     if ( planeNormal[0] >= planeNormal[1] && planeNormal[0] >= planeNormal[2] ) {
00239         w = size[1];
00240         h = size[2];
00241         axis = 0;
00242         vecs[0][1] = 1.0 / ssize;
00243         vecs[1][2] = 1.0 / ssize;
00244     } else if ( planeNormal[1] >= planeNormal[0] && planeNormal[1] >= planeNormal[2] ) {
00245         w = size[0];
00246         h = size[2];
00247         axis = 1;
00248         vecs[0][0] = 1.0 / ssize;
00249         vecs[1][2] = 1.0 / ssize;
00250     } else {
00251         w = size[0];
00252         h = size[1];
00253         axis = 2;
00254         vecs[0][0] = 1.0 / ssize;
00255         vecs[1][1] = 1.0 / ssize;
00256     }
00257 
00258     if ( !plane->normal[axis] ) {
00259         Error( "Chose a 0 valued axis" );
00260     }
00261 
00262     if ( w > LIGHTMAP_WIDTH ) {
00263         VectorScale ( vecs[0], (float)LIGHTMAP_WIDTH/w, vecs[0] );
00264         w = LIGHTMAP_WIDTH;
00265     }
00266     
00267     if ( h > LIGHTMAP_HEIGHT ) {
00268         VectorScale ( vecs[1], (float)LIGHTMAP_HEIGHT/h, vecs[1] );
00269         h = LIGHTMAP_HEIGHT;
00270     }
00271     
00272     c_exactLightmap += w * h;
00273 
00274     if ( !AllocLMBlock( w, h, &x, &y ) ) {
00275         PrepareNewLightmap();
00276         if ( !AllocLMBlock( w, h, &x, &y ) ) {
00277             Error("Entity %i, brush %i: Lightmap allocation failed", 
00278                 ds->mapBrush->entitynum, ds->mapBrush->brushnum );
00279         }
00280     }
00281 
00282     // set the lightmap texture coordinates in the drawVerts
00283     ds->lightmapNum = numLightmaps - 1;
00284     ds->lightmapWidth = w;
00285     ds->lightmapHeight = h;
00286     ds->lightmapX = x;
00287     ds->lightmapY = y;
00288 
00289     for ( i = 0 ; i < ds->numVerts ; i++ ) {
00290         VectorSubtract( verts[i].xyz, mins, delta );
00291         s = DotProduct( delta, vecs[0] ) + x + 0.5;
00292         t = DotProduct( delta, vecs[1] ) + y + 0.5;
00293         verts[i].lightmap[0] = s / LIGHTMAP_WIDTH;
00294         verts[i].lightmap[1] = t / LIGHTMAP_HEIGHT;
00295     }
00296 
00297     // calculate the world coordinates of the lightmap samples
00298 
00299     // project mins onto plane to get origin
00300     d = DotProduct( mins, plane->normal ) - plane->dist;
00301     d /= plane->normal[ axis ];
00302     VectorCopy( mins, origin );
00303     origin[axis] -= d;
00304 
00305     // project stepped lightmap blocks and subtract to get planevecs
00306     for ( i = 0 ; i < 2 ; i++ ) {
00307         vec3_t  normalized;
00308         float   len;
00309 
00310         len = VectorNormalize( vecs[i], normalized );
00311         VectorScale( normalized, (1.0/len), vecs[i] );
00312         d = DotProduct( vecs[i], plane->normal );
00313         d /= plane->normal[ axis ];
00314         vecs[i][axis] -= d;
00315     }
00316 
00317     VectorCopy( origin, ds->lightmapOrigin );
00318     VectorCopy( vecs[0], ds->lightmapVecs[0] );
00319     VectorCopy( vecs[1], ds->lightmapVecs[1] );
00320     VectorCopy( plane->normal, ds->lightmapVecs[2] );
00321 }

Here is the call graph for this function:

void AllocateLightmaps entity_t e  ) 
 

Definition at line 328 of file lightmaps.c.

References AllocateLightmapForSurface(), c_exactLightmap, e, Error(), entity_t::firstDrawSurf, i, j, LIGHTMAP_HEIGHT, LIGHTMAP_WIDTH, drawsurf_s::lightmapNum, drawsurf_s::lightmapVecs, mapDrawSurface_t, mapDrawSurfs, mapplanes, drawsurf_s::miscModel, drawsurf_s::nextOnShader, numLightmaps, numSortShaders, drawsurf_s::numVerts, drawsurf_s::patch, side_s::planenum, qprintf(), drawsurf_s::shaderInfo, shaderInfo_t, drawsurf_s::side, shaderInfo_s::surfaceFlags, surfsOnShader, and VectorCopy.

Referenced by ProcessSubModel(), and ProcessWorldModel().

00328                                       {
00329     int             i, j;
00330     mapDrawSurface_t    *ds;
00331     shaderInfo_t    *si;
00332 
00333     qprintf ("--- AllocateLightmaps ---\n");
00334 
00335 
00336     // sort all surfaces by shader so common shaders will usually
00337     // be in the same lightmap
00338     numSortShaders = 0;
00339 
00340     for ( i = e->firstDrawSurf ; i < numMapDrawSurfs ; i++ ) {
00341         ds = &mapDrawSurfs[i];
00342         if ( !ds->numVerts ) {
00343             continue;       // leftover from a surface subdivision
00344         }
00345         if ( ds->miscModel ) {
00346             continue;
00347         }
00348         if ( !ds->patch ) {
00349             VectorCopy( mapplanes[ds->side->planenum].normal, ds->lightmapVecs[2] );
00350         }
00351 
00352         // search for this shader
00353         for ( j = 0 ; j < numSortShaders ; j++ ) {
00354             if ( ds->shaderInfo == surfsOnShader[j]->shaderInfo ) {
00355                 ds->nextOnShader = surfsOnShader[j];
00356                 surfsOnShader[j] = ds;
00357                 break;
00358             }
00359         }
00360         if ( j == numSortShaders ) {
00361             if ( numSortShaders >= MAX_MAP_SHADERS ) {
00362                 Error( "MAX_MAP_SHADERS" );
00363             }
00364             surfsOnShader[j] = ds;
00365             numSortShaders++;
00366         }
00367     }
00368     qprintf( "%5i unique shaders\n", numSortShaders );
00369 
00370     // for each shader, allocate lightmaps for each surface
00371 
00372 //  numLightmaps = 0;
00373 //  PrepareNewLightmap();
00374 
00375     for ( i = 0 ; i < numSortShaders ; i++ ) {
00376         si = surfsOnShader[i]->shaderInfo;
00377 
00378         for ( ds = surfsOnShader[i] ; ds ; ds = ds->nextOnShader ) {
00379             // some surfaces don't need lightmaps allocated for them
00380             if ( si->surfaceFlags & SURF_NOLIGHTMAP ) {
00381                 ds->lightmapNum = -1;
00382             } else if ( si->surfaceFlags & SURF_POINTLIGHT ) {
00383                 ds->lightmapNum = -3;
00384             } else {
00385                 AllocateLightmapForSurface( ds );
00386             }
00387         }
00388     }
00389 
00390     qprintf( "%7i exact lightmap texels\n", c_exactLightmap );
00391     qprintf( "%7i block lightmap texels\n", numLightmaps * LIGHTMAP_WIDTH*LIGHTMAP_HEIGHT );
00392 }

Here is the call graph for this function:

qboolean AllocLMBlock int  w,
int  h,
int *  x,
int *  y
 

Definition at line 54 of file lightmaps.c.

References allocated, h(), i, j, LIGHTMAP_WIDTH, qboolean, x, and y.

Referenced by AllocateLightmapForPatch(), and AllocateLightmapForSurface().

00055 {
00056     int     i, j;
00057     int     best, best2;
00058 
00059     best = LIGHTMAP_HEIGHT;
00060 
00061     for ( i=0 ; i <= LIGHTMAP_WIDTH-w ; i++ ) {
00062         best2 = 0;
00063 
00064         for (j=0 ; j<w ; j++) {
00065             if (allocated[i+j] >= best) {
00066                 break;
00067             }
00068             if (allocated[i+j] > best2) {
00069                 best2 = allocated[i+j];
00070             }
00071         }
00072         if (j == w) {   // this is a valid spot
00073             *x = i;
00074             *y = best = best2;
00075         }
00076     }
00077 
00078     if (best + h > LIGHTMAP_HEIGHT) {
00079         return qfalse;
00080     }
00081 
00082     for (i=0 ; i<w ; i++) {
00083         allocated[*x + i] = best + h;
00084     }
00085 
00086     return qtrue;
00087 }

Here is the call graph for this function:

void PrepareNewLightmap void   ) 
 

Definition at line 42 of file lightmaps.c.

References allocated, memset(), and numLightmaps.

Referenced by AllocateLightmapForPatch(), and AllocateLightmapForSurface().

00042                                 {
00043     memset( allocated, 0, sizeof( allocated ) );
00044     numLightmaps++;
00045 }

Here is the call graph for this function:


Variable Documentation

int allocated[LIGHTMAP_WIDTH]
 

Definition at line 36 of file lightmaps.c.

Referenced by AllocLMBlock(), and PrepareNewLightmap().

int c_exactLightmap
 

Definition at line 39 of file lightmaps.c.

Referenced by AllocateLightmapForPatch(), AllocateLightmapForSurface(), and AllocateLightmaps().

int numLightmaps = 1
 

Definition at line 38 of file lightmaps.c.

Referenced by AllocateLightmapForPatch(), AllocateLightmapForSurface(), AllocateLightmaps(), and PrepareNewLightmap().

int numSortShaders
 

Definition at line 32 of file lightmaps.c.

Referenced by AllocateLightmaps().

mapDrawSurface_t* surfsOnShader[MAX_MAP_SHADERS]
 

Definition at line 33 of file lightmaps.c.

Referenced by AllocateLightmaps().


Generated on Thu Aug 25 16:50:12 2005 for Quake III Arena by  doxygen 1.3.9.1