示例#1
0
void GFXTextureManager::cleanupCache( U32 secondsToLive )
{
   PROFILE_SCOPE( GFXTextureManager_CleanupCache );

   U32 killTime = Platform::getTime() - secondsToLive;

   for ( U32 i=0; i < mToDelete.size(); )
   {
      GFXTextureObject *tex = mToDelete[i];

      // If the texture was picked back up by a user
      // then just remove it from the list.
      if ( tex->getRefCount() != 0 )
      {
         mToDelete.erase_fast( i );
         continue;
      }

      // If its time has expired delete it for real.
      if ( tex->mDeleteTime <= killTime )
      {
         //Con::errorf( "Killed texture: %s", tex->mTextureLookupName.c_str() );
         delete tex;
         mToDelete.erase_fast( i );
         continue;
      }

      i++;
   }
}
U32 GFXTextureObject::dumpActiveTOs()
{
   if(!smActiveTOCount)
   {
      Con::printf( "GFXTextureObject::dumpActiveTOs - no active TOs to dump." );
      return 0;
   }

   Con::printf("GFXTextureObject Usage Report - %d active TOs", smActiveTOCount);
   Con::printf("---------------------------------------------------------------");
   Con::printf(" Addr   Dim. GFXTextureProfile  ProfilerPath DebugDescription");

   for(GFXTextureObject *walk = smHead; walk; walk=walk->mDebugNext)
      Con::printf(" %x  (%4d, %4d)  %s    %s    %s", walk, walk->getWidth(), 
      walk->getHeight(), walk->mProfile->getName().c_str(), walk->mDebugCreationPath.c_str(), walk->mDebugDescription.c_str());

   Con::printf("----- dump complete -------------------------------------------");
   return smActiveTOCount;
}
示例#3
0
void GFXTextureManager::kill()
{
   AssertFatal( mTextureManagerState != GFXTextureManager::Dead, "Texture Manager already killed!" );

   // Release everything in the cache we can
   // so we don't leak any textures.
   cleanupCache();

   GFXTextureObject *curr = mListHead;
   GFXTextureObject *temp;

   // Actually delete all the textures we know about.
   while( curr != NULL ) 
   {
      temp = curr->mNext;
      curr->kill();
      curr = temp;
   }

   mCubemapTable.clear();

   mTextureManagerState = GFXTextureManager::Dead;
}
示例#4
0
void PostEffectVis::onPFXProcessed( PostEffect *pfx )
{
   // If we have no windows we can early out before even testing
   // isAwake so we avoid creating the content control unnecessarily.
   if ( mWindows.empty() )
      return;

   if ( !_getContentControl()->isAwake() )
      return;

   VisVector::iterator itr = mWindows.begin();
   for ( ; itr != mWindows.end(); itr++ )
   {
      if ( itr->pfx == pfx )
      {
         GuiBitmapCtrl *pBmpCtrl = NULL;
         GuiWindowCtrl *pWinCtrl = NULL;

         if ( itr->bmp[Target] != NULL )
         {            
            pBmpCtrl = itr->bmp[Target];
            pWinCtrl = itr->window[Target];

            GFXTextureObject *tex;

            if ( pfx->mTargetTex )
               tex = pfx->mTargetTex;         
            else
               tex = PFXMGR->getBackBufferTex();

            pBmpCtrl->setBitmapHandle( tex );

            char caption[256];           
            char name[256];

            if ( pfx->getName() == NULL || dStrlen( pfx->getName() ) == 0 )
               dSprintf( name, 256, "(none)" );
            else
               dSprintf( name, 256, "%s", pfx->getName() );


            if ( tex )
               dSprintf( caption, 256, "%s[%i] target - %s [ %ix%i ]", name, pfx->getId(), pfx->mTargetName.c_str(), tex->getWidth(), tex->getHeight() );               
            else
               dSprintf( caption, 256, "%s[%i] target", name, pfx->getId() );


            pWinCtrl->setDataField( StringTable->insert("text"), NULL, caption );
         }

         for ( U32 i = Input1; i < TexCount; i++ )
         {
            if ( itr->bmp[i] == NULL )
               continue;

            pBmpCtrl = itr->bmp[i];
            pWinCtrl = itr->window[i];            

            GFXTextureObject *tex = pfx->mActiveTextures[i-1];

            pBmpCtrl->setBitmapHandle( tex );

            char caption[256];            
            char name[256];

            if ( pfx->getName() == NULL || dStrlen( pfx->getName() ) == 0 )
               dSprintf( name, 256, "(none)" );
            else
               dSprintf( name, 256, "%s", pfx->getName() );


            if ( tex )
               dSprintf( caption, 256, "%s[%i] input%i - %s [ %ix%i ]", name, pfx->getId(), i-1, pfx->mTexFilename[i-1].c_str(), tex->getWidth(), tex->getHeight() );               
            else
               dSprintf( caption, 256, "%s[%i] input%i - %s", name, pfx->getId(), i-1, pfx->mTexFilename[i-1].c_str() );

            pWinCtrl->setDataField( StringTable->insert("text"), NULL, caption );
         }
      }
   }
}
示例#5
0
bool TerrainCellMaterial::setupPass(   const SceneRenderState *state, 
                                       const SceneData &sceneData )
{
   PROFILE_SCOPE( TerrainCellMaterial_SetupPass );

   if ( mCurrPass >= mPasses.size() )
   {
      mCurrPass = 0;
      return false;
   }

   Pass &pass = mPasses[mCurrPass];

   _updateMaterialConsts( &pass );

   if ( pass.baseTexMapConst->isValid() )
      GFX->setTexture( pass.baseTexMapConst->getSamplerRegister(), mTerrain->mBaseTex.getPointer() );

   if ( pass.layerTexConst->isValid() )
      GFX->setTexture( pass.layerTexConst->getSamplerRegister(), mTerrain->mLayerTex.getPointer() );

   if ( pass.lightMapTexConst->isValid() )
      GFX->setTexture( pass.lightMapTexConst->getSamplerRegister(), mTerrain->getLightMapTex() );

   if ( sceneData.wireframe )
      GFX->setStateBlock( pass.wireframeStateBlock );
   else if ( state->isReflectPass( ))
      GFX->setStateBlock( pass.reflectionStateBlock );
   else
      GFX->setStateBlock( pass.stateBlock );

   GFX->setShader( pass.shader );
   GFX->setShaderConstBuffer( pass.consts );

   // Let the light manager prepare any light stuff it needs.
   LIGHTMGR->setLightInfo( NULL,
                           NULL,
                           sceneData,
                           state,
                           mCurrPass,
                           pass.consts );

   for ( U32 i=0; i < pass.materials.size(); i++ )
   {
      MaterialInfo *matInfo = pass.materials[i];

      if ( matInfo->detailTexConst->isValid() )
         GFX->setTexture( matInfo->detailTexConst->getSamplerRegister(), matInfo->detailTex );
      if ( matInfo->macroTexConst->isValid() )
         GFX->setTexture( matInfo->macroTexConst->getSamplerRegister(), matInfo->macroTex );
      if ( matInfo->normalTexConst->isValid() )
         GFX->setTexture( matInfo->normalTexConst->getSamplerRegister(), matInfo->normalTex );
   }

   pass.consts->setSafe( pass.layerSizeConst, (F32)mTerrain->mLayerTex.getWidth() );

   if ( pass.oneOverTerrainSize->isValid() )
   {
      F32 oneOverTerrainSize = 1.0f / mTerrain->getWorldBlockSize();
      pass.consts->set( pass.oneOverTerrainSize, oneOverTerrainSize );
   }

   pass.consts->setSafe( pass.squareSize, mTerrain->getSquareSize() );

   if ( pass.fogDataConst->isValid() )
   {
      Point3F fogData;
      fogData.x = sceneData.fogDensity;
      fogData.y = sceneData.fogDensityOffset;
      fogData.z = sceneData.fogHeightFalloff;     
      pass.consts->set( pass.fogDataConst, fogData );
   }

   pass.consts->setSafe( pass.fogColorConst, sceneData.fogColor );

   if (  pass.lightInfoBufferConst->isValid() &&
         pass.lightParamsConst->isValid() )
   {
      if ( !mLightInfoTarget )
         mLightInfoTarget = NamedTexTarget::find( "lightinfo" );

      GFXTextureObject *texObject = mLightInfoTarget->getTexture();
      
      // TODO: Sometimes during reset of the light manager we get a
      // NULL texture here.  This is corrected on the next frame, but
      // we should still investigate why that happens.
      
      if ( texObject )
      {
         GFX->setTexture( pass.lightInfoBufferConst->getSamplerRegister(), texObject );

         const Point3I &targetSz = texObject->getSize();
         const RectI &targetVp = mLightInfoTarget->getViewport();
         Point4F rtParams;
         ScreenSpace::RenderTargetParameters(targetSz, targetVp, rtParams);
         pass.consts->setSafe( pass.lightParamsConst, rtParams );
      }
   }

   ++mCurrPass;
   return true;
}
void ProcessedCustomMaterial::setTextureStages( SceneRenderState *state, const SceneData &sgData, U32 pass )
{      
   LightManager* lm = state ? LIGHTMGR : NULL;   
   ShaderRenderPassData* rpd = _getRPD(pass);
   ShaderConstHandles* handles = _getShaderConstHandles(pass);
   GFXShaderConstBuffer* shaderConsts = _getShaderConstBuffer(pass);

   const NamedTexTarget *texTarget;
   GFXTextureObject *texObject; 
   
   for( U32 i=0; i<mMaxTex; i++ )
   {            
      U32 currTexFlag = rpd->mTexType[i];
      if ( !lm || !lm->setTextureStage(sgData, currTexFlag, i, shaderConsts, handles ) )
      {
      	GFXShaderConstHandle* handle = handles->mTexHandlesSC[i];
         if ( !handle->isValid() )
         	continue;

         S32 samplerRegister = handle->getSamplerRegister();
         
         switch( currTexFlag )
         {
         case 0:
         default:
            break;

         case Material::Mask:
         case Material::Standard:
         case Material::Bump:
         case Material::Detail:
            {
               GFX->setTexture( samplerRegister, rpd->mTexSlot[i].texObject );
               break;
            }

         case Material::Lightmap:
            {
               GFX->setTexture( samplerRegister, sgData.lightmap );
               break;
            }
         case Material::Cube:
            {
               GFX->setCubeTexture( samplerRegister, rpd->mCubeMap );
               break;
            }
         case Material::SGCube:
            {
               GFX->setCubeTexture( samplerRegister, sgData.cubemap );
               break;
            }
         case Material::BackBuff:
            {
               GFX->setTexture( samplerRegister, sgData.backBuffTex );
               //if ( sgData.reflectTex )
               //   GFX->setTexture( samplerRegister, sgData.reflectTex );
               //else
               //{
               //    GFXTextureObject *refractTex = REFLECTMGR->getRefractTex( true );
               //    GFX->setTexture( samplerRegister, refractTex );
               //}
               break;
            }
         case Material::ReflectBuff:
            {
               GFX->setTexture( samplerRegister, sgData.reflectTex );
               break;
            }
         case Material::Misc:
            {
               GFX->setTexture( samplerRegister, sgData.miscTex );
               break;
            }
         case Material::TexTarget:
            {
               texTarget = rpd->mTexSlot[i].texTarget;
               if ( !texTarget )
               {
                  GFX->setTexture( samplerRegister, NULL );
                  break;
               }
               
               texObject = texTarget->getTexture();

               // If no texture is available then map the default 2x2
               // black texture to it.  This at least will ensure that
               // we get consistant behavior across GPUs and platforms.
               if ( !texObject )
                  texObject = GFXTexHandle::ZERO;

               if ( handles->mRTParamsSC[samplerRegister]->isValid() && texObject )
               {
                  const Point3I &targetSz = texObject->getSize();
                  const RectI &targetVp = texTarget->getViewport();
                  Point4F rtParams;

                  ScreenSpace::RenderTargetParameters(targetSz, targetVp, rtParams);
                  shaderConsts->set(handles->mRTParamsSC[samplerRegister], rtParams);
               }
              
               GFX->setTexture( samplerRegister, texObject );
               break;
            }
         }
      }
   }
}
示例#7
0
void ProcessedShaderMaterial::setTextureStages( SceneRenderState *state, const SceneData &sgData, U32 pass )
{
   PROFILE_SCOPE( ProcessedShaderMaterial_SetTextureStages );

   ShaderConstHandles *handles = _getShaderConstHandles(pass);

   // Set all of the textures we need to render the give pass.
#ifdef TORQUE_DEBUG
   AssertFatal( pass<mPasses.size(), "Pass out of bounds" );
#endif

   RenderPassData *rpd = mPasses[pass];
   GFXShaderConstBuffer* shaderConsts = _getShaderConstBuffer(pass);
   NamedTexTarget *texTarget;
   GFXTextureObject *texObject; 

   for( U32 i=0; i<rpd->mNumTex; i++ )
   {
      U32 currTexFlag = rpd->mTexType[i];
      if (!LIGHTMGR || !LIGHTMGR->setTextureStage(sgData, currTexFlag, i, shaderConsts, handles))
      {
         switch( currTexFlag )
         {
         // If the flag is unset then assume its just
         // a regular texture to set... nothing special.
         case 0:
         default:
            GFX->setTexture(i, rpd->mTexSlot[i].texObject);
            break;

         case Material::NormalizeCube:
            GFX->setCubeTexture(i, Material::GetNormalizeCube());
            break;

         case Material::Lightmap:
            GFX->setTexture( i, sgData.lightmap );
            break;

         case Material::ToneMapTex:
            shaderConsts->setSafe(handles->mToneMapTexSC, (S32)i);
            GFX->setTexture(i, rpd->mTexSlot[i].texObject);
            break;

         case Material::Cube:
            GFX->setCubeTexture( i, rpd->mCubeMap );
            break;

         case Material::SGCube:
            GFX->setCubeTexture( i, sgData.cubemap );
            break;

         case Material::BackBuff:
            GFX->setTexture( i, sgData.backBuffTex );
            break;
            
         case Material::TexTarget:
            {
               texTarget = rpd->mTexSlot[i].texTarget;
               if ( !texTarget )
               {
                  GFX->setTexture( i, NULL );
                  break;
               }
            
               texObject = texTarget->getTexture();

               // If no texture is available then map the default 2x2
               // black texture to it.  This at least will ensure that
               // we get consistant behavior across GPUs and platforms.
               if ( !texObject )
                  texObject = GFXTexHandle::ZERO;

               if ( handles->mRTParamsSC[i]->isValid() && texObject )
               {
                  const Point3I &targetSz = texObject->getSize();
                  const RectI &targetVp = texTarget->getViewport();
                  Point4F rtParams;

                  ScreenSpace::RenderTargetParameters(targetSz, targetVp, rtParams);

                  shaderConsts->set(handles->mRTParamsSC[i], rtParams);
               }

               GFX->setTexture( i, texObject );
               break;
            }
         }
      }
   }
}
void RenderImposterMgr::_innerRender( const SceneState *state, ShaderState &shaderState )
{
   PROFILE_SCOPE( RenderImposterMgr_InnerRender );

   // Capture the GFX stats for this render.
   GFXDeviceStatistics stats;
   stats.start( GFX->getDeviceStatistics() );

   GFXTransformSaver saver;

   // Init the shader.
   GFX->setShader( shaderState.mShader );
   GFX->setShaderConstBuffer( shaderState.mConsts );
   GFX->setStateBlock( shaderState.mSB );

   // Set the projection and world transform info.
   MatrixF proj = GFX->getProjectionMatrix() * GFX->getWorldMatrix();
   shaderState.mConsts->set( shaderState.mWorldViewProjectSC, proj );

   if (  shaderState.mSunDirSC ||
         shaderState.mLightColorSC ||
         shaderState.mAmbientSC )
   {
      // Pass the lighting consts.
      const LightInfo *sunlight = state->getLightManager()->getSpecialLight( LightManager::slSunLightType );
      VectorF sunDir( sunlight->getDirection() );
      sunDir.normalize();

      shaderState.mConsts->set( shaderState.mSunDirSC, sunDir );
      shaderState.mConsts->set( shaderState.mLightColorSC, sunlight->getColor() );
      shaderState.mConsts->set( shaderState.mAmbientSC, sunlight->getAmbient() );
   }

   // Get the data we need from the camera matrix.
   const MatrixF &camMat = state->getCameraTransform();
   Point3F camPos; 
   VectorF camRight, camUp, camDir;
   camMat.getColumn( 0, &camRight );
   camMat.getColumn( 1, &camDir );
   camMat.getColumn( 2, &camUp );
   camMat.getColumn( 3, &camPos );
   shaderState.mConsts->set( shaderState.mCamPosSC, camPos );
   shaderState.mConsts->set( shaderState.mCamRightSC, camRight );
   shaderState.mConsts->set( shaderState.mCamUpSC, camUp );

   if ( shaderState.mLightTexRT && shaderState.mLightTarget )
   {
      GFXTextureObject *texObject = shaderState.mLightTarget->getTargetTexture( 0 );
      GFX->setTexture( 2, texObject );
   
      // TODO: This normally shouldn't be NULL, but can be on the
      // first render... not sure why... we should investigate and
      // fix that rather than protect against it.
      if ( texObject )
      {
         const Point3I &targetSz = texObject->getSize();
         const RectI &targetVp = shaderState.mLightTarget->getTargetViewport();
         Point4F rtParams;

         ScreenSpace::RenderTargetParameters(targetSz, targetVp, rtParams);

         shaderState.mConsts->set( shaderState.mLightTexRT, rtParams ); 
      }
   }

   // Setup a fairly large dynamic vb to hold a bunch of imposters.
   if ( !mVB.isValid() )
   {
      // Setup the vb to hold a bunch of imposters at once.
      mVB.set( GFX, mImposterBatchSize * 4, GFXBufferTypeDynamic );
      
      // Setup a static index buffer for rendering.
      mIB.set( GFX, mImposterBatchSize * 6, 0, GFXBufferTypeStatic );
      U16 *idxBuff;
      mIB.lock(&idxBuff, NULL, NULL, NULL);
      for ( U32 i=0; i < mImposterBatchSize; i++ )
      {
         //
         // The vertex pattern in the VB for each 
         // imposter is as follows...
         //
         //     0----1
         //     |\   |
         //     | \  |
         //     |  \ |
         //     |   \|
         //     3----2
         //
         // We setup the index order below to ensure
         // sequental, cache friendly, access.
         //
         U32 offset = i * 4;
         idxBuff[i*6+0] = 0 + offset;
         idxBuff[i*6+1] = 1 + offset;
         idxBuff[i*6+2] = 2 + offset;
         idxBuff[i*6+3] = 2 + offset;
         idxBuff[i*6+4] = 3 + offset;
         idxBuff[i*6+5] = 0 + offset;
      }
      mIB.unlock();
   }

   // Set the buffers here once.
   GFX->setPrimitiveBuffer( mIB );
   GFX->setVertexBuffer( mVB );

   // Batch up the imposters into the buffer.  These
   // are already sorted by texture, to minimize switches
   // so just batch them up and render as they come.

   ImposterVertex* vertPtr = NULL;
   U32 vertCount = 0;
   F32 halfSize, fade, scale;
   Point3F center;
   QuatF rotQuat;

   const U32 binSize = mElementList.size();
   for( U32 i=0; i < binSize; )
   {
      ImposterRenderInst *ri = static_cast<ImposterRenderInst*>( mElementList[i].inst );

      TSLastDetail* detail = ri->detail;

      // Setup the textures.
      GFX->setTexture( 0, detail->getTextureMap() );
      GFX->setTexture( 1, detail->getNormalMap() );

      // Setup the constants for this batch.
      Point4F params( (detail->getNumPolarSteps() * 2) + 1, detail->getNumEquatorSteps(), detail->getPolarAngle(), detail->getIncludePoles() );
      shaderState.mConsts->set( shaderState.mParamsSC, params );

      U32 uvCount = getMin( detail->getTextureUVs().size(), 64 );
      AlignedArray<Point4F> rectData( uvCount, sizeof( Point4F ), (U8*)detail->getTextureUVs().address(), false );
      shaderState.mConsts->set( shaderState.mUVsSC, rectData );

      vertPtr = mVB.lock();
      vertCount = 0;

      for ( ; i < binSize; i++ )
      {
         ri = static_cast<ImposterRenderInst*>( mElementList[i].inst );

         // Stop the loop if the detail changed.
         if ( ri->detail != detail )
            break;

         ++smRendered;

         // If we're out of vb space then draw what we got.
         if ( vertCount + 4 >= mVB->mNumVerts )
         {
            mVB.unlock();
            GFX->drawIndexedPrimitive( GFXTriangleList, 0, 0, vertCount, 0, vertCount / 2 );
            vertPtr = mVB.lock();
            vertCount = 0;
         }

         center   = ri->center;
         halfSize = ri->halfSize;
         fade     = ri->alpha;
         scale    = ri->scale;
         rotQuat  = ri->rotQuat;

         // Fill in the points for this instance.
         vertPtr->center = center;
         vertPtr->center.w = 0;
         vertPtr->miscParams.set( halfSize, fade, scale );
         vertPtr->rotQuat.set( rotQuat.x, rotQuat.y, rotQuat.z, rotQuat.w );
         vertPtr++;

         vertPtr->center = center;
         vertPtr->center.w = 1;
         vertPtr->miscParams.set( halfSize, fade, scale );
         vertPtr->rotQuat.set( rotQuat.x, rotQuat.y, rotQuat.z, rotQuat.w );
         vertPtr++;

         vertPtr->center = center;
         vertPtr->center.w = 2;
         vertPtr->miscParams.set( halfSize, fade, scale );
         vertPtr->rotQuat.set( rotQuat.x, rotQuat.y, rotQuat.z, rotQuat.w );
         vertPtr++;

         vertPtr->center = center;
         vertPtr->center.w = 3;
         vertPtr->miscParams.set( halfSize, fade, scale );
         vertPtr->rotQuat.set( rotQuat.x, rotQuat.y, rotQuat.z, rotQuat.w );
         vertPtr++;

         vertCount += 4;
      }

      // Any remainder to dump?
      if ( vertCount > 0 )
      {
         smBatches++;
         mVB.unlock();
         GFX->drawIndexedPrimitive( GFXTriangleList, 0, 0, vertCount, 0, vertCount / 2 );
      }
   }

   // Capture the GFX stats for this render.
   stats.end( GFX->getDeviceStatistics() );
   smDrawCalls += stats.mDrawCalls;
   smPolyCount += stats.mPolyCount;
   smRTChanges += stats.mRenderTargetChanges;
}