Exemple #1
0
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);
			}
		}
	}
}
Exemple #4
0
//-----------------------------------------------------------------------
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);
    }
    
}