//--------------------------------------------------------------------- bool CompositorManager::isInputToOutputTarget(CompositorInstance* inst, const Ogre::String& localName) { CompositionTargetPass* tp = inst->getTechnique()->getOutputTargetPass(); CompositionTargetPass::PassIterator pit = tp->getPassIterator(); while(pit.hasMoreElements()) { CompositionPass* p = pit.getNext(); for (size_t i = 0; i < p->getNumInputs(); ++i) { if (p->getInput(i).name == localName) return true; } } return false; }
//---------------------------------------------------------------------() bool CompositorManager::isInputToOutputTarget(CompositorInstance* inst, TexturePtr tex) { CompositionTargetPass* tp = inst->getTechnique()->getOutputTargetPass(); CompositionTargetPass::PassIterator pit = tp->getPassIterator(); while(pit.hasMoreElements()) { CompositionPass* p = pit.getNext(); for (size_t i = 0; i < p->getNumInputs(); ++i) { TexturePtr t = inst->getTextureInstance(p->getInput(i).name, 0); if (!t.isNull() && t.get() == tex.get()) return true; } } return false; }
void CompositorInstance::collectPasses(TargetOperation &finalState, CompositionTargetPass *target) { /// Here, passes are converted into render target operations Pass *targetpass; Technique *srctech; MaterialPtr mat, srcmat; CompositionTargetPass::PassIterator it = target->getPassIterator(); while(it.hasMoreElements()) { CompositionPass *pass = it.getNext(); switch(pass->getType()) { case CompositionPass::PT_CLEAR: queueRenderSystemOp(finalState, new RSClearOperation( pass->getClearBuffers(), pass->getClearColour(), pass->getClearDepth(), pass->getClearStencil() )); break; case CompositionPass::PT_STENCIL: queueRenderSystemOp(finalState, new RSStencilOperation( pass->getStencilCheck(),pass->getStencilFunc(), pass->getStencilRefValue(), pass->getStencilMask(), pass->getStencilFailOp(), pass->getStencilDepthFailOp(), pass->getStencilPassOp(), pass->getStencilTwoSidedOperation() )); break; case CompositionPass::PT_RENDERSCENE: if(pass->getFirstRenderQueue() < finalState.currentQueueGroupID) { /// Mismatch -- warn user /// XXX We could support repeating the last queue, with some effort LogManager::getSingleton().logMessage("Warning in compilation of Compositor " +mCompositor->getName()+": Attempt to render queue "+ StringConverter::toString(pass->getFirstRenderQueue())+" before "+ StringConverter::toString(finalState.currentQueueGroupID)); } /// Add render queues for(int x=pass->getFirstRenderQueue(); x<=pass->getLastRenderQueue(); ++x) { assert(x>=0); finalState.renderQueues.set(x); } finalState.currentQueueGroupID = pass->getLastRenderQueue()+1; finalState.findVisibleObjects = true; finalState.materialScheme = target->getMaterialScheme(); break; case CompositionPass::PT_RENDERQUAD: srcmat = pass->getMaterial(); if(srcmat.isNull()) { /// No material -- warn user LogManager::getSingleton().logMessage("Warning in compilation of Compositor " +mCompositor->getName()+": No material defined for composition pass"); break; } srcmat->compile(); if(srcmat->getNumSupportedTechniques()==0) { /// No supported techniques -- warn user LogManager::getSingleton().logMessage("Warning in compilation of Compositor " +mCompositor->getName()+": material "+srcmat->getName()+" has no supported techniques"); break; } srctech = srcmat->getBestTechnique(0); /// Create local material MaterialPtr mat = createLocalMaterial(); /// Copy and adapt passes from source material Technique::PassIterator i = srctech->getPassIterator(); while(i.hasMoreElements()) { Pass *srcpass = i.getNext(); /// Create new target pass targetpass = mat->getTechnique(0)->createPass(); (*targetpass) = (*srcpass); /// Set up inputs for(size_t x=0; x<pass->getNumInputs(); ++x) { String inp = pass->getInput(x); if(!inp.empty()) { if(x < targetpass->getNumTextureUnitStates()) { targetpass->getTextureUnitState((ushort)x)->setTextureName(getSourceForTex(inp)); } else { /// Texture unit not there LogManager::getSingleton().logMessage("Warning in compilation of Compositor " +mCompositor->getName()+": material "+srcmat->getName()+" texture unit " +StringConverter::toString(x)+" out of bounds"); } } } } queueRenderSystemOp(finalState, new RSQuadOperation(this,pass->getIdentifier(),mat)); break; } } }
//--------------------------------------------------------------------- void CompositorInstance::deriveTextureRenderTargetOptions( const String& texname, bool *hwGammaWrite, uint *fsaa) { // search for passes on this texture def that either include a render_scene // or use input previous bool renderingScene = false; CompositionTechnique::TargetPassIterator it = mTechnique->getTargetPassIterator(); while (it.hasMoreElements()) { CompositionTargetPass* tp = it.getNext(); if (tp->getOutputName() == texname) { if (tp->getInputMode() == CompositionTargetPass::IM_PREVIOUS) { // this may be rendering the scene implicitly // Can't check mPreviousInstance against mChain->_getOriginalSceneCompositor() // at this time, so check the position CompositorChain::InstanceIterator instit = mChain->getCompositors(); renderingScene = true; while(instit.hasMoreElements()) { CompositorInstance* inst = instit.getNext(); if (inst == this) break; else if (inst->getEnabled()) { // nope, we have another compositor before us, this will // be doing the AA renderingScene = false; } } if (renderingScene) break; } else { // look for a render_scene pass CompositionTargetPass::PassIterator pit = tp->getPassIterator(); while(pit.hasMoreElements()) { CompositionPass* pass = pit.getNext(); if (pass->getType() == CompositionPass::PT_RENDERSCENE) { renderingScene = true; break; } } } } } if (renderingScene) { // Ok, inherit settings from target RenderTarget* target = mChain->getViewport()->getTarget(); *hwGammaWrite = target->isHardwareGammaEnabled(); *fsaa = target->getFSAA(); } else { *hwGammaWrite = false; *fsaa = 0; } }