interiorRender.cpp 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359
  1. //-----------------------------------------------------------------------------
  2. // Copyright (c) 2012 GarageGames, LLC
  3. //
  4. // Permission is hereby granted, free of charge, to any person obtaining a copy
  5. // of this software and associated documentation files (the "Software"), to
  6. // deal in the Software without restriction, including without limitation the
  7. // rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
  8. // sell copies of the Software, and to permit persons to whom the Software is
  9. // furnished to do so, subject to the following conditions:
  10. //
  11. // The above copyright notice and this permission notice shall be included in
  12. // all copies or substantial portions of the Software.
  13. //
  14. // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  15. // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  16. // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
  17. // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
  18. // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
  19. // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
  20. // IN THE SOFTWARE.
  21. //-----------------------------------------------------------------------------
  22. #include "interior/interior.h"
  23. #include "scene/sceneRenderState.h"
  24. #include "scene/sceneManager.h"
  25. #include "lighting/lightManager.h"
  26. #include "gfx/bitmap/gBitmap.h"
  27. #include "math/mMatrix.h"
  28. #include "math/mRect.h"
  29. #include "core/bitVector.h"
  30. #include "platform/profiler.h"
  31. #include "gfx/gfxDevice.h"
  32. #include "interior/interiorInstance.h"
  33. #include "gfx/gfxTextureHandle.h"
  34. #include "materials/materialList.h"
  35. #include "materials/sceneData.h"
  36. #include "materials/matInstance.h"
  37. #include "materials/materialFeatureTypes.h"
  38. #include "math/mathUtils.h"
  39. #include "renderInstance/renderPassManager.h"
  40. #include "core/frameAllocator.h"
  41. extern bool sgFogActive;
  42. extern U16* sgActivePolyList;
  43. extern U32 sgActivePolyListSize;
  44. extern U16* sgFogPolyList;
  45. extern U32 sgFogPolyListSize;
  46. extern U16* sgEnvironPolyList;
  47. extern U32 sgEnvironPolyListSize;
  48. Point3F sgOSCamPosition;
  49. U32 sgRenderIndices[2048];
  50. U32 csgNumAllowedPoints = 256;
  51. extern "C" {
  52. F32 texGen0[8];
  53. F32 texGen1[8];
  54. Point2F *fogCoordinatePointer;
  55. }
  56. //------------------------------------------------------------------------------
  57. // Set up render states for interor rendering
  58. //------------------------------------------------------------------------------
  59. void Interior::setupRenderStates()
  60. {
  61. // GFX2_RENDER_MERGE
  62. // I suspect we don't need this anymore - MDF
  63. GFX->setStateBlock(mInteriorSB);
  64. }
  65. //------------------------------------------------------------------------------
  66. // Setup zone visibility
  67. //------------------------------------------------------------------------------
  68. ZoneVisDeterminer Interior::setupZoneVis( InteriorInstance *intInst, SceneRenderState *state )
  69. {
  70. U32 zoneOffset = intInst->getZoneRangeStart() != 0xFFFFFFFF ? intInst->getZoneRangeStart() : 0;
  71. U32 baseZone = 0xFFFFFFFF;
  72. if (intInst->_getNumCurrZones() == 1)
  73. {
  74. baseZone = intInst->_getCurrZone(0);
  75. }
  76. else
  77. {
  78. for (U32 i = 0; i < intInst->_getNumCurrZones(); i++)
  79. {
  80. if (state->getCullingState().getZoneState(intInst->_getCurrZone(i)).isZoneVisible())
  81. {
  82. if (baseZone == 0xFFFFFFFF) {
  83. baseZone = intInst->_getCurrZone(i);
  84. break;
  85. }
  86. }
  87. }
  88. if (baseZone == 0xFFFFFFFF)
  89. {
  90. baseZone = intInst->_getCurrZone(0);
  91. }
  92. }
  93. ZoneVisDeterminer zoneVis;
  94. zoneVis.runFromState(state, zoneOffset, baseZone);
  95. return zoneVis;
  96. }
  97. //------------------------------------------------------------------------------
  98. // Setup scenegraph data structure for materials
  99. //------------------------------------------------------------------------------
  100. SceneData Interior::setupSceneGraphInfo( InteriorInstance *intInst,
  101. SceneRenderState *state )
  102. {
  103. SceneData sgData;
  104. sgData.init( state );
  105. // TODO: This sucks... interiors only get sunlight?
  106. sgData.lights[0] = LIGHTMGR->getSpecialLight( LightManager::slSunLightType );
  107. sgData.objTrans = &intInst->getTransform();
  108. //sgData.backBuffTex = GFX->getSfxBackBuffer(); // NOTICE: SFXBB is removed and refraction is disabled!
  109. return sgData;
  110. }
  111. //------------------------------------------------------------------------------
  112. // Render zone RenderNode
  113. //------------------------------------------------------------------------------
  114. void Interior::renderZoneNode( SceneRenderState *state,
  115. RenderNode &node,
  116. InteriorInstance *intInst,
  117. SceneData &sgData,
  118. MeshRenderInst *coreRi )
  119. {
  120. BaseMatInstance *matInst = state->getOverrideMaterial( node.matInst );
  121. if ( !matInst )
  122. return;
  123. MeshRenderInst *ri = state->getRenderPass()->allocInst<MeshRenderInst>();
  124. *ri = *coreRi;
  125. ri->lights[0] = LIGHTMGR->getSpecialLight( LightManager::slSunLightType );
  126. // setup lightmap
  127. if (dStricmp(LIGHTMGR->getId(), "BLM") == 0)
  128. {
  129. if ( node.lightMapIndex != U8(-1) &&
  130. matInst->getFeatures().hasFeature( MFT_LightMap ) )
  131. ri->lightmap = gInteriorLMManager.getHandle(mLMHandle, intInst->getLMHandle(), node.lightMapIndex );
  132. }
  133. ri->matInst = matInst;
  134. ri->primBuffIndex = node.primInfoIndex;
  135. if ( matInst->getMaterial()->isTranslucent() )
  136. {
  137. ri->type = RenderPassManager::RIT_Translucent;
  138. ri->translucentSort = true;
  139. ri->sortDistSq = intInst->getRenderWorldBox().getSqDistanceToPoint( state->getCameraPosition() );
  140. }
  141. // Sort by the material then the normal map or vertex buffer!
  142. ri->defaultKey = matInst->getStateHint();
  143. ri->defaultKey2 = ri->lightmap ? (U32)ri->lightmap : (U32)ri->vertBuff;
  144. state->getRenderPass()->addInst( ri );
  145. }
  146. //------------------------------------------------------------------------------
  147. // Render zone RenderNode
  148. //------------------------------------------------------------------------------
  149. void Interior::renderReflectNode( SceneRenderState *state,
  150. ReflectRenderNode &node,
  151. InteriorInstance *intInst,
  152. SceneData &sgData,
  153. MeshRenderInst *coreRi )
  154. {
  155. BaseMatInstance *matInst = state->getOverrideMaterial( node.matInst );
  156. if ( !matInst )
  157. return;
  158. MeshRenderInst *ri = state->getRenderPass()->allocInst<MeshRenderInst>();
  159. *ri = *coreRi;
  160. ri->vertBuff = &mReflectVertBuff;
  161. ri->primBuff = &mReflectPrimBuff;
  162. // use sgData.backBuffer to transfer the reflect texture to the materials
  163. PlaneReflector *rp = &intInst->mPlaneReflectors[ node.reflectPlaneIndex ];
  164. ri->reflectTex = rp->reflectTex;
  165. ri->reflective = true;
  166. // setup lightmap
  167. if (dStricmp(LIGHTMGR->getId(), "BLM") == 0)
  168. {
  169. if ( node.lightMapIndex != U8(-1) &&
  170. matInst->getFeatures().hasFeature( MFT_LightMap ) )
  171. ri->lightmap = gInteriorLMManager.getHandle(mLMHandle, intInst->getLMHandle(), node.lightMapIndex );
  172. }
  173. ri->matInst = matInst;
  174. ri->primBuffIndex = node.primInfoIndex;
  175. // Sort by the material then the normal map or vertex buffer!
  176. ri->defaultKey = matInst->getStateHint();
  177. ri->defaultKey2 = ri->lightmap ? (U32)ri->lightmap : (U32)ri->vertBuff;
  178. state->getRenderPass()->addInst( ri );
  179. }
  180. //------------------------------------------------------------------------------
  181. // Setup the rendering
  182. //------------------------------------------------------------------------------
  183. void Interior::setupRender( InteriorInstance *intInst,
  184. SceneRenderState *state,
  185. MeshRenderInst *coreRi, const MatrixF* worldToCamera )
  186. {
  187. // Set the vertex and primitive buffers
  188. coreRi->vertBuff = &mVertBuff;
  189. coreRi->primBuff = &mPrimBuff;
  190. // Grab our render transform and scale it
  191. MatrixF objectToWorld = intInst->getRenderTransform();
  192. objectToWorld.scale( intInst->getScale() );
  193. coreRi->objectToWorld = state->getRenderPass()->allocUniqueXform(objectToWorld);
  194. coreRi->worldToCamera = state->getRenderPass()->allocUniqueXform(*worldToCamera); // This is handed down from SceneRenderState::renderCurrentImages()
  195. coreRi->projection = state->getRenderPass()->allocSharedXform(RenderPassManager::Projection);
  196. coreRi->type = RenderPassManager::RIT_Interior;
  197. // NOTICE: SFXBB is removed and refraction is disabled!
  198. //coreRi->backBuffTex = GFX->getSfxBackBuffer();
  199. }
  200. //------------------------------------------------------------------------------
  201. // Render
  202. //------------------------------------------------------------------------------
  203. void Interior::prepBatchRender( InteriorInstance *intInst, SceneRenderState *state )
  204. {
  205. // coreRi - used as basis for subsequent interior ri allocations
  206. MeshRenderInst *coreRi = state->getRenderPass()->allocInst<MeshRenderInst>();
  207. SceneData sgData;
  208. sgData.init( state );
  209. setupRender( intInst, state, coreRi, &state->getWorldViewMatrix() );
  210. ZoneVisDeterminer zoneVis = setupZoneVis( intInst, state );
  211. // GFX2_RENDER_MERGE
  212. #ifndef TORQUE_SHIPPING
  213. if( smRenderMode != 0 )
  214. {
  215. ObjectRenderInst *ri = state->getRenderPass()->allocInst<ObjectRenderInst>();
  216. ri->renderDelegate.bind(intInst, &InteriorInstance::_renderObject);
  217. ri->type = RenderPassManager::RIT_Object;
  218. state->getRenderPass()->addInst( ri );
  219. return;
  220. }
  221. #endif
  222. // render zones
  223. for( U32 i=0; i<mZones.size(); i++ )
  224. {
  225. // No need to try to render zones without any surfaces
  226. if (mZones[i].surfaceCount == 0)
  227. continue;
  228. if( zoneVis.isZoneVisible(i) == false && !state->isReflectPass() )
  229. continue;
  230. for( U32 j=0; j<mZoneRNList[i].renderNodeList.size(); j++ )
  231. {
  232. RenderNode &node = mZoneRNList[i].renderNodeList[j];
  233. renderZoneNode( state, node, intInst, sgData, coreRi );
  234. }
  235. }
  236. // render static meshes...
  237. for(U32 i=0; i<mStaticMeshes.size(); i++)
  238. mStaticMeshes[i]->render( state, *coreRi, getLMHandle(),
  239. intInst->getLMHandle(), intInst );
  240. // render reflective surfaces
  241. if ( !state->isReflectPass() )
  242. {
  243. renderLights(state, intInst, sgData, coreRi, zoneVis);
  244. for( U32 i=0; i<mZones.size(); i++ )
  245. {
  246. if( zoneVis.isZoneVisible(i) == false ) continue;
  247. for( U32 j=0; j<mZoneReflectRNList[i].reflectList.size(); j++ )
  248. {
  249. ReflectRenderNode &node = mZoneReflectRNList[i].reflectList[j];
  250. renderReflectNode( state, node, intInst, sgData, coreRi );
  251. }
  252. }
  253. }
  254. }
  255. void Interior::renderLights( SceneRenderState* state,
  256. InteriorInstance *intInst,
  257. SceneData &sgData,
  258. MeshRenderInst *coreRi,
  259. const ZoneVisDeterminer &zonevis )
  260. {
  261. // TODO!
  262. /*
  263. if (!smLightPlugin)
  264. return;
  265. if (!smLightPlugin->interiorInstInit(intInst))
  266. return;
  267. // build the render instances...
  268. for(U32 z=0; z<mZones.size(); z++)
  269. {
  270. if(!zonevis.isZoneVisible(z))
  271. continue;
  272. Zone &zone = mZones[z];
  273. S32 zoneid = zone.zoneId - 1;
  274. if(zoneid > -1)
  275. zoneid += intInst->getZoneRangeStart();// only zone managers...
  276. else
  277. zoneid = intInst->_getCurrZone(0);// if not what zone is it in...
  278. if (!smLightPlugin->zoneInit(zoneid))
  279. continue;
  280. static Vector<MeshRenderInst*> sRenderList;
  281. sRenderList.clear();
  282. for(U32 j=0; j<mZoneRNList[z].renderNodeList.size(); j++)
  283. {
  284. RenderNode &node = mZoneRNList[z].renderNodeList[j];
  285. if (!node.matInst)
  286. continue;
  287. MeshRenderInst *ri = state->getRenderPass()->allocInst<MeshRenderInst>();
  288. *ri = *coreRi;
  289. ri->type = RenderPassManager::RIT_InteriorDynamicLighting;
  290. ri->matInst = node.matInst;
  291. ri->primBuffIndex = node.primInfoIndex;
  292. sRenderList.push_back(ri);
  293. }
  294. smLightPlugin->processRI(state, sRenderList);
  295. }
  296. */
  297. }