1
0
mirror of https://gitlab.com/OpenMW/openmw.git synced 2025-01-30 21:32:42 +00:00
OpenMW/apps/openmw/mwrender/postprocessor.hpp

268 lines
6.8 KiB
C++
Raw Normal View History

2021-06-01 12:15:25 -07:00
#ifndef OPENMW_MWRENDER_POSTPROCESSOR_H
#define OPENMW_MWRENDER_POSTPROCESSOR_H
2022-05-13 18:58:00 -07:00
#include <array>
#include <vector>
#include <string>
#include <unordered_map>
#include <filesystem>
2021-08-04 17:49:57 -07:00
#include <osg/Texture2D>
#include <osg/Group>
#include <osg/FrameBufferObject>
#include <osg/Camera>
2022-05-13 18:58:00 -07:00
#include <osgViewer/Viewer>
#include <components/fx/stateupdater.hpp>
#include <components/fx/technique.hpp>
#include <components/debug/debuglog.hpp>
#include "pingpongcanvas.hpp"
#include "transparentpass.hpp"
2021-06-01 12:15:25 -07:00
#include <memory>
2021-06-01 12:15:25 -07:00
namespace osgViewer
{
class Viewer;
}
namespace Stereo
{
class MultiviewFramebuffer;
}
2022-05-13 18:58:00 -07:00
namespace VFS
{
class Manager;
}
namespace Shader
{
class ShaderManager;
}
2021-06-01 12:15:25 -07:00
namespace MWRender
{
2022-05-13 18:58:00 -07:00
class RenderingManager;
class PingPongCull;
class PingPongCanvas;
class TransparentDepthBinCallback;
class PostProcessor : public osg::Group
2021-06-01 12:15:25 -07:00
{
public:
2022-05-13 18:58:00 -07:00
using FBOArray = std::array<osg::ref_ptr<osg::FrameBufferObject>, 5>;
2022-06-21 15:55:06 +00:00
using TextureArray = std::array<osg::ref_ptr<osg::Texture>, 5>;
2022-05-13 18:58:00 -07:00
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
};
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]; }
2022-06-21 15:55:06 +00:00
osg::ref_ptr<osg::Texture> getTexture(TextureIndex index, unsigned int frameId) { return mTextures[frameId][index]; }
2022-05-13 18:58:00 -07:00
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();
enum Status
{
Status_Error,
Status_Toggled,
Status_Unchanged
};
2022-05-13 18:58:00 -07:00
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);
2022-05-13 18:58:00 -07:00
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);
2021-06-01 12:15:25 -07:00
2022-05-13 18:58:00 -07:00
if (it == technique->getUniformMap().end())
return;
2021-06-01 12:15:25 -07:00
2022-05-13 18:58:00 -07:00
if ((*it)->mStatic)
{
Log(Debug::Warning) << "Attempting to set a configration variable [" << name << "] as a uniform";
return;
}
2022-05-13 18:58:00 -07:00
(*it)->setValue(value);
}
2022-05-22 18:53:38 -07:00
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();
}
2022-05-13 18:58:00 -07:00
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);
2022-05-13 18:58:00 -07:00
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; }
2021-06-01 12:15:25 -07:00
void disableDynamicShaders();
2022-06-21 15:55:06 +00:00
int renderWidth() const;
int renderHeight() const;
void triggerShaderReload();
bool mEnableLiveReload;
2021-06-01 12:15:25 -07:00
private:
2022-05-21 06:42:05 +00:00
void populateTechniqueFiles();
2022-05-13 18:58:00 -07:00
size_t frame() const { return mViewer->getFrameStamp()->getFrameNumber(); }
void createObjectsForFrame(size_t frameId);
void createTexturesAndCamera(size_t frameId);
void reloadTechniques();
void reloadMainPass(fx::Technique& technique);
void dirtyTechniques();
void update(size_t frameId);
2022-05-21 06:42:05 +00:00
void reloadIfRequired();
void updateLiveReload();
2022-05-13 18:58:00 -07:00
void cull(size_t frameId, osgUtil::CullVisitor* cv);
2021-08-04 17:49:57 -07:00
2021-06-01 12:15:25 -07:00
osg::ref_ptr<osg::Group> mRootNode;
osg::ref_ptr<osg::Camera> mHUDCamera;
2022-05-13 18:58:00 -07:00
std::array<TextureArray, 2> mTextures;
std::array<FBOArray, 2> mFbos;
TechniqueList mTechniques;
TechniqueList mTemplates;
2022-05-22 18:53:38 -07:00
TechniqueList mQueuedTemplates;
2022-05-13 18:58:00 -07:00
std::unordered_map<std::string, std::filesystem::path> mTechniqueFileMap;
int mSamples;
bool mDirty;
size_t mDirtyFrameId;
2021-06-01 12:15:25 -07:00
2022-05-13 18:58:00 -07:00
RenderingManager& mRendering;
osgViewer::Viewer* mViewer;
const VFS::Manager* mVFS;
bool mTriggerShaderReload;
2022-05-13 18:58:00 -07:00
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;
2022-05-14 22:53:53 -07:00
bool mPassLights;
bool mPrevPassLights;
2022-05-13 18:58:00 -07:00
bool mUBO;
int mGLSLVersion;
2022-06-21 15:55:06 +00:00
osg::ref_ptr<osg::Texture> mMainTemplate;
2022-05-13 18:58:00 -07:00
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;
2021-06-01 12:15:25 -07:00
};
}
#endif