//----------------------------------------------------------------------- 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); } }