virtual void execute(SceneManager *sm, RenderSystem *rs)
	{
		// Fire listener
		instance->_fireNotifyMaterialRender(pass_id, mat);

        Rectangle2D * mRectangle=static_cast<Rectangle2D *>(CompositorManager::getSingleton()._getTexturedRectangle2D());
        if (mQuadCornerModified)
        {
            // insure positions are using peculiar render system offsets 
            RenderSystem* rs = Root::getSingleton().getRenderSystem();
            Viewport* vp = rs->_getViewport();
            Real hOffset = rs->getHorizontalTexelOffset() / (0.5 * vp->getActualWidth());
            Real vOffset = rs->getVerticalTexelOffset() / (0.5 * vp->getActualHeight());
            mRectangle->setCorners(mQuadLeft + hOffset, mQuadTop - vOffset, mQuadRight + hOffset, mQuadBottom - vOffset);
        }
        
		// Queue passes from mat
		Technique::PassIterator i = technique->getPassIterator();
		while(i.hasMoreElements())
		{
			sm->_injectRenderWithPass(
				i.getNext(), 
				mRectangle,
				false // don't allow replacement of shadow passes
				);
		}
	}
//-----------------------------------------------------------------------
Renderable *CompositorManager::_getTexturedRectangle2D()
{
    if(!mRectangle)
    {
        /// 2D rectangle, to use for render_quad passes
        mRectangle = OGRE_NEW Rectangle2D(true, HardwareBuffer::HBU_DYNAMIC_WRITE_ONLY_DISCARDABLE);
    }
    RenderSystem* rs = Root::getSingleton().getRenderSystem();
    Viewport* vp = rs->_getViewport();
    Real hOffset = rs->getHorizontalTexelOffset() / (0.5f * vp->getActualWidth());
    Real vOffset = rs->getVerticalTexelOffset() / (0.5f * vp->getActualHeight());
    mRectangle->setCorners(-1 + hOffset, 1 - vOffset, 1 + hOffset, -1 - vOffset);
    return mRectangle;
}
示例#3
0
//-----------------------------------------------------------------------
Renderable *CompositorManager::_getTexturedRectangle2D()
{
	if(!mRectangle)
	{
		/// 2D rectangle, to use for render_quad passes
		mRectangle = new Rectangle2D(true);
	}
	RenderSystem* rs = Root::getSingleton().getRenderSystem();
	Viewport* vp = rs->_getViewport();
	Real hOffset = rs->getHorizontalTexelOffset() / (0.5 * vp->getActualWidth());
	Real vOffset = rs->getVerticalTexelOffset() / (0.5 * vp->getActualHeight());
	mRectangle->setCorners(-1 + hOffset, 1 - vOffset, 1 + hOffset, -1 - vOffset);
	return mRectangle;
}
    //---------------------------------------------------------------------
    void OverlayElement::_updateFromParent(void)
    {
        Real parentLeft = 0, parentTop = 0, parentBottom = 0, parentRight = 0;

        if (mParent)
        {
            parentLeft = mParent->_getDerivedLeft();
            parentTop = mParent->_getDerivedTop();
            if (mHorzAlign == GHA_CENTER || mHorzAlign == GHA_RIGHT)
            {
                parentRight = parentLeft + mParent->_getRelativeWidth();
            }
            if (mVertAlign == GVA_CENTER || mVertAlign == GVA_BOTTOM)
            {
                parentBottom = parentTop + mParent->_getRelativeHeight();
            }

        }
        else
        {
            RenderSystem* rSys = Root::getSingleton().getRenderSystem();
            OverlayManager& oMgr = OverlayManager::getSingleton();

            // Calculate offsets required for mapping texel origins to pixel origins in the
            // current rendersystem
            Real hOffset = rSys->getHorizontalTexelOffset() / oMgr.getViewportWidth();
            Real vOffset = rSys->getVerticalTexelOffset() / oMgr.getViewportHeight();

            parentLeft = 0.0f + hOffset;
            parentTop = 0.0f + vOffset;
            parentRight = 1.0f + hOffset;
            parentBottom = 1.0f + vOffset;
        }

        // Sort out position based on alignment
        // NB all we do is derived the origin, we don't automatically sort out the position
        // This is more flexible than forcing absolute right & middle 
        switch(mHorzAlign)
        {
        case GHA_CENTER:
            mDerivedLeft = ((parentLeft + parentRight) * 0.5f) + mLeft;
            break;
        case GHA_LEFT:
            mDerivedLeft = parentLeft + mLeft;
            break;
        case GHA_RIGHT:
            mDerivedLeft = parentRight + mLeft;
            break;
        };
        switch(mVertAlign)
        {
        case GVA_CENTER:
            mDerivedTop = ((parentTop + parentBottom) * 0.5f) + mTop;
            break;
        case GVA_TOP:
            mDerivedTop = parentTop + mTop;
            break;
        case GVA_BOTTOM:
            mDerivedTop = parentBottom + mTop;
            break;
        };

        mDerivedOutOfDate = false;

        if (mParent != 0)
        {
            Rectangle parent;
            Rectangle child;

            mParent->_getClippingRegion(parent);

            child.left   = mDerivedLeft;
            child.top    = mDerivedTop;
            child.right  = mDerivedLeft + mWidth;
            child.bottom = mDerivedTop + mHeight;

            mClippingRegion = intersect(parent, child);
        }
        else
        {
            mClippingRegion.left   = mDerivedLeft;
            mClippingRegion.top    = mDerivedTop;
            mClippingRegion.right  = mDerivedLeft + mWidth;
            mClippingRegion.bottom = mDerivedTop + mHeight;
        }
    }
	//---------------------------------------------------------------------
	void TerrainMaterialGenerator::_renderCompositeMap(size_t size, 
		const Rect& rect, const MaterialPtr& mat, const TexturePtr& destCompositeMap)
	{
		if (!mCompositeMapSM)
		{
			// dedicated SceneManager
			mCompositeMapSM = Root::getSingleton().createSceneManager(DefaultSceneManagerFactory::FACTORY_TYPE_NAME);
			float camDist = 100;
			float halfCamDist = camDist * 0.5f;
			mCompositeMapCam = mCompositeMapSM->createCamera("cam");
			mCompositeMapCam->setPosition(0, 0, camDist);
			mCompositeMapCam->lookAt(Vector3::ZERO);
			mCompositeMapCam->setProjectionType(PT_ORTHOGRAPHIC);
			mCompositeMapCam->setNearClipDistance(10);
			mCompositeMapCam->setFarClipDistance(500);
			mCompositeMapCam->setOrthoWindow(camDist, camDist);

			// Just in case material relies on light auto params
			mCompositeMapLight = mCompositeMapSM->createLight();
			mCompositeMapLight->setType(Light::LT_DIRECTIONAL);

			RenderSystem* rSys = Root::getSingleton().getRenderSystem();
			Real hOffset = rSys->getHorizontalTexelOffset() / (Real)size;
			Real vOffset = rSys->getVerticalTexelOffset() / (Real)size;


			// set up scene
			mCompositeMapPlane = mCompositeMapSM->createManualObject();
			mCompositeMapPlane->begin(mat->getName());
			mCompositeMapPlane->position(-halfCamDist, halfCamDist, 0);
			mCompositeMapPlane->textureCoord(0 - hOffset, 0 - vOffset);
			mCompositeMapPlane->position(-halfCamDist, -halfCamDist, 0);
			mCompositeMapPlane->textureCoord(0 - hOffset, 1 - vOffset);
			mCompositeMapPlane->position(halfCamDist, -halfCamDist, 0);
			mCompositeMapPlane->textureCoord(1 - hOffset, 1 - vOffset);
			mCompositeMapPlane->position(halfCamDist, halfCamDist, 0);
			mCompositeMapPlane->textureCoord(1 - hOffset, 0 - vOffset);
			mCompositeMapPlane->quad(0, 1, 2, 3);
			mCompositeMapPlane->end();
			mCompositeMapSM->getRootSceneNode()->attachObject(mCompositeMapPlane);

		}

		// update
		mCompositeMapPlane->setMaterialName(0, mat->getName());
		TerrainGlobalOptions& globalopts = TerrainGlobalOptions::getSingleton();
		mCompositeMapLight->setDirection(globalopts.getLightMapDirection());
		mCompositeMapLight->setDiffuseColour(globalopts.getCompositeMapDiffuse());
		mCompositeMapSM->setAmbientLight(globalopts.getCompositeMapAmbient());


		// check for size change (allow smaller to be reused)
		if (mCompositeMapRTT && size != mCompositeMapRTT->getWidth())
		{
			TextureManager::getSingleton().remove(mCompositeMapRTT->getHandle());
			mCompositeMapRTT = 0;
		}

		if (!mCompositeMapRTT)
		{
			mCompositeMapRTT = TextureManager::getSingleton().createManual(
				mCompositeMapSM->getName() + "/compRTT", 
				ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME, TEX_TYPE_2D, size, size, 0, PF_BYTE_RGBA, 
				TU_RENDERTARGET).get();
			RenderTarget* rtt = mCompositeMapRTT->getBuffer()->getRenderTarget();
			// don't render all the time, only on demand
			rtt->setAutoUpdated(false);
			Viewport* vp = rtt->addViewport(mCompositeMapCam);
			// don't render overlays
			vp->setOverlaysEnabled(false);

		}

		// calculate the area we need to update
		Real vpleft = (Real)rect.left / (Real)size;
		Real vptop = (Real)rect.top / (Real)size;
		Real vpright = (Real)rect.right / (Real)size;
		Real vpbottom = (Real)rect.bottom / (Real)size;

		RenderTarget* rtt = mCompositeMapRTT->getBuffer()->getRenderTarget();
		mCompositeMapCam->setWindow(vpleft, vptop, vpright, vpbottom);

		rtt->update();

		// We have an RTT, we want to copy the results into a regular texture
		// That's because in non-update scenarios we don't want to keep an RTT
		// around. We use a single RTT to serve all terrain pages which is more
		// efficient.
		Image::Box box(rect.left, rect.top, rect.right, rect.bottom);
		destCompositeMap->getBuffer()->blit(mCompositeMapRTT->getBuffer(), box, box);

		
	}