mirror of
https://gitlab.com/OpenMW/openmw.git
synced 2025-01-26 18:35:20 +00:00
280 lines
6.9 KiB
C++
280 lines
6.9 KiB
C++
#ifndef OPENMW_MWRENDER_POSTPROCESSOR_H
|
|
#define OPENMW_MWRENDER_POSTPROCESSOR_H
|
|
|
|
#include <array>
|
|
#include <string>
|
|
#include <unordered_map>
|
|
#include <vector>
|
|
|
|
#include <filesystem>
|
|
|
|
#include <osg/Camera>
|
|
#include <osg/FrameBufferObject>
|
|
#include <osg/Group>
|
|
#include <osg/Texture2D>
|
|
|
|
#include <osgViewer/Viewer>
|
|
|
|
#include <components/debug/debuglog.hpp>
|
|
#include <components/fx/stateupdater.hpp>
|
|
#include <components/fx/technique.hpp>
|
|
|
|
#include "pingpongcanvas.hpp"
|
|
#include "transparentpass.hpp"
|
|
|
|
#include <memory>
|
|
|
|
namespace osgViewer
|
|
{
|
|
class Viewer;
|
|
}
|
|
|
|
namespace Stereo
|
|
{
|
|
class MultiviewFramebuffer;
|
|
}
|
|
|
|
namespace VFS
|
|
{
|
|
class Manager;
|
|
}
|
|
|
|
namespace Shader
|
|
{
|
|
class ShaderManager;
|
|
}
|
|
|
|
namespace MWRender
|
|
{
|
|
class RenderingManager;
|
|
class PingPongCull;
|
|
class PingPongCanvas;
|
|
class TransparentDepthBinCallback;
|
|
|
|
class PostProcessor : public osg::Group
|
|
{
|
|
public:
|
|
using FBOArray = std::array<osg::ref_ptr<osg::FrameBufferObject>, 5>;
|
|
using TextureArray = std::array<osg::ref_ptr<osg::Texture>, 5>;
|
|
using TechniqueList = std::vector<std::shared_ptr<fx::Technique>>;
|
|
|
|
enum TextureIndex
|
|
{
|
|
Tex_Scene,
|
|
Tex_Scene_LDR,
|
|
Tex_Depth,
|
|
Tex_OpaqueDepth,
|
|
Tex_Normal
|
|
};
|
|
|
|
enum FBOIndex
|
|
{
|
|
FBO_Primary,
|
|
FBO_Multisample,
|
|
FBO_FirstPerson,
|
|
FBO_OpaqueDepth,
|
|
FBO_Intercept
|
|
};
|
|
|
|
enum TextureUnits
|
|
{
|
|
Unit_LastShader = 0,
|
|
Unit_LastPass,
|
|
Unit_Depth,
|
|
Unit_EyeAdaptation,
|
|
Unit_Normals,
|
|
Unit_NextFree
|
|
};
|
|
|
|
enum Status
|
|
{
|
|
Status_Error,
|
|
Status_Toggled,
|
|
Status_Unchanged
|
|
};
|
|
|
|
PostProcessor(
|
|
RenderingManager& rendering, osgViewer::Viewer* viewer, osg::Group* rootNode, const VFS::Manager* vfs);
|
|
|
|
~PostProcessor();
|
|
|
|
void traverse(osg::NodeVisitor& nv) override;
|
|
|
|
osg::ref_ptr<osg::FrameBufferObject> getFbo(FBOIndex index, unsigned int frameId)
|
|
{
|
|
return mFbos[frameId][index];
|
|
}
|
|
|
|
osg::ref_ptr<osg::Texture> getTexture(TextureIndex index, unsigned int frameId)
|
|
{
|
|
return mTextures[frameId][index];
|
|
}
|
|
|
|
osg::ref_ptr<osg::FrameBufferObject> getPrimaryFbo(unsigned int frameId)
|
|
{
|
|
return mFbos[frameId][FBO_Multisample] ? mFbos[frameId][FBO_Multisample] : mFbos[frameId][FBO_Primary];
|
|
}
|
|
|
|
osg::ref_ptr<fx::StateUpdater> getStateUpdater() { return mStateUpdater; }
|
|
|
|
const TechniqueList& getTechniques() { return mTechniques; }
|
|
|
|
const TechniqueList& getTemplates() const { return mTemplates; }
|
|
|
|
osg::ref_ptr<PingPongCanvas> getCanvas() { return mPingPongCanvas; }
|
|
|
|
const auto& getTechniqueMap() const { return mTechniqueFileMap; }
|
|
|
|
void resize();
|
|
|
|
Status enableTechnique(std::shared_ptr<fx::Technique> technique, std::optional<int> location = std::nullopt);
|
|
|
|
Status disableTechnique(std::shared_ptr<fx::Technique> technique, bool dirty = true);
|
|
|
|
bool getSupportsNormalsRT() const { return mNormalsSupported; }
|
|
|
|
template <class T>
|
|
void setUniform(std::shared_ptr<fx::Technique> technique, const std::string& name, const T& value)
|
|
{
|
|
if (!isEnabled())
|
|
return;
|
|
|
|
auto it = technique->findUniform(name);
|
|
|
|
if (it == technique->getUniformMap().end())
|
|
return;
|
|
|
|
if ((*it)->mStatic)
|
|
{
|
|
Log(Debug::Warning) << "Attempting to set a configration variable [" << name << "] as a uniform";
|
|
return;
|
|
}
|
|
|
|
(*it)->setValue(value);
|
|
}
|
|
|
|
std::optional<size_t> getUniformSize(std::shared_ptr<fx::Technique> technique, const std::string& name)
|
|
{
|
|
auto it = technique->findUniform(name);
|
|
|
|
if (it == technique->getUniformMap().end())
|
|
return std::nullopt;
|
|
|
|
return (*it)->getNumElements();
|
|
}
|
|
|
|
bool isTechniqueEnabled(const std::shared_ptr<fx::Technique>& technique) const;
|
|
|
|
void setExteriorFlag(bool exterior) { mExteriorFlag = exterior; }
|
|
|
|
void setUnderwaterFlag(bool underwater) { mUnderwater = underwater; }
|
|
|
|
void toggleMode();
|
|
|
|
std::shared_ptr<fx::Technique> loadTechnique(const std::string& name, bool loadNextFrame = false);
|
|
|
|
bool isEnabled() const { return mUsePostProcessing && mEnabled; }
|
|
|
|
bool softParticlesEnabled() const { return mSoftParticles; }
|
|
|
|
bool getHDR() const { return mHDR; }
|
|
|
|
void disable();
|
|
|
|
void enable(bool usePostProcessing = true);
|
|
|
|
void setRenderTargetSize(int width, int height)
|
|
{
|
|
mWidth = width;
|
|
mHeight = height;
|
|
}
|
|
|
|
void disableDynamicShaders();
|
|
|
|
int renderWidth() const;
|
|
int renderHeight() const;
|
|
|
|
void triggerShaderReload();
|
|
|
|
bool mEnableLiveReload;
|
|
|
|
void loadChain();
|
|
void saveChain();
|
|
|
|
private:
|
|
void populateTechniqueFiles();
|
|
|
|
size_t frame() const { return mViewer->getFrameStamp()->getFrameNumber(); }
|
|
|
|
void createObjectsForFrame(size_t frameId);
|
|
|
|
void createTexturesAndCamera(size_t frameId);
|
|
|
|
void reloadMainPass(fx::Technique& technique);
|
|
|
|
void dirtyTechniques();
|
|
|
|
void update(size_t frameId);
|
|
|
|
void reloadIfRequired();
|
|
|
|
void updateLiveReload();
|
|
|
|
void cull(size_t frameId, osgUtil::CullVisitor* cv);
|
|
|
|
osg::ref_ptr<osg::Group> mRootNode;
|
|
osg::ref_ptr<osg::Camera> mHUDCamera;
|
|
|
|
std::array<TextureArray, 2> mTextures;
|
|
std::array<FBOArray, 2> mFbos;
|
|
|
|
TechniqueList mTechniques;
|
|
TechniqueList mTemplates;
|
|
TechniqueList mQueuedTemplates;
|
|
|
|
std::unordered_map<std::string, std::filesystem::path> mTechniqueFileMap;
|
|
|
|
int mSamples;
|
|
|
|
bool mDirty;
|
|
size_t mDirtyFrameId;
|
|
|
|
RenderingManager& mRendering;
|
|
osgViewer::Viewer* mViewer;
|
|
const VFS::Manager* mVFS;
|
|
|
|
bool mTriggerShaderReload;
|
|
bool mReload;
|
|
bool mEnabled;
|
|
bool mUsePostProcessing;
|
|
bool mSoftParticles;
|
|
bool mDisableDepthPasses;
|
|
|
|
size_t mLastFrameNumber;
|
|
float mLastSimulationTime;
|
|
|
|
bool mExteriorFlag;
|
|
bool mUnderwater;
|
|
bool mHDR;
|
|
bool mNormals;
|
|
bool mPrevNormals;
|
|
bool mNormalsSupported;
|
|
bool mPassLights;
|
|
bool mPrevPassLights;
|
|
bool mUBO;
|
|
int mGLSLVersion;
|
|
|
|
osg::ref_ptr<fx::StateUpdater> mStateUpdater;
|
|
osg::ref_ptr<PingPongCull> mPingPongCull;
|
|
osg::ref_ptr<PingPongCanvas> mPingPongCanvas;
|
|
osg::ref_ptr<TransparentDepthBinCallback> mTransparentDepthPostPass;
|
|
|
|
int mWidth;
|
|
int mHeight;
|
|
|
|
fx::DispatchArray mTemplateData;
|
|
};
|
|
}
|
|
|
|
#endif
|