mirror of
				https://github.com/OpenMW/openmw.git
				synced 2025-11-04 08:26:39 +00:00 
			
		
		
		
	
		
			
				
	
	
		
			108 lines
		
	
	
	
		
			4.3 KiB
		
	
	
	
		
			C++
		
	
	
	
	
	
			
		
		
	
	
			108 lines
		
	
	
	
		
			4.3 KiB
		
	
	
	
		
			C++
		
	
	
	
	
	
#include "rtt.hpp"
 | 
						|
#include "util.hpp"
 | 
						|
 | 
						|
#include <osg/Node>
 | 
						|
#include <osg/NodeVisitor>
 | 
						|
#include <osg/Texture2D>
 | 
						|
#include <osgUtil/CullVisitor>
 | 
						|
 | 
						|
#include <components/sceneutil/nodecallback.hpp>
 | 
						|
#include <components/settings/settings.hpp>
 | 
						|
#include <components/sceneutil/depth.hpp>
 | 
						|
 | 
						|
namespace SceneUtil
 | 
						|
{
 | 
						|
    class CullCallback : public SceneUtil::NodeCallback<CullCallback, RTTNode*, osgUtil::CullVisitor*>
 | 
						|
    {
 | 
						|
    public:
 | 
						|
 | 
						|
        void operator()(RTTNode* node, osgUtil::CullVisitor* cv)
 | 
						|
        {
 | 
						|
            node->cull(cv);
 | 
						|
        }
 | 
						|
    };
 | 
						|
 | 
						|
    RTTNode::RTTNode(uint32_t textureWidth, uint32_t textureHeight, int renderOrderNum, bool doPerViewMapping)
 | 
						|
        : mTextureWidth(textureWidth)
 | 
						|
        , mTextureHeight(textureHeight)
 | 
						|
        , mRenderOrderNum(renderOrderNum)
 | 
						|
        , mDoPerViewMapping(doPerViewMapping)
 | 
						|
    {
 | 
						|
        addCullCallback(new CullCallback);
 | 
						|
        setCullingActive(false);
 | 
						|
    }
 | 
						|
 | 
						|
    RTTNode::~RTTNode()
 | 
						|
    {
 | 
						|
    }
 | 
						|
 | 
						|
    void RTTNode::cull(osgUtil::CullVisitor* cv)
 | 
						|
    {
 | 
						|
        auto* vdd = getViewDependentData(cv);
 | 
						|
        apply(vdd->mCamera);
 | 
						|
        vdd->mCamera->accept(*cv);
 | 
						|
    }
 | 
						|
 | 
						|
    osg::Texture* RTTNode::getColorTexture(osgUtil::CullVisitor* cv)
 | 
						|
    {
 | 
						|
        return getViewDependentData(cv)->mCamera->getBufferAttachmentMap()[osg::Camera::COLOR_BUFFER]._texture;
 | 
						|
    }
 | 
						|
 | 
						|
    osg::Texture* RTTNode::getDepthTexture(osgUtil::CullVisitor* cv)
 | 
						|
    {
 | 
						|
        return getViewDependentData(cv)->mCamera->getBufferAttachmentMap()[osg::Camera::PACKED_DEPTH_STENCIL_BUFFER]._texture;
 | 
						|
    }
 | 
						|
 | 
						|
    RTTNode::ViewDependentData* RTTNode::getViewDependentData(osgUtil::CullVisitor* cv)
 | 
						|
    {
 | 
						|
        if (!mDoPerViewMapping)
 | 
						|
            // Always setting it to null is an easy way to disable per-view mapping when mDoPerViewMapping is false.
 | 
						|
            // This is safe since the visitor is never dereferenced.
 | 
						|
            cv = nullptr;
 | 
						|
 | 
						|
        if (mViewDependentDataMap.count(cv) == 0)
 | 
						|
        {
 | 
						|
            auto camera = new osg::Camera();
 | 
						|
            mViewDependentDataMap[cv].reset(new ViewDependentData);
 | 
						|
            mViewDependentDataMap[cv]->mCamera = camera;
 | 
						|
 | 
						|
            camera->setRenderOrder(osg::Camera::PRE_RENDER, mRenderOrderNum);
 | 
						|
            camera->setClearMask(GL_DEPTH_BUFFER_BIT | GL_COLOR_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);
 | 
						|
            camera->setRenderTargetImplementation(osg::Camera::FRAME_BUFFER_OBJECT);
 | 
						|
            camera->setViewport(0, 0, mTextureWidth, mTextureHeight);
 | 
						|
            SceneUtil::setCameraClearDepth(camera);
 | 
						|
 | 
						|
            setDefaults(mViewDependentDataMap[cv]->mCamera.get());
 | 
						|
 | 
						|
            // Create any buffer attachments not added in setDefaults
 | 
						|
            if (camera->getBufferAttachmentMap().count(osg::Camera::COLOR_BUFFER) == 0)
 | 
						|
            {
 | 
						|
                auto colorBuffer = new osg::Texture2D;
 | 
						|
                colorBuffer->setTextureSize(mTextureWidth, mTextureHeight);
 | 
						|
                colorBuffer->setWrap(osg::Texture::WRAP_S, osg::Texture::CLAMP_TO_EDGE);
 | 
						|
                colorBuffer->setWrap(osg::Texture::WRAP_T, osg::Texture::CLAMP_TO_EDGE);
 | 
						|
                colorBuffer->setInternalFormat(GL_RGB);
 | 
						|
                colorBuffer->setFilter(osg::Texture::MIN_FILTER, osg::Texture::LINEAR);
 | 
						|
                colorBuffer->setFilter(osg::Texture::MAG_FILTER, osg::Texture::LINEAR);
 | 
						|
                camera->attach(osg::Camera::COLOR_BUFFER, colorBuffer);
 | 
						|
                SceneUtil::attachAlphaToCoverageFriendlyFramebufferToCamera(camera, osg::Camera::COLOR_BUFFER, colorBuffer);
 | 
						|
            }
 | 
						|
 | 
						|
            if (camera->getBufferAttachmentMap().count(osg::Camera::PACKED_DEPTH_STENCIL_BUFFER) == 0)
 | 
						|
            {
 | 
						|
                auto depthBuffer = new osg::Texture2D;
 | 
						|
                depthBuffer->setTextureSize(mTextureWidth, mTextureHeight);
 | 
						|
                depthBuffer->setSourceFormat(GL_DEPTH_STENCIL_EXT);
 | 
						|
                depthBuffer->setInternalFormat(GL_DEPTH24_STENCIL8_EXT);
 | 
						|
                depthBuffer->setWrap(osg::Texture::WRAP_S, osg::Texture::CLAMP_TO_EDGE);
 | 
						|
                depthBuffer->setWrap(osg::Texture::WRAP_T, osg::Texture::CLAMP_TO_EDGE);
 | 
						|
                depthBuffer->setSourceType(GL_UNSIGNED_INT_24_8_EXT);
 | 
						|
                depthBuffer->setFilter(osg::Texture::MIN_FILTER, osg::Texture::LINEAR);
 | 
						|
                depthBuffer->setFilter(osg::Texture::MAG_FILTER, osg::Texture::LINEAR);
 | 
						|
                camera->attach(osg::Camera::PACKED_DEPTH_STENCIL_BUFFER, depthBuffer);
 | 
						|
            }
 | 
						|
        }
 | 
						|
 | 
						|
        return mViewDependentDataMap[cv].get();
 | 
						|
    }
 | 
						|
}
 |