mirror of
				https://github.com/OpenMW/openmw.git
				synced 2025-11-04 09:56:39 +00:00 
			
		
		
		
	
		
			
				
	
	
		
			187 lines
		
	
	
	
		
			5.9 KiB
		
	
	
	
		
			C++
		
	
	
	
	
	
			
		
		
	
	
			187 lines
		
	
	
	
		
			5.9 KiB
		
	
	
	
		
			C++
		
	
	
	
	
	
#ifndef OPENMW_COMPONENTS_SCENEUTIL_DEPTH_H
 | 
						|
#define OPENMW_COMPONENTS_SCENEUTIL_DEPTH_H
 | 
						|
 | 
						|
#include <osg/Depth>
 | 
						|
 | 
						|
#include "util.hpp"
 | 
						|
 | 
						|
#ifndef GL_DEPTH32F_STENCIL8_NV
 | 
						|
#define GL_DEPTH32F_STENCIL8_NV 0x8DAC
 | 
						|
#endif
 | 
						|
 | 
						|
#ifndef GL_DEPTH32F_STENCIL8
 | 
						|
#define GL_DEPTH32F_STENCIL8 0x8CAD
 | 
						|
#endif
 | 
						|
 | 
						|
#ifndef GL_FLOAT_32_UNSIGNED_INT_24_8_REV
 | 
						|
#define GL_FLOAT_32_UNSIGNED_INT_24_8_REV 0x8DAD
 | 
						|
#endif
 | 
						|
 | 
						|
#ifndef GL_DEPTH24_STENCIL8
 | 
						|
#define GL_DEPTH24_STENCIL8 0x88F0
 | 
						|
#endif
 | 
						|
 | 
						|
#ifndef GL_DEPTH_STENCIL_EXT
 | 
						|
#define GL_DEPTH_STENCIL_EXT 0x84F9
 | 
						|
#endif
 | 
						|
 | 
						|
#ifndef GL_UNSIGNED_INT_24_8_EXT
 | 
						|
#define GL_UNSIGNED_INT_24_8_EXT 0x84FA
 | 
						|
#endif
 | 
						|
 | 
						|
