aboutsummaryrefslogtreecommitdiffstats
path: root/q3map/lightmaps.c
diff options
context:
space:
mode:
Diffstat (limited to 'q3map/lightmaps.c')
-rw-r--r--q3map/lightmaps.c395
1 files changed, 0 insertions, 395 deletions
diff --git a/q3map/lightmaps.c b/q3map/lightmaps.c
deleted file mode 100644
index ce1fc12..0000000
--- a/q3map/lightmaps.c
+++ /dev/null
@@ -1,395 +0,0 @@
-/*
-===========================================================================
-Copyright (C) 1999-2005 Id Software, Inc.
-
-This file is part of Quake III Arena source code.
-
-Quake III Arena source code is free software; you can redistribute it
-and/or modify it under the terms of the GNU General Public License as
-published by the Free Software Foundation; either version 2 of the License,
-or (at your option) any later version.
-
-Quake III Arena source code is distributed in the hope that it will be
-useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
-MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-GNU General Public License for more details.
-
-You should have received a copy of the GNU General Public License
-along with Foobar; if not, write to the Free Software
-Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
-===========================================================================
-*/
-#include "qbsp.h"
-
-
-/*
-
- Lightmap allocation has to be done after all flood filling and
- visible surface determination.
-
-*/
-
-int numSortShaders;
-mapDrawSurface_t *surfsOnShader[MAX_MAP_SHADERS];
-
-
-int allocated[LIGHTMAP_WIDTH];
-
-int numLightmaps = 1;
-int c_exactLightmap;
-
-
-void PrepareNewLightmap( void ) {
- memset( allocated, 0, sizeof( allocated ) );
- numLightmaps++;
-}
-
-/*
-===============
-AllocLMBlock
-
-returns a texture number and the position inside it
-===============
-*/
-qboolean AllocLMBlock (int w, int h, int *x, int *y)
-{
- int i, j;
- int best, best2;
-
- best = LIGHTMAP_HEIGHT;
-
- for ( i=0 ; i <= LIGHTMAP_WIDTH-w ; i++ ) {
- best2 = 0;
-
- for (j=0 ; j<w ; j++) {
- if (allocated[i+j] >= best) {
- break;
- }
- if (allocated[i+j] > best2) {
- best2 = allocated[i+j];
- }
- }
- if (j == w) { // this is a valid spot
- *x = i;
- *y = best = best2;
- }
- }
-
- if (best + h > LIGHTMAP_HEIGHT) {
- return qfalse;
- }
-
- for (i=0 ; i<w ; i++) {
- allocated[*x + i] = best + h;
- }
-
- return qtrue;
-}
-
-
-/*
-===================
-AllocateLightmapForPatch
-===================
-*/
-//#define LIGHTMAP_PATCHSHIFT
-
-void AllocateLightmapForPatch( mapDrawSurface_t *ds ) {
- int i, j, k;
- drawVert_t *verts;
- int w, h;
- int x, y;
- float s, t;
- mesh_t mesh, *subdividedMesh, *tempMesh, *newmesh;
- int widthtable[LIGHTMAP_WIDTH], heighttable[LIGHTMAP_HEIGHT], ssize;
-
- verts = ds->verts;
-
- mesh.width = ds->patchWidth;
- mesh.height = ds->patchHeight;
- mesh.verts = verts;
- newmesh = SubdivideMesh( mesh, 8, 999 );
-
- PutMeshOnCurve( *newmesh );
- tempMesh = RemoveLinearMeshColumnsRows( newmesh );
- FreeMesh(newmesh);
-
- ssize = samplesize;
- if (ds->shaderInfo->lightmapSampleSize)
- ssize = ds->shaderInfo->lightmapSampleSize;
-
-#ifdef LIGHTMAP_PATCHSHIFT
- subdividedMesh = SubdivideMeshQuads( tempMesh, ssize, LIGHTMAP_WIDTH-1, widthtable, heighttable);
-#else
- subdividedMesh = SubdivideMeshQuads( tempMesh, ssize, LIGHTMAP_WIDTH, widthtable, heighttable);
-#endif
-
- w = subdividedMesh->width;
- h = subdividedMesh->height;
-
-#ifdef LIGHTMAP_PATCHSHIFT
- w++;
- h++;
-#endif
-
- FreeMesh(subdividedMesh);
-
- // allocate the lightmap
- c_exactLightmap += w * h;
-
- if ( !AllocLMBlock( w, h, &x, &y ) ) {
- PrepareNewLightmap();
- if ( !AllocLMBlock( w, h, &x, &y ) ) {
- Error("Entity %i, brush %i: Lightmap allocation failed",
- ds->mapBrush->entitynum, ds->mapBrush->brushnum );
- }
- }
-
-#ifdef LIGHTMAP_PATCHSHIFT
- w--;
- h--;
-#endif
-
- // set the lightmap texture coordinates in the drawVerts
- ds->lightmapNum = numLightmaps - 1;
- ds->lightmapWidth = w;
- ds->lightmapHeight = h;
- ds->lightmapX = x;
- ds->lightmapY = y;
-
- for ( i = 0 ; i < ds->patchWidth ; i++ ) {
- for ( k = 0 ; k < w ; k++ ) {
- if ( originalWidths[k] >= i ) {
- break;
- }
- }
- if (k >= w)
- k = w-1;
- s = x + k;
- for ( j = 0 ; j < ds->patchHeight ; j++ ) {
- for ( k = 0 ; k < h ; k++ ) {
- if ( originalHeights[k] >= j ) {
- break;
- }
- }
- if (k >= h)
- k = h-1;
- t = y + k;
- verts[i + j * ds->patchWidth].lightmap[0] = ( s + 0.5 ) / LIGHTMAP_WIDTH;
- verts[i + j * ds->patchWidth].lightmap[1] = ( t + 0.5 ) / LIGHTMAP_HEIGHT;
- }
- }
-}
-
-
-/*
-===================
-AllocateLightmapForSurface
-===================
-*/
-//#define LIGHTMAP_BLOCK 16
-void AllocateLightmapForSurface( mapDrawSurface_t *ds ) {
- vec3_t mins, maxs, size, exactSize, delta;
- int i;
- drawVert_t *verts;
- int w, h;
- int x, y, ssize;
- int axis;
- vec3_t vecs[2];
- float s, t;
- vec3_t origin;
- plane_t *plane;
- float d;
- vec3_t planeNormal;
-
- if ( ds->patch ) {
- AllocateLightmapForPatch( ds );
- return;
- }
-
- ssize = samplesize;
- if (ds->shaderInfo->lightmapSampleSize)
- ssize = ds->shaderInfo->lightmapSampleSize;
-
- plane = &mapplanes[ ds->side->planenum ];
-
- // bound the surface
- ClearBounds( mins, maxs );
- verts = ds->verts;
- for ( i = 0 ; i < ds->numVerts ; i++ ) {
- AddPointToBounds( verts[i].xyz, mins, maxs );
- }
-
- // round to the lightmap resolution
- for ( i = 0 ; i < 3 ; i++ ) {
- exactSize[i] = maxs[i] - mins[i];
- mins[i] = ssize * floor( mins[i] / ssize );
- maxs[i] = ssize * ceil( maxs[i] / ssize );
- size[i] = (maxs[i] - mins[i]) / ssize + 1;
- }
-
- // the two largest axis will be the lightmap size
- memset( vecs, 0, sizeof( vecs ) );
-
- planeNormal[0] = fabs( plane->normal[0] );
- planeNormal[1] = fabs( plane->normal[1] );
- planeNormal[2] = fabs( plane->normal[2] );
-
- if ( planeNormal[0] >= planeNormal[1] && planeNormal[0] >= planeNormal[2] ) {
- w = size[1];
- h = size[2];
- axis = 0;
- vecs[0][1] = 1.0 / ssize;
- vecs[1][2] = 1.0 / ssize;
- } else if ( planeNormal[1] >= planeNormal[0] && planeNormal[1] >= planeNormal[2] ) {
- w = size[0];
- h = size[2];
- axis = 1;
- vecs[0][0] = 1.0 / ssize;
- vecs[1][2] = 1.0 / ssize;
- } else {
- w = size[0];
- h = size[1];
- axis = 2;
- vecs[0][0] = 1.0 / ssize;
- vecs[1][1] = 1.0 / ssize;
- }
-
- if ( !plane->normal[axis] ) {
- Error( "Chose a 0 valued axis" );
- }
-
- if ( w > LIGHTMAP_WIDTH ) {
- VectorScale ( vecs[0], (float)LIGHTMAP_WIDTH/w, vecs[0] );
- w = LIGHTMAP_WIDTH;
- }
-
- if ( h > LIGHTMAP_HEIGHT ) {
- VectorScale ( vecs[1], (float)LIGHTMAP_HEIGHT/h, vecs[1] );
- h = LIGHTMAP_HEIGHT;
- }
-
- c_exactLightmap += w * h;
-
- if ( !AllocLMBlock( w, h, &x, &y ) ) {
- PrepareNewLightmap();
- if ( !AllocLMBlock( w, h, &x, &y ) ) {
- Error("Entity %i, brush %i: Lightmap allocation failed",
- ds->mapBrush->entitynum, ds->mapBrush->brushnum );
- }
- }
-
- // set the lightmap texture coordinates in the drawVerts
- ds->lightmapNum = numLightmaps - 1;
- ds->lightmapWidth = w;
- ds->lightmapHeight = h;
- ds->lightmapX = x;
- ds->lightmapY = y;
-
- for ( i = 0 ; i < ds->numVerts ; i++ ) {
- VectorSubtract( verts[i].xyz, mins, delta );
- s = DotProduct( delta, vecs[0] ) + x + 0.5;
- t = DotProduct( delta, vecs[1] ) + y + 0.5;
- verts[i].lightmap[0] = s / LIGHTMAP_WIDTH;
- verts[i].lightmap[1] = t / LIGHTMAP_HEIGHT;
- }
-
- // calculate the world coordinates of the lightmap samples
-
- // project mins onto plane to get origin
- d = DotProduct( mins, plane->normal ) - plane->dist;
- d /= plane->normal[ axis ];
- VectorCopy( mins, origin );
- origin[axis] -= d;
-
- // project stepped lightmap blocks and subtract to get planevecs
- for ( i = 0 ; i < 2 ; i++ ) {
- vec3_t normalized;
- float len;
-
- len = VectorNormalize( vecs[i], normalized );
- VectorScale( normalized, (1.0/len), vecs[i] );
- d = DotProduct( vecs[i], plane->normal );
- d /= plane->normal[ axis ];
- vecs[i][axis] -= d;
- }
-
- VectorCopy( origin, ds->lightmapOrigin );
- VectorCopy( vecs[0], ds->lightmapVecs[0] );
- VectorCopy( vecs[1], ds->lightmapVecs[1] );
- VectorCopy( plane->normal, ds->lightmapVecs[2] );
-}
-
-/*
-===================
-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 );
-}
-
-
-