lightmaps.c 9.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396
  1. /*
  2. ===========================================================================
  3. Copyright (C) 1999-2005 Id Software, Inc.
  4. This file is part of Quake III Arena source code.
  5. Quake III Arena source code is free software; you can redistribute it
  6. and/or modify it under the terms of the GNU General Public License as
  7. published by the Free Software Foundation; either version 2 of the License,
  8. or (at your option) any later version.
  9. Quake III Arena source code is distributed in the hope that it will be
  10. useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
  11. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  12. GNU General Public License for more details.
  13. You should have received a copy of the GNU General Public License
  14. along with Foobar; if not, write to the Free Software
  15. Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
  16. ===========================================================================
  17. */
  18. #include "qbsp.h"
  19. /*
  20. Lightmap allocation has to be done after all flood filling and
  21. visible surface determination.
  22. */
  23. int numSortShaders;
  24. mapDrawSurface_t *surfsOnShader[MAX_MAP_SHADERS];
  25. int allocated[LIGHTMAP_WIDTH];
  26. int numLightmaps = 1;
  27. int c_exactLightmap;
  28. void PrepareNewLightmap( void ) {
  29. memset( allocated, 0, sizeof( allocated ) );
  30. numLightmaps++;
  31. }
  32. /*
  33. ===============
  34. AllocLMBlock
  35. returns a texture number and the position inside it
  36. ===============
  37. */
  38. qboolean AllocLMBlock (int w, int h, int *x, int *y)
  39. {
  40. int i, j;
  41. int best, best2;
  42. best = LIGHTMAP_HEIGHT;
  43. for ( i=0 ; i <= LIGHTMAP_WIDTH-w ; i++ ) {
  44. best2 = 0;
  45. for (j=0 ; j<w ; j++) {
  46. if (allocated[i+j] >= best) {
  47. break;
  48. }
  49. if (allocated[i+j] > best2) {
  50. best2 = allocated[i+j];
  51. }
  52. }
  53. if (j == w) { // this is a valid spot
  54. *x = i;
  55. *y = best = best2;
  56. }
  57. }
  58. if (best + h > LIGHTMAP_HEIGHT) {
  59. return qfalse;
  60. }
  61. for (i=0 ; i<w ; i++) {
  62. allocated[*x + i] = best + h;
  63. }
  64. return qtrue;
  65. }
  66. /*
  67. ===================
  68. AllocateLightmapForPatch
  69. ===================
  70. */
  71. //#define LIGHTMAP_PATCHSHIFT
  72. void AllocateLightmapForPatch( mapDrawSurface_t *ds ) {
  73. int i, j, k;
  74. drawVert_t *verts;
  75. int w, h;
  76. int x, y;
  77. float s, t;
  78. mesh_t mesh, *subdividedMesh, *tempMesh, *newmesh;
  79. int widthtable[LIGHTMAP_WIDTH], heighttable[LIGHTMAP_HEIGHT], ssize;
  80. verts = ds->verts;
  81. mesh.width = ds->patchWidth;
  82. mesh.height = ds->patchHeight;
  83. mesh.verts = verts;
  84. newmesh = SubdivideMesh( mesh, 8, 999 );
  85. PutMeshOnCurve( *newmesh );
  86. tempMesh = RemoveLinearMeshColumnsRows( newmesh );
  87. FreeMesh(newmesh);
  88. ssize = samplesize;
  89. if (ds->shaderInfo->lightmapSampleSize)
  90. ssize = ds->shaderInfo->lightmapSampleSize;
  91. #ifdef LIGHTMAP_PATCHSHIFT
  92. subdividedMesh = SubdivideMeshQuads( tempMesh, ssize, LIGHTMAP_WIDTH-1, widthtable, heighttable);
  93. #else
  94. subdividedMesh = SubdivideMeshQuads( tempMesh, ssize, LIGHTMAP_WIDTH, widthtable, heighttable);
  95. #endif
  96. w = subdividedMesh->width;
  97. h = subdividedMesh->height;
  98. #ifdef LIGHTMAP_PATCHSHIFT
  99. w++;
  100. h++;
  101. #endif
  102. FreeMesh(subdividedMesh);
  103. // allocate the lightmap
  104. c_exactLightmap += w * h;
  105. if ( !AllocLMBlock( w, h, &x, &y ) ) {
  106. PrepareNewLightmap();
  107. if ( !AllocLMBlock( w, h, &x, &y ) ) {
  108. Error("Entity %i, brush %i: Lightmap allocation failed",
  109. ds->mapBrush->entitynum, ds->mapBrush->brushnum );
  110. }
  111. }
  112. #ifdef LIGHTMAP_PATCHSHIFT
  113. w--;
  114. h--;
  115. #endif
  116. // set the lightmap texture coordinates in the drawVerts
  117. ds->lightmapNum = numLightmaps - 1;
  118. ds->lightmapWidth = w;
  119. ds->lightmapHeight = h;
  120. ds->lightmapX = x;
  121. ds->lightmapY = y;
  122. for ( i = 0 ; i < ds->patchWidth ; i++ ) {
  123. for ( k = 0 ; k < w ; k++ ) {
  124. if ( originalWidths[k] >= i ) {
  125. break;
  126. }
  127. }
  128. if (k >= w)
  129. k = w-1;
  130. s = x + k;
  131. for ( j = 0 ; j < ds->patchHeight ; j++ ) {
  132. for ( k = 0 ; k < h ; k++ ) {
  133. if ( originalHeights[k] >= j ) {
  134. break;
  135. }
  136. }
  137. if (k >= h)
  138. k = h-1;
  139. t = y + k;
  140. verts[i + j * ds->patchWidth].lightmap[0] = ( s + 0.5 ) / LIGHTMAP_WIDTH;
  141. verts[i + j * ds->patchWidth].lightmap[1] = ( t + 0.5 ) / LIGHTMAP_HEIGHT;
  142. }
  143. }
  144. }
  145. /*
  146. ===================
  147. AllocateLightmapForSurface
  148. ===================
  149. */
  150. //#define LIGHTMAP_BLOCK 16
  151. void AllocateLightmapForSurface( mapDrawSurface_t *ds ) {
  152. vec3_t mins, maxs, size, exactSize, delta;
  153. int i;
  154. drawVert_t *verts;
  155. int w, h;
  156. int x, y, ssize;
  157. int axis;
  158. vec3_t vecs[2];
  159. float s, t;
  160. vec3_t origin;
  161. plane_t *plane;
  162. float d;
  163. vec3_t planeNormal;
  164. if ( ds->patch ) {
  165. AllocateLightmapForPatch( ds );
  166. return;
  167. }
  168. ssize = samplesize;
  169. if (ds->shaderInfo->lightmapSampleSize)
  170. ssize = ds->shaderInfo->lightmapSampleSize;
  171. plane = &mapplanes[ ds->side->planenum ];
  172. // bound the surface
  173. ClearBounds( mins, maxs );
  174. verts = ds->verts;
  175. for ( i = 0 ; i < ds->numVerts ; i++ ) {
  176. AddPointToBounds( verts[i].xyz, mins, maxs );
  177. }
  178. // round to the lightmap resolution
  179. for ( i = 0 ; i < 3 ; i++ ) {
  180. exactSize[i] = maxs[i] - mins[i];
  181. mins[i] = ssize * floor( mins[i] / ssize );
  182. maxs[i] = ssize * ceil( maxs[i] / ssize );
  183. size[i] = (maxs[i] - mins[i]) / ssize + 1;
  184. }
  185. // the two largest axis will be the lightmap size
  186. memset( vecs, 0, sizeof( vecs ) );
  187. planeNormal[0] = fabs( plane->normal[0] );
  188. planeNormal[1] = fabs( plane->normal[1] );
  189. planeNormal[2] = fabs( plane->normal[2] );
  190. if ( planeNormal[0] >= planeNormal[1] && planeNormal[0] >= planeNormal[2] ) {
  191. w = size[1];
  192. h = size[2];
  193. axis = 0;
  194. vecs[0][1] = 1.0 / ssize;
  195. vecs[1][2] = 1.0 / ssize;
  196. } else if ( planeNormal[1] >= planeNormal[0] && planeNormal[1] >= planeNormal[2] ) {
  197. w = size[0];
  198. h = size[2];
  199. axis = 1;
  200. vecs[0][0] = 1.0 / ssize;
  201. vecs[1][2] = 1.0 / ssize;
  202. } else {
  203. w = size[0];
  204. h = size[1];
  205. axis = 2;
  206. vecs[0][0] = 1.0 / ssize;
  207. vecs[1][1] = 1.0 / ssize;
  208. }
  209. if ( !plane->normal[axis] ) {
  210. Error( "Chose a 0 valued axis" );
  211. }
  212. if ( w > LIGHTMAP_WIDTH ) {
  213. VectorScale ( vecs[0], (float)LIGHTMAP_WIDTH/w, vecs[0] );
  214. w = LIGHTMAP_WIDTH;
  215. }
  216. if ( h > LIGHTMAP_HEIGHT ) {
  217. VectorScale ( vecs[1], (float)LIGHTMAP_HEIGHT/h, vecs[1] );
  218. h = LIGHTMAP_HEIGHT;
  219. }
  220. c_exactLightmap += w * h;
  221. if ( !AllocLMBlock( w, h, &x, &y ) ) {
  222. PrepareNewLightmap();
  223. if ( !AllocLMBlock( w, h, &x, &y ) ) {
  224. Error("Entity %i, brush %i: Lightmap allocation failed",
  225. ds->mapBrush->entitynum, ds->mapBrush->brushnum );
  226. }
  227. }
  228. // set the lightmap texture coordinates in the drawVerts
  229. ds->lightmapNum = numLightmaps - 1;
  230. ds->lightmapWidth = w;
  231. ds->lightmapHeight = h;
  232. ds->lightmapX = x;
  233. ds->lightmapY = y;
  234. for ( i = 0 ; i < ds->numVerts ; i++ ) {
  235. VectorSubtract( verts[i].xyz, mins, delta );
  236. s = DotProduct( delta, vecs[0] ) + x + 0.5;
  237. t = DotProduct( delta, vecs[1] ) + y + 0.5;
  238. verts[i].lightmap[0] = s / LIGHTMAP_WIDTH;
  239. verts[i].lightmap[1] = t / LIGHTMAP_HEIGHT;
  240. }
  241. // calculate the world coordinates of the lightmap samples
  242. // project mins onto plane to get origin
  243. d = DotProduct( mins, plane->normal ) - plane->dist;
  244. d /= plane->normal[ axis ];
  245. VectorCopy( mins, origin );
  246. origin[axis] -= d;
  247. // project stepped lightmap blocks and subtract to get planevecs
  248. for ( i = 0 ; i < 2 ; i++ ) {
  249. vec3_t normalized;
  250. float len;
  251. len = VectorNormalize( vecs[i], normalized );
  252. VectorScale( normalized, (1.0/len), vecs[i] );
  253. d = DotProduct( vecs[i], plane->normal );
  254. d /= plane->normal[ axis ];
  255. vecs[i][axis] -= d;
  256. }
  257. VectorCopy( origin, ds->lightmapOrigin );
  258. VectorCopy( vecs[0], ds->lightmapVecs[0] );
  259. VectorCopy( vecs[1], ds->lightmapVecs[1] );
  260. VectorCopy( plane->normal, ds->lightmapVecs[2] );
  261. }
  262. /*
  263. ===================
  264. AllocateLightmaps
  265. ===================
  266. */
  267. void AllocateLightmaps( entity_t *e ) {
  268. int i, j;
  269. mapDrawSurface_t *ds;
  270. shaderInfo_t *si;
  271. qprintf ("--- AllocateLightmaps ---\n");
  272. // sort all surfaces by shader so common shaders will usually
  273. // be in the same lightmap
  274. numSortShaders = 0;
  275. for ( i = e->firstDrawSurf ; i < numMapDrawSurfs ; i++ ) {
  276. ds = &mapDrawSurfs[i];
  277. if ( !ds->numVerts ) {
  278. continue; // leftover from a surface subdivision
  279. }
  280. if ( ds->miscModel ) {
  281. continue;
  282. }
  283. if ( !ds->patch ) {
  284. VectorCopy( mapplanes[ds->side->planenum].normal, ds->lightmapVecs[2] );
  285. }
  286. // search for this shader
  287. for ( j = 0 ; j < numSortShaders ; j++ ) {
  288. if ( ds->shaderInfo == surfsOnShader[j]->shaderInfo ) {
  289. ds->nextOnShader = surfsOnShader[j];
  290. surfsOnShader[j] = ds;
  291. break;
  292. }
  293. }
  294. if ( j == numSortShaders ) {
  295. if ( numSortShaders >= MAX_MAP_SHADERS ) {
  296. Error( "MAX_MAP_SHADERS" );
  297. }
  298. surfsOnShader[j] = ds;
  299. numSortShaders++;
  300. }
  301. }
  302. qprintf( "%5i unique shaders\n", numSortShaders );
  303. // for each shader, allocate lightmaps for each surface
  304. // numLightmaps = 0;
  305. // PrepareNewLightmap();
  306. for ( i = 0 ; i < numSortShaders ; i++ ) {
  307. si = surfsOnShader[i]->shaderInfo;
  308. for ( ds = surfsOnShader[i] ; ds ; ds = ds->nextOnShader ) {
  309. // some surfaces don't need lightmaps allocated for them
  310. if ( si->surfaceFlags & SURF_NOLIGHTMAP ) {
  311. ds->lightmapNum = -1;
  312. } else if ( si->surfaceFlags & SURF_POINTLIGHT ) {
  313. ds->lightmapNum = -3;
  314. } else {
  315. AllocateLightmapForSurface( ds );
  316. }
  317. }
  318. }
  319. qprintf( "%7i exact lightmap texels\n", c_exactLightmap );
  320. qprintf( "%7i block lightmap texels\n", numLightmaps * LIGHTMAP_WIDTH*LIGHTMAP_HEIGHT );
  321. }