namespace SceneUtil
 | 
						|
{
 | 
						|
    // Sets camera clear depth to 0 if reversed depth buffer is in use, 1 otherwise.
 | 
						|
    void setCameraClearDepth(osg::Camera* camera);
 | 
						|
 | 
						|
    // Returns a perspective projection matrix for use with a reversed z-buffer
 | 
						|
    // and an infinite far plane. This is derived by mapping the default z-range
 | 
						|
    // of [0,1] to [1,0], then taking the limit as far plane approaches infinity.
 | 
						|
    osg::Matrix getReversedZProjectionMatrixAsPerspectiveInf(double fov, double aspect, double near);
 | 
						|
 | 
						|
    // Returns a perspective projection matrix for use with a reversed z-buffer.
 | 
						|
    osg::Matrix getReversedZProjectionMatrixAsPerspective(double fov, double aspect, double near, double far);
 | 
						|
 | 
						|
    // Returns an orthographic projection matrix for use with a reversed z-buffer.
 | 
						|
    osg::Matrix getReversedZProjectionMatrixAsOrtho(double left, double right, double bottom, double top, double near, double far);
 | 
						|
 | 
						|
    // Returns true if the GL format is a depth format
 | 
						|
    bool isDepthFormat(GLenum format);
 | 
						|
 | 
						|
    // Returns true if the GL format is a depth+stencil format
 | 
						|
    bool isDepthStencilFormat(GLenum format);
 | 
						|
 | 
						|
    // Returns the corresponding source format and type for the given internal format
 | 
						|
    void getDepthFormatSourceFormatAndType(GLenum internalFormat, GLenum& sourceFormat, GLenum& sourceType);
 | 
						|
 | 
						|
    // Converts depth-stencil formats to their corresponding depth formats.
 | 
						|
    GLenum getDepthFormatOfDepthStencilFormat(GLenum internalFormat);
 | 
						|
 | 
						|
    // Brief wrapper around an osg::Depth that applies the reversed depth function when a reversed depth buffer is in use
 | 
						|
    class AutoDepth : public osg::Depth
 | 
						|
    {
 | 
						|
    public:
 | 
						|
        AutoDepth(osg::Depth::Function func=osg::Depth::LESS, double zNear=0.0, double zFar=1.0, bool writeMask=true)
 | 
						|
        {
 | 
						|
            setFunction(func);
 | 
						|
            setZNear(zNear);
 | 
						|
            setZFar(zFar);
 | 
						|
            setWriteMask(writeMask);
 | 
						|
        }
 | 
						|
 | 
						|
        AutoDepth(const osg::Depth& copy, const osg::CopyOp& copyop = osg::CopyOp::SHALLOW_COPY) : osg::Depth(copy, copyop) {}
 | 
						|
 | 
						|
        osg::Object* cloneType() const override { return new AutoDepth; }
 | 
						|
        osg::Object* clone(const osg::CopyOp& copyop) const override { return new AutoDepth(*this,copyop); }
 | 
						|
 | 
						|
        void apply(osg::State& state) const override
 | 
						|
        {
 | 
						|
            glDepthFunc(static_cast<GLenum>(AutoDepth::isReversed() ? getReversedDepthFunction() : getFunction()));
 | 
						|
            glDepthMask(static_cast<GLboolean>(getWriteMask()));
 | 
						|
        #if defined(OSG_GLES1_AVAILABLE) || defined(OSG_GLES2_AVAILABLE) || defined(OSG_GLES3_AVAILABLE)
 | 
						|
            glDepthRangef(getZNear(),getZFar());
 | 
						|
        #else
 | 
						|
            glDepthRange(getZNear(),getZFar());
 | 
						|
        #endif
 | 
						|
        }
 | 
						|
 | 
						|
        static void setReversed(bool reverseZ)
 | 
						|
        {
 | 
						|
            static bool init = false;
 | 
						|
 | 
						|
            if (!init)
 | 
						|
            {
 | 
						|
                AutoDepth::sReversed = reverseZ;
 | 
						|
                init = true;
 | 
						|
            }
 | 
						|
        }
 | 
						|
 | 
						|
        static bool isReversed()
 | 
						|
        {
 | 
						|
            return AutoDepth::sReversed;
 | 
						|
        }
 | 
						|
 | 
						|
        static void setDepthFormat(GLenum format);
 | 
						|
 | 
						|
        static GLenum depthInternalFormat()
 | 
						|
        {
 | 
						|
            return AutoDepth::sDepthInternalFormat;
 | 
						|
        }
 | 
						|
 | 
						|
        static GLenum depthSourceFormat()
 | 
						|
        {
 | 
						|
            return AutoDepth::sDepthSourceFormat;
 | 
						|
        }
 | 
						|
 | 
						|
        static GLenum depthSourceType()
 | 
						|
        {
 | 
						|
            return AutoDepth::sDepthSourceType;
 | 
						|
        }
 | 
						|
 | 
						|
    private:
 | 
						|
 | 
						|
        static inline bool sReversed = false;
 | 
						|
        static inline GLenum sDepthSourceFormat = GL_DEPTH_COMPONENT;
 | 
						|
        static inline GLenum sDepthInternalFormat = GL_DEPTH_COMPONENT24;
 | 
						|
        static inline GLenum sDepthSourceType = GL_UNSIGNED_INT;
 | 
						|
 | 
						|
        osg::Depth::Function getReversedDepthFunction() const
 | 
						|
        {
 | 
						|
            const osg::Depth::Function func = getFunction();
 | 
						|
 | 
						|
            switch (func)
 | 
						|
            {
 | 
						|
            case osg::Depth::LESS:
 | 
						|
                return osg::Depth::GREATER;
 | 
						|
            case osg::Depth::LEQUAL:
 | 
						|
                return osg::Depth::GEQUAL;
 | 
						|
            case osg::Depth::GREATER:
 | 
						|
                return osg::Depth::LESS;
 | 
						|
            case osg::Depth::GEQUAL:
 | 
						|
                return osg::Depth::LEQUAL;
 | 
						|
            default:
 | 
						|
                return func;
 | 
						|
            }
 | 
						|
        }
 | 
						|
 | 
						|
    };
 | 
						|
 | 
						|
    // Replaces all nodes osg::Depth state attributes with SceneUtil::AutoDepth.
 | 
						|
    class ReplaceDepthVisitor : public osg::NodeVisitor
 | 
						|
    {
 | 
						|
    public:
 | 
						|
        ReplaceDepthVisitor() : osg::NodeVisitor(TRAVERSE_ALL_CHILDREN) {}
 | 
						|
 | 
						|
        void apply(osg::Node& node) override
 | 
						|
        {
 | 
						|
            osg::StateSet* stateSet = node.getStateSet();
 | 
						|
 | 
						|
            if (stateSet)
 | 
						|
            {
 | 
						|
                if (osg::Depth* depth = static_cast<osg::Depth*>(stateSet->getAttribute(osg::StateAttribute::DEPTH)))
 | 
						|
                    stateSet->setAttribute(new SceneUtil::AutoDepth(*depth));
 | 
						|
            };
 | 
						|
 | 
						|
            traverse(node);
 | 
						|
        }
 | 
						|
    };
 | 
						|
 | 
						|
    class SelectDepthFormatOperation : public osg::GraphicsOperation
 | 
						|
    {
 | 
						|
    public:
 | 
						|
        SelectDepthFormatOperation() : GraphicsOperation("SelectDepthFormatOperation", false)
 | 
						|
        {}
 | 
						|
 | 
						|
        void operator()(osg::GraphicsContext* graphicsContext) override;
 | 
						|
 | 
						|
        void setSupportedFormats(const std::vector<GLenum>& supportedFormats)
 | 
						|
        {
 | 
						|
            mSupportedFormats = supportedFormats;
 | 
						|
        }
 | 
						|
 | 
						|
    private:
 | 
						|
        std::vector<GLenum> mSupportedFormats;
 | 
						|
    };
 | 
						|
}
 | 
						|
 | 
						|
#endif
 |