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 _init(void) { CompositorPtr compositor = CompositorManager::getSingleton().create( _theType(), ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME); CompositionTechnique *t; CompositionTechnique::TextureDefinition *td; CompositionTargetPass *tp; CompositionPass *pass; t = compositor->createTechnique(); td = t->createTextureDefinition("scene"); td->width.viewport = 1; td->height.viewport = 1; td->format = PF_X8R8G8B8; td = t->createTextureDefinition("blur0"); td->width.viewport = 0.5; td->height.viewport = 0.5; td->format = PF_X8R8G8B8; td = t->createTextureDefinition("blur1"); td->width.viewport = 0.5; td->height.viewport = 0.5; td->format = PF_X8R8G8B8; tp = t->createTargetPass(); tp->setInputMode(CompositionTargetPass::IM_PREVIOUS); tp->setOutputName("scene"); tp = t->createTargetPass(); tp->setInputMode(CompositionTargetPass::IM_NONE); tp->setOutputName("blur0"); pass = tp->createPass(); pass->setType(CompositionPass::PT_RENDERQUAD); pass->setMaterialName("PostFilters/Floodlighting/DownSample"); pass->setInput(0, "scene"); tp = t->createTargetPass(); tp->setInputMode(CompositionTargetPass::IM_NONE); tp->setOutputName("blur1"); pass = tp->createPass(); pass->setType(CompositionPass::PT_RENDERQUAD); pass->setMaterialName("PostFilters/Floodlighting/BlurHorizontal"); pass->setInput(0, "blur0"); tp = t->createTargetPass(); tp->setInputMode(CompositionTargetPass::IM_NONE); tp->setOutputName("blur1"); pass = tp->createPass(); pass->setType(CompositionPass::PT_RENDERQUAD); pass->setMaterialName("PostFilters/Floodlighting/BlurVertical"); pass->setInput(0, "blur0"); tp = t->getOutputTargetPass(); tp->setInputMode(CompositionTargetPass::IM_NONE); pass = tp->createPass(); pass->setType(CompositionPass::PT_RENDERQUAD); pass->setMaterialName("PostFilters/Floodlighting/Blend"); pass->setInput(0, "scene"); pass->setInput(1, "blur1"); pass->setIdentifier(0xDEADBADE); mBlurAmount = 0.2f; mShineAmount = 0.3f; // receive default parameters from material script if (!pass->getMaterial().isNull()) { GpuProgramParametersSharedPtr parameters = pass->getMaterial()->getTechnique(0)->getPass(0)->getFragmentProgramParameters(); #if OGRE_VERSION >= 0x010300 const GpuConstantDefinition* def; def = parameters->_findNamedConstantDefinition("blur_amount"); if (def) parameters->_readRawConstants(def->physicalIndex, 1, &mBlurAmount); def = parameters->_findNamedConstantDefinition("shine_amount"); if (def) parameters->_readRawConstants(def->physicalIndex, 1, &mShineAmount); #else GpuProgramParameters::RealConstantEntry* entry; entry = parameters->getNamedRealConstantEntry("blur_amount"); if (entry && entry->isSet) mBlurAmount = entry->val[0]; entry = parameters->getNamedRealConstantEntry("shine_amount"); if (entry && entry->isSet) mShineAmount = entry->val[0]; #endif } }