1
0
Fork 1
mirror of https://github.com/TES3MP/openmw-tes3mp.git synced 2025-01-20 06:23:52 +00:00

De-hardcode settings and buffers.

This commit is contained in:
madsbuvi 2021-01-25 19:58:27 +01:00
parent 6dc61b904f
commit 5f0aae0523
3 changed files with 60 additions and 57 deletions

View file

@ -232,8 +232,8 @@ osg::ref_ptr<osg::Image> readPngImage (const std::string& file)
class Refraction : public SceneUtil::RTTNode class Refraction : public SceneUtil::RTTNode
{ {
public: public:
Refraction() Refraction(uint32_t rttSize)
: RTTNode(false) : RTTNode(rttSize, rttSize, false)
{ {
mClipCullNode = new ClipCullNode; mClipCullNode = new ClipCullNode;
} }
@ -296,8 +296,8 @@ private:
class Reflection : public SceneUtil::RTTNode class Reflection : public SceneUtil::RTTNode
{ {
public: public:
Reflection(bool isInterior) Reflection(uint32_t rttSize, bool isInterior)
: RTTNode(false) : RTTNode(rttSize, rttSize, false)
{ {
setInterior(isInterior); setInterior(isInterior);
mClipCullNode = new ClipCullNode; mClipCullNode = new ClipCullNode;
@ -477,7 +477,9 @@ void Water::updateWaterMaterial()
if (Settings::Manager::getBool("shader", "Water")) if (Settings::Manager::getBool("shader", "Water"))
{ {
mReflection = new Reflection(mInterior); unsigned int rttSize = Settings::Manager::getInt("rtt size", "Water");
mReflection = new Reflection(rttSize, mInterior);
mReflection->setWaterLevel(mTop); mReflection->setWaterLevel(mTop);
mReflection->setScene(mSceneRoot); mReflection->setScene(mSceneRoot);
if (mCullCallback) if (mCullCallback)
@ -486,7 +488,7 @@ void Water::updateWaterMaterial()
if (Settings::Manager::getBool("refraction", "Water")) if (Settings::Manager::getBool("refraction", "Water"))
{ {
mRefraction = new Refraction; mRefraction = new Refraction(rttSize);
mRefraction->setWaterLevel(mTop); mRefraction->setWaterLevel(mTop);
mRefraction->setScene(mSceneRoot); mRefraction->setScene(mSceneRoot);
if (mCullCallback) if (mCullCallback)

View file

@ -24,46 +24,10 @@ namespace SceneUtil
RTTNode* mGroup; RTTNode* mGroup;
}; };
// RTT camera RTTNode::RTTNode(uint32_t textureWidth, uint32_t textureHeight, bool doPerViewMapping)
class RTTCamera : public osg::Camera : mTextureWidth(textureWidth)
{ , mTextureHeight(textureHeight)
public: , mDoPerViewMapping(doPerViewMapping)
RTTCamera()
{
setRenderOrder(osg::Camera::PRE_RENDER, 1);
setClearMask(GL_DEPTH_BUFFER_BIT | GL_COLOR_BUFFER_BIT);
setRenderTargetImplementation(osg::Camera::FRAME_BUFFER_OBJECT);
unsigned int rttSize = Settings::Manager::getInt("rtt size", "Water");
setViewport(0, 0, rttSize, rttSize);
mColorBuffer = new osg::Texture2D;
mColorBuffer->setTextureSize(rttSize, rttSize);
mColorBuffer->setWrap(osg::Texture::WRAP_S, osg::Texture::CLAMP_TO_EDGE);
mColorBuffer->setWrap(osg::Texture::WRAP_T, osg::Texture::CLAMP_TO_EDGE);
mColorBuffer->setInternalFormat(GL_RGB);
mColorBuffer->setFilter(osg::Texture::MIN_FILTER, osg::Texture::LINEAR);
mColorBuffer->setFilter(osg::Texture::MAG_FILTER, osg::Texture::LINEAR);
attach(osg::Camera::COLOR_BUFFER, mColorBuffer);
mDepthBuffer = new osg::Texture2D;
mDepthBuffer->setTextureSize(rttSize, rttSize);
mDepthBuffer->setSourceFormat(GL_DEPTH_COMPONENT);
mDepthBuffer->setInternalFormat(GL_DEPTH_COMPONENT24);
mDepthBuffer->setWrap(osg::Texture::WRAP_S, osg::Texture::CLAMP_TO_EDGE);
mDepthBuffer->setWrap(osg::Texture::WRAP_T, osg::Texture::CLAMP_TO_EDGE);
mDepthBuffer->setSourceType(GL_UNSIGNED_INT);
mDepthBuffer->setFilter(osg::Texture::MIN_FILTER, osg::Texture::LINEAR);
mDepthBuffer->setFilter(osg::Texture::MAG_FILTER, osg::Texture::LINEAR);
attach(osg::Camera::DEPTH_BUFFER, mDepthBuffer);
}
osg::ref_ptr<osg::Texture2D> mColorBuffer;
osg::ref_ptr<osg::Texture2D> mDepthBuffer;
};
RTTNode::RTTNode(bool doPerViewMapping)
: mDoPerViewMapping(doPerViewMapping)
{ {
addCullCallback(new CullCallback(this)); addCullCallback(new CullCallback(this));
} }
@ -79,14 +43,14 @@ namespace SceneUtil
vdd->mCamera->accept(*cv); vdd->mCamera->accept(*cv);
} }
osg::Texture2D* RTTNode::getColorTexture(osgUtil::CullVisitor* cv) osg::Texture* RTTNode::getColorTexture(osgUtil::CullVisitor* cv)
{ {
return getViewDependentData(cv)->mCamera->mColorBuffer.get(); return getViewDependentData(cv)->mCamera->getBufferAttachmentMap()[osg::Camera::COLOR_BUFFER]._texture;
} }
osg::Texture2D* RTTNode::getDepthTexture(osgUtil::CullVisitor* cv) osg::Texture* RTTNode::getDepthTexture(osgUtil::CullVisitor* cv)
{ {
return getViewDependentData(cv)->mCamera->mDepthBuffer.get(); return getViewDependentData(cv)->mCamera->getBufferAttachmentMap()[osg::Camera::DEPTH_BUFFER]._texture;
} }
RTTNode::ViewDependentData* RTTNode::getViewDependentData(osgUtil::CullVisitor* cv) RTTNode::ViewDependentData* RTTNode::getViewDependentData(osgUtil::CullVisitor* cv)
@ -98,9 +62,43 @@ namespace SceneUtil
if (mViewDependentDataMap.count(cv) == 0) if (mViewDependentDataMap.count(cv) == 0)
{ {
auto camera = new osg::Camera();
mViewDependentDataMap[cv].reset(new ViewDependentData); mViewDependentDataMap[cv].reset(new ViewDependentData);
mViewDependentDataMap[cv]->mCamera = new RTTCamera(); mViewDependentDataMap[cv]->mCamera = camera;
camera->setRenderOrder(osg::Camera::PRE_RENDER);
camera->setClearMask(GL_DEPTH_BUFFER_BIT | GL_COLOR_BUFFER_BIT);
camera->setRenderTargetImplementation(osg::Camera::FRAME_BUFFER_OBJECT);
camera->setViewport(0, 0, mTextureWidth, mTextureHeight);
setDefaults(mViewDependentDataMap[cv]->mCamera.get()); 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);
}
if (camera->getBufferAttachmentMap().count(osg::Camera::DEPTH_BUFFER) == 0)
{
auto depthBuffer = new osg::Texture2D;
depthBuffer->setTextureSize(mTextureWidth, mTextureHeight);
depthBuffer->setSourceFormat(GL_DEPTH_COMPONENT);
depthBuffer->setInternalFormat(GL_DEPTH_COMPONENT24);
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);
depthBuffer->setFilter(osg::Texture::MIN_FILTER, osg::Texture::LINEAR);
depthBuffer->setFilter(osg::Texture::MAG_FILTER, osg::Texture::LINEAR);
camera->attach(osg::Camera::DEPTH_BUFFER, depthBuffer);
}
} }
return mViewDependentDataMap[cv].get(); return mViewDependentDataMap[cv].get();

View file

@ -9,6 +9,7 @@
namespace osg namespace osg
{ {
class Texture2D; class Texture2D;
class Camera;
} }
namespace osgUtil namespace osgUtil
@ -18,8 +19,6 @@ namespace osgUtil
namespace SceneUtil namespace SceneUtil
{ {
class RTTCamera;
/// @brief Implements per-view RTT operations. /// @brief Implements per-view RTT operations.
/// @par With a naive RTT implementation, subsequent views of multiple views will overwrite the results of the previous views, leading to /// @par With a naive RTT implementation, subsequent views of multiple views will overwrite the results of the previous views, leading to
/// the results of the last view being broadcast to all views. An error in all cases where the RTT result depends on the view. /// the results of the last view being broadcast to all views. An error in all cases where the RTT result depends on the view.
@ -28,15 +27,17 @@ namespace SceneUtil
/// @par Camera settings should be effectuated by overriding the setDefaults() and apply() methods, following a pattern similar to SceneUtil::StateSetUpdater /// @par Camera settings should be effectuated by overriding the setDefaults() and apply() methods, following a pattern similar to SceneUtil::StateSetUpdater
/// @par When using the RTT texture in your statesets, it is recommended to use SceneUtil::StateSetUpdater as a cull callback to handle this as the appropriate /// @par When using the RTT texture in your statesets, it is recommended to use SceneUtil::StateSetUpdater as a cull callback to handle this as the appropriate
/// textures can be retrieved during SceneUtil::StateSetUpdater::Apply() /// textures can be retrieved during SceneUtil::StateSetUpdater::Apply()
/// @par For any of COLOR_BUFFER or DEPTH_BUFFER not added during setDefaults(), RTTNode will attach a default buffer. The default color buffer has an internal format of GL_RGB.
/// The default depth buffer has internal format GL_DEPTH_COMPONENT24, source format GL_DEPTH_COMPONENT, and source type GL_UNSIGNED_INT. Default wrap is CLAMP_TO_EDGE and filter LINEAR.
class RTTNode : public osg::Node class RTTNode : public osg::Node
{ {
public: public:
RTTNode(bool doPerViewMapping); RTTNode(uint32_t textureWidth, uint32_t textureHeight, bool doPerViewMapping);
~RTTNode(); ~RTTNode();
osg::Texture2D* getColorTexture(osgUtil::CullVisitor* cv); osg::Texture* getColorTexture(osgUtil::CullVisitor* cv);
osg::Texture2D* getDepthTexture(osgUtil::CullVisitor* cv); osg::Texture* getDepthTexture(osgUtil::CullVisitor* cv);
/// Apply state - to override in derived classes /// Apply state - to override in derived classes
@ -51,13 +52,15 @@ namespace SceneUtil
private: private:
struct ViewDependentData struct ViewDependentData
{ {
osg::ref_ptr<RTTCamera> mCamera; osg::ref_ptr<osg::Camera> mCamera;
}; };
ViewDependentData* getViewDependentData(osgUtil::CullVisitor* cv); ViewDependentData* getViewDependentData(osgUtil::CullVisitor* cv);
typedef std::map< osgUtil::CullVisitor*, std::unique_ptr<ViewDependentData> > ViewDependentDataMap; typedef std::map< osgUtil::CullVisitor*, std::unique_ptr<ViewDependentData> > ViewDependentDataMap;
ViewDependentDataMap mViewDependentDataMap; ViewDependentDataMap mViewDependentDataMap;
uint32_t mTextureWidth;
uint32_t mTextureHeight;
bool mDoPerViewMapping; bool mDoPerViewMapping;
}; };
} }