mirror of
https://github.com/OpenMW/openmw.git
synced 2025-01-16 21:59:55 +00:00
dd5901d351
Multiview shaders. Refactor Frustum management Rewrite shared shadow map cull mask should respect stereo Stereo savegame screencap LocalMap refactoring use the vertex buffer hint instead of the display list patch to enable/disable display lists Character preview fixes
190 lines
6 KiB
C++
190 lines
6 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 floating point depth format.
|
|
bool isFloatingPointDepthFormat(GLenum format);
|
|
|
|
// 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
|