void HDRListener::notifyCompositor(CompositorInstance* instance) { // Get some RTT dimensions for later calculations CompositionTechnique::TextureDefinitionIterator defIter = instance->getTechnique()->getTextureDefinitionIterator(); while (defIter.hasMoreElements()) { CompositionTechnique::TextureDefinition* def = defIter.getNext(); if (def->name == "rt_bloom0") { mBloomSize = (int)def->width; // should be square // Calculate gaussian texture offsets & weights float deviation = 3.0f; float texelSize = 1.0f / (float)mBloomSize; // central sample, no offset mBloomTexOffsetsHorz[0][0] = 0.0f; mBloomTexOffsetsHorz[0][1] = 0.0f; mBloomTexOffsetsVert[0][0] = 0.0f; mBloomTexOffsetsVert[0][1] = 0.0f; mBloomTexWeights[0][0] = mBloomTexWeights[0][1] = mBloomTexWeights[0][2] = Math::gaussianDistribution(0, 0, deviation); mBloomTexWeights[0][3] = 1.0f; // 'pre' samples for(int i = 1; i < 8; ++i) { mBloomTexWeights[i][0] = mBloomTexWeights[i][1] = mBloomTexWeights[i][2] = 1.25f * Math::gaussianDistribution(i, 0, deviation); mBloomTexWeights[i][3] = 1.0f; mBloomTexOffsetsHorz[i][0] = i * texelSize; mBloomTexOffsetsHorz[i][1] = 0.0f; mBloomTexOffsetsVert[i][0] = 0.0f; mBloomTexOffsetsVert[i][1] = i * texelSize; } // 'post' samples for(int i = 8; i < 15; ++i) { mBloomTexWeights[i][0] = mBloomTexWeights[i][1] = mBloomTexWeights[i][2] = mBloomTexWeights[i - 7][0]; mBloomTexWeights[i][3] = 1.0f; mBloomTexOffsetsHorz[i][0] = -mBloomTexOffsetsHorz[i - 7][0]; mBloomTexOffsetsHorz[i][1] = 0.0f; mBloomTexOffsetsVert[i][0] = 0.0f; mBloomTexOffsetsVert[i][1] = -mBloomTexOffsetsVert[i - 7][1]; } } } }
//----------------------------------------------------------------------- void CompositorInstance::createResources() { static size_t dummyCounter = 0; freeResources(); /// Create temporary textures /// In principle, temporary textures could be shared between multiple viewports /// (CompositorChains). This will save a lot of memory in case more viewports /// are composited. CompositionTechnique::TextureDefinitionIterator it = mTechnique->getTextureDefinitionIterator(); while(it.hasMoreElements()) { CompositionTechnique::TextureDefinition *def = it.getNext(); /// Determine width and height int width = def->width.adjust + static_cast<int>(mChain->getViewport()->getActualWidth() * def->width.viewport) + static_cast<int>(mChain->getViewport()->getActualWidth() * def->width.previous); // FIXME int height = def->height.adjust + static_cast<int>(mChain->getViewport()->getActualHeight() * def->height.viewport) + static_cast<int>(mChain->getViewport()->getActualHeight() * def->height.previous); // FIXME if (width <= 0) { // Throw exception? Not that case, because user can't guarantee // provides correct parameters always, since it might related to // viewport dimensions which can't control by user all the way. width = 1; } if (height <= 0) { // Throw exception? Not that case, because user can't guarantee // provides correct parameters always, since it might related to // viewport dimensions which can't control by user all the way. height = 1; } /// Make the tetxure TexturePtr tex = TextureManager::getSingleton().createManual( "CompositorInstanceTexture"+StringConverter::toString(dummyCounter), ResourceGroupManager::INTERNAL_RESOURCE_GROUP_NAME, TEX_TYPE_2D, (uint)width, (uint)height, 0, def->format, TU_RENDERTARGET ); ++dummyCounter; mLocalTextures[def->name] = tex; /// Set up viewport over entire texture RenderTexture *rtt = tex->getBuffer()->getRenderTarget(); rtt->setAutoUpdated( false ); Camera* camera = mChain->getViewport()->getCamera(); // Save last viewport and current aspect ratio Viewport* oldViewport = camera->getViewport(); Real aspectRatio = camera->getAspectRatio(); Viewport* v = rtt->addViewport( camera ); v->setClearEveryFrame( false ); v->setOverlaysEnabled( false ); v->setBackgroundColour( ColourValue( 0, 0, 0, 0 ) ); // Should restore aspect ratio, in case of auto aspect ratio // enabled, it'll changed when add new viewport. camera->setAspectRatio(aspectRatio); // Should restore last viewport, i.e. never disturb user code // which might based on that. camera->_notifyViewport(oldViewport); } }
//----------------------------------------------------------------------------------- void Sample_Compositor::checkBoxToggled(OgreBites::CheckBox * box) { if (Ogre::StringUtil::startsWith(box->getName(), "Compositor_", false)) { String compositorName = box->getCaption(); String activeTex = mDebugTextureSelectMenu->getSelectedItem(); if (!box->isChecked()) { //Remove the items from the debug menu and remove debug texture if from disabled compositor bool debuggingRemovedTex = StringUtil::startsWith(activeTex, compositorName, false); if (debuggingRemovedTex) { mDebugTextureTUS->setContentType(TextureUnitState::CONTENT_NAMED); mDebugTextureSelectMenu->selectItem(0, true); } for (unsigned int i = 1; i < mDebugTextureSelectMenu->getNumItems(); i++) { if (StringUtil::startsWith(mDebugTextureSelectMenu->getItems()[i], compositorName, false)) { mDebugTextureSelectMenu->removeItem(i); i--; } } if (!debuggingRemovedTex) { //Selection clears itself when removing items. Restore. mDebugTextureSelectMenu->selectItem(activeTex, false); } } CompositorManager::getSingleton().setCompositorEnabled(mViewport, compositorName, box->isChecked()); if (box->isChecked()) { //Add the items to the selectable texture menu CompositorInstance* instance = CompositorManager::getSingleton().getCompositorChain(mViewport)->getCompositor(compositorName); if (instance) { CompositionTechnique::TextureDefinitionIterator it = instance->getTechnique()->getTextureDefinitionIterator(); while (it.hasMoreElements()) { CompositionTechnique::TextureDefinition* texDef = it.getNext(); size_t numTextures = texDef->formatList.size(); if (numTextures > 1) { for (size_t i=0; i<numTextures; i++) { //Dirty string composition. NOT ROBUST! mDebugTextureSelectMenu->addItem(compositorName + ";" + texDef->name + ";" + Ogre::StringConverter::toString((Ogre::uint32)i)); } } else { mDebugTextureSelectMenu->addItem(compositorName + ";" + texDef->name); } } mDebugTextureSelectMenu->selectItem(activeTex, false); } } } }
//----------------------------------------------------------------------- void Compositor::createGlobalTextures() { static size_t dummyCounter = 0; if (mSupportedTechniques.empty()) return; //To make sure that we are consistent, it is demanded that all composition //techniques define the same set of global textures. typedef std::set<String> StringSet; StringSet globalTextureNames; //Initialize global textures from first supported technique CompositionTechnique* firstTechnique = mSupportedTechniques[0]; CompositionTechnique::TextureDefinitionIterator texDefIt = firstTechnique->getTextureDefinitionIterator(); while (texDefIt.hasMoreElements()) { CompositionTechnique::TextureDefinition* def = texDefIt.getNext(); if (def->scope == CompositionTechnique::TS_GLOBAL) { //Check that this is a legit global texture if (!def->refCompName.empty()) { OGRE_EXCEPT(Exception::ERR_INVALID_STATE, "Global compositor texture definition can not be a reference", "Compositor::createGlobalTextures"); } if (def->width == 0 || def->height == 0) { OGRE_EXCEPT(Exception::ERR_INVALID_STATE, "Global compositor texture definition must have absolute size", "Compositor::createGlobalTextures"); } if (def->pooled) { LogManager::getSingleton().logMessage( "Pooling global compositor textures has no effect"); } globalTextureNames.insert(def->name); //TODO GSOC : Heavy copy-pasting from CompositorInstance. How to we solve it? /// Make the tetxure RenderTarget* rendTarget; if (def->formatList.size() > 1) { String MRTbaseName = "c" + StringConverter::toString(dummyCounter++) + "/" + mName + "/" + def->name; MultiRenderTarget* mrt = Root::getSingleton().getRenderSystem()->createMultiRenderTarget(MRTbaseName); mGlobalMRTs[def->name] = mrt; // create and bind individual surfaces size_t atch = 0; for (PixelFormatList::iterator p = def->formatList.begin(); p != def->formatList.end(); ++p, ++atch) { String texname = MRTbaseName + "/" + StringConverter::toString(atch); TexturePtr tex; tex = TextureManager::getSingleton().createManual( texname, ResourceGroupManager::INTERNAL_RESOURCE_GROUP_NAME, TEX_TYPE_2D, (uint)def->width, (uint)def->height, 0, *p, TU_RENDERTARGET, 0, def->hwGammaWrite && !PixelUtil::isFloatingPoint(*p), def->fsaa); RenderTexture* rt = tex->getBuffer()->getRenderTarget(); rt->setAutoUpdated(false); mrt->bindSurface(atch, rt); // Also add to local textures so we can look up String mrtLocalName = getMRTTexLocalName(def->name, atch); mGlobalTextures[mrtLocalName] = tex; } rendTarget = mrt; } else { String texName = "c" + StringConverter::toString(dummyCounter++) + "/" + mName + "/" + def->name; // space in the name mixup the cegui in the compositor demo // this is an auto generated name - so no spaces can't hart us. std::replace( texName.begin(), texName.end(), ' ', '_' ); TexturePtr tex; tex = TextureManager::getSingleton().createManual( texName, ResourceGroupManager::INTERNAL_RESOURCE_GROUP_NAME, TEX_TYPE_2D, (uint)def->width, (uint)def->height, 0, def->formatList[0], TU_RENDERTARGET, 0, def->hwGammaWrite && !PixelUtil::isFloatingPoint(def->formatList[0]), def->fsaa); rendTarget = tex->getBuffer()->getRenderTarget(); mGlobalTextures[def->name] = tex; } //Set DepthBuffer pool for sharing rendTarget->setDepthBufferPool( def->depthBufferId ); } } //Validate that all other supported techniques expose the same set of global textures. for (size_t i=1; i<mSupportedTechniques.size(); i++) { CompositionTechnique* technique = mSupportedTechniques[i]; bool isConsistent = true; size_t numGlobals = 0; texDefIt = technique->getTextureDefinitionIterator(); while (texDefIt.hasMoreElements()) { CompositionTechnique::TextureDefinition* texDef = texDefIt.getNext(); if (texDef->scope == CompositionTechnique::TS_GLOBAL) { if (globalTextureNames.find(texDef->name) == globalTextureNames.end()) { isConsistent = false; break; } numGlobals++; } } if (numGlobals != globalTextureNames.size()) isConsistent = false; if (!isConsistent) { OGRE_EXCEPT(Exception::ERR_INVALID_STATE, "Different composition techniques define different global textures", "Compositor::createGlobalTextures"); } } }
//----------------------------------------------------------------------- void CompositorInstance::createResources() { static size_t dummyCounter = 0; freeResources(); /// Create temporary textures /// In principle, temporary textures could be shared between multiple viewports /// (CompositorChains). This will save a lot of memory in case more viewports /// are composited. CompositionTechnique::TextureDefinitionIterator it = mTechnique->getTextureDefinitionIterator(); while(it.hasMoreElements()) { CompositionTechnique::TextureDefinition *def = it.getNext(); /// Determine width and height size_t width = def->width; size_t height = def->height; uint fsaa = 0; bool hwGammaWrite = false; deriveTextureRenderTargetOptions(def->name, &hwGammaWrite, &fsaa); if(width == 0) width = static_cast<size_t>( static_cast<float>(mChain->getViewport()->getActualWidth()) * def->widthFactor); if(height == 0) height = static_cast<size_t>( static_cast<float>(mChain->getViewport()->getActualHeight()) * def->heightFactor); /// Make the tetxure RenderTarget* rendTarget; if (def->formatList.size() > 1) { String MRTbaseName = "c" + StringConverter::toString(dummyCounter++) + "/" + def->name + "/" + mChain->getViewport()->getTarget()->getName(); MultiRenderTarget* mrt = Root::getSingleton().getRenderSystem()->createMultiRenderTarget(MRTbaseName); mLocalMRTs[def->name] = mrt; // create and bind individual surfaces size_t atch = 0; for (PixelFormatList::iterator p = def->formatList.begin(); p != def->formatList.end(); ++p, ++atch) { TexturePtr tex = TextureManager::getSingleton().createManual( MRTbaseName + "/" + StringConverter::toString(atch), ResourceGroupManager::INTERNAL_RESOURCE_GROUP_NAME, TEX_TYPE_2D, (uint)width, (uint)height, 0, *p, TU_RENDERTARGET ); RenderTexture* rt = tex->getBuffer()->getRenderTarget(); rt->setAutoUpdated(false); mrt->bindSurface(atch, rt); // Also add to local textures so we can look up String mrtLocalName = getMRTTexLocalName(def->name, atch); mLocalTextures[mrtLocalName] = tex; } rendTarget = mrt; } else { String texName = "c" + StringConverter::toString(dummyCounter++) + "/" + def->name + "/" + mChain->getViewport()->getTarget()->getName(); // space in the name mixup the cegui in the compositor demo // this is an auto generated name - so no spaces can't hart us. std::replace( texName.begin(), texName.end(), ' ', '_' ); TexturePtr tex = TextureManager::getSingleton().createManual( texName, ResourceGroupManager::INTERNAL_RESOURCE_GROUP_NAME, TEX_TYPE_2D, (uint)width, (uint)height, 0, def->formatList[0], TU_RENDERTARGET, 0, hwGammaWrite, fsaa); rendTarget = tex->getBuffer()->getRenderTarget(); mLocalTextures[def->name] = tex; } /// Set up viewport over entire texture rendTarget->setAutoUpdated( false ); Camera* camera = mChain->getViewport()->getCamera(); // Save last viewport and current aspect ratio Viewport* oldViewport = camera->getViewport(); Real aspectRatio = camera->getAspectRatio(); Viewport* v = rendTarget->addViewport( camera ); v->setClearEveryFrame( false ); v->setOverlaysEnabled( false ); v->setBackgroundColour( ColourValue( 0, 0, 0, 0 ) ); // Should restore aspect ratio, in case of auto aspect ratio // enabled, it'll changed when add new viewport. camera->setAspectRatio(aspectRatio); // Should restore last viewport, i.e. never disturb user code // which might based on that. camera->_notifyViewport(oldViewport); } }