| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359 |
- //-----------------------------------------------------------------------------
- // Copyright (c) 2012 GarageGames, LLC
- //
- // Permission is hereby granted, free of charge, to any person obtaining a copy
- // of this software and associated documentation files (the "Software"), to
- // deal in the Software without restriction, including without limitation the
- // rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
- // sell copies of the Software, and to permit persons to whom the Software is
- // furnished to do so, subject to the following conditions:
- //
- // The above copyright notice and this permission notice shall be included in
- // all copies or substantial portions of the Software.
- //
- // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
- // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
- // IN THE SOFTWARE.
- //-----------------------------------------------------------------------------
- #include "interior/interior.h"
- #include "scene/sceneRenderState.h"
- #include "scene/sceneManager.h"
- #include "lighting/lightManager.h"
- #include "gfx/bitmap/gBitmap.h"
- #include "math/mMatrix.h"
- #include "math/mRect.h"
- #include "core/bitVector.h"
- #include "platform/profiler.h"
- #include "gfx/gfxDevice.h"
- #include "interior/interiorInstance.h"
- #include "gfx/gfxTextureHandle.h"
- #include "materials/materialList.h"
- #include "materials/sceneData.h"
- #include "materials/matInstance.h"
- #include "materials/materialFeatureTypes.h"
- #include "math/mathUtils.h"
- #include "renderInstance/renderPassManager.h"
- #include "core/frameAllocator.h"
- extern bool sgFogActive;
- extern U16* sgActivePolyList;
- extern U32 sgActivePolyListSize;
- extern U16* sgFogPolyList;
- extern U32 sgFogPolyListSize;
- extern U16* sgEnvironPolyList;
- extern U32 sgEnvironPolyListSize;
- Point3F sgOSCamPosition;
- U32 sgRenderIndices[2048];
- U32 csgNumAllowedPoints = 256;
- extern "C" {
- F32 texGen0[8];
- F32 texGen1[8];
- Point2F *fogCoordinatePointer;
- }
- //------------------------------------------------------------------------------
- // Set up render states for interor rendering
- //------------------------------------------------------------------------------
- void Interior::setupRenderStates()
- {
- // GFX2_RENDER_MERGE
- // I suspect we don't need this anymore - MDF
- GFX->setStateBlock(mInteriorSB);
- }
- //------------------------------------------------------------------------------
- // Setup zone visibility
- //------------------------------------------------------------------------------
- ZoneVisDeterminer Interior::setupZoneVis( InteriorInstance *intInst, SceneRenderState *state )
- {
- U32 zoneOffset = intInst->getZoneRangeStart() != 0xFFFFFFFF ? intInst->getZoneRangeStart() : 0;
- U32 baseZone = 0xFFFFFFFF;
- if (intInst->_getNumCurrZones() == 1)
- {
- baseZone = intInst->_getCurrZone(0);
- }
- else
- {
- for (U32 i = 0; i < intInst->_getNumCurrZones(); i++)
- {
- if (state->getCullingState().getZoneState(intInst->_getCurrZone(i)).isZoneVisible())
- {
- if (baseZone == 0xFFFFFFFF) {
- baseZone = intInst->_getCurrZone(i);
- break;
- }
- }
- }
- if (baseZone == 0xFFFFFFFF)
- {
- baseZone = intInst->_getCurrZone(0);
- }
- }
- ZoneVisDeterminer zoneVis;
- zoneVis.runFromState(state, zoneOffset, baseZone);
- return zoneVis;
- }
- //------------------------------------------------------------------------------
- // Setup scenegraph data structure for materials
- //------------------------------------------------------------------------------
- SceneData Interior::setupSceneGraphInfo( InteriorInstance *intInst,
- SceneRenderState *state )
- {
- SceneData sgData;
- sgData.init( state );
- // TODO: This sucks... interiors only get sunlight?
- sgData.lights[0] = LIGHTMGR->getSpecialLight( LightManager::slSunLightType );
- sgData.objTrans = &intInst->getTransform();
- //sgData.backBuffTex = GFX->getSfxBackBuffer(); // NOTICE: SFXBB is removed and refraction is disabled!
- return sgData;
- }
- //------------------------------------------------------------------------------
- // Render zone RenderNode
- //------------------------------------------------------------------------------
- void Interior::renderZoneNode( SceneRenderState *state,
- RenderNode &node,
- InteriorInstance *intInst,
- SceneData &sgData,
- MeshRenderInst *coreRi )
- {
- BaseMatInstance *matInst = state->getOverrideMaterial( node.matInst );
- if ( !matInst )
- return;
- MeshRenderInst *ri = state->getRenderPass()->allocInst<MeshRenderInst>();
- *ri = *coreRi;
- ri->lights[0] = LIGHTMGR->getSpecialLight( LightManager::slSunLightType );
- // setup lightmap
- if (dStricmp(LIGHTMGR->getId(), "BLM") == 0)
- {
- if ( node.lightMapIndex != U8(-1) &&
- matInst->getFeatures().hasFeature( MFT_LightMap ) )
- ri->lightmap = gInteriorLMManager.getHandle(mLMHandle, intInst->getLMHandle(), node.lightMapIndex );
- }
- ri->matInst = matInst;
- ri->primBuffIndex = node.primInfoIndex;
- if ( matInst->getMaterial()->isTranslucent() )
- {
- ri->type = RenderPassManager::RIT_Translucent;
- ri->translucentSort = true;
- ri->sortDistSq = intInst->getRenderWorldBox().getSqDistanceToPoint( state->getCameraPosition() );
- }
- // Sort by the material then the normal map or vertex buffer!
- ri->defaultKey = matInst->getStateHint();
- ri->defaultKey2 = ri->lightmap ? (U32)ri->lightmap : (U32)ri->vertBuff;
- state->getRenderPass()->addInst( ri );
- }
- //------------------------------------------------------------------------------
- // Render zone RenderNode
- //------------------------------------------------------------------------------
- void Interior::renderReflectNode( SceneRenderState *state,
- ReflectRenderNode &node,
- InteriorInstance *intInst,
- SceneData &sgData,
- MeshRenderInst *coreRi )
- {
- BaseMatInstance *matInst = state->getOverrideMaterial( node.matInst );
- if ( !matInst )
- return;
-
- MeshRenderInst *ri = state->getRenderPass()->allocInst<MeshRenderInst>();
- *ri = *coreRi;
- ri->vertBuff = &mReflectVertBuff;
- ri->primBuff = &mReflectPrimBuff;
- // use sgData.backBuffer to transfer the reflect texture to the materials
- PlaneReflector *rp = &intInst->mPlaneReflectors[ node.reflectPlaneIndex ];
- ri->reflectTex = rp->reflectTex;
- ri->reflective = true;
- // setup lightmap
- if (dStricmp(LIGHTMGR->getId(), "BLM") == 0)
- {
- if ( node.lightMapIndex != U8(-1) &&
- matInst->getFeatures().hasFeature( MFT_LightMap ) )
- ri->lightmap = gInteriorLMManager.getHandle(mLMHandle, intInst->getLMHandle(), node.lightMapIndex );
- }
- ri->matInst = matInst;
- ri->primBuffIndex = node.primInfoIndex;
- // Sort by the material then the normal map or vertex buffer!
- ri->defaultKey = matInst->getStateHint();
- ri->defaultKey2 = ri->lightmap ? (U32)ri->lightmap : (U32)ri->vertBuff;
- state->getRenderPass()->addInst( ri );
- }
- //------------------------------------------------------------------------------
- // Setup the rendering
- //------------------------------------------------------------------------------
- void Interior::setupRender( InteriorInstance *intInst,
- SceneRenderState *state,
- MeshRenderInst *coreRi, const MatrixF* worldToCamera )
- {
- // Set the vertex and primitive buffers
- coreRi->vertBuff = &mVertBuff;
- coreRi->primBuff = &mPrimBuff;
- // Grab our render transform and scale it
- MatrixF objectToWorld = intInst->getRenderTransform();
- objectToWorld.scale( intInst->getScale() );
- coreRi->objectToWorld = state->getRenderPass()->allocUniqueXform(objectToWorld);
- coreRi->worldToCamera = state->getRenderPass()->allocUniqueXform(*worldToCamera); // This is handed down from SceneRenderState::renderCurrentImages()
- coreRi->projection = state->getRenderPass()->allocSharedXform(RenderPassManager::Projection);
- coreRi->type = RenderPassManager::RIT_Interior;
-
- // NOTICE: SFXBB is removed and refraction is disabled!
- //coreRi->backBuffTex = GFX->getSfxBackBuffer();
- }
- //------------------------------------------------------------------------------
- // Render
- //------------------------------------------------------------------------------
- void Interior::prepBatchRender( InteriorInstance *intInst, SceneRenderState *state )
- {
- // coreRi - used as basis for subsequent interior ri allocations
- MeshRenderInst *coreRi = state->getRenderPass()->allocInst<MeshRenderInst>();
- SceneData sgData;
- sgData.init( state );
- setupRender( intInst, state, coreRi, &state->getWorldViewMatrix() );
- ZoneVisDeterminer zoneVis = setupZoneVis( intInst, state );
- // GFX2_RENDER_MERGE
- #ifndef TORQUE_SHIPPING
- if( smRenderMode != 0 )
- {
- ObjectRenderInst *ri = state->getRenderPass()->allocInst<ObjectRenderInst>();
- ri->renderDelegate.bind(intInst, &InteriorInstance::_renderObject);
- ri->type = RenderPassManager::RIT_Object;
- state->getRenderPass()->addInst( ri );
- return;
- }
- #endif
- // render zones
- for( U32 i=0; i<mZones.size(); i++ )
- {
- // No need to try to render zones without any surfaces
- if (mZones[i].surfaceCount == 0)
- continue;
- if( zoneVis.isZoneVisible(i) == false && !state->isReflectPass() )
- continue;
- for( U32 j=0; j<mZoneRNList[i].renderNodeList.size(); j++ )
- {
- RenderNode &node = mZoneRNList[i].renderNodeList[j];
- renderZoneNode( state, node, intInst, sgData, coreRi );
- }
- }
-
- // render static meshes...
- for(U32 i=0; i<mStaticMeshes.size(); i++)
- mStaticMeshes[i]->render( state, *coreRi, getLMHandle(),
- intInst->getLMHandle(), intInst );
- // render reflective surfaces
- if ( !state->isReflectPass() )
- {
- renderLights(state, intInst, sgData, coreRi, zoneVis);
- for( U32 i=0; i<mZones.size(); i++ )
- {
- if( zoneVis.isZoneVisible(i) == false ) continue;
- for( U32 j=0; j<mZoneReflectRNList[i].reflectList.size(); j++ )
- {
- ReflectRenderNode &node = mZoneReflectRNList[i].reflectList[j];
- renderReflectNode( state, node, intInst, sgData, coreRi );
- }
- }
- }
- }
- void Interior::renderLights( SceneRenderState* state,
- InteriorInstance *intInst,
- SceneData &sgData,
- MeshRenderInst *coreRi,
- const ZoneVisDeterminer &zonevis )
- {
- // TODO!
- /*
- if (!smLightPlugin)
- return;
- if (!smLightPlugin->interiorInstInit(intInst))
- return;
- // build the render instances...
- for(U32 z=0; z<mZones.size(); z++)
- {
- if(!zonevis.isZoneVisible(z))
- continue;
- Zone &zone = mZones[z];
- S32 zoneid = zone.zoneId - 1;
- if(zoneid > -1)
- zoneid += intInst->getZoneRangeStart();// only zone managers...
- else
- zoneid = intInst->_getCurrZone(0);// if not what zone is it in...
- if (!smLightPlugin->zoneInit(zoneid))
- continue;
- static Vector<MeshRenderInst*> sRenderList;
- sRenderList.clear();
- for(U32 j=0; j<mZoneRNList[z].renderNodeList.size(); j++)
- {
- RenderNode &node = mZoneRNList[z].renderNodeList[j];
- if (!node.matInst)
- continue;
- MeshRenderInst *ri = state->getRenderPass()->allocInst<MeshRenderInst>();
- *ri = *coreRi;
- ri->type = RenderPassManager::RIT_InteriorDynamicLighting;
- ri->matInst = node.matInst;
- ri->primBuffIndex = node.primInfoIndex;
- sRenderList.push_back(ri);
- }
- smLightPlugin->processRI(state, sRenderList);
- }
- */
- }
|