tr_frontend_addmodels.cpp 45 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082
  1. /*
  2. ===========================================================================
  3. Doom 3 BFG Edition GPL Source Code
  4. Copyright (C) 1993-2012 id Software LLC, a ZeniMax Media company.
  5. This file is part of the Doom 3 BFG Edition GPL Source Code ("Doom 3 BFG Edition Source Code").
  6. Doom 3 BFG Edition 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 BFG Edition 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 BFG Edition Source Code. If not, see <http://www.gnu.org/licenses/>.
  16. In addition, the Doom 3 BFG Edition 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 BFG Edition 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. #pragma hdrstop
  21. #include "../idlib/precompiled.h"
  22. #include "tr_local.h"
  23. #include "Model_local.h"
  24. idCVar r_skipStaticShadows( "r_skipStaticShadows", "0", CVAR_RENDERER | CVAR_BOOL, "skip static shadows" );
  25. idCVar r_skipDynamicShadows( "r_skipDynamicShadows", "0", CVAR_RENDERER | CVAR_BOOL, "skip dynamic shadows" );
  26. idCVar r_useParallelAddModels( "r_useParallelAddModels", "1", CVAR_RENDERER | CVAR_BOOL, "add all models in parallel with jobs" );
  27. idCVar r_useParallelAddShadows( "r_useParallelAddShadows", "1", CVAR_RENDERER | CVAR_INTEGER, "0 = off, 1 = threaded", 0, 1 );
  28. idCVar r_useShadowPreciseInsideTest( "r_useShadowPreciseInsideTest", "1", CVAR_RENDERER | CVAR_BOOL, "use a precise and more expensive test to determine whether the view is inside a shadow volume" );
  29. idCVar r_cullDynamicShadowTriangles( "r_cullDynamicShadowTriangles", "1", CVAR_RENDERER | CVAR_BOOL, "cull occluder triangles that are outside the light frustum so they do not contribute to the dynamic shadow volume" );
  30. idCVar r_cullDynamicLightTriangles( "r_cullDynamicLightTriangles", "1", CVAR_RENDERER | CVAR_BOOL, "cull surface triangles that are outside the light frustum so they do not get rendered for interactions" );
  31. idCVar r_forceShadowCaps( "r_forceShadowCaps", "0", CVAR_RENDERER | CVAR_BOOL, "0 = skip rendering shadow caps if view is outside shadow volume, 1 = always render shadow caps" );
  32. static const float CHECK_BOUNDS_EPSILON = 1.0f;
  33. /*
  34. ==================
  35. R_SortViewEntities
  36. ==================
  37. */
  38. viewEntity_t * R_SortViewEntities( viewEntity_t * vEntities ) {
  39. SCOPED_PROFILE_EVENT( "R_SortViewEntities" );
  40. // We want to avoid having a single AddModel for something complex be
  41. // the last thing processed and hurt the parallel occupancy, so
  42. // sort dynamic models first, _area models second, then everything else.
  43. viewEntity_t * dynamics = NULL;
  44. viewEntity_t * areas = NULL;
  45. viewEntity_t * others = NULL;
  46. for ( viewEntity_t * vEntity = vEntities; vEntity != NULL; ) {
  47. viewEntity_t * next = vEntity->next;
  48. const idRenderModel * model = vEntity->entityDef->parms.hModel;
  49. if ( model->IsDynamicModel() != DM_STATIC ) {
  50. vEntity->next = dynamics;
  51. dynamics = vEntity;
  52. } else if ( model->IsStaticWorldModel() ) {
  53. vEntity->next = areas;
  54. areas = vEntity;
  55. } else {
  56. vEntity->next = others;
  57. others = vEntity;
  58. }
  59. vEntity = next;
  60. }
  61. // concatenate the lists
  62. viewEntity_t * all = others;
  63. for ( viewEntity_t * vEntity = areas; vEntity != NULL; ) {
  64. viewEntity_t * next = vEntity->next;
  65. vEntity->next = all;
  66. all = vEntity;
  67. vEntity = next;
  68. }
  69. for ( viewEntity_t * vEntity = dynamics; vEntity != NULL; ) {
  70. viewEntity_t * next = vEntity->next;
  71. vEntity->next = all;
  72. all = vEntity;
  73. vEntity = next;
  74. }
  75. return all;
  76. }
  77. /*
  78. ==================
  79. R_ClearEntityDefDynamicModel
  80. If we know the reference bounds stays the same, we
  81. only need to do this on entity update, not the full
  82. R_FreeEntityDefDerivedData
  83. ==================
  84. */
  85. void R_ClearEntityDefDynamicModel( idRenderEntityLocal *def ) {
  86. // free all the interaction surfaces
  87. for ( idInteraction *inter = def->firstInteraction; inter != NULL && !inter->IsEmpty(); inter = inter->entityNext ) {
  88. inter->FreeSurfaces();
  89. }
  90. // clear the dynamic model if present
  91. if ( def->dynamicModel ) {
  92. // this is copied from cachedDynamicModel, so it doesn't need to be freed
  93. def->dynamicModel = NULL;
  94. }
  95. def->dynamicModelFrameCount = 0;
  96. }
  97. /*
  98. ==================
  99. R_IssueEntityDefCallback
  100. ==================
  101. */
  102. bool R_IssueEntityDefCallback( idRenderEntityLocal *def ) {
  103. idBounds oldBounds = def->localReferenceBounds;
  104. def->archived = false; // will need to be written to the demo file
  105. bool update;
  106. if ( tr.viewDef != NULL ) {
  107. update = def->parms.callback( &def->parms, &tr.viewDef->renderView );
  108. } else {
  109. update = def->parms.callback( &def->parms, NULL );
  110. }
  111. tr.pc.c_entityDefCallbacks++;
  112. if ( def->parms.hModel == NULL ) {
  113. common->Error( "R_IssueEntityDefCallback: dynamic entity callback didn't set model" );
  114. }
  115. if ( r_checkBounds.GetBool() ) {
  116. if ( oldBounds[0][0] > def->localReferenceBounds[0][0] + CHECK_BOUNDS_EPSILON ||
  117. oldBounds[0][1] > def->localReferenceBounds[0][1] + CHECK_BOUNDS_EPSILON ||
  118. oldBounds[0][2] > def->localReferenceBounds[0][2] + CHECK_BOUNDS_EPSILON ||
  119. oldBounds[1][0] < def->localReferenceBounds[1][0] - CHECK_BOUNDS_EPSILON ||
  120. oldBounds[1][1] < def->localReferenceBounds[1][1] - CHECK_BOUNDS_EPSILON ||
  121. oldBounds[1][2] < def->localReferenceBounds[1][2] - CHECK_BOUNDS_EPSILON ) {
  122. common->Printf( "entity %i callback extended reference bounds\n", def->index );
  123. }
  124. }
  125. return update;
  126. }
  127. /*
  128. ===================
  129. R_EntityDefDynamicModel
  130. This is also called by the game code for idRenderWorldLocal::ModelTrace(), and idRenderWorldLocal::Trace() which is bad for performance...
  131. Issues a deferred entity callback if necessary.
  132. If the model isn't dynamic, it returns the original.
  133. Returns the cached dynamic model if present, otherwise creates it.
  134. ===================
  135. */
  136. idRenderModel *R_EntityDefDynamicModel( idRenderEntityLocal *def ) {
  137. if ( def->dynamicModelFrameCount == tr.frameCount ) {
  138. return def->dynamicModel;
  139. }
  140. // allow deferred entities to construct themselves
  141. bool callbackUpdate;
  142. if ( def->parms.callback != NULL ) {
  143. SCOPED_PROFILE_EVENT( "R_IssueEntityDefCallback" );
  144. callbackUpdate = R_IssueEntityDefCallback( def );
  145. } else {
  146. callbackUpdate = false;
  147. }
  148. idRenderModel *model = def->parms.hModel;
  149. if ( model == NULL ) {
  150. common->Error( "R_EntityDefDynamicModel: NULL model" );
  151. return NULL;
  152. }
  153. if ( model->IsDynamicModel() == DM_STATIC ) {
  154. def->dynamicModel = NULL;
  155. def->dynamicModelFrameCount = 0;
  156. return model;
  157. }
  158. // continously animating models (particle systems, etc) will have their snapshot updated every single view
  159. if ( callbackUpdate || ( model->IsDynamicModel() == DM_CONTINUOUS && def->dynamicModelFrameCount != tr.frameCount ) ) {
  160. R_ClearEntityDefDynamicModel( def );
  161. }
  162. // if we don't have a snapshot of the dynamic model, generate it now
  163. if ( def->dynamicModel == NULL ) {
  164. SCOPED_PROFILE_EVENT( "InstantiateDynamicModel" );
  165. // instantiate the snapshot of the dynamic model, possibly reusing memory from the cached snapshot
  166. def->cachedDynamicModel = model->InstantiateDynamicModel( &def->parms, tr.viewDef, def->cachedDynamicModel );
  167. if ( def->cachedDynamicModel != NULL && r_checkBounds.GetBool() ) {
  168. idBounds b = def->cachedDynamicModel->Bounds();
  169. if ( b[0][0] < def->localReferenceBounds[0][0] - CHECK_BOUNDS_EPSILON ||
  170. b[0][1] < def->localReferenceBounds[0][1] - CHECK_BOUNDS_EPSILON ||
  171. b[0][2] < def->localReferenceBounds[0][2] - CHECK_BOUNDS_EPSILON ||
  172. b[1][0] > def->localReferenceBounds[1][0] + CHECK_BOUNDS_EPSILON ||
  173. b[1][1] > def->localReferenceBounds[1][1] + CHECK_BOUNDS_EPSILON ||
  174. b[1][2] > def->localReferenceBounds[1][2] + CHECK_BOUNDS_EPSILON ) {
  175. common->Printf( "entity %i dynamic model exceeded reference bounds\n", def->index );
  176. }
  177. }
  178. def->dynamicModel = def->cachedDynamicModel;
  179. def->dynamicModelFrameCount = tr.frameCount;
  180. }
  181. // set model depth hack value
  182. if ( def->dynamicModel != NULL && model->DepthHack() != 0.0f && tr.viewDef != NULL ) {
  183. idPlane eye, clip;
  184. idVec3 ndc;
  185. R_TransformModelToClip( def->parms.origin, tr.viewDef->worldSpace.modelViewMatrix, tr.viewDef->projectionMatrix, eye, clip );
  186. R_TransformClipToDevice( clip, ndc );
  187. def->parms.modelDepthHack = model->DepthHack() * ( 1.0f - ndc.z );
  188. } else {
  189. def->parms.modelDepthHack = 0.0f;
  190. }
  191. return def->dynamicModel;
  192. }
  193. /*
  194. ===================
  195. R_SetupDrawSurfShader
  196. ===================
  197. */
  198. void R_SetupDrawSurfShader( drawSurf_t * drawSurf, const idMaterial * shader, const renderEntity_t * renderEntity ) {
  199. drawSurf->material = shader;
  200. drawSurf->sort = shader->GetSort();
  201. // process the shader expressions for conditionals / color / texcoords
  202. const float *constRegs = shader->ConstantRegisters();
  203. if ( likely( constRegs != NULL ) ) {
  204. // shader only uses constant values
  205. drawSurf->shaderRegisters = constRegs;
  206. } else {
  207. // by default evaluate with the entityDef's shader parms
  208. const float * shaderParms = renderEntity->shaderParms;
  209. // a reference shader will take the calculated stage color value from another shader
  210. // and use that for the parm0-parm3 of the current shader, which allows a stage of
  211. // a light model and light flares to pick up different flashing tables from
  212. // different light shaders
  213. float generatedShaderParms[MAX_ENTITY_SHADER_PARMS];
  214. if ( unlikely( renderEntity->referenceShader != NULL ) ) {
  215. // evaluate the reference shader to find our shader parms
  216. float refRegs[MAX_EXPRESSION_REGISTERS];
  217. renderEntity->referenceShader->EvaluateRegisters( refRegs, renderEntity->shaderParms,
  218. tr.viewDef->renderView.shaderParms,
  219. tr.viewDef->renderView.time[renderEntity->timeGroup] * 0.001f, renderEntity->referenceSound );
  220. const shaderStage_t * pStage = renderEntity->referenceShader->GetStage( 0 );
  221. memcpy( generatedShaderParms, renderEntity->shaderParms, sizeof( generatedShaderParms ) );
  222. generatedShaderParms[0] = refRegs[ pStage->color.registers[0] ];
  223. generatedShaderParms[1] = refRegs[ pStage->color.registers[1] ];
  224. generatedShaderParms[2] = refRegs[ pStage->color.registers[2] ];
  225. shaderParms = generatedShaderParms;
  226. }
  227. // allocte frame memory for the shader register values
  228. float * regs = (float *)R_FrameAlloc( shader->GetNumRegisters() * sizeof( float ), FRAME_ALLOC_SHADER_REGISTER );
  229. drawSurf->shaderRegisters = regs;
  230. // process the shader expressions for conditionals / color / texcoords
  231. shader->EvaluateRegisters( regs, shaderParms, tr.viewDef->renderView.shaderParms,
  232. tr.viewDef->renderView.time[renderEntity->timeGroup] * 0.001f, renderEntity->referenceSound );
  233. }
  234. }
  235. /*
  236. ===================
  237. R_SetupDrawSurfJoints
  238. ===================
  239. */
  240. void R_SetupDrawSurfJoints( drawSurf_t * drawSurf, const srfTriangles_t * tri, const idMaterial * shader ) {
  241. if ( tri->staticModelWithJoints == NULL || !r_useGPUSkinning.GetBool() ) {
  242. drawSurf->jointCache = 0;
  243. return;
  244. }
  245. idRenderModelStatic * model = tri->staticModelWithJoints;
  246. assert( model->jointsInverted != NULL );
  247. if ( !vertexCache.CacheIsCurrent( model->jointsInvertedBuffer ) ) {
  248. const int alignment = glConfig.uniformBufferOffsetAlignment;
  249. model->jointsInvertedBuffer = vertexCache.AllocJoint( model->jointsInverted, ALIGN( model->numInvertedJoints * sizeof( idJointMat ), alignment ) );
  250. }
  251. drawSurf->jointCache = model->jointsInvertedBuffer;
  252. }
  253. /*
  254. ===================
  255. R_AddSingleModel
  256. May be run in parallel.
  257. Here is where dynamic models actually get instantiated, and necessary
  258. interaction surfaces get created. This is all done on a sort-by-model
  259. basis to keep source data in cache (most likely L2) as any interactions
  260. and shadows are generated, since dynamic models will typically be lit by
  261. two or more lights.
  262. ===================
  263. */
  264. void R_AddSingleModel( viewEntity_t * vEntity ) {
  265. // we will add all interaction surfs here, to be chained to the lights in later serial code
  266. vEntity->drawSurfs = NULL;
  267. vEntity->staticShadowVolumes = NULL;
  268. vEntity->dynamicShadowVolumes = NULL;
  269. // globals we really should pass in...
  270. const viewDef_t * viewDef = tr.viewDef;
  271. idRenderEntityLocal * entityDef = vEntity->entityDef;
  272. const renderEntity_t * renderEntity = &entityDef->parms;
  273. const idRenderWorldLocal * world = entityDef->world;
  274. if ( viewDef->isXraySubview && entityDef->parms.xrayIndex == 1 ) {
  275. return;
  276. } else if ( !viewDef->isXraySubview && entityDef->parms.xrayIndex == 2 ) {
  277. return;
  278. }
  279. SCOPED_PROFILE_EVENT( renderEntity->hModel == NULL ? "Unknown Model" : renderEntity->hModel->Name() );
  280. // calculate the znear for testing whether or not the view is inside a shadow projection
  281. const float znear = ( viewDef->renderView.cramZNear ) ? ( r_znear.GetFloat() * 0.25f ) : r_znear.GetFloat();
  282. // if the entity wasn't seen through a portal chain, it was added just for light shadows
  283. const bool modelIsVisible = !vEntity->scissorRect.IsEmpty();
  284. const bool addInteractions = modelIsVisible && ( !viewDef->isXraySubview || entityDef->parms.xrayIndex == 2 );
  285. const int entityIndex = entityDef->index;
  286. //---------------------------
  287. // Find which of the visible lights contact this entity
  288. //
  289. // If the entity doesn't accept light or cast shadows from any surface,
  290. // this can be skipped.
  291. //
  292. // OPTIMIZE: world areas can assume all referenced lights are used
  293. //---------------------------
  294. int numContactedLights = 0;
  295. static const int MAX_CONTACTED_LIGHTS = 128;
  296. viewLight_t * contactedLights[MAX_CONTACTED_LIGHTS];
  297. idInteraction * staticInteractions[MAX_CONTACTED_LIGHTS];
  298. if ( renderEntity->hModel == NULL ||
  299. renderEntity->hModel->ModelHasInteractingSurfaces() ||
  300. renderEntity->hModel->ModelHasShadowCastingSurfaces() ) {
  301. SCOPED_PROFILE_EVENT( "Find lights" );
  302. for ( viewLight_t * vLight = viewDef->viewLights; vLight != NULL; vLight = vLight->next ) {
  303. if ( vLight->scissorRect.IsEmpty() ) {
  304. continue;
  305. }
  306. if ( vLight->entityInteractionState != NULL ) {
  307. // new code path, everything was done in AddLight
  308. if ( vLight->entityInteractionState[entityIndex] == viewLight_t::INTERACTION_YES ) {
  309. contactedLights[numContactedLights] = vLight;
  310. staticInteractions[numContactedLights] = world->interactionTable[vLight->lightDef->index * world->interactionTableWidth + entityIndex];
  311. if ( ++numContactedLights == MAX_CONTACTED_LIGHTS ) {
  312. break;
  313. }
  314. }
  315. continue;
  316. }
  317. const idRenderLightLocal * lightDef = vLight->lightDef;
  318. if ( !lightDef->globalLightBounds.IntersectsBounds( entityDef->globalReferenceBounds ) ) {
  319. continue;
  320. }
  321. if ( R_CullModelBoundsToLight( lightDef, entityDef->localReferenceBounds, entityDef->modelRenderMatrix ) ) {
  322. continue;
  323. }
  324. if ( !modelIsVisible ) {
  325. // some lights have their center of projection outside the world
  326. if ( lightDef->areaNum != -1 ) {
  327. // if no part of the model is in an area that is connected to
  328. // the light center (it is behind a solid, closed door), we can ignore it
  329. bool areasConnected = false;
  330. for ( areaReference_t *ref = entityDef->entityRefs; ref != NULL; ref = ref->ownerNext ) {
  331. if ( world->AreasAreConnected( lightDef->areaNum, ref->area->areaNum, PS_BLOCK_VIEW ) ) {
  332. areasConnected = true;
  333. break;
  334. }
  335. }
  336. if ( areasConnected == false ) {
  337. // can't possibly be seen or shadowed
  338. continue;
  339. }
  340. }
  341. // check more precisely for shadow visibility
  342. idBounds shadowBounds;
  343. R_ShadowBounds( entityDef->globalReferenceBounds, lightDef->globalLightBounds, lightDef->globalLightOrigin, shadowBounds );
  344. // this doesn't say that the shadow can't effect anything, only that it can't
  345. // effect anything in the view
  346. if ( idRenderMatrix::CullBoundsToMVP( viewDef->worldSpace.mvp, shadowBounds ) ) {
  347. continue;
  348. }
  349. }
  350. contactedLights[numContactedLights] = vLight;
  351. staticInteractions[numContactedLights] = world->interactionTable[vLight->lightDef->index * world->interactionTableWidth + entityIndex];
  352. if ( ++numContactedLights == MAX_CONTACTED_LIGHTS ) {
  353. break;
  354. }
  355. }
  356. }
  357. // if we aren't visible and none of the shadows stretch into the view,
  358. // we don't need to do anything else
  359. if ( !modelIsVisible && numContactedLights == 0 ) {
  360. return;
  361. }
  362. //---------------------------
  363. // create a dynamic model if the geometry isn't static
  364. //---------------------------
  365. idRenderModel * model = R_EntityDefDynamicModel( entityDef );
  366. if ( model == NULL || model->NumSurfaces() <= 0 ) {
  367. return;
  368. }
  369. // add the lightweight blood decal surfaces if the model is directly visible
  370. if ( modelIsVisible ) {
  371. assert( !vEntity->scissorRect.IsEmpty() );
  372. if ( entityDef->decals != NULL && !r_skipDecals.GetBool() ) {
  373. entityDef->decals->CreateDeferredDecals( model );
  374. unsigned int numDrawSurfs = entityDef->decals->GetNumDecalDrawSurfs();
  375. for ( unsigned int i = 0; i < numDrawSurfs; i++ ) {
  376. drawSurf_t * decalDrawSurf = entityDef->decals->CreateDecalDrawSurf( vEntity, i );
  377. if ( decalDrawSurf != NULL ) {
  378. decalDrawSurf->linkChain = NULL;
  379. decalDrawSurf->nextOnLight = vEntity->drawSurfs;
  380. vEntity->drawSurfs = decalDrawSurf;
  381. }
  382. }
  383. }
  384. if ( entityDef->overlays != NULL && !r_skipOverlays.GetBool() ) {
  385. entityDef->overlays->CreateDeferredOverlays( model );
  386. unsigned int numDrawSurfs = entityDef->overlays->GetNumOverlayDrawSurfs();
  387. for ( unsigned int i = 0; i < numDrawSurfs; i++ ) {
  388. drawSurf_t * overlayDrawSurf = entityDef->overlays->CreateOverlayDrawSurf( vEntity, model, i );
  389. if ( overlayDrawSurf != NULL ) {
  390. overlayDrawSurf->linkChain = NULL;
  391. overlayDrawSurf->nextOnLight = vEntity->drawSurfs;
  392. vEntity->drawSurfs = overlayDrawSurf;
  393. }
  394. }
  395. }
  396. }
  397. //---------------------------
  398. // copy matrix related stuff for back-end use
  399. // and setup a render matrix for faster culling
  400. //---------------------------
  401. vEntity->modelDepthHack = renderEntity->modelDepthHack;
  402. vEntity->weaponDepthHack = renderEntity->weaponDepthHack;
  403. vEntity->skipMotionBlur = renderEntity->skipMotionBlur;
  404. memcpy( vEntity->modelMatrix, entityDef->modelMatrix, sizeof( vEntity->modelMatrix ) );
  405. R_MatrixMultiply( entityDef->modelMatrix, viewDef->worldSpace.modelViewMatrix, vEntity->modelViewMatrix );
  406. idRenderMatrix viewMat;
  407. idRenderMatrix::Transpose( *(idRenderMatrix *)vEntity->modelViewMatrix, viewMat );
  408. idRenderMatrix::Multiply( viewDef->projectionRenderMatrix, viewMat, vEntity->mvp );
  409. if ( renderEntity->weaponDepthHack ) {
  410. idRenderMatrix::ApplyDepthHack( vEntity->mvp );
  411. }
  412. if ( renderEntity->modelDepthHack != 0.0f ) {
  413. idRenderMatrix::ApplyModelDepthHack( vEntity->mvp, renderEntity->modelDepthHack );
  414. }
  415. // local light and view origins are used to determine if the view is definitely outside
  416. // an extruded shadow volume, which means we can skip drawing the end caps
  417. idVec3 localViewOrigin;
  418. R_GlobalPointToLocal( vEntity->modelMatrix, viewDef->renderView.vieworg, localViewOrigin );
  419. //---------------------------
  420. // add all the model surfaces
  421. //---------------------------
  422. for ( int surfaceNum = 0; surfaceNum < model->NumSurfaces(); surfaceNum++ ) {
  423. const modelSurface_t *surf = model->Surface( surfaceNum );
  424. // for debugging, only show a single surface at a time
  425. if ( r_singleSurface.GetInteger() >= 0 && surfaceNum != r_singleSurface.GetInteger() ) {
  426. continue;
  427. }
  428. srfTriangles_t * tri = surf->geometry;
  429. if ( tri == NULL ) {
  430. continue;
  431. }
  432. if ( tri->numIndexes == NULL ) {
  433. continue; // happens for particles
  434. }
  435. const idMaterial * shader = surf->shader;
  436. if ( shader == NULL ) {
  437. continue;
  438. }
  439. if ( !shader->IsDrawn() ) {
  440. continue; // collision hulls, etc
  441. }
  442. // RemapShaderBySkin
  443. if ( entityDef->parms.customShader != NULL ) {
  444. // this is sort of a hack, but causes deformed surfaces to map to empty surfaces,
  445. // so the item highlight overlay doesn't highlight the autosprite surface
  446. if ( shader->Deform() ) {
  447. continue;
  448. }
  449. shader = entityDef->parms.customShader;
  450. } else if ( entityDef->parms.customSkin ) {
  451. shader = entityDef->parms.customSkin->RemapShaderBySkin( shader );
  452. if ( shader == NULL ) {
  453. continue;
  454. }
  455. if ( !shader->IsDrawn() ) {
  456. continue;
  457. }
  458. }
  459. // optionally override with the renderView->globalMaterial
  460. if ( tr.primaryRenderView.globalMaterial != NULL ) {
  461. shader = tr.primaryRenderView.globalMaterial;
  462. }
  463. SCOPED_PROFILE_EVENT( shader->GetName() );
  464. // debugging tool to make sure we have the correct pre-calculated bounds
  465. if ( r_checkBounds.GetBool() ) {
  466. for ( int j = 0; j < tri->numVerts; j++ ) {
  467. int k;
  468. for ( k = 0; k < 3; k++ ) {
  469. if ( tri->verts[j].xyz[k] > tri->bounds[1][k] + CHECK_BOUNDS_EPSILON
  470. || tri->verts[j].xyz[k] < tri->bounds[0][k] - CHECK_BOUNDS_EPSILON ) {
  471. common->Printf( "bad tri->bounds on %s:%s\n", entityDef->parms.hModel->Name(), shader->GetName() );
  472. break;
  473. }
  474. if ( tri->verts[j].xyz[k] > entityDef->localReferenceBounds[1][k] + CHECK_BOUNDS_EPSILON
  475. || tri->verts[j].xyz[k] < entityDef->localReferenceBounds[0][k] - CHECK_BOUNDS_EPSILON ) {
  476. common->Printf( "bad referenceBounds on %s:%s\n", entityDef->parms.hModel->Name(), shader->GetName() );
  477. break;
  478. }
  479. }
  480. if ( k != 3 ) {
  481. break;
  482. }
  483. }
  484. }
  485. // view frustum culling for the precise surface bounds, which is tighter
  486. // than the entire entity reference bounds
  487. // If the entire model wasn't visible, there is no need to check the
  488. // individual surfaces.
  489. const bool surfaceDirectlyVisible = modelIsVisible && !idRenderMatrix::CullBoundsToMVP( vEntity->mvp, tri->bounds );
  490. const bool gpuSkinned = ( tri->staticModelWithJoints != NULL && r_useGPUSkinning.GetBool() );
  491. //--------------------------
  492. // base drawing surface
  493. //--------------------------
  494. drawSurf_t * baseDrawSurf = NULL;
  495. if ( surfaceDirectlyVisible ) {
  496. // make sure we have an ambient cache and all necessary normals / tangents
  497. if ( !vertexCache.CacheIsCurrent( tri->indexCache ) ) {
  498. tri->indexCache = vertexCache.AllocIndex( tri->indexes, ALIGN( tri->numIndexes * sizeof( triIndex_t ), INDEX_CACHE_ALIGN ) );
  499. }
  500. if ( !vertexCache.CacheIsCurrent( tri->ambientCache ) ) {
  501. // we are going to use it for drawing, so make sure we have the tangents and normals
  502. if ( shader->ReceivesLighting() && !tri->tangentsCalculated ) {
  503. assert( tri->staticModelWithJoints == NULL );
  504. R_DeriveTangents( tri );
  505. assert( false ); // this should no longer be hit
  506. }
  507. tri->ambientCache = vertexCache.AllocVertex( tri->verts, ALIGN( tri->numVerts * sizeof( idDrawVert ), VERTEX_CACHE_ALIGN ) );
  508. }
  509. // add the surface for drawing
  510. // we can re-use some of the values for light interaction surfaces
  511. baseDrawSurf = (drawSurf_t *)R_FrameAlloc( sizeof( *baseDrawSurf ), FRAME_ALLOC_DRAW_SURFACE );
  512. baseDrawSurf->frontEndGeo = tri;
  513. baseDrawSurf->space = vEntity;
  514. baseDrawSurf->scissorRect = vEntity->scissorRect;
  515. baseDrawSurf->extraGLState = 0;
  516. baseDrawSurf->renderZFail = 0;
  517. R_SetupDrawSurfShader( baseDrawSurf, shader, renderEntity );
  518. // Check for deformations (eyeballs, flares, etc)
  519. const deform_t shaderDeform = shader->Deform();
  520. if ( shaderDeform != DFRM_NONE ) {
  521. drawSurf_t * deformDrawSurf = R_DeformDrawSurf( baseDrawSurf );
  522. if ( deformDrawSurf != NULL ) {
  523. // any deforms may have created multiple draw surfaces
  524. for ( drawSurf_t * surf = deformDrawSurf, * next = NULL; surf != NULL; surf = next ) {
  525. next = surf->nextOnLight;
  526. surf->linkChain = NULL;
  527. surf->nextOnLight = vEntity->drawSurfs;
  528. vEntity->drawSurfs = surf;
  529. }
  530. }
  531. }
  532. // Most deform source surfaces do not need to be rendered.
  533. // However, particles are rendered in conjunction with the source surface.
  534. if ( shaderDeform == DFRM_NONE || shaderDeform == DFRM_PARTICLE || shaderDeform == DFRM_PARTICLE2 ) {
  535. // copy verts and indexes to this frame's hardware memory if they aren't already there
  536. if ( !vertexCache.CacheIsCurrent( tri->ambientCache ) ) {
  537. tri->ambientCache = vertexCache.AllocVertex( tri->verts, ALIGN( tri->numVerts * sizeof( tri->verts[0] ), VERTEX_CACHE_ALIGN ) );
  538. }
  539. if ( !vertexCache.CacheIsCurrent( tri->indexCache ) ) {
  540. tri->indexCache = vertexCache.AllocIndex( tri->indexes, ALIGN( tri->numIndexes * sizeof( tri->indexes[0] ), INDEX_CACHE_ALIGN ) );
  541. }
  542. R_SetupDrawSurfJoints( baseDrawSurf, tri, shader );
  543. baseDrawSurf->numIndexes = tri->numIndexes;
  544. baseDrawSurf->ambientCache = tri->ambientCache;
  545. baseDrawSurf->indexCache = tri->indexCache;
  546. baseDrawSurf->shadowCache = 0;
  547. baseDrawSurf->linkChain = NULL; // link to the view
  548. baseDrawSurf->nextOnLight = vEntity->drawSurfs;
  549. vEntity->drawSurfs = baseDrawSurf;
  550. }
  551. }
  552. //----------------------------------------
  553. // add all light interactions
  554. //----------------------------------------
  555. for ( int contactedLight = 0; contactedLight < numContactedLights; contactedLight++ ) {
  556. viewLight_t * vLight = contactedLights[contactedLight];
  557. const idRenderLightLocal * lightDef = vLight->lightDef;
  558. const idInteraction * interaction = staticInteractions[contactedLight];
  559. // check for a static interaction
  560. surfaceInteraction_t *surfInter = NULL;
  561. if ( interaction > INTERACTION_EMPTY && interaction->staticInteraction ) {
  562. // we have a static interaction that was calculated accurately
  563. assert( model->NumSurfaces() == interaction->numSurfaces );
  564. surfInter = &interaction->surfaces[surfaceNum];
  565. } else {
  566. // try to do a more precise cull of this model surface to the light
  567. if ( R_CullModelBoundsToLight( lightDef, tri->bounds, entityDef->modelRenderMatrix ) ) {
  568. continue;
  569. }
  570. }
  571. // "invisible ink" lights and shaders (imp spawn drawing on walls, etc)
  572. if ( shader->Spectrum() != lightDef->lightShader->Spectrum() ) {
  573. continue;
  574. }
  575. // Calculate the local light origin to determine if the view is inside the shadow
  576. // projection and to calculate the triangle facing for dynamic shadow volumes.
  577. idVec3 localLightOrigin;
  578. R_GlobalPointToLocal( vEntity->modelMatrix, lightDef->globalLightOrigin, localLightOrigin );
  579. //--------------------------
  580. // surface light interactions
  581. //--------------------------
  582. dynamicShadowVolumeParms_t * dynamicShadowParms = NULL;
  583. if ( addInteractions && surfaceDirectlyVisible && shader->ReceivesLighting() ) {
  584. // static interactions can commonly find that no triangles from a surface
  585. // contact the light, even when the total model does
  586. if ( surfInter == NULL || surfInter->lightTrisIndexCache > 0 ) {
  587. // create a drawSurf for this interaction
  588. drawSurf_t * lightDrawSurf = (drawSurf_t *)R_FrameAlloc( sizeof( *lightDrawSurf ), FRAME_ALLOC_DRAW_SURFACE );
  589. if ( surfInter != NULL ) {
  590. // optimized static interaction
  591. lightDrawSurf->numIndexes = surfInter->numLightTrisIndexes;
  592. lightDrawSurf->indexCache = surfInter->lightTrisIndexCache;
  593. } else {
  594. // throw the entire source surface at it without any per-triangle culling
  595. lightDrawSurf->numIndexes = tri->numIndexes;
  596. lightDrawSurf->indexCache = tri->indexCache;
  597. // optionally cull the triangles to the light volume
  598. if ( r_cullDynamicLightTriangles.GetBool() ) {
  599. vertCacheHandle_t lightIndexCache = vertexCache.AllocIndex( NULL, ALIGN( lightDrawSurf->numIndexes * sizeof( triIndex_t ), INDEX_CACHE_ALIGN ) );
  600. if ( vertexCache.CacheIsCurrent( lightIndexCache ) ) {
  601. lightDrawSurf->indexCache = lightIndexCache;
  602. dynamicShadowParms = (dynamicShadowVolumeParms_t *)R_FrameAlloc( sizeof( dynamicShadowParms[0] ), FRAME_ALLOC_SHADOW_VOLUME_PARMS );
  603. dynamicShadowParms->verts = tri->verts;
  604. dynamicShadowParms->numVerts = tri->numVerts;
  605. dynamicShadowParms->indexes = tri->indexes;
  606. dynamicShadowParms->numIndexes = tri->numIndexes;
  607. dynamicShadowParms->silEdges = tri->silEdges;
  608. dynamicShadowParms->numSilEdges = tri->numSilEdges;
  609. dynamicShadowParms->joints = gpuSkinned ? tri->staticModelWithJoints->jointsInverted : NULL;
  610. dynamicShadowParms->numJoints = gpuSkinned ? tri->staticModelWithJoints->numInvertedJoints : 0;
  611. dynamicShadowParms->triangleBounds = tri->bounds;
  612. dynamicShadowParms->triangleMVP = vEntity->mvp;
  613. dynamicShadowParms->localLightOrigin = localLightOrigin;
  614. dynamicShadowParms->localViewOrigin = localViewOrigin;
  615. idRenderMatrix::Multiply( vLight->lightDef->baseLightProject, entityDef->modelRenderMatrix, dynamicShadowParms->localLightProject );
  616. dynamicShadowParms->zNear = znear;
  617. dynamicShadowParms->lightZMin = vLight->scissorRect.zmin;
  618. dynamicShadowParms->lightZMax = vLight->scissorRect.zmax;
  619. dynamicShadowParms->cullShadowTrianglesToLight = false;
  620. dynamicShadowParms->forceShadowCaps = false;
  621. dynamicShadowParms->useShadowPreciseInsideTest = false;
  622. dynamicShadowParms->useShadowDepthBounds = false;
  623. dynamicShadowParms->tempFacing = NULL;
  624. dynamicShadowParms->tempCulled = NULL;
  625. dynamicShadowParms->tempVerts = NULL;
  626. dynamicShadowParms->indexBuffer = NULL;
  627. dynamicShadowParms->shadowIndices = NULL;
  628. dynamicShadowParms->maxShadowIndices = 0;
  629. dynamicShadowParms->numShadowIndices = NULL;
  630. dynamicShadowParms->lightIndices = (triIndex_t *)vertexCache.MappedIndexBuffer( lightIndexCache );
  631. dynamicShadowParms->maxLightIndices = lightDrawSurf->numIndexes;
  632. dynamicShadowParms->numLightIndices = &lightDrawSurf->numIndexes;
  633. dynamicShadowParms->renderZFail = NULL;
  634. dynamicShadowParms->shadowZMin = NULL;
  635. dynamicShadowParms->shadowZMax = NULL;
  636. dynamicShadowParms->shadowVolumeState = & lightDrawSurf->shadowVolumeState;
  637. lightDrawSurf->shadowVolumeState = SHADOWVOLUME_UNFINISHED;
  638. dynamicShadowParms->next = vEntity->dynamicShadowVolumes;
  639. vEntity->dynamicShadowVolumes = dynamicShadowParms;
  640. }
  641. }
  642. }
  643. lightDrawSurf->ambientCache = tri->ambientCache;
  644. lightDrawSurf->shadowCache = 0;
  645. lightDrawSurf->frontEndGeo = tri;
  646. lightDrawSurf->space = vEntity;
  647. lightDrawSurf->material = shader;
  648. lightDrawSurf->extraGLState = 0;
  649. lightDrawSurf->scissorRect = vLight->scissorRect; // interactionScissor;
  650. lightDrawSurf->sort = 0.0f;
  651. lightDrawSurf->renderZFail = 0;
  652. lightDrawSurf->shaderRegisters = baseDrawSurf->shaderRegisters;
  653. R_SetupDrawSurfJoints( lightDrawSurf, tri, shader );
  654. // Determine which linked list to add the light surface to.
  655. // There will only be localSurfaces if the light casts shadows and
  656. // there are surfaces with NOSELFSHADOW.
  657. if ( shader->Coverage() == MC_TRANSLUCENT ) {
  658. lightDrawSurf->linkChain = &vLight->translucentInteractions;
  659. } else if ( !lightDef->parms.noShadows && shader->TestMaterialFlag( MF_NOSELFSHADOW ) ) {
  660. lightDrawSurf->linkChain = &vLight->localInteractions;
  661. } else {
  662. lightDrawSurf->linkChain = &vLight->globalInteractions;
  663. }
  664. lightDrawSurf->nextOnLight = vEntity->drawSurfs;
  665. vEntity->drawSurfs = lightDrawSurf;
  666. }
  667. }
  668. //--------------------------
  669. // surface shadows
  670. //--------------------------
  671. if ( !shader->SurfaceCastsShadow() ) {
  672. continue;
  673. }
  674. if ( !lightDef->LightCastsShadows() ) {
  675. continue;
  676. }
  677. if ( tri->silEdges == NULL ) {
  678. continue; // can happen for beam models (shouldn't use a shadow casting material, though...)
  679. }
  680. // if the static shadow does not have any shadows
  681. if ( surfInter != NULL && surfInter->numShadowIndexes == 0 ) {
  682. continue;
  683. }
  684. // some entities, like view weapons, don't cast any shadows
  685. if ( entityDef->parms.noShadow ) {
  686. continue;
  687. }
  688. // No shadow if it's suppressed for this light.
  689. if ( entityDef->parms.suppressShadowInLightID && entityDef->parms.suppressShadowInLightID == lightDef->parms.lightId ) {
  690. continue;
  691. }
  692. if ( lightDef->parms.prelightModel && lightDef->lightHasMoved == false &&
  693. entityDef->parms.hModel->IsStaticWorldModel() && !r_skipPrelightShadows.GetBool() ) {
  694. // static light / world model shadow interacitons
  695. // are always captured in the prelight shadow volume
  696. continue;
  697. }
  698. // If the shadow is drawn (or translucent), but the model isn't, we must include the shadow caps
  699. // because we may be able to see into the shadow volume even though the view is outside it.
  700. // This happens for the player world weapon and possibly some animations in multiplayer.
  701. const bool forceShadowCaps = !addInteractions || r_forceShadowCaps.GetBool();
  702. drawSurf_t * shadowDrawSurf = (drawSurf_t *)R_FrameAlloc( sizeof( *shadowDrawSurf ), FRAME_ALLOC_DRAW_SURFACE );
  703. if ( surfInter != NULL ) {
  704. shadowDrawSurf->numIndexes = 0;
  705. shadowDrawSurf->indexCache = surfInter->shadowIndexCache;
  706. shadowDrawSurf->shadowCache = tri->shadowCache;
  707. shadowDrawSurf->scissorRect = vLight->scissorRect; // default to the light scissor and light depth bounds
  708. shadowDrawSurf->shadowVolumeState = SHADOWVOLUME_DONE; // assume the shadow volume is done in case r_skipStaticShadows is set
  709. if ( !r_skipStaticShadows.GetBool() ) {
  710. staticShadowVolumeParms_t * staticShadowParms = (staticShadowVolumeParms_t *)R_FrameAlloc( sizeof( staticShadowParms[0] ), FRAME_ALLOC_SHADOW_VOLUME_PARMS );
  711. staticShadowParms->verts = tri->staticShadowVertexes;
  712. staticShadowParms->numVerts = tri->numVerts * 2;
  713. staticShadowParms->indexes = surfInter->shadowIndexes;
  714. staticShadowParms->numIndexes = surfInter->numShadowIndexes;
  715. staticShadowParms->numShadowIndicesWithCaps = surfInter->numShadowIndexes;
  716. staticShadowParms->numShadowIndicesNoCaps = surfInter->numShadowIndexesNoCaps;
  717. staticShadowParms->triangleBounds = tri->bounds;
  718. staticShadowParms->triangleMVP = vEntity->mvp;
  719. staticShadowParms->localLightOrigin = localLightOrigin;
  720. staticShadowParms->localViewOrigin = localViewOrigin;
  721. staticShadowParms->zNear = znear;
  722. staticShadowParms->lightZMin = vLight->scissorRect.zmin;
  723. staticShadowParms->lightZMax = vLight->scissorRect.zmax;
  724. staticShadowParms->forceShadowCaps = forceShadowCaps;
  725. staticShadowParms->useShadowPreciseInsideTest = r_useShadowPreciseInsideTest.GetBool();
  726. staticShadowParms->useShadowDepthBounds = r_useShadowDepthBounds.GetBool();
  727. staticShadowParms->numShadowIndices = & shadowDrawSurf->numIndexes;
  728. staticShadowParms->renderZFail = & shadowDrawSurf->renderZFail;
  729. staticShadowParms->shadowZMin = & shadowDrawSurf->scissorRect.zmin;
  730. staticShadowParms->shadowZMax = & shadowDrawSurf->scissorRect.zmax;
  731. staticShadowParms->shadowVolumeState = & shadowDrawSurf->shadowVolumeState;
  732. shadowDrawSurf->shadowVolumeState = SHADOWVOLUME_UNFINISHED;
  733. staticShadowParms->next = vEntity->staticShadowVolumes;
  734. vEntity->staticShadowVolumes = staticShadowParms;
  735. }
  736. } else {
  737. // When CPU skinning the dynamic shadow verts of a dynamic model may not have been copied to buffer memory yet.
  738. if ( !vertexCache.CacheIsCurrent( tri->shadowCache ) ) {
  739. assert( !gpuSkinned ); // the shadow cache should be static when using GPU skinning
  740. // Extracts just the xyz values from a set of full size drawverts, and
  741. // duplicates them with w set to 0 and 1 for the vertex program to project.
  742. // This is constant for any number of lights, the vertex program takes care
  743. // of projecting the verts to infinity for a particular light.
  744. tri->shadowCache = vertexCache.AllocVertex( NULL, ALIGN( tri->numVerts * 2 * sizeof( idShadowVert ), VERTEX_CACHE_ALIGN ) );
  745. idShadowVert * shadowVerts = (idShadowVert *)vertexCache.MappedVertexBuffer( tri->shadowCache );
  746. idShadowVert::CreateShadowCache( shadowVerts, tri->verts, tri->numVerts );
  747. }
  748. const int maxShadowVolumeIndexes = tri->numSilEdges * 6 + tri->numIndexes * 2;
  749. shadowDrawSurf->numIndexes = 0;
  750. shadowDrawSurf->indexCache = vertexCache.AllocIndex( NULL, ALIGN( maxShadowVolumeIndexes * sizeof( triIndex_t ), INDEX_CACHE_ALIGN ) );
  751. shadowDrawSurf->shadowCache = tri->shadowCache;
  752. shadowDrawSurf->scissorRect = vLight->scissorRect; // default to the light scissor and light depth bounds
  753. shadowDrawSurf->shadowVolumeState = SHADOWVOLUME_DONE; // assume the shadow volume is done in case the index cache allocation failed
  754. // if the index cache was successfully allocated then setup the parms to create a shadow volume in parallel
  755. if ( vertexCache.CacheIsCurrent( shadowDrawSurf->indexCache ) && !r_skipDynamicShadows.GetBool() ) {
  756. // if the parms were not already allocated for culling interaction triangles to the light frustum
  757. if ( dynamicShadowParms == NULL ) {
  758. dynamicShadowParms = (dynamicShadowVolumeParms_t *)R_FrameAlloc( sizeof( dynamicShadowParms[0] ), FRAME_ALLOC_SHADOW_VOLUME_PARMS );
  759. } else {
  760. // the shadow volume will be rendered first so when the interaction surface is drawn the triangles have been culled for sure
  761. *dynamicShadowParms->shadowVolumeState = SHADOWVOLUME_DONE;
  762. }
  763. dynamicShadowParms->verts = tri->verts;
  764. dynamicShadowParms->numVerts = tri->numVerts;
  765. dynamicShadowParms->indexes = tri->indexes;
  766. dynamicShadowParms->numIndexes = tri->numIndexes;
  767. dynamicShadowParms->silEdges = tri->silEdges;
  768. dynamicShadowParms->numSilEdges = tri->numSilEdges;
  769. dynamicShadowParms->joints = gpuSkinned ? tri->staticModelWithJoints->jointsInverted : NULL;
  770. dynamicShadowParms->numJoints = gpuSkinned ? tri->staticModelWithJoints->numInvertedJoints : 0;
  771. dynamicShadowParms->triangleBounds = tri->bounds;
  772. dynamicShadowParms->triangleMVP = vEntity->mvp;
  773. dynamicShadowParms->localLightOrigin = localLightOrigin;
  774. dynamicShadowParms->localViewOrigin = localViewOrigin;
  775. idRenderMatrix::Multiply( vLight->lightDef->baseLightProject, entityDef->modelRenderMatrix, dynamicShadowParms->localLightProject );
  776. dynamicShadowParms->zNear = znear;
  777. dynamicShadowParms->lightZMin = vLight->scissorRect.zmin;
  778. dynamicShadowParms->lightZMax = vLight->scissorRect.zmax;
  779. dynamicShadowParms->cullShadowTrianglesToLight = r_cullDynamicShadowTriangles.GetBool();
  780. dynamicShadowParms->forceShadowCaps = forceShadowCaps;
  781. dynamicShadowParms->useShadowPreciseInsideTest = r_useShadowPreciseInsideTest.GetBool();
  782. dynamicShadowParms->useShadowDepthBounds = r_useShadowDepthBounds.GetBool();
  783. dynamicShadowParms->tempFacing = NULL;
  784. dynamicShadowParms->tempCulled = NULL;
  785. dynamicShadowParms->tempVerts = NULL;
  786. dynamicShadowParms->indexBuffer = NULL;
  787. dynamicShadowParms->shadowIndices = (triIndex_t *)vertexCache.MappedIndexBuffer( shadowDrawSurf->indexCache );
  788. dynamicShadowParms->maxShadowIndices = maxShadowVolumeIndexes;
  789. dynamicShadowParms->numShadowIndices = & shadowDrawSurf->numIndexes;
  790. // dynamicShadowParms->lightIndices may have already been set for the interaction surface
  791. // dynamicShadowParms->maxLightIndices may have already been set for the interaction surface
  792. // dynamicShadowParms->numLightIndices may have already been set for the interaction surface
  793. dynamicShadowParms->renderZFail = & shadowDrawSurf->renderZFail;
  794. dynamicShadowParms->shadowZMin = & shadowDrawSurf->scissorRect.zmin;
  795. dynamicShadowParms->shadowZMax = & shadowDrawSurf->scissorRect.zmax;
  796. dynamicShadowParms->shadowVolumeState = & shadowDrawSurf->shadowVolumeState;
  797. shadowDrawSurf->shadowVolumeState = SHADOWVOLUME_UNFINISHED;
  798. // if the parms we not already linked for culling interaction triangles to the light frustum
  799. if ( dynamicShadowParms->lightIndices == NULL ) {
  800. dynamicShadowParms->next = vEntity->dynamicShadowVolumes;
  801. vEntity->dynamicShadowVolumes = dynamicShadowParms;
  802. }
  803. tr.pc.c_createShadowVolumes++;
  804. }
  805. }
  806. assert( vertexCache.CacheIsCurrent( shadowDrawSurf->shadowCache ) );
  807. assert( vertexCache.CacheIsCurrent( shadowDrawSurf->indexCache ) );
  808. shadowDrawSurf->ambientCache = 0;
  809. shadowDrawSurf->frontEndGeo = NULL;
  810. shadowDrawSurf->space = vEntity;
  811. shadowDrawSurf->material = NULL;
  812. shadowDrawSurf->extraGLState = 0;
  813. shadowDrawSurf->sort = 0.0f;
  814. shadowDrawSurf->shaderRegisters = NULL;
  815. R_SetupDrawSurfJoints( shadowDrawSurf, tri, NULL );
  816. // determine which linked list to add the shadow surface to
  817. shadowDrawSurf->linkChain = shader->TestMaterialFlag( MF_NOSELFSHADOW ) ? &vLight->localShadows : &vLight->globalShadows;
  818. shadowDrawSurf->nextOnLight = vEntity->drawSurfs;
  819. vEntity->drawSurfs = shadowDrawSurf;
  820. }
  821. }
  822. }
  823. REGISTER_PARALLEL_JOB( R_AddSingleModel, "R_AddSingleModel" );
  824. /*
  825. =================
  826. R_LinkDrawSurfToView
  827. Als called directly by GuiModel
  828. =================
  829. */
  830. void R_LinkDrawSurfToView( drawSurf_t * drawSurf, viewDef_t * viewDef ) {
  831. // if it doesn't fit, resize the list
  832. if ( viewDef->numDrawSurfs == viewDef->maxDrawSurfs ) {
  833. drawSurf_t **old = viewDef->drawSurfs;
  834. int count;
  835. if ( viewDef->maxDrawSurfs == 0 ) {
  836. viewDef->maxDrawSurfs = INITIAL_DRAWSURFS;
  837. count = 0;
  838. } else {
  839. count = viewDef->maxDrawSurfs * sizeof( viewDef->drawSurfs[0] );
  840. viewDef->maxDrawSurfs *= 2;
  841. }
  842. viewDef->drawSurfs = (drawSurf_t **)R_FrameAlloc( viewDef->maxDrawSurfs * sizeof( viewDef->drawSurfs[0] ), FRAME_ALLOC_DRAW_SURFACE_POINTER );
  843. memcpy( viewDef->drawSurfs, old, count );
  844. }
  845. viewDef->drawSurfs[viewDef->numDrawSurfs] = drawSurf;
  846. viewDef->numDrawSurfs++;
  847. }
  848. /*
  849. ===================
  850. R_AddModels
  851. The end result of running this is the addition of drawSurf_t to the
  852. tr.viewDef->drawSurfs[] array and light link chains, along with
  853. frameData and vertexCache allocations to support the drawSurfs.
  854. ===================
  855. */
  856. void R_AddModels() {
  857. SCOPED_PROFILE_EVENT( "R_AddModels" );
  858. tr.viewDef->viewEntitys = R_SortViewEntities( tr.viewDef->viewEntitys );
  859. //-------------------------------------------------
  860. // Go through each view entity that is either visible to the view, or to
  861. // any light that intersects the view (for shadows).
  862. //-------------------------------------------------
  863. if ( r_useParallelAddModels.GetBool() ) {
  864. for ( viewEntity_t * vEntity = tr.viewDef->viewEntitys; vEntity != NULL; vEntity = vEntity->next ) {
  865. tr.frontEndJobList->AddJob( (jobRun_t)R_AddSingleModel, vEntity );
  866. }
  867. tr.frontEndJobList->Submit();
  868. tr.frontEndJobList->Wait();
  869. } else {
  870. for ( viewEntity_t * vEntity = tr.viewDef->viewEntitys; vEntity != NULL; vEntity = vEntity->next ) {
  871. R_AddSingleModel( vEntity );
  872. }
  873. }
  874. //-------------------------------------------------
  875. // Kick off jobs to setup static and dynamic shadow volumes.
  876. //-------------------------------------------------
  877. if ( r_useParallelAddShadows.GetInteger() == 1 ) {
  878. for ( viewEntity_t * vEntity = tr.viewDef->viewEntitys; vEntity != NULL; vEntity = vEntity->next ) {
  879. for ( staticShadowVolumeParms_t * shadowParms = vEntity->staticShadowVolumes; shadowParms != NULL; shadowParms = shadowParms->next ) {
  880. tr.frontEndJobList->AddJob( (jobRun_t)StaticShadowVolumeJob, shadowParms );
  881. }
  882. for ( dynamicShadowVolumeParms_t * shadowParms = vEntity->dynamicShadowVolumes; shadowParms != NULL; shadowParms = shadowParms->next ) {
  883. tr.frontEndJobList->AddJob( (jobRun_t)DynamicShadowVolumeJob, shadowParms );
  884. }
  885. vEntity->staticShadowVolumes = NULL;
  886. vEntity->dynamicShadowVolumes = NULL;
  887. }
  888. tr.frontEndJobList->Submit();
  889. // wait here otherwise the shadow volume index buffer may be unmapped before all shadow volumes have been constructed
  890. tr.frontEndJobList->Wait();
  891. } else {
  892. int start = Sys_Microseconds();
  893. for ( viewEntity_t * vEntity = tr.viewDef->viewEntitys; vEntity != NULL; vEntity = vEntity->next ) {
  894. for ( staticShadowVolumeParms_t * shadowParms = vEntity->staticShadowVolumes; shadowParms != NULL; shadowParms = shadowParms->next ) {
  895. StaticShadowVolumeJob( shadowParms );
  896. }
  897. for ( dynamicShadowVolumeParms_t * shadowParms = vEntity->dynamicShadowVolumes; shadowParms != NULL; shadowParms = shadowParms->next ) {
  898. DynamicShadowVolumeJob( shadowParms );
  899. }
  900. vEntity->staticShadowVolumes = NULL;
  901. vEntity->dynamicShadowVolumes = NULL;
  902. }
  903. int end = Sys_Microseconds();
  904. backEnd.pc.shadowMicroSec += end - start;
  905. }
  906. //-------------------------------------------------
  907. // Move the draw surfs to the view.
  908. //-------------------------------------------------
  909. tr.viewDef->numDrawSurfs = 0; // clear the ambient surface list
  910. tr.viewDef->maxDrawSurfs = 0; // will be set to INITIAL_DRAWSURFS on R_LinkDrawSurfToView
  911. for ( viewEntity_t * vEntity = tr.viewDef->viewEntitys; vEntity != NULL; vEntity = vEntity->next ) {
  912. for ( drawSurf_t * ds = vEntity->drawSurfs; ds != NULL; ) {
  913. drawSurf_t * next = ds->nextOnLight;
  914. if ( ds->linkChain == NULL ) {
  915. R_LinkDrawSurfToView( ds, tr.viewDef );
  916. } else {
  917. ds->nextOnLight = *ds->linkChain;
  918. *ds->linkChain = ds;
  919. }
  920. ds = next;
  921. }
  922. vEntity->drawSurfs = NULL;
  923. }
  924. }