tr_turboshadow.cpp 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357
  1. /*
  2. ===========================================================================
  3. Doom 3 GPL Source Code
  4. Copyright (C) 1999-2011 id Software LLC, a ZeniMax Media company.
  5. This file is part of the Doom 3 GPL Source Code (?Doom 3 Source Code?).
  6. Doom 3 Source Code is free software: you can redistribute it and/or modify
  7. it under the terms of the GNU General Public License as published by
  8. the Free Software Foundation, either version 3 of the License, or
  9. (at your option) any later version.
  10. Doom 3 Source Code is distributed in the hope that it will be useful,
  11. but WITHOUT ANY WARRANTY; without even the implied warranty of
  12. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  13. GNU General Public License for more details.
  14. You should have received a copy of the GNU General Public License
  15. along with Doom 3 Source Code. If not, see <http://www.gnu.org/licenses/>.
  16. In addition, the Doom 3 Source Code is also subject to certain additional terms. You should have received a copy of these additional terms immediately following the terms and conditions of the GNU General Public License which accompanied the Doom 3 Source Code. If not, please request a copy in writing from id Software at the address below.
  17. If you have questions concerning this license or the applicable additional terms, you may contact in writing id Software LLC, c/o ZeniMax Media Inc., Suite 120, Rockville, Maryland 20850 USA.
  18. ===========================================================================
  19. */
  20. #include "../idlib/precompiled.h"
  21. #pragma hdrstop
  22. #include "tr_local.h"
  23. int c_turboUsedVerts;
  24. int c_turboUnusedVerts;
  25. /*
  26. =====================
  27. R_CreateVertexProgramTurboShadowVolume
  28. are dangling edges that are outside the light frustum still making planes?
  29. =====================
  30. */
  31. srfTriangles_t *R_CreateVertexProgramTurboShadowVolume( const idRenderEntityLocal *ent,
  32. const srfTriangles_t *tri, const idRenderLightLocal *light,
  33. srfCullInfo_t &cullInfo ) {
  34. int i, j;
  35. srfTriangles_t *newTri;
  36. silEdge_t *sil;
  37. const glIndex_t *indexes;
  38. const byte *facing;
  39. R_CalcInteractionFacing( ent, tri, light, cullInfo );
  40. if ( r_useShadowProjectedCull.GetBool() ) {
  41. R_CalcInteractionCullBits( ent, tri, light, cullInfo );
  42. }
  43. int numFaces = tri->numIndexes / 3;
  44. int numShadowingFaces = 0;
  45. facing = cullInfo.facing;
  46. // if all the triangles are inside the light frustum
  47. if ( cullInfo.cullBits == LIGHT_CULL_ALL_FRONT || !r_useShadowProjectedCull.GetBool() ) {
  48. // count the number of shadowing faces
  49. for ( i = 0; i < numFaces; i++ ) {
  50. numShadowingFaces += facing[i];
  51. }
  52. numShadowingFaces = numFaces - numShadowingFaces;
  53. } else {
  54. // make all triangles that are outside the light frustum "facing", so they won't cast shadows
  55. indexes = tri->indexes;
  56. byte *modifyFacing = cullInfo.facing;
  57. const byte *cullBits = cullInfo.cullBits;
  58. for ( j = i = 0; i < tri->numIndexes; i += 3, j++ ) {
  59. if ( !modifyFacing[j] ) {
  60. int i1 = indexes[i+0];
  61. int i2 = indexes[i+1];
  62. int i3 = indexes[i+2];
  63. if ( cullBits[i1] & cullBits[i2] & cullBits[i3] ) {
  64. modifyFacing[j] = 1;
  65. } else {
  66. numShadowingFaces++;
  67. }
  68. }
  69. }
  70. }
  71. if ( !numShadowingFaces ) {
  72. // no faces are inside the light frustum and still facing the right way
  73. return NULL;
  74. }
  75. // shadowVerts will be NULL on these surfaces, so the shadowVerts will be taken from the ambient surface
  76. newTri = R_AllocStaticTriSurf();
  77. newTri->numVerts = tri->numVerts * 2;
  78. // alloc the max possible size
  79. #ifdef USE_TRI_DATA_ALLOCATOR
  80. R_AllocStaticTriSurfIndexes( newTri, ( numShadowingFaces + tri->numSilEdges ) * 6 );
  81. glIndex_t *tempIndexes = newTri->indexes;
  82. glIndex_t *shadowIndexes = newTri->indexes;
  83. #else
  84. glIndex_t *tempIndexes = (glIndex_t *)_alloca16( tri->numSilEdges * 6 * sizeof( tempIndexes[0] ) );
  85. glIndex_t *shadowIndexes = tempIndexes;
  86. #endif
  87. // create new triangles along sil planes
  88. for ( sil = tri->silEdges, i = tri->numSilEdges; i > 0; i--, sil++ ) {
  89. int f1 = facing[sil->p1];
  90. int f2 = facing[sil->p2];
  91. if ( !( f1 ^ f2 ) ) {
  92. continue;
  93. }
  94. int v1 = sil->v1 << 1;
  95. int v2 = sil->v2 << 1;
  96. // set the two triangle winding orders based on facing
  97. // without using a poorly-predictable branch
  98. shadowIndexes[0] = v1;
  99. shadowIndexes[1] = v2 ^ f1;
  100. shadowIndexes[2] = v2 ^ f2;
  101. shadowIndexes[3] = v1 ^ f2;
  102. shadowIndexes[4] = v1 ^ f1;
  103. shadowIndexes[5] = v2 ^ 1;
  104. shadowIndexes += 6;
  105. }
  106. int numShadowIndexes = shadowIndexes - tempIndexes;
  107. // we aren't bothering to separate front and back caps on these
  108. newTri->numIndexes = newTri->numShadowIndexesNoFrontCaps = numShadowIndexes + numShadowingFaces * 6;
  109. newTri->numShadowIndexesNoCaps = numShadowIndexes;
  110. newTri->shadowCapPlaneBits = SHADOW_CAP_INFINITE;
  111. #ifdef USE_TRI_DATA_ALLOCATOR
  112. // decrease the size of the memory block to only store the used indexes
  113. R_ResizeStaticTriSurfIndexes( newTri, newTri->numIndexes );
  114. #else
  115. // allocate memory for the indexes
  116. R_AllocStaticTriSurfIndexes( newTri, newTri->numIndexes );
  117. // copy the indexes we created for the sil planes
  118. SIMDProcessor->Memcpy( newTri->indexes, tempIndexes, numShadowIndexes * sizeof( tempIndexes[0] ) );
  119. #endif
  120. // these have no effect, because they extend to infinity
  121. newTri->bounds.Clear();
  122. // put some faces on the model and some on the distant projection
  123. indexes = tri->indexes;
  124. shadowIndexes = newTri->indexes + numShadowIndexes;
  125. for ( i = 0, j = 0; i < tri->numIndexes; i += 3, j++ ) {
  126. if ( facing[j] ) {
  127. continue;
  128. }
  129. int i0 = indexes[i+0] << 1;
  130. shadowIndexes[2] = i0;
  131. shadowIndexes[3] = i0 ^ 1;
  132. int i1 = indexes[i+1] << 1;
  133. shadowIndexes[1] = i1;
  134. shadowIndexes[4] = i1 ^ 1;
  135. int i2 = indexes[i+2] << 1;
  136. shadowIndexes[0] = i2;
  137. shadowIndexes[5] = i2 ^ 1;
  138. shadowIndexes += 6;
  139. }
  140. return newTri;
  141. }
  142. /*
  143. =====================
  144. R_CreateTurboShadowVolume
  145. =====================
  146. */
  147. srfTriangles_t *R_CreateTurboShadowVolume( const idRenderEntityLocal *ent,
  148. const srfTriangles_t *tri, const idRenderLightLocal *light,
  149. srfCullInfo_t &cullInfo ) {
  150. int i, j;
  151. idVec3 localLightOrigin;
  152. srfTriangles_t *newTri;
  153. silEdge_t *sil;
  154. const glIndex_t *indexes;
  155. const byte *facing;
  156. R_CalcInteractionFacing( ent, tri, light, cullInfo );
  157. if ( r_useShadowProjectedCull.GetBool() ) {
  158. R_CalcInteractionCullBits( ent, tri, light, cullInfo );
  159. }
  160. int numFaces = tri->numIndexes / 3;
  161. int numShadowingFaces = 0;
  162. facing = cullInfo.facing;
  163. // if all the triangles are inside the light frustum
  164. if ( cullInfo.cullBits == LIGHT_CULL_ALL_FRONT || !r_useShadowProjectedCull.GetBool() ) {
  165. // count the number of shadowing faces
  166. for ( i = 0; i < numFaces; i++ ) {
  167. numShadowingFaces += facing[i];
  168. }
  169. numShadowingFaces = numFaces - numShadowingFaces;
  170. } else {
  171. // make all triangles that are outside the light frustum "facing", so they won't cast shadows
  172. indexes = tri->indexes;
  173. byte *modifyFacing = cullInfo.facing;
  174. const byte *cullBits = cullInfo.cullBits;
  175. for ( j = i = 0; i < tri->numIndexes; i += 3, j++ ) {
  176. if ( !modifyFacing[j] ) {
  177. int i1 = indexes[i+0];
  178. int i2 = indexes[i+1];
  179. int i3 = indexes[i+2];
  180. if ( cullBits[i1] & cullBits[i2] & cullBits[i3] ) {
  181. modifyFacing[j] = 1;
  182. } else {
  183. numShadowingFaces++;
  184. }
  185. }
  186. }
  187. }
  188. if ( !numShadowingFaces ) {
  189. // no faces are inside the light frustum and still facing the right way
  190. return NULL;
  191. }
  192. newTri = R_AllocStaticTriSurf();
  193. #ifdef USE_TRI_DATA_ALLOCATOR
  194. R_AllocStaticTriSurfShadowVerts( newTri, tri->numVerts * 2 );
  195. shadowCache_t *shadowVerts = newTri->shadowVertexes;
  196. #else
  197. shadowCache_t *shadowVerts = (shadowCache_t *)_alloca16( tri->numVerts * 2 * sizeof( shadowVerts[0] ) );
  198. #endif
  199. R_GlobalPointToLocal( ent->modelMatrix, light->globalLightOrigin, localLightOrigin );
  200. int *vertRemap = (int *)_alloca16( tri->numVerts * sizeof( vertRemap[0] ) );
  201. SIMDProcessor->Memset( vertRemap, -1, tri->numVerts * sizeof( vertRemap[0] ) );
  202. for ( i = 0, j = 0; i < tri->numIndexes; i += 3, j++ ) {
  203. if ( facing[j] ) {
  204. continue;
  205. }
  206. // this may pull in some vertexes that are outside
  207. // the frustum, because they connect to vertexes inside
  208. vertRemap[tri->silIndexes[i+0]] = 0;
  209. vertRemap[tri->silIndexes[i+1]] = 0;
  210. vertRemap[tri->silIndexes[i+2]] = 0;
  211. }
  212. newTri->numVerts = SIMDProcessor->CreateShadowCache( &shadowVerts->xyz, vertRemap, localLightOrigin, tri->verts, tri->numVerts );
  213. c_turboUsedVerts += newTri->numVerts;
  214. c_turboUnusedVerts += tri->numVerts * 2 - newTri->numVerts;
  215. #ifdef USE_TRI_DATA_ALLOCATOR
  216. R_ResizeStaticTriSurfShadowVerts( newTri, newTri->numVerts );
  217. #else
  218. R_AllocStaticTriSurfShadowVerts( newTri, newTri->numVerts );
  219. SIMDProcessor->Memcpy( newTri->shadowVertexes, shadowVerts, newTri->numVerts * sizeof( shadowVerts[0] ) );
  220. #endif
  221. // alloc the max possible size
  222. #ifdef USE_TRI_DATA_ALLOCATOR
  223. R_AllocStaticTriSurfIndexes( newTri, ( numShadowingFaces + tri->numSilEdges ) * 6 );
  224. glIndex_t *tempIndexes = newTri->indexes;
  225. glIndex_t *shadowIndexes = newTri->indexes;
  226. #else
  227. glIndex_t *tempIndexes = (glIndex_t *)_alloca16( tri->numSilEdges * 6 * sizeof( tempIndexes[0] ) );
  228. glIndex_t *shadowIndexes = tempIndexes;
  229. #endif
  230. // create new triangles along sil planes
  231. for ( sil = tri->silEdges, i = tri->numSilEdges; i > 0; i--, sil++ ) {
  232. int f1 = facing[sil->p1];
  233. int f2 = facing[sil->p2];
  234. if ( !( f1 ^ f2 ) ) {
  235. continue;
  236. }
  237. int v1 = vertRemap[sil->v1];
  238. int v2 = vertRemap[sil->v2];
  239. // set the two triangle winding orders based on facing
  240. // without using a poorly-predictable branch
  241. shadowIndexes[0] = v1;
  242. shadowIndexes[1] = v2 ^ f1;
  243. shadowIndexes[2] = v2 ^ f2;
  244. shadowIndexes[3] = v1 ^ f2;
  245. shadowIndexes[4] = v1 ^ f1;
  246. shadowIndexes[5] = v2 ^ 1;
  247. shadowIndexes += 6;
  248. }
  249. int numShadowIndexes = shadowIndexes - tempIndexes;
  250. // we aren't bothering to separate front and back caps on these
  251. newTri->numIndexes = newTri->numShadowIndexesNoFrontCaps = numShadowIndexes + numShadowingFaces * 6;
  252. newTri->numShadowIndexesNoCaps = numShadowIndexes;
  253. newTri->shadowCapPlaneBits = SHADOW_CAP_INFINITE;
  254. #ifdef USE_TRI_DATA_ALLOCATOR
  255. // decrease the size of the memory block to only store the used indexes
  256. R_ResizeStaticTriSurfIndexes( newTri, newTri->numIndexes );
  257. #else
  258. // allocate memory for the indexes
  259. R_AllocStaticTriSurfIndexes( newTri, newTri->numIndexes );
  260. // copy the indexes we created for the sil planes
  261. SIMDProcessor->Memcpy( newTri->indexes, tempIndexes, numShadowIndexes * sizeof( tempIndexes[0] ) );
  262. #endif
  263. // these have no effect, because they extend to infinity
  264. newTri->bounds.Clear();
  265. // put some faces on the model and some on the distant projection
  266. indexes = tri->silIndexes;
  267. shadowIndexes = newTri->indexes + numShadowIndexes;
  268. for ( i = 0, j = 0; i < tri->numIndexes; i += 3, j++ ) {
  269. if ( facing[j] ) {
  270. continue;
  271. }
  272. int i0 = vertRemap[indexes[i+0]];
  273. shadowIndexes[2] = i0;
  274. shadowIndexes[3] = i0 ^ 1;
  275. int i1 = vertRemap[indexes[i+1]];
  276. shadowIndexes[1] = i1;
  277. shadowIndexes[4] = i1 ^ 1;
  278. int i2 = vertRemap[indexes[i+2]];
  279. shadowIndexes[0] = i2;
  280. shadowIndexes[5] = i2 ^ 1;
  281. shadowIndexes += 6;
  282. }
  283. return newTri;
  284. }