renderGlowMgr.cpp
Engine/source/renderInstance/renderGlowMgr.cpp
Public Functions
ConsoleDocClass(RenderGlowMgr , "@brief A <a href="/coding/file/editortool_8cpp/#editortool_8cpp_1a4cb041169a32ea3d4cacadbb955e06b4">render</a> bin <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1a2732ab74fa0237854c2ba0f75f88a624">for</a> the glow <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">pass.\n\n</a>" "When the glow buffer <a href="/coding/class/classposteffect/">PostEffect</a> is enabled this bin gathers mesh <a href="/coding/file/editortool_8cpp/#editortool_8cpp_1a4cb041169a32ea3d4cacadbb955e06b4">render</a> " "instances with glow materials and renders them <a href="/coding/file/cmdgram_8cpp/#cmdgram_8cpp_1a5bafda9519252aa2d0fd038153f77dca">to</a> the #glowbuffer offscreen " "<a href="/coding/file/editortool_8cpp/#editortool_8cpp_1a4cb041169a32ea3d4cacadbb955e06b4">render</a> <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">target.\n\n</a>" "This <a href="/coding/file/editortool_8cpp/#editortool_8cpp_1a4cb041169a32ea3d4cacadbb955e06b4">render</a> target is then used by the 'GlowPostFx' <a href="/coding/class/classposteffect/">PostEffect</a> <a href="/coding/file/cmdgram_8cpp/#cmdgram_8cpp_1a5bafda9519252aa2d0fd038153f77dca">to</a> blur and " "<a href="/coding/file/editortool_8cpp/#editortool_8cpp_1a4cb041169a32ea3d4cacadbb955e06b4">render</a> the glowing portions of the <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">screen.\n\n</a>" "@ingroup <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">RenderBin\n</a>" )
Detailed Description
Public Functions
ConsoleDocClass(RenderGlowMgr , "@brief A <a href="/coding/file/editortool_8cpp/#editortool_8cpp_1a4cb041169a32ea3d4cacadbb955e06b4">render</a> bin <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1a2732ab74fa0237854c2ba0f75f88a624">for</a> the glow <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">pass.\n\n</a>" "When the glow buffer <a href="/coding/class/classposteffect/">PostEffect</a> is enabled this bin gathers mesh <a href="/coding/file/editortool_8cpp/#editortool_8cpp_1a4cb041169a32ea3d4cacadbb955e06b4">render</a> " "instances with glow materials and renders them <a href="/coding/file/cmdgram_8cpp/#cmdgram_8cpp_1a5bafda9519252aa2d0fd038153f77dca">to</a> the #glowbuffer offscreen " "<a href="/coding/file/editortool_8cpp/#editortool_8cpp_1a4cb041169a32ea3d4cacadbb955e06b4">render</a> <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">target.\n\n</a>" "This <a href="/coding/file/editortool_8cpp/#editortool_8cpp_1a4cb041169a32ea3d4cacadbb955e06b4">render</a> target is then used by the 'GlowPostFx' <a href="/coding/class/classposteffect/">PostEffect</a> <a href="/coding/file/cmdgram_8cpp/#cmdgram_8cpp_1a5bafda9519252aa2d0fd038153f77dca">to</a> blur and " "<a href="/coding/file/editortool_8cpp/#editortool_8cpp_1a4cb041169a32ea3d4cacadbb955e06b4">render</a> the glowing portions of the <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">screen.\n\n</a>" "@ingroup <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">RenderBin\n</a>" )
IMPLEMENT_CONOBJECT(RenderGlowMgr )
1 2//----------------------------------------------------------------------------- 3// Copyright (c) 2012 GarageGames, LLC 4// 5// Permission is hereby granted, free of charge, to any person obtaining a copy 6// of this software and associated documentation files (the "Software"), to 7// deal in the Software without restriction, including without limitation the 8// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or 9// sell copies of the Software, and to permit persons to whom the Software is 10// furnished to do so, subject to the following conditions: 11// 12// The above copyright notice and this permission notice shall be included in 13// all copies or substantial portions of the Software. 14// 15// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 20// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS 21// IN THE SOFTWARE. 22//----------------------------------------------------------------------------- 23 24#include "platform/platform.h" 25#include "renderInstance/renderGlowMgr.h" 26#include "renderInstance/renderParticleMgr.h" 27 28#include "scene/sceneManager.h" 29#include "scene/sceneRenderState.h" 30#include "materials/sceneData.h" 31#include "materials/matInstance.h" 32#include "materials/materialFeatureTypes.h" 33#include "materials/processedMaterial.h" 34#include "postFx/postEffect.h" 35#include "gfx/gfxTransformSaver.h" 36#include "gfx/gfxDebugEvent.h" 37#include "math/util/matrixSet.h" 38 39IMPLEMENT_CONOBJECT( RenderGlowMgr ); 40 41 42ConsoleDocClass( RenderGlowMgr, 43 "@brief A render bin for the glow pass.\n\n" 44 "When the glow buffer PostEffect is enabled this bin gathers mesh render " 45 "instances with glow materials and renders them to the #glowbuffer offscreen " 46 "render target.\n\n" 47 "This render target is then used by the 'GlowPostFx' PostEffect to blur and " 48 "render the glowing portions of the screen.\n\n" 49 "@ingroup RenderBin\n" ); 50 51const MatInstanceHookType RenderGlowMgr::GlowMaterialHook::Type( "Glow" ); 52 53 54RenderGlowMgr::GlowMaterialHook::GlowMaterialHook( BaseMatInstance *matInst ) 55 : mGlowMatInst( NULL ) 56{ 57 mGlowMatInst = (MatInstance*)matInst->getMaterial()->createMatInstance(); 58 mGlowMatInst->getFeaturesDelegate().bind( &GlowMaterialHook::_overrideFeatures ); 59 mGlowMatInst->setUserObject(matInst->getUserObject()); 60 mGlowMatInst->init( matInst->getRequestedFeatures(), 61 matInst->getVertexFormat() ); 62} 63 64RenderGlowMgr::GlowMaterialHook::~GlowMaterialHook() 65{ 66 SAFE_DELETE( mGlowMatInst ); 67} 68 69void RenderGlowMgr::GlowMaterialHook::_overrideFeatures( ProcessedMaterial *mat, 70 U32 stageNum, 71 MaterialFeatureData &fd, 72 const FeatureSet &features ) 73{ 74 // If this isn't a glow pass... then add the glow mask feature. 75 if ( mat->getMaterial() && 76 !mat->getMaterial()->mGlow[stageNum] ) 77 fd.features.addFeature( MFT_GlowMask ); 78 79 // Don't allow fog or HDR encoding on 80 // the glow materials. 81 fd.features.removeFeature( MFT_Fog ); 82 fd.features.addFeature( MFT_Imposter ); 83} 84 85RenderGlowMgr::RenderGlowMgr() 86 : RenderTexTargetBinManager( RenderPassManager::RIT_Mesh, 87 1.0f, 88 1.0f, 89 GFXFormatR8G8B8A8, 90 Point2I( 512, 512 ) ) 91{ 92 notifyType( RenderPassManager::RIT_Decal ); 93 notifyType( RenderPassManager::RIT_DecalRoad ); 94 notifyType( RenderPassManager::RIT_Translucent ); 95 notifyType( RenderPassManager::RIT_Particle ); 96 97 mParticleRenderMgr = NULL; 98 99 mNamedTarget.registerWithName( "glowbuffer" ); 100 mTargetSizeType = WindowSize; 101} 102 103RenderGlowMgr::~RenderGlowMgr() 104{ 105} 106 107PostEffect* RenderGlowMgr::getGlowEffect() 108{ 109 if ( !mGlowEffect ) 110 mGlowEffect = dynamic_cast<PostEffect*>( Sim::findObject( "GlowPostFx" ) ); 111 112 return mGlowEffect; 113} 114 115bool RenderGlowMgr::isGlowEnabled() 116{ 117 return getGlowEffect() && getGlowEffect()->isEnabled(); 118} 119 120void RenderGlowMgr::addElement( RenderInst *inst ) 121{ 122 // Skip out if we don't have the glow post 123 // effect enabled at this time. 124 if ( !isGlowEnabled() ) 125 return; 126 127 // TODO: We need to get the scene state here in a more reliable 128 // manner so we can skip glow in a non-diffuse render pass. 129 //if ( !mParentManager->getSceneManager()->getSceneState()->isDiffusePass() ) 130 //return RenderBinManager::arSkipped; 131 ParticleRenderInst *particleInst = NULL; 132 if(inst->type == RenderPassManager::RIT_Particle) 133 particleInst = static_cast<ParticleRenderInst*>(inst); 134 if(particleInst && particleInst->glow) 135 { 136 internalAddElement(inst); 137 return; 138 } 139 140 // Skip it if we don't have a glowing material. 141 BaseMatInstance *matInst = getMaterial( inst ); 142 if ( !matInst || !matInst->hasGlow() ) 143 return; 144 145 internalAddElement(inst); 146} 147 148void RenderGlowMgr::render( SceneRenderState *state ) 149{ 150 PROFILE_SCOPE( RenderGlowMgr_Render ); 151 152 if ( !isGlowEnabled() ) 153 return; 154 155 const U32 binSize = mElementList.size(); 156 157 // If this is a non-diffuse pass or we have no objects to 158 // render then tell the effect to skip rendering. 159 if ( !state->isDiffusePass() || binSize == 0 ) 160 { 161 getGlowEffect()->setSkip( true ); 162 return; 163 } 164 165 GFXDEBUGEVENT_SCOPE( RenderGlowMgr_Render, ColorI::GREEN ); 166 167 GFXTransformSaver saver; 168 169 // Respect the current viewport 170 mNamedTarget.setViewport(GFX->getViewport()); 171 172 // Tell the superclass we're about to render, preserve contents 173 const bool isRenderingToTarget = _onPreRender( state, true ); 174 175 // Clear all the buffers to black. 176 GFX->clear( GFXClearTarget, ColorI::BLACK, 1.0f, 0); 177 178 // Restore transforms 179 MatrixSet &matrixSet = getRenderPass()->getMatrixSet(); 180 matrixSet.restoreSceneViewProjection(); 181 182 // init loop data 183 SceneData sgData; 184 sgData.init( state, SceneData::GlowBin ); 185 186 for( U32 j=0; j<binSize; ) 187 { 188 RenderInst *_ri = mElementList[j].inst; 189 if(_ri->type == RenderPassManager::RIT_Particle) 190 { 191 // Find the particle render manager (if we don't have it) 192 if(mParticleRenderMgr == NULL) 193 { 194 RenderPassManager *rpm = state->getRenderPass(); 195 for( U32 i = 0; i < rpm->getManagerCount(); i++ ) 196 { 197 RenderBinManager *bin = rpm->getManager(i); 198 if( bin->getRenderInstType() == RenderParticleMgr::RIT_Particles ) 199 { 200 mParticleRenderMgr = reinterpret_cast<RenderParticleMgr *>(bin); 201 break; 202 } 203 } 204 } 205 206 ParticleRenderInst *ri = static_cast<ParticleRenderInst*>(_ri); 207 208 GFX->setStateBlock(mParticleRenderMgr->_getHighResStateBlock(ri)); 209 mParticleRenderMgr->_getShaderConsts().mShaderConsts->setSafe(mParticleRenderMgr->_getShaderConsts().mModelViewProjSC, *ri->modelViewProj); 210 211 mParticleRenderMgr->renderParticle(ri, state); 212 j++; 213 continue; 214 } 215 216 MeshRenderInst *ri = static_cast<MeshRenderInst*>(_ri); 217 218 setupSGData( ri, sgData ); 219 220 BaseMatInstance *mat = ri->matInst; 221 GlowMaterialHook *hook = mat->getHook<GlowMaterialHook>(); 222 if ( !hook ) 223 { 224 hook = new GlowMaterialHook( ri->matInst ); 225 ri->matInst->addHook( hook ); 226 } 227 BaseMatInstance *glowMat = hook->getMatInstance(); 228 229 U32 matListEnd = j; 230 231 while( glowMat && glowMat->setupPass( state, sgData ) ) 232 { 233 U32 a; 234 for( a=j; a<binSize; a++ ) 235 { 236 if (mElementList[a].inst->type == RenderPassManager::RIT_Particle) 237 break; 238 239 MeshRenderInst *passRI = static_cast<MeshRenderInst*>(mElementList[a].inst); 240 241 if ( newPassNeeded( ri, passRI ) ) 242 break; 243 244 matrixSet.setWorld(*passRI->objectToWorld); 245 matrixSet.setView(*passRI->worldToCamera); 246 matrixSet.setProjection(*passRI->projection); 247 glowMat->setTransforms(matrixSet, state); 248 249 // Setup HW skinning transforms if applicable 250 if (glowMat->usesHardwareSkinning()) 251 { 252 glowMat->setNodeTransforms(passRI->mNodeTransforms, passRI->mNodeTransformCount); 253 } 254 255 //push along any overriden fields that are instance-specific as well 256 if (passRI->mCustomShaderData.size() > 0) 257 { 258 mat->setCustomShaderData(passRI->mCustomShaderData); 259 } 260 261 glowMat->setSceneInfo(state, sgData); 262 glowMat->setBuffers(passRI->vertBuff, passRI->primBuff); 263 264 if ( passRI->prim ) 265 GFX->drawPrimitive( *passRI->prim ); 266 else 267 GFX->drawPrimitive( passRI->primBuffIndex ); 268 } 269 matListEnd = a; 270 setupSGData( ri, sgData ); 271 } 272 273 // force increment if none happened, otherwise go to end of batch 274 j = ( j == matListEnd ) ? j+1 : matListEnd; 275 } 276 277 // Finish up. 278 if ( isRenderingToTarget ) 279 _onPostRender(); 280 281 // Make sure the effect is gonna render. 282 getGlowEffect()->setSkip( false ); 283} 284