mirror of
https://github.com/ZDoom/Raze.git
synced 2025-05-30 00:41:24 +00:00
- updated common code.
Most of what got added is still unused. # Conflicts: # source/build/src/palette.cpp # Conflicts: # source/build/src/palette.cpp # Conflicts: # source/common/engine/i_interface.h
This commit is contained in:
parent
82eb807090
commit
ea08fa0a4e
20 changed files with 1494 additions and 62 deletions
83
source/common/rendering/hwrenderer/data/buffers.h
Normal file
83
source/common/rendering/hwrenderer/data/buffers.h
Normal file
|
@ -0,0 +1,83 @@
|
|||
#pragma once
|
||||
|
||||
#include <stddef.h>
|
||||
#include <assert.h>
|
||||
|
||||
class FRenderState;
|
||||
|
||||
// The low level code needs to know which attributes exist.
|
||||
// OpenGL needs to change the state of all of them per buffer binding.
|
||||
// VAOs are mostly useless for this because they lump buffer and binding state together which the model code does not want.
|
||||
enum
|
||||
{
|
||||
VATTR_VERTEX,
|
||||
VATTR_TEXCOORD,
|
||||
VATTR_COLOR,
|
||||
VATTR_VERTEX2,
|
||||
VATTR_NORMAL,
|
||||
VATTR_NORMAL2,
|
||||
|
||||
VATTR_MAX
|
||||
};
|
||||
|
||||
enum EVertexAttributeFormat
|
||||
{
|
||||
VFmt_Float4,
|
||||
VFmt_Float3,
|
||||
VFmt_Float2,
|
||||
VFmt_Float,
|
||||
VFmt_Byte4,
|
||||
VFmt_Packed_A2R10G10B10,
|
||||
};
|
||||
|
||||
struct FVertexBufferAttribute
|
||||
{
|
||||
int binding;
|
||||
int location;
|
||||
int format;
|
||||
int offset;
|
||||
};
|
||||
|
||||
class IBuffer
|
||||
{
|
||||
protected:
|
||||
size_t buffersize = 0;
|
||||
void *map = nullptr;
|
||||
public:
|
||||
IBuffer() = default;
|
||||
IBuffer(const IBuffer &) = delete;
|
||||
IBuffer &operator=(const IBuffer &) = delete;
|
||||
virtual ~IBuffer() = default;
|
||||
|
||||
virtual void SetData(size_t size, const void *data, bool staticdata = true) = 0;
|
||||
virtual void SetSubData(size_t offset, size_t size, const void *data) = 0;
|
||||
virtual void *Lock(unsigned int size) = 0;
|
||||
virtual void Unlock() = 0;
|
||||
virtual void Resize(size_t newsize) = 0;
|
||||
virtual void Map() {} // Only needed by old OpenGL but this needs to be in the interface.
|
||||
virtual void Unmap() {}
|
||||
void *Memory() { assert(map); return map; }
|
||||
size_t Size() { return buffersize; }
|
||||
};
|
||||
|
||||
class IVertexBuffer : virtual public IBuffer
|
||||
{
|
||||
public:
|
||||
virtual void SetFormat(int numBindingPoints, int numAttributes, size_t stride, const FVertexBufferAttribute *attrs) = 0;
|
||||
};
|
||||
|
||||
// This merely exists to have a dedicated type for index buffers to inherit from.
|
||||
class IIndexBuffer : virtual public IBuffer
|
||||
{
|
||||
// Element size is fixed to 4, thanks to OpenGL requiring this info to be coded into the glDrawElements call.
|
||||
// This mostly prohibits a more flexible buffer setup but GZDoom doesn't use any other format anyway.
|
||||
// Ob Vulkam, element size is a buffer property and of no concern to the drawing functions (as it should be.)
|
||||
};
|
||||
|
||||
class IDataBuffer : virtual public IBuffer
|
||||
{
|
||||
// Can be either uniform or shader storage buffer, depending on its needs.
|
||||
public:
|
||||
virtual void BindRange(FRenderState *state, size_t start, size_t length) = 0;
|
||||
|
||||
};
|
665
source/common/rendering/hwrenderer/data/hw_renderstate.h
Normal file
665
source/common/rendering/hwrenderer/data/hw_renderstate.h
Normal file
|
@ -0,0 +1,665 @@
|
|||
#pragma once
|
||||
|
||||
#include "v_palette.h"
|
||||
#include "vectors.h"
|
||||
#include "matrix.h"
|
||||
#include "hw_material.h"
|
||||
#include "texmanip.h"
|
||||
|
||||
struct FColormap;
|
||||
class IVertexBuffer;
|
||||
class IIndexBuffer;
|
||||
|
||||
enum EClearTarget
|
||||
{
|
||||
CT_Depth = 1,
|
||||
CT_Stencil = 2,
|
||||
CT_Color = 4
|
||||
};
|
||||
|
||||
enum ERenderEffect
|
||||
{
|
||||
EFF_NONE = -1,
|
||||
EFF_FOGBOUNDARY,
|
||||
EFF_SPHEREMAP,
|
||||
EFF_BURN,
|
||||
EFF_STENCIL,
|
||||
|
||||
MAX_EFFECTS
|
||||
};
|
||||
|
||||
enum EAlphaFunc
|
||||
{
|
||||
Alpha_GEqual = 0,
|
||||
Alpha_Greater = 1
|
||||
};
|
||||
|
||||
enum EDrawType
|
||||
{
|
||||
DT_Points = 0,
|
||||
DT_Lines = 1,
|
||||
DT_Triangles = 2,
|
||||
DT_TriangleFan = 3,
|
||||
DT_TriangleStrip = 4
|
||||
};
|
||||
|
||||
enum EDepthFunc
|
||||
{
|
||||
DF_Less,
|
||||
DF_LEqual,
|
||||
DF_Always
|
||||
};
|
||||
|
||||
enum EStencilFlags
|
||||
{
|
||||
SF_AllOn = 0,
|
||||
SF_ColorMaskOff = 1,
|
||||
SF_DepthMaskOff = 2,
|
||||
};
|
||||
|
||||
enum EStencilOp
|
||||
{
|
||||
SOP_Keep = 0,
|
||||
SOP_Increment = 1,
|
||||
SOP_Decrement = 2
|
||||
};
|
||||
|
||||
enum ECull
|
||||
{
|
||||
Cull_None,
|
||||
Cull_CCW,
|
||||
Cull_CW
|
||||
};
|
||||
|
||||
|
||||
|
||||
struct FStateVec4
|
||||
{
|
||||
float vec[4];
|
||||
|
||||
void Set(float r, float g, float b, float a)
|
||||
{
|
||||
vec[0] = r;
|
||||
vec[1] = g;
|
||||
vec[2] = b;
|
||||
vec[3] = a;
|
||||
}
|
||||
};
|
||||
|
||||
struct FMaterialState
|
||||
{
|
||||
FMaterial *mMaterial;
|
||||
int mClampMode;
|
||||
int mTranslation;
|
||||
int mOverrideShader;
|
||||
bool mChanged;
|
||||
|
||||
void Reset()
|
||||
{
|
||||
mMaterial = nullptr;
|
||||
mTranslation = 0;
|
||||
mClampMode = CLAMP_NONE;
|
||||
mOverrideShader = -1;
|
||||
mChanged = false;
|
||||
}
|
||||
};
|
||||
|
||||
struct FDepthBiasState
|
||||
{
|
||||
float mFactor;
|
||||
float mUnits;
|
||||
bool mChanged;
|
||||
|
||||
void Reset()
|
||||
{
|
||||
mFactor = 0;
|
||||
mUnits = 0;
|
||||
mChanged = false;
|
||||
}
|
||||
};
|
||||
|
||||
enum EPassType
|
||||
{
|
||||
NORMAL_PASS,
|
||||
GBUFFER_PASS,
|
||||
MAX_PASS_TYPES
|
||||
};
|
||||
|
||||
struct FVector4PalEntry
|
||||
{
|
||||
float r, g, b, a;
|
||||
|
||||
bool operator==(const FVector4PalEntry &other) const
|
||||
{
|
||||
return r == other.r && g == other.g && b == other.b && a == other.a;
|
||||
}
|
||||
|
||||
bool operator!=(const FVector4PalEntry &other) const
|
||||
{
|
||||
return r != other.r || g != other.g || b != other.b || a != other.a;
|
||||
}
|
||||
|
||||
FVector4PalEntry &operator=(PalEntry newvalue)
|
||||
{
|
||||
const float normScale = 1.0f / 255.0f;
|
||||
r = newvalue.r * normScale;
|
||||
g = newvalue.g * normScale;
|
||||
b = newvalue.b * normScale;
|
||||
a = newvalue.a * normScale;
|
||||
return *this;
|
||||
}
|
||||
|
||||
FVector4PalEntry& SetIA(PalEntry newvalue)
|
||||
{
|
||||
const float normScale = 1.0f / 255.0f;
|
||||
r = newvalue.r * normScale;
|
||||
g = newvalue.g * normScale;
|
||||
b = newvalue.b * normScale;
|
||||
a = 1;
|
||||
return *this;
|
||||
}
|
||||
|
||||
FVector4PalEntry& SetFlt(float v1, float v2, float v3, float v4)
|
||||
{
|
||||
r = v1;
|
||||
g = v2;
|
||||
b = v3;
|
||||
a = v4;
|
||||
return *this;
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
struct StreamData
|
||||
{
|
||||
FVector4PalEntry uObjectColor;
|
||||
FVector4PalEntry uObjectColor2;
|
||||
FVector4 uDynLightColor;
|
||||
FVector4PalEntry uAddColor;
|
||||
FVector4PalEntry uTextureAddColor;
|
||||
FVector4PalEntry uTextureModulateColor;
|
||||
FVector4PalEntry uTextureBlendColor;
|
||||
FVector4PalEntry uFogColor;
|
||||
float uDesaturationFactor;
|
||||
float uInterpolationFactor;
|
||||
float timer;
|
||||
int useVertexData;
|
||||
FVector4 uVertexColor;
|
||||
FVector4 uVertexNormal;
|
||||
|
||||
FVector4 uGlowTopPlane;
|
||||
FVector4 uGlowTopColor;
|
||||
FVector4 uGlowBottomPlane;
|
||||
FVector4 uGlowBottomColor;
|
||||
|
||||
FVector4 uGradientTopPlane;
|
||||
FVector4 uGradientBottomPlane;
|
||||
|
||||
FVector4 uSplitTopPlane;
|
||||
FVector4 uSplitBottomPlane;
|
||||
|
||||
FVector4 uDetailParms;
|
||||
};
|
||||
|
||||
class FRenderState
|
||||
{
|
||||
protected:
|
||||
uint8_t mFogEnabled;
|
||||
uint8_t mTextureEnabled:1;
|
||||
uint8_t mGlowEnabled : 1;
|
||||
uint8_t mGradientEnabled : 1;
|
||||
uint8_t mModelMatrixEnabled : 1;
|
||||
uint8_t mTextureMatrixEnabled : 1;
|
||||
uint8_t mSplitEnabled : 1;
|
||||
uint8_t mBrightmapEnabled : 1;
|
||||
|
||||
int mLightIndex;
|
||||
int mSpecialEffect;
|
||||
int mTextureMode;
|
||||
int mTextureModeFlags;
|
||||
int mSoftLight;
|
||||
float mLightParms[4];
|
||||
|
||||
float mAlphaThreshold;
|
||||
float mClipSplit[2];
|
||||
|
||||
StreamData mStreamData = {};
|
||||
PalEntry mFogColor;
|
||||
|
||||
FRenderStyle mRenderStyle;
|
||||
|
||||
FMaterialState mMaterial;
|
||||
FDepthBiasState mBias;
|
||||
|
||||
IVertexBuffer *mVertexBuffer;
|
||||
int mVertexOffsets[2]; // one per binding point
|
||||
IIndexBuffer *mIndexBuffer;
|
||||
|
||||
EPassType mPassType = NORMAL_PASS;
|
||||
|
||||
public:
|
||||
|
||||
uint64_t firstFrame = 0;
|
||||
VSMatrix mModelMatrix;
|
||||
VSMatrix mTextureMatrix;
|
||||
|
||||
public:
|
||||
|
||||
void Reset()
|
||||
{
|
||||
mTextureEnabled = true;
|
||||
mBrightmapEnabled = mGradientEnabled = mFogEnabled = mGlowEnabled = false;
|
||||
mFogColor = 0xffffffff;
|
||||
mStreamData.uFogColor = mFogColor;
|
||||
mTextureMode = -1;
|
||||
mTextureModeFlags = 0;
|
||||
mStreamData.uDesaturationFactor = 0.0f;
|
||||
mAlphaThreshold = 0.5f;
|
||||
mModelMatrixEnabled = false;
|
||||
mTextureMatrixEnabled = false;
|
||||
mSplitEnabled = false;
|
||||
mStreamData.uAddColor = 0;
|
||||
mStreamData.uObjectColor = 0xffffffff;
|
||||
mStreamData.uObjectColor2 = 0;
|
||||
mStreamData.uTextureBlendColor = 0;
|
||||
mStreamData.uTextureAddColor = 0;
|
||||
mStreamData.uTextureModulateColor = 0;
|
||||
mSoftLight = 0;
|
||||
mLightParms[0] = mLightParms[1] = mLightParms[2] = 0.0f;
|
||||
mLightParms[3] = -1.f;
|
||||
mSpecialEffect = EFF_NONE;
|
||||
mLightIndex = -1;
|
||||
mStreamData.uInterpolationFactor = 0;
|
||||
mRenderStyle = DefaultRenderStyle();
|
||||
mMaterial.Reset();
|
||||
mBias.Reset();
|
||||
mPassType = NORMAL_PASS;
|
||||
|
||||
mVertexBuffer = nullptr;
|
||||
mVertexOffsets[0] = mVertexOffsets[1] = 0;
|
||||
mIndexBuffer = nullptr;
|
||||
|
||||
mStreamData.uVertexColor = { 1.0f, 1.0f, 1.0f, 1.0f };
|
||||
mStreamData.uGlowTopColor = { 0.0f, 0.0f, 0.0f, 0.0f };
|
||||
mStreamData.uGlowBottomColor = { 0.0f, 0.0f, 0.0f, 0.0f };
|
||||
mStreamData.uGlowTopPlane = { 0.0f, 0.0f, 0.0f, 0.0f };
|
||||
mStreamData.uGlowBottomPlane = { 0.0f, 0.0f, 0.0f, 0.0f };
|
||||
mStreamData.uGradientTopPlane = { 0.0f, 0.0f, 0.0f, 0.0f };
|
||||
mStreamData.uGradientBottomPlane = { 0.0f, 0.0f, 0.0f, 0.0f };
|
||||
mStreamData.uSplitTopPlane = { 0.0f, 0.0f, 0.0f, 0.0f };
|
||||
mStreamData.uSplitBottomPlane = { 0.0f, 0.0f, 0.0f, 0.0f };
|
||||
mStreamData.uDynLightColor = { 0.0f, 0.0f, 0.0f, 0.0f };
|
||||
mStreamData.uDetailParms = { 0.0f, 0.0f, 0.0f, 0.0f };
|
||||
|
||||
mModelMatrix.loadIdentity();
|
||||
mTextureMatrix.loadIdentity();
|
||||
ClearClipSplit();
|
||||
}
|
||||
|
||||
void SetNormal(FVector3 norm)
|
||||
{
|
||||
mStreamData.uVertexNormal = { norm.X, norm.Y, norm.Z, 0.f };
|
||||
}
|
||||
|
||||
void SetNormal(float x, float y, float z)
|
||||
{
|
||||
mStreamData.uVertexNormal = { x, y, z, 0.f };
|
||||
}
|
||||
|
||||
void SetColor(float r, float g, float b, float a = 1.f, int desat = 0)
|
||||
{
|
||||
mStreamData.uVertexColor = { r, g, b, a };
|
||||
mStreamData.uDesaturationFactor = desat * (1.0f / 255.0f);
|
||||
}
|
||||
|
||||
void SetColor(PalEntry pe, int desat = 0)
|
||||
{
|
||||
const float scale = 1.0f / 255.0f;
|
||||
mStreamData.uVertexColor = { pe.r * scale, pe.g * scale, pe.b * scale, pe.a * scale };
|
||||
mStreamData.uDesaturationFactor = desat * (1.0f / 255.0f);
|
||||
}
|
||||
|
||||
void SetColorAlpha(PalEntry pe, float alpha = 1.f, int desat = 0)
|
||||
{
|
||||
const float scale = 1.0f / 255.0f;
|
||||
mStreamData.uVertexColor = { pe.r * scale, pe.g * scale, pe.b * scale, alpha };
|
||||
mStreamData.uDesaturationFactor = desat * (1.0f / 255.0f);
|
||||
}
|
||||
|
||||
void ResetColor()
|
||||
{
|
||||
mStreamData.uVertexColor = { 1.0f, 1.0f, 1.0f, 1.0f };
|
||||
mStreamData.uDesaturationFactor = 0.0f;
|
||||
}
|
||||
|
||||
void SetTextureMode(int mode)
|
||||
{
|
||||
mTextureMode = mode;
|
||||
}
|
||||
|
||||
void SetTextureMode(FRenderStyle style)
|
||||
{
|
||||
if (style.Flags & STYLEF_RedIsAlpha)
|
||||
{
|
||||
SetTextureMode(TM_ALPHATEXTURE);
|
||||
}
|
||||
else if (style.Flags & STYLEF_ColorIsFixed)
|
||||
{
|
||||
SetTextureMode(TM_STENCIL);
|
||||
}
|
||||
else if (style.Flags & STYLEF_InvertSource)
|
||||
{
|
||||
SetTextureMode(TM_INVERSE);
|
||||
}
|
||||
}
|
||||
|
||||
int GetTextureMode()
|
||||
{
|
||||
return mTextureMode;
|
||||
}
|
||||
|
||||
void EnableTexture(bool on)
|
||||
{
|
||||
mTextureEnabled = on;
|
||||
}
|
||||
|
||||
void EnableFog(uint8_t on)
|
||||
{
|
||||
mFogEnabled = on;
|
||||
}
|
||||
|
||||
void SetEffect(int eff)
|
||||
{
|
||||
mSpecialEffect = eff;
|
||||
}
|
||||
|
||||
void EnableGlow(bool on)
|
||||
{
|
||||
if (mGlowEnabled && !on)
|
||||
{
|
||||
mStreamData.uGlowTopColor = { 0.0f, 0.0f, 0.0f, 0.0f };
|
||||
mStreamData.uGlowBottomColor = { 0.0f, 0.0f, 0.0f, 0.0f };
|
||||
}
|
||||
mGlowEnabled = on;
|
||||
}
|
||||
|
||||
void EnableGradient(bool on)
|
||||
{
|
||||
mGradientEnabled = on;
|
||||
}
|
||||
|
||||
void EnableBrightmap(bool on)
|
||||
{
|
||||
mBrightmapEnabled = on;
|
||||
}
|
||||
|
||||
void EnableSplit(bool on)
|
||||
{
|
||||
if (mSplitEnabled && !on)
|
||||
{
|
||||
mStreamData.uSplitTopPlane = { 0.0f, 0.0f, 0.0f, 0.0f };
|
||||
mStreamData.uSplitBottomPlane = { 0.0f, 0.0f, 0.0f, 0.0f };
|
||||
}
|
||||
mSplitEnabled = on;
|
||||
}
|
||||
|
||||
void EnableModelMatrix(bool on)
|
||||
{
|
||||
mModelMatrixEnabled = on;
|
||||
}
|
||||
|
||||
void EnableTextureMatrix(bool on)
|
||||
{
|
||||
mTextureMatrixEnabled = on;
|
||||
}
|
||||
|
||||
void SetGlowParams(float *t, float *b)
|
||||
{
|
||||
mStreamData.uGlowTopColor = { t[0], t[1], t[2], t[3] };
|
||||
mStreamData.uGlowBottomColor = { b[0], b[1], b[2], b[3] };
|
||||
}
|
||||
|
||||
void SetSoftLightLevel(int llevel, int blendfactor = 0)
|
||||
{
|
||||
if (blendfactor == 0) mLightParms[3] = llevel / 255.f;
|
||||
else mLightParms[3] = -1.f;
|
||||
}
|
||||
|
||||
void SetNoSoftLightLevel()
|
||||
{
|
||||
mLightParms[3] = -1.f;
|
||||
}
|
||||
|
||||
void SetGlowPlanes(const FVector4 &tp, const FVector4& bp)
|
||||
{
|
||||
mStreamData.uGlowTopPlane = tp;
|
||||
mStreamData.uGlowBottomPlane = bp;
|
||||
}
|
||||
|
||||
void SetGradientPlanes(const FVector4& tp, const FVector4& bp)
|
||||
{
|
||||
mStreamData.uGradientTopPlane = tp;
|
||||
mStreamData.uGradientBottomPlane = bp;
|
||||
}
|
||||
|
||||
void SetSplitPlanes(const FVector4& tp, const FVector4& bp)
|
||||
{
|
||||
mStreamData.uSplitTopPlane = tp;
|
||||
mStreamData.uSplitBottomPlane = bp;
|
||||
}
|
||||
|
||||
void SetDetailParms(float xscale, float yscale, float bias)
|
||||
{
|
||||
mStreamData.uDetailParms = { xscale, yscale, bias, 0 };
|
||||
}
|
||||
|
||||
void SetDynLight(float r, float g, float b)
|
||||
{
|
||||
mStreamData.uDynLightColor = { r, g, b, 0.0f };
|
||||
}
|
||||
|
||||
void SetObjectColor(PalEntry pe)
|
||||
{
|
||||
mStreamData.uObjectColor = pe;
|
||||
}
|
||||
|
||||
void SetObjectColor2(PalEntry pe)
|
||||
{
|
||||
mStreamData.uObjectColor2 = pe;
|
||||
}
|
||||
|
||||
void SetAddColor(PalEntry pe)
|
||||
{
|
||||
mStreamData.uAddColor = pe;
|
||||
}
|
||||
|
||||
void ApplyTextureManipulation(TextureManipulation* texfx)
|
||||
{
|
||||
if (!texfx || texfx->AddColor.a == 0)
|
||||
{
|
||||
mStreamData.uTextureAddColor.a = 0; // we only need to set the flags to 0
|
||||
}
|
||||
else
|
||||
{
|
||||
// set up the whole thing
|
||||
mStreamData.uTextureAddColor.SetIA(texfx->AddColor);
|
||||
auto pe = texfx->ModulateColor;
|
||||
mStreamData.uTextureModulateColor.SetFlt(pe.r * pe.a / 255.f, pe.g * pe.a / 255.f, pe.b * pe.a / 255.f, texfx->DesaturationFactor);
|
||||
mStreamData.uTextureBlendColor = texfx->BlendColor;
|
||||
}
|
||||
}
|
||||
|
||||
void SetFog(PalEntry c, float d)
|
||||
{
|
||||
const float LOG2E = 1.442692f; // = 1/log(2)
|
||||
mFogColor = c;
|
||||
mStreamData.uFogColor = mFogColor;
|
||||
if (d >= 0.0f) mLightParms[2] = d * (-LOG2E / 64000.f);
|
||||
}
|
||||
|
||||
void SetLightParms(float f, float d)
|
||||
{
|
||||
mLightParms[1] = f;
|
||||
mLightParms[0] = d;
|
||||
}
|
||||
|
||||
PalEntry GetFogColor() const
|
||||
{
|
||||
return mFogColor;
|
||||
}
|
||||
|
||||
void AlphaFunc(int func, float thresh)
|
||||
{
|
||||
if (func == Alpha_Greater) mAlphaThreshold = thresh;
|
||||
else mAlphaThreshold = thresh - 0.001f;
|
||||
}
|
||||
|
||||
void SetLightIndex(int index)
|
||||
{
|
||||
mLightIndex = index;
|
||||
}
|
||||
|
||||
void SetRenderStyle(FRenderStyle rs)
|
||||
{
|
||||
mRenderStyle = rs;
|
||||
}
|
||||
|
||||
void SetRenderStyle(ERenderStyle rs)
|
||||
{
|
||||
mRenderStyle = rs;
|
||||
}
|
||||
|
||||
void SetDepthBias(float a, float b)
|
||||
{
|
||||
mBias.mFactor = a;
|
||||
mBias.mUnits = b;
|
||||
mBias.mChanged = true;
|
||||
}
|
||||
|
||||
void ClearDepthBias()
|
||||
{
|
||||
mBias.mFactor = 0;
|
||||
mBias.mUnits = 0;
|
||||
mBias.mChanged = true;
|
||||
}
|
||||
|
||||
void SetMaterial(FMaterial *mat, int clampmode, int translation, int overrideshader)
|
||||
{
|
||||
mMaterial.mMaterial = mat;
|
||||
mMaterial.mClampMode = clampmode;
|
||||
mMaterial.mTranslation = translation;
|
||||
mMaterial.mOverrideShader = overrideshader;
|
||||
mMaterial.mChanged = true;
|
||||
mTextureModeFlags = mat->GetLayerFlags();
|
||||
}
|
||||
|
||||
void SetMaterial(FGameTexture* tex, EUpscaleFlags upscalemask, int scaleflags, int clampmode, int translation, int overrideshader)
|
||||
{
|
||||
if (shouldUpscale(tex, upscalemask)) scaleflags |= CTF_Upscale;
|
||||
SetMaterial(FMaterial::ValidateTexture(tex, scaleflags), clampmode, translation, overrideshader);
|
||||
}
|
||||
|
||||
void SetClipSplit(float bottom, float top)
|
||||
{
|
||||
mClipSplit[0] = bottom;
|
||||
mClipSplit[1] = top;
|
||||
}
|
||||
|
||||
void SetClipSplit(float *vals)
|
||||
{
|
||||
memcpy(mClipSplit, vals, 2 * sizeof(float));
|
||||
}
|
||||
|
||||
void GetClipSplit(float *out)
|
||||
{
|
||||
memcpy(out, mClipSplit, 2 * sizeof(float));
|
||||
}
|
||||
|
||||
void ClearClipSplit()
|
||||
{
|
||||
mClipSplit[0] = -1000000.f;
|
||||
mClipSplit[1] = 1000000.f;
|
||||
}
|
||||
|
||||
void SetVertexBuffer(IVertexBuffer *vb, int offset0, int offset1)
|
||||
{
|
||||
assert(vb);
|
||||
mVertexBuffer = vb;
|
||||
mVertexOffsets[0] = offset0;
|
||||
mVertexOffsets[1] = offset1;
|
||||
}
|
||||
|
||||
void SetIndexBuffer(IIndexBuffer *ib)
|
||||
{
|
||||
mIndexBuffer = ib;
|
||||
}
|
||||
|
||||
template <class T> void SetVertexBuffer(T *buffer)
|
||||
{
|
||||
auto ptrs = buffer->GetBufferObjects();
|
||||
SetVertexBuffer(ptrs.first, 0, 0);
|
||||
SetIndexBuffer(ptrs.second);
|
||||
}
|
||||
|
||||
void SetInterpolationFactor(float fac)
|
||||
{
|
||||
mStreamData.uInterpolationFactor = fac;
|
||||
}
|
||||
|
||||
float GetInterpolationFactor()
|
||||
{
|
||||
return mStreamData.uInterpolationFactor;
|
||||
}
|
||||
|
||||
void EnableDrawBufferAttachments(bool on) // Used by fog boundary drawer
|
||||
{
|
||||
EnableDrawBuffers(on ? GetPassDrawBufferCount() : 1);
|
||||
}
|
||||
|
||||
int GetPassDrawBufferCount()
|
||||
{
|
||||
return mPassType == GBUFFER_PASS ? 3 : 1;
|
||||
}
|
||||
|
||||
void SetPassType(EPassType passType)
|
||||
{
|
||||
mPassType = passType;
|
||||
}
|
||||
|
||||
EPassType GetPassType()
|
||||
{
|
||||
return mPassType;
|
||||
}
|
||||
|
||||
// API-dependent render interface
|
||||
|
||||
// Draw commands
|
||||
virtual void ClearScreen() = 0;
|
||||
virtual void Draw(int dt, int index, int count, bool apply = true) = 0;
|
||||
virtual void DrawIndexed(int dt, int index, int count, bool apply = true) = 0;
|
||||
|
||||
// Immediate render state change commands. These only change infrequently and should not clutter the render state.
|
||||
virtual bool SetDepthClamp(bool on) = 0; // Deactivated only by skyboxes.
|
||||
virtual void SetDepthMask(bool on) = 0; // Used by decals and indirectly by portal setup.
|
||||
virtual void SetDepthFunc(int func) = 0; // Used by models, portals and mirror surfaces.
|
||||
virtual void SetDepthRange(float min, float max) = 0; // Used by portal setup.
|
||||
virtual void SetColorMask(bool r, bool g, bool b, bool a) = 0; // Used by portals.
|
||||
virtual void SetStencil(int offs, int op, int flags=-1) = 0; // Used by portal setup and render hacks.
|
||||
virtual void SetCulling(int mode) = 0; // Used by model drawer only.
|
||||
virtual void EnableClipDistance(int num, bool state) = 0; // Use by sprite sorter for vertical splits.
|
||||
virtual void Clear(int targets) = 0; // not used during normal rendering
|
||||
virtual void EnableStencil(bool on) = 0; // always on for 3D, always off for 2D
|
||||
virtual void SetScissor(int x, int y, int w, int h) = 0; // constant for 3D, changes for 2D
|
||||
virtual void SetViewport(int x, int y, int w, int h) = 0; // constant for all 3D and all 2D
|
||||
virtual void EnableDepthTest(bool on) = 0; // used by 2D, portals and render hacks.
|
||||
virtual void EnableMultisampling(bool on) = 0; // only active for 2D
|
||||
virtual void EnableLineSmooth(bool on) = 0; // constant setting for each 2D drawer operation
|
||||
virtual void EnableDrawBuffers(int count, bool apply = false) = 0; // Used by SSAO and EnableDrawBufferAttachments
|
||||
|
||||
void SetColorMask(bool on)
|
||||
{
|
||||
SetColorMask(on, on, on, on);
|
||||
}
|
||||
|
||||
};
|
||||
|
33
source/common/rendering/hwrenderer/data/renderqueue.h
Normal file
33
source/common/rendering/hwrenderer/data/renderqueue.h
Normal file
|
@ -0,0 +1,33 @@
|
|||
#pragma once
|
||||
|
||||
#include <stdint.h>
|
||||
#include "tflags.h"
|
||||
|
||||
// A render queue is what contains all render commands.
|
||||
// On Vulkan there can be several of them so this interface is needed to allow for the needed parallelism.
|
||||
// On OpenGL the render state is global so all this will do is to translate the system independent calls into OpenGL API calls.
|
||||
|
||||
enum class ColormaskBits
|
||||
{
|
||||
RED = 1,
|
||||
GREEN = 2,
|
||||
BLUE = 4,
|
||||
ALPHA = 8
|
||||
};
|
||||
|
||||
typedef TFlags<ColormaskBits, uint8_t> Colormask;
|
||||
|
||||
class IRenderQueue
|
||||
{
|
||||
Colormask mColorMask;
|
||||
|
||||
|
||||
Colormask GetColorMask() const
|
||||
{
|
||||
return mColorMask;
|
||||
}
|
||||
|
||||
virtual void SetColorMask(Colormask mask) = 0;
|
||||
|
||||
|
||||
};
|
154
source/common/rendering/hwrenderer/data/shaderuniforms.h
Normal file
154
source/common/rendering/hwrenderer/data/shaderuniforms.h
Normal file
|
@ -0,0 +1,154 @@
|
|||
#pragma once
|
||||
|
||||
#include <vector>
|
||||
#include "hwrenderer/data/buffers.h"
|
||||
#include "v_video.h"
|
||||
|
||||
enum
|
||||
{
|
||||
LIGHTBUF_BINDINGPOINT = 1,
|
||||
POSTPROCESS_BINDINGPOINT = 2,
|
||||
VIEWPOINT_BINDINGPOINT = 3,
|
||||
LIGHTNODES_BINDINGPOINT = 4,
|
||||
LIGHTLINES_BINDINGPOINT = 5,
|
||||
LIGHTLIST_BINDINGPOINT = 6
|
||||
};
|
||||
|
||||
enum class UniformType
|
||||
{
|
||||
Int,
|
||||
UInt,
|
||||
Float,
|
||||
Vec2,
|
||||
Vec3,
|
||||
Vec4,
|
||||
IVec2,
|
||||
IVec3,
|
||||
IVec4,
|
||||
UVec2,
|
||||
UVec3,
|
||||
UVec4,
|
||||
Mat4
|
||||
};
|
||||
|
||||
class UniformFieldDesc
|
||||
{
|
||||
public:
|
||||
UniformFieldDesc() { }
|
||||
UniformFieldDesc(const char *name, UniformType type, std::size_t offset) : Name(name), Type(type), Offset(offset) { }
|
||||
|
||||
const char *Name;
|
||||
UniformType Type;
|
||||
std::size_t Offset;
|
||||
};
|
||||
|
||||
class UniformBlockDecl
|
||||
{
|
||||
public:
|
||||
static FString Create(const char *name, const std::vector<UniformFieldDesc> &fields, int bindingpoint)
|
||||
{
|
||||
FString decl;
|
||||
FString layout;
|
||||
if (bindingpoint == -1)
|
||||
{
|
||||
layout = "push_constant";
|
||||
}
|
||||
else if (screen->glslversion < 4.20)
|
||||
{
|
||||
layout = "std140";
|
||||
}
|
||||
else
|
||||
{
|
||||
layout.Format("std140, binding = %d", bindingpoint);
|
||||
}
|
||||
decl.Format("layout(%s) uniform %s\n{\n", layout.GetChars(), name);
|
||||
for (size_t i = 0; i < fields.size(); i++)
|
||||
{
|
||||
decl.AppendFormat("\t%s %s;\n", GetTypeStr(fields[i].Type), fields[i].Name);
|
||||
}
|
||||
decl += "};\n";
|
||||
|
||||
return decl;
|
||||
}
|
||||
|
||||
private:
|
||||
static const char *GetTypeStr(UniformType type)
|
||||
{
|
||||
switch (type)
|
||||
{
|
||||
default:
|
||||
case UniformType::Int: return "int";
|
||||
case UniformType::UInt: return "uint";
|
||||
case UniformType::Float: return "float";
|
||||
case UniformType::Vec2: return "vec2";
|
||||
case UniformType::Vec3: return "vec3";
|
||||
case UniformType::Vec4: return "vec4";
|
||||
case UniformType::IVec2: return "ivec2";
|
||||
case UniformType::IVec3: return "ivec3";
|
||||
case UniformType::IVec4: return "ivec4";
|
||||
case UniformType::UVec2: return "uvec2";
|
||||
case UniformType::UVec3: return "uvec3";
|
||||
case UniformType::UVec4: return "uvec4";
|
||||
case UniformType::Mat4: return "mat4";
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
template<typename T, int bindingpoint>
|
||||
class ShaderUniforms
|
||||
{
|
||||
public:
|
||||
ShaderUniforms()
|
||||
{
|
||||
memset(&Values, 0, sizeof(Values));
|
||||
}
|
||||
|
||||
~ShaderUniforms()
|
||||
{
|
||||
if (mBuffer != nullptr)
|
||||
delete mBuffer;
|
||||
}
|
||||
|
||||
int BindingPoint() const
|
||||
{
|
||||
return bindingpoint;
|
||||
}
|
||||
|
||||
FString CreateDeclaration(const char *name, const std::vector<UniformFieldDesc> &fields)
|
||||
{
|
||||
mFields = fields;
|
||||
return UniformBlockDecl::Create(name, fields, bindingpoint);
|
||||
}
|
||||
|
||||
void Init()
|
||||
{
|
||||
if (mBuffer == nullptr)
|
||||
mBuffer = screen->CreateDataBuffer(bindingpoint, false, false);
|
||||
}
|
||||
|
||||
void SetData()
|
||||
{
|
||||
if (mBuffer != nullptr)
|
||||
mBuffer->SetData(sizeof(T), &Values);
|
||||
}
|
||||
|
||||
IDataBuffer* GetBuffer() const
|
||||
{
|
||||
// OpenGL needs to mess around with this in ways that should not be part of the interface.
|
||||
return mBuffer;
|
||||
}
|
||||
|
||||
T *operator->() { return &Values; }
|
||||
const T *operator->() const { return &Values; }
|
||||
|
||||
T Values;
|
||||
|
||||
private:
|
||||
ShaderUniforms(const ShaderUniforms &) = delete;
|
||||
ShaderUniforms &operator=(const ShaderUniforms &) = delete;
|
||||
|
||||
IDataBuffer *mBuffer = nullptr;
|
||||
std::vector<UniformFieldDesc> mFields;
|
||||
};
|
||||
|
||||
|
1106
source/common/rendering/hwrenderer/postprocessing/hw_postprocess.cpp
Normal file
1106
source/common/rendering/hwrenderer/postprocessing/hw_postprocess.cpp
Normal file
File diff suppressed because it is too large
Load diff
|
@ -0,0 +1,843 @@
|
|||
#pragma once
|
||||
|
||||
#include "hwrenderer/data/shaderuniforms.h"
|
||||
#include <memory>
|
||||
#include <map>
|
||||
|
||||
struct PostProcessShader;
|
||||
|
||||
typedef FRenderStyle PPBlendMode;
|
||||
typedef IntRect PPViewport;
|
||||
|
||||
class PPTexture;
|
||||
class PPShader;
|
||||
|
||||
enum class PPFilterMode { Nearest, Linear };
|
||||
enum class PPWrapMode { Clamp, Repeat };
|
||||
enum class PPTextureType { CurrentPipelineTexture, NextPipelineTexture, PPTexture, SceneColor, SceneFog, SceneNormal, SceneDepth, SwapChain, ShadowMap };
|
||||
|
||||
class PPTextureInput
|
||||
{
|
||||
public:
|
||||
PPFilterMode Filter = PPFilterMode::Nearest;
|
||||
PPWrapMode Wrap = PPWrapMode::Clamp;
|
||||
PPTextureType Type = PPTextureType::CurrentPipelineTexture;
|
||||
PPTexture *Texture = nullptr;
|
||||
};
|
||||
|
||||
class PPOutput
|
||||
{
|
||||
public:
|
||||
PPTextureType Type = PPTextureType::NextPipelineTexture;
|
||||
PPTexture *Texture = nullptr;
|
||||
};
|
||||
|
||||
class PPUniforms
|
||||
{
|
||||
public:
|
||||
PPUniforms()
|
||||
{
|
||||
}
|
||||
|
||||
PPUniforms(const PPUniforms &src)
|
||||
{
|
||||
Data = src.Data;
|
||||
}
|
||||
|
||||
~PPUniforms()
|
||||
{
|
||||
Clear();
|
||||
}
|
||||
|
||||
PPUniforms &operator=(const PPUniforms &src)
|
||||
{
|
||||
Data = src.Data;
|
||||
return *this;
|
||||
}
|
||||
|
||||
void Clear()
|
||||
{
|
||||
Data.Clear();
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
void Set(const T &v)
|
||||
{
|
||||
if (Data.Size() != (int)sizeof(T))
|
||||
{
|
||||
Data.Resize(sizeof(T));
|
||||
memcpy(Data.Data(), &v, Data.Size());
|
||||
}
|
||||
}
|
||||
|
||||
TArray<uint8_t> Data;
|
||||
};
|
||||
|
||||
class PPRenderState
|
||||
{
|
||||
public:
|
||||
virtual ~PPRenderState() = default;
|
||||
|
||||
virtual void PushGroup(const FString &name) = 0;
|
||||
virtual void PopGroup() = 0;
|
||||
|
||||
virtual void Draw() = 0;
|
||||
|
||||
void Clear()
|
||||
{
|
||||
Shader = nullptr;
|
||||
Textures = TArray<PPTextureInput>();
|
||||
Uniforms = PPUniforms();
|
||||
Viewport = PPViewport();
|
||||
BlendMode = PPBlendMode();
|
||||
Output = PPOutput();
|
||||
ShadowMapBuffers = false;
|
||||
}
|
||||
|
||||
void SetInputTexture(int index, PPTexture *texture, PPFilterMode filter = PPFilterMode::Nearest, PPWrapMode wrap = PPWrapMode::Clamp)
|
||||
{
|
||||
if ((int)Textures.Size() < index + 1)
|
||||
Textures.Resize(index + 1);
|
||||
auto &tex = Textures[index];
|
||||
tex.Filter = filter;
|
||||
tex.Wrap = wrap;
|
||||
tex.Type = PPTextureType::PPTexture;
|
||||
tex.Texture = texture;
|
||||
}
|
||||
|
||||
void SetInputCurrent(int index, PPFilterMode filter = PPFilterMode::Nearest, PPWrapMode wrap = PPWrapMode::Clamp)
|
||||
{
|
||||
SetInputSpecialType(index, PPTextureType::CurrentPipelineTexture, filter, wrap);
|
||||
}
|
||||
|
||||
void SetInputSceneColor(int index, PPFilterMode filter = PPFilterMode::Nearest, PPWrapMode wrap = PPWrapMode::Clamp)
|
||||
{
|
||||
SetInputSpecialType(index, PPTextureType::SceneColor, filter, wrap);
|
||||
}
|
||||
|
||||
void SetInputSceneFog(int index, PPFilterMode filter = PPFilterMode::Nearest, PPWrapMode wrap = PPWrapMode::Clamp)
|
||||
{
|
||||
SetInputSpecialType(index, PPTextureType::SceneFog, filter, wrap);
|
||||
}
|
||||
|
||||
void SetInputSceneNormal(int index, PPFilterMode filter = PPFilterMode::Nearest, PPWrapMode wrap = PPWrapMode::Clamp)
|
||||
{
|
||||
SetInputSpecialType(index, PPTextureType::SceneNormal, filter, wrap);
|
||||
}
|
||||
|
||||
void SetInputSceneDepth(int index, PPFilterMode filter = PPFilterMode::Nearest, PPWrapMode wrap = PPWrapMode::Clamp)
|
||||
{
|
||||
SetInputSpecialType(index, PPTextureType::SceneDepth, filter, wrap);
|
||||
}
|
||||
|
||||
void SetInputSpecialType(int index, PPTextureType type, PPFilterMode filter = PPFilterMode::Nearest, PPWrapMode wrap = PPWrapMode::Clamp)
|
||||
{
|
||||
if ((int)Textures.Size() < index + 1)
|
||||
Textures.Resize(index + 1);
|
||||
auto &tex = Textures[index];
|
||||
tex.Filter = filter;
|
||||
tex.Wrap = wrap;
|
||||
tex.Type = type;
|
||||
tex.Texture = nullptr;
|
||||
}
|
||||
|
||||
void SetShadowMapBuffers(bool enable)
|
||||
{
|
||||
ShadowMapBuffers = enable;
|
||||
}
|
||||
|
||||
void SetOutputTexture(PPTexture *texture)
|
||||
{
|
||||
Output.Type = PPTextureType::PPTexture;
|
||||
Output.Texture = texture;
|
||||
}
|
||||
|
||||
void SetOutputCurrent()
|
||||
{
|
||||
Output.Type = PPTextureType::CurrentPipelineTexture;
|
||||
Output.Texture = nullptr;
|
||||
}
|
||||
|
||||
void SetOutputNext()
|
||||
{
|
||||
Output.Type = PPTextureType::NextPipelineTexture;
|
||||
Output.Texture = nullptr;
|
||||
}
|
||||
|
||||
void SetOutputSceneColor()
|
||||
{
|
||||
Output.Type = PPTextureType::SceneColor;
|
||||
Output.Texture = nullptr;
|
||||
}
|
||||
|
||||
void SetOutputSwapChain()
|
||||
{
|
||||
Output.Type = PPTextureType::SwapChain;
|
||||
Output.Texture = nullptr;
|
||||
}
|
||||
|
||||
void SetOutputShadowMap()
|
||||
{
|
||||
Output.Type = PPTextureType::ShadowMap;
|
||||
Output.Texture = nullptr;
|
||||
}
|
||||
|
||||
void SetNoBlend()
|
||||
{
|
||||
BlendMode.BlendOp = STYLEOP_Add;
|
||||
BlendMode.SrcAlpha = STYLEALPHA_One;
|
||||
BlendMode.DestAlpha = STYLEALPHA_Zero;
|
||||
BlendMode.Flags = 0;
|
||||
}
|
||||
|
||||
void SetAdditiveBlend()
|
||||
{
|
||||
BlendMode.BlendOp = STYLEOP_Add;
|
||||
BlendMode.SrcAlpha = STYLEALPHA_One;
|
||||
BlendMode.DestAlpha = STYLEALPHA_One;
|
||||
BlendMode.Flags = 0;
|
||||
}
|
||||
|
||||
void SetAlphaBlend()
|
||||
{
|
||||
BlendMode.BlendOp = STYLEOP_Add;
|
||||
BlendMode.SrcAlpha = STYLEALPHA_Src;
|
||||
BlendMode.DestAlpha = STYLEALPHA_InvSrc;
|
||||
BlendMode.Flags = 0;
|
||||
}
|
||||
|
||||
PPShader *Shader;
|
||||
TArray<PPTextureInput> Textures;
|
||||
PPUniforms Uniforms;
|
||||
PPViewport Viewport;
|
||||
PPBlendMode BlendMode;
|
||||
PPOutput Output;
|
||||
bool ShadowMapBuffers = false;
|
||||
};
|
||||
|
||||
enum class PixelFormat
|
||||
{
|
||||
Rgba8,
|
||||
Rgba16f,
|
||||
R32f,
|
||||
Rg16f,
|
||||
Rgba16_snorm
|
||||
};
|
||||
|
||||
class PPResource
|
||||
{
|
||||
public:
|
||||
PPResource()
|
||||
{
|
||||
Next = First;
|
||||
First = this;
|
||||
if (Next) Next->Prev = this;
|
||||
}
|
||||
|
||||
PPResource(const PPResource &)
|
||||
{
|
||||
Next = First;
|
||||
First = this;
|
||||
if (Next) Next->Prev = this;
|
||||
}
|
||||
|
||||
virtual ~PPResource()
|
||||
{
|
||||
if (Next) Next->Prev = Prev;
|
||||
if (Prev) Prev->Next = Next;
|
||||
else First = Next;
|
||||
}
|
||||
|
||||
PPResource &operator=(const PPResource &other)
|
||||
{
|
||||
return *this;
|
||||
}
|
||||
|
||||
static void ResetAll()
|
||||
{
|
||||
for (PPResource *cur = First; cur; cur = cur->Next)
|
||||
cur->ResetBackend();
|
||||
}
|
||||
|
||||
virtual void ResetBackend() = 0;
|
||||
|
||||
private:
|
||||
static PPResource *First;
|
||||
PPResource *Prev = nullptr;
|
||||
PPResource *Next = nullptr;
|
||||
};
|
||||
|
||||
class PPTextureBackend
|
||||
{
|
||||
public:
|
||||
virtual ~PPTextureBackend() = default;
|
||||
};
|
||||
|
||||
class PPTexture : public PPResource
|
||||
{
|
||||
public:
|
||||
PPTexture() = default;
|
||||
PPTexture(int width, int height, PixelFormat format, std::shared_ptr<void> data = {}) : Width(width), Height(height), Format(format), Data(data) { }
|
||||
|
||||
void ResetBackend() override { Backend.reset(); }
|
||||
|
||||
int Width;
|
||||
int Height;
|
||||
PixelFormat Format;
|
||||
std::shared_ptr<void> Data;
|
||||
|
||||
std::unique_ptr<PPTextureBackend> Backend;
|
||||
};
|
||||
|
||||
class PPShaderBackend
|
||||
{
|
||||
public:
|
||||
virtual ~PPShaderBackend() = default;
|
||||
};
|
||||
|
||||
class PPShader : public PPResource
|
||||
{
|
||||
public:
|
||||
PPShader() = default;
|
||||
PPShader(const FString &fragment, const FString &defines, const std::vector<UniformFieldDesc> &uniforms, int version = 330) : FragmentShader(fragment), Defines(defines), Uniforms(uniforms), Version(version) { }
|
||||
|
||||
void ResetBackend() override { Backend.reset(); }
|
||||
|
||||
FString VertexShader = "shaders/glsl/screenquad.vp";
|
||||
FString FragmentShader;
|
||||
FString Defines;
|
||||
std::vector<UniformFieldDesc> Uniforms;
|
||||
int Version = 330;
|
||||
|
||||
std::unique_ptr<PPShaderBackend> Backend;
|
||||
};
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
struct ExtractUniforms
|
||||
{
|
||||
FVector2 Scale;
|
||||
FVector2 Offset;
|
||||
|
||||
static std::vector<UniformFieldDesc> Desc()
|
||||
{
|
||||
return
|
||||
{
|
||||
{ "Scale", UniformType::Vec2, offsetof(ExtractUniforms, Scale) },
|
||||
{ "Offset", UniformType::Vec2, offsetof(ExtractUniforms, Offset) }
|
||||
};
|
||||
}
|
||||
};
|
||||
|
||||
struct BlurUniforms
|
||||
{
|
||||
float SampleWeights[8];
|
||||
|
||||
static std::vector<UniformFieldDesc> Desc()
|
||||
{
|
||||
return
|
||||
{
|
||||
{ "SampleWeights0", UniformType::Float, offsetof(BlurUniforms, SampleWeights[0]) },
|
||||
{ "SampleWeights1", UniformType::Float, offsetof(BlurUniforms, SampleWeights[1]) },
|
||||
{ "SampleWeights2", UniformType::Float, offsetof(BlurUniforms, SampleWeights[2]) },
|
||||
{ "SampleWeights3", UniformType::Float, offsetof(BlurUniforms, SampleWeights[3]) },
|
||||
{ "SampleWeights4", UniformType::Float, offsetof(BlurUniforms, SampleWeights[4]) },
|
||||
{ "SampleWeights5", UniformType::Float, offsetof(BlurUniforms, SampleWeights[5]) },
|
||||
{ "SampleWeights6", UniformType::Float, offsetof(BlurUniforms, SampleWeights[6]) },
|
||||
{ "SampleWeights7", UniformType::Float, offsetof(BlurUniforms, SampleWeights[7]) },
|
||||
};
|
||||
}
|
||||
};
|
||||
|
||||
enum { NumBloomLevels = 4 };
|
||||
|
||||
class PPBlurLevel
|
||||
{
|
||||
public:
|
||||
PPViewport Viewport;
|
||||
PPTexture VTexture;
|
||||
PPTexture HTexture;
|
||||
};
|
||||
|
||||
class PPBloom
|
||||
{
|
||||
public:
|
||||
void RenderBloom(PPRenderState *renderstate, int sceneWidth, int sceneHeight, int fixedcm);
|
||||
void RenderBlur(PPRenderState *renderstate, int sceneWidth, int sceneHeight, float gameinfobluramount);
|
||||
|
||||
private:
|
||||
void BlurStep(PPRenderState *renderstate, const BlurUniforms &blurUniforms, PPTexture &input, PPTexture &output, PPViewport viewport, bool vertical);
|
||||
void UpdateTextures(int width, int height);
|
||||
|
||||
static float ComputeBlurGaussian(float n, float theta);
|
||||
static void ComputeBlurSamples(int sampleCount, float blurAmount, float *sampleWeights);
|
||||
|
||||
PPBlurLevel levels[NumBloomLevels];
|
||||
int lastWidth = 0;
|
||||
int lastHeight = 0;
|
||||
|
||||
PPShader BloomCombine = { "shaders/glsl/bloomcombine.fp", "", {} };
|
||||
PPShader BloomExtract = { "shaders/glsl/bloomextract.fp", "", ExtractUniforms::Desc() };
|
||||
PPShader BlurVertical = { "shaders/glsl/blur.fp", "#define BLUR_VERTICAL\n", BlurUniforms::Desc() };
|
||||
PPShader BlurHorizontal = { "shaders/glsl/blur.fp", "#define BLUR_HORIZONTAL\n", BlurUniforms::Desc() };
|
||||
};
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
struct LensUniforms
|
||||
{
|
||||
float AspectRatio;
|
||||
float Scale;
|
||||
float Padding0, Padding1;
|
||||
FVector4 LensDistortionCoefficient;
|
||||
FVector4 CubicDistortionValue;
|
||||
|
||||
static std::vector<UniformFieldDesc> Desc()
|
||||
{
|
||||
return
|
||||
{
|
||||
{ "Aspect", UniformType::Float, offsetof(LensUniforms, AspectRatio) },
|
||||
{ "Scale", UniformType::Float, offsetof(LensUniforms, Scale) },
|
||||
{ "Padding0", UniformType::Float, offsetof(LensUniforms, Padding0) },
|
||||
{ "Padding1", UniformType::Float, offsetof(LensUniforms, Padding1) },
|
||||
{ "k", UniformType::Vec4, offsetof(LensUniforms, LensDistortionCoefficient) },
|
||||
{ "kcube", UniformType::Vec4, offsetof(LensUniforms, CubicDistortionValue) }
|
||||
};
|
||||
}
|
||||
};
|
||||
|
||||
class PPLensDistort
|
||||
{
|
||||
public:
|
||||
void Render(PPRenderState *renderstate);
|
||||
|
||||
private:
|
||||
PPShader Lens = { "shaders/glsl/lensdistortion.fp", "", LensUniforms::Desc() };
|
||||
};
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
struct FXAAUniforms
|
||||
{
|
||||
FVector2 ReciprocalResolution;
|
||||
float Padding0, Padding1;
|
||||
|
||||
static std::vector<UniformFieldDesc> Desc()
|
||||
{
|
||||
return
|
||||
{
|
||||
{ "ReciprocalResolution", UniformType::Vec2, offsetof(FXAAUniforms, ReciprocalResolution) },
|
||||
{ "Padding0", UniformType::Float, offsetof(FXAAUniforms, Padding0) },
|
||||
{ "Padding1", UniformType::Float, offsetof(FXAAUniforms, Padding1) }
|
||||
};
|
||||
}
|
||||
};
|
||||
|
||||
class PPFXAA
|
||||
{
|
||||
public:
|
||||
void Render(PPRenderState *renderstate);
|
||||
|
||||
private:
|
||||
void CreateShaders();
|
||||
int GetMaxVersion();
|
||||
FString GetDefines();
|
||||
|
||||
PPShader FXAALuma;
|
||||
PPShader FXAA;
|
||||
int LastQuality = -1;
|
||||
};
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
struct ExposureExtractUniforms
|
||||
{
|
||||
FVector2 Scale;
|
||||
FVector2 Offset;
|
||||
|
||||
static std::vector<UniformFieldDesc> Desc()
|
||||
{
|
||||
return
|
||||
{
|
||||
{ "Scale", UniformType::Vec2, offsetof(ExposureExtractUniforms, Scale) },
|
||||
{ "Offset", UniformType::Vec2, offsetof(ExposureExtractUniforms, Offset) }
|
||||
};
|
||||
}
|
||||
};
|
||||
|
||||
struct ExposureCombineUniforms
|
||||
{
|
||||
float ExposureBase;
|
||||
float ExposureMin;
|
||||
float ExposureScale;
|
||||
float ExposureSpeed;
|
||||
|
||||
static std::vector<UniformFieldDesc> Desc()
|
||||
{
|
||||
return
|
||||
{
|
||||
{ "ExposureBase", UniformType::Float, offsetof(ExposureCombineUniforms, ExposureBase) },
|
||||
{ "ExposureMin", UniformType::Float, offsetof(ExposureCombineUniforms, ExposureMin) },
|
||||
{ "ExposureScale", UniformType::Float, offsetof(ExposureCombineUniforms, ExposureScale) },
|
||||
{ "ExposureSpeed", UniformType::Float, offsetof(ExposureCombineUniforms, ExposureSpeed) }
|
||||
};
|
||||
}
|
||||
};
|
||||
|
||||
class PPExposureLevel
|
||||
{
|
||||
public:
|
||||
PPViewport Viewport;
|
||||
PPTexture Texture;
|
||||
};
|
||||
|
||||
class PPCameraExposure
|
||||
{
|
||||
public:
|
||||
void Render(PPRenderState *renderstate, int sceneWidth, int sceneHeight);
|
||||
|
||||
PPTexture CameraTexture = { 1, 1, PixelFormat::R32f };
|
||||
|
||||
private:
|
||||
void UpdateTextures(int width, int height);
|
||||
|
||||
std::vector<PPExposureLevel> ExposureLevels;
|
||||
bool FirstExposureFrame = true;
|
||||
|
||||
PPShader ExposureExtract = { "shaders/glsl/exposureextract.fp", "", ExposureExtractUniforms::Desc() };
|
||||
PPShader ExposureAverage = { "shaders/glsl/exposureaverage.fp", "", {}, 400 };
|
||||
PPShader ExposureCombine = { "shaders/glsl/exposurecombine.fp", "", ExposureCombineUniforms::Desc() };
|
||||
};
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
struct ColormapUniforms
|
||||
{
|
||||
FVector4 MapStart;
|
||||
FVector4 MapRange;
|
||||
|
||||
static std::vector<UniformFieldDesc> Desc()
|
||||
{
|
||||
return
|
||||
{
|
||||
{ "uFixedColormapStart", UniformType::Vec4, offsetof(ColormapUniforms, MapStart) },
|
||||
{ "uFixedColormapRange", UniformType::Vec4, offsetof(ColormapUniforms, MapRange) },
|
||||
};
|
||||
}
|
||||
};
|
||||
|
||||
class PPColormap
|
||||
{
|
||||
public:
|
||||
void Render(PPRenderState *renderstate, int fixedcm);
|
||||
|
||||
private:
|
||||
PPShader Colormap = { "shaders/glsl/colormap.fp", "", ColormapUniforms::Desc() };
|
||||
};
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
class PPTonemap
|
||||
{
|
||||
public:
|
||||
void Render(PPRenderState *renderstate);
|
||||
void ClearTonemapPalette() { PaletteTexture = {}; }
|
||||
|
||||
private:
|
||||
void UpdateTextures();
|
||||
|
||||
PPTexture PaletteTexture;
|
||||
|
||||
PPShader LinearShader = { "shaders/glsl/tonemap.fp", "#define LINEAR\n", {} };
|
||||
PPShader ReinhardShader = { "shaders/glsl/tonemap.fp", "#define REINHARD\n", {} };
|
||||
PPShader HejlDawsonShader = { "shaders/glsl/tonemap.fp", "#define HEJLDAWSON\n", {} };
|
||||
PPShader Uncharted2Shader = { "shaders/glsl/tonemap.fp", "#define UNCHARTED2\n", {} };
|
||||
PPShader PaletteShader = { "shaders/glsl/tonemap.fp", "#define PALETTE\n", {} };
|
||||
|
||||
enum TonemapMode
|
||||
{
|
||||
None,
|
||||
Uncharted2,
|
||||
HejlDawson,
|
||||
Reinhard,
|
||||
Linear,
|
||||
Palette,
|
||||
NumTonemapModes
|
||||
};
|
||||
};
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
struct LinearDepthUniforms
|
||||
{
|
||||
int SampleIndex;
|
||||
float LinearizeDepthA;
|
||||
float LinearizeDepthB;
|
||||
float InverseDepthRangeA;
|
||||
float InverseDepthRangeB;
|
||||
float Padding0, Padding1, Padding2;
|
||||
FVector2 Scale;
|
||||
FVector2 Offset;
|
||||
|
||||
static std::vector<UniformFieldDesc> Desc()
|
||||
{
|
||||
return
|
||||
{
|
||||
{ "SampleIndex", UniformType::Int, offsetof(LinearDepthUniforms, SampleIndex) },
|
||||
{ "LinearizeDepthA", UniformType::Float, offsetof(LinearDepthUniforms, LinearizeDepthA) },
|
||||
{ "LinearizeDepthB", UniformType::Float, offsetof(LinearDepthUniforms, LinearizeDepthB) },
|
||||
{ "InverseDepthRangeA", UniformType::Float, offsetof(LinearDepthUniforms, InverseDepthRangeA) },
|
||||
{ "InverseDepthRangeB", UniformType::Float, offsetof(LinearDepthUniforms, InverseDepthRangeB) },
|
||||
{ "Padding0", UniformType::Float, offsetof(LinearDepthUniforms, Padding0) },
|
||||
{ "Padding1", UniformType::Float, offsetof(LinearDepthUniforms, Padding1) },
|
||||
{ "Padding2", UniformType::Float, offsetof(LinearDepthUniforms, Padding2) },
|
||||
{ "Scale", UniformType::Vec2, offsetof(LinearDepthUniforms, Scale) },
|
||||
{ "Offset", UniformType::Vec2, offsetof(LinearDepthUniforms, Offset) }
|
||||
};
|
||||
}
|
||||
};
|
||||
|
||||
struct SSAOUniforms
|
||||
{
|
||||
FVector2 UVToViewA;
|
||||
FVector2 UVToViewB;
|
||||
FVector2 InvFullResolution;
|
||||
float NDotVBias;
|
||||
float NegInvR2;
|
||||
float RadiusToScreen;
|
||||
float AOMultiplier;
|
||||
float AOStrength;
|
||||
int SampleIndex;
|
||||
float Padding0, Padding1;
|
||||
FVector2 Scale;
|
||||
FVector2 Offset;
|
||||
|
||||
static std::vector<UniformFieldDesc> Desc()
|
||||
{
|
||||
return
|
||||
{
|
||||
{ "UVToViewA", UniformType::Vec2, offsetof(SSAOUniforms, UVToViewA) },
|
||||
{ "UVToViewB", UniformType::Vec2, offsetof(SSAOUniforms, UVToViewB) },
|
||||
{ "InvFullResolution", UniformType::Vec2, offsetof(SSAOUniforms, InvFullResolution) },
|
||||
{ "NDotVBias", UniformType::Float, offsetof(SSAOUniforms, NDotVBias) },
|
||||
{ "NegInvR2", UniformType::Float, offsetof(SSAOUniforms, NegInvR2) },
|
||||
{ "RadiusToScreen", UniformType::Float, offsetof(SSAOUniforms, RadiusToScreen) },
|
||||
{ "AOMultiplier", UniformType::Float, offsetof(SSAOUniforms, AOMultiplier) },
|
||||
{ "AOStrength", UniformType::Float, offsetof(SSAOUniforms, AOStrength) },
|
||||
{ "SampleIndex", UniformType::Int, offsetof(SSAOUniforms, SampleIndex) },
|
||||
{ "Padding0", UniformType::Float, offsetof(SSAOUniforms, Padding0) },
|
||||
{ "Padding1", UniformType::Float, offsetof(SSAOUniforms, Padding1) },
|
||||
{ "Scale", UniformType::Vec2, offsetof(SSAOUniforms, Scale) },
|
||||
{ "Offset", UniformType::Vec2, offsetof(SSAOUniforms, Offset) },
|
||||
};
|
||||
}
|
||||
};
|
||||
|
||||
struct DepthBlurUniforms
|
||||
{
|
||||
float BlurSharpness;
|
||||
float PowExponent;
|
||||
float Padding0, Padding1;
|
||||
|
||||
static std::vector<UniformFieldDesc> Desc()
|
||||
{
|
||||
return
|
||||
{
|
||||
{ "BlurSharpness", UniformType::Float, offsetof(DepthBlurUniforms, BlurSharpness) },
|
||||
{ "PowExponent", UniformType::Float, offsetof(DepthBlurUniforms, PowExponent) },
|
||||
{ "Padding0", UniformType::Float, offsetof(DepthBlurUniforms, Padding0) },
|
||||
{ "Padding1", UniformType::Float, offsetof(DepthBlurUniforms, Padding1) }
|
||||
};
|
||||
}
|
||||
};
|
||||
|
||||
struct AmbientCombineUniforms
|
||||
{
|
||||
int SampleCount;
|
||||
int DebugMode, Padding1, Padding2;
|
||||
FVector2 Scale;
|
||||
FVector2 Offset;
|
||||
|
||||
static std::vector<UniformFieldDesc> Desc()
|
||||
{
|
||||
return
|
||||
{
|
||||
{ "SampleCount", UniformType::Int, offsetof(AmbientCombineUniforms, SampleCount) },
|
||||
{ "DebugMode", UniformType::Int, offsetof(AmbientCombineUniforms, DebugMode) },
|
||||
{ "Padding1", UniformType::Int, offsetof(AmbientCombineUniforms, Padding1) },
|
||||
{ "Padding2", UniformType::Int, offsetof(AmbientCombineUniforms, Padding2) },
|
||||
{ "Scale", UniformType::Vec2, offsetof(AmbientCombineUniforms, Scale) },
|
||||
{ "Offset", UniformType::Vec2, offsetof(AmbientCombineUniforms, Offset) }
|
||||
};
|
||||
}
|
||||
};
|
||||
|
||||
class PPAmbientOcclusion
|
||||
{
|
||||
public:
|
||||
PPAmbientOcclusion();
|
||||
void Render(PPRenderState *renderstate, float m5, int sceneWidth, int sceneHeight);
|
||||
|
||||
private:
|
||||
void CreateShaders();
|
||||
void UpdateTextures(int width, int height);
|
||||
|
||||
enum Quality
|
||||
{
|
||||
Off,
|
||||
LowQuality,
|
||||
MediumQuality,
|
||||
HighQuality,
|
||||
NumQualityModes
|
||||
};
|
||||
|
||||
int AmbientWidth = 0;
|
||||
int AmbientHeight = 0;
|
||||
|
||||
int LastQuality = -1;
|
||||
int LastWidth = 0;
|
||||
int LastHeight = 0;
|
||||
|
||||
PPShader LinearDepth;
|
||||
PPShader LinearDepthMS;
|
||||
PPShader AmbientOcclude;
|
||||
PPShader AmbientOccludeMS;
|
||||
PPShader BlurVertical;
|
||||
PPShader BlurHorizontal;
|
||||
PPShader Combine;
|
||||
PPShader CombineMS;
|
||||
|
||||
PPTexture LinearDepthTexture;
|
||||
PPTexture Ambient0;
|
||||
PPTexture Ambient1;
|
||||
|
||||
enum { NumAmbientRandomTextures = 3 };
|
||||
PPTexture AmbientRandomTexture[NumAmbientRandomTextures];
|
||||
};
|
||||
|
||||
struct PresentUniforms
|
||||
{
|
||||
float InvGamma;
|
||||
float Contrast;
|
||||
float Brightness;
|
||||
float Saturation;
|
||||
int GrayFormula;
|
||||
int WindowPositionParity; // top-of-window might not be top-of-screen
|
||||
FVector2 Scale;
|
||||
FVector2 Offset;
|
||||
float ColorScale;
|
||||
int HdrMode;
|
||||
|
||||
static std::vector<UniformFieldDesc> Desc()
|
||||
{
|
||||
return
|
||||
{
|
||||
{ "InvGamma", UniformType::Float, offsetof(PresentUniforms, InvGamma) },
|
||||
{ "Contrast", UniformType::Float, offsetof(PresentUniforms, Contrast) },
|
||||
{ "Brightness", UniformType::Float, offsetof(PresentUniforms, Brightness) },
|
||||
{ "Saturation", UniformType::Float, offsetof(PresentUniforms, Saturation) },
|
||||
{ "GrayFormula", UniformType::Int, offsetof(PresentUniforms, GrayFormula) },
|
||||
{ "WindowPositionParity", UniformType::Int, offsetof(PresentUniforms, WindowPositionParity) },
|
||||
{ "UVScale", UniformType::Vec2, offsetof(PresentUniforms, Scale) },
|
||||
{ "UVOffset", UniformType::Vec2, offsetof(PresentUniforms, Offset) },
|
||||
{ "ColorScale", UniformType::Float, offsetof(PresentUniforms, ColorScale) },
|
||||
{ "HdrMode", UniformType::Int, offsetof(PresentUniforms, HdrMode) }
|
||||
};
|
||||
}
|
||||
};
|
||||
|
||||
class PPPresent
|
||||
{
|
||||
public:
|
||||
PPPresent();
|
||||
|
||||
PPTexture Dither;
|
||||
|
||||
PPShader Present = { "shaders/glsl/present.fp", "", PresentUniforms::Desc() };
|
||||
PPShader Checker3D = { "shaders/glsl/present_checker3d.fp", "", PresentUniforms::Desc() };
|
||||
PPShader Column3D = { "shaders/glsl/present_column3d.fp", "", PresentUniforms::Desc() };
|
||||
PPShader Row3D = { "shaders/glsl/present_row3d.fp", "", PresentUniforms::Desc() };
|
||||
};
|
||||
|
||||
struct ShadowMapUniforms
|
||||
{
|
||||
float ShadowmapQuality;
|
||||
int NodesCount;
|
||||
float Padding0, Padding1;
|
||||
|
||||
static std::vector<UniformFieldDesc> Desc()
|
||||
{
|
||||
return
|
||||
{
|
||||
{ "ShadowmapQuality", UniformType::Float, offsetof(ShadowMapUniforms, ShadowmapQuality) },
|
||||
{ "NodesCount", UniformType::Int, offsetof(ShadowMapUniforms, NodesCount) },
|
||||
{ "Padding0", UniformType::Float, offsetof(ShadowMapUniforms, Padding0) },
|
||||
{ "Padding1", UniformType::Float, offsetof(ShadowMapUniforms, Padding1) },
|
||||
};
|
||||
}
|
||||
};
|
||||
|
||||
class PPShadowMap
|
||||
{
|
||||
public:
|
||||
void Update(PPRenderState *renderstate);
|
||||
|
||||
private:
|
||||
PPShader ShadowMap = { "shaders/glsl/shadowmap.fp", "", ShadowMapUniforms::Desc() };
|
||||
};
|
||||
|
||||
class PPCustomShaderInstance
|
||||
{
|
||||
public:
|
||||
PPCustomShaderInstance(PostProcessShader *desc);
|
||||
|
||||
void Run(PPRenderState *renderstate);
|
||||
|
||||
PostProcessShader *Desc = nullptr;
|
||||
|
||||
private:
|
||||
void AddUniformField(size_t &offset, const FString &name, UniformType type, size_t fieldsize, size_t alignment = 0);
|
||||
void SetTextures(PPRenderState *renderstate);
|
||||
void SetUniforms(PPRenderState *renderstate);
|
||||
|
||||
PPShader Shader;
|
||||
int UniformStructSize = 0;
|
||||
std::vector<UniformFieldDesc> Fields;
|
||||
std::vector<std::unique_ptr<FString>> FieldNames;
|
||||
std::map<FTexture*, std::unique_ptr<PPTexture>> Textures;
|
||||
std::map<FString, size_t> FieldOffset;
|
||||
};
|
||||
|
||||
class PPCustomShaders
|
||||
{
|
||||
public:
|
||||
void Run(PPRenderState *renderstate, FString target);
|
||||
|
||||
private:
|
||||
void CreateShaders();
|
||||
|
||||
std::vector<std::unique_ptr<PPCustomShaderInstance>> mShaders;
|
||||
};
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
class Postprocess
|
||||
{
|
||||
public:
|
||||
PPBloom bloom;
|
||||
PPLensDistort lens;
|
||||
PPFXAA fxaa;
|
||||
PPCameraExposure exposure;
|
||||
PPColormap colormap;
|
||||
PPTonemap tonemap;
|
||||
PPAmbientOcclusion ssao;
|
||||
PPPresent present;
|
||||
PPShadowMap shadowmap;
|
||||
PPCustomShaders customShaders;
|
||||
|
||||
|
||||
void Pass1(PPRenderState *state, int fixedcm, int sceneWidth, int sceneHeight);
|
||||
void Pass2(PPRenderState* state, int fixedcm, int sceneWidth, int sceneHeight);
|
||||
};
|
||||
|
||||
extern Postprocess hw_postprocess;
|
|
@ -0,0 +1,98 @@
|
|||
/*
|
||||
** Postprocessing framework
|
||||
** Copyright (c) 2016-2020 Magnus Norddahl
|
||||
**
|
||||
** This software is provided 'as-is', without any express or implied
|
||||
** warranty. In no event will the authors be held liable for any damages
|
||||
** arising from the use of this software.
|
||||
**
|
||||
** Permission is granted to anyone to use this software for any purpose,
|
||||
** including commercial applications, and to alter it and redistribute it
|
||||
** freely, subject to the following restrictions:
|
||||
**
|
||||
** 1. The origin of this software must not be misrepresented; you must not
|
||||
** claim that you wrote the original software. If you use this software
|
||||
** in a product, an acknowledgment in the product documentation would be
|
||||
** appreciated but is not required.
|
||||
** 2. Altered source versions must be plainly marked as such, and must not be
|
||||
** misrepresented as being the original software.
|
||||
** 3. This notice may not be removed or altered from any source distribution.
|
||||
*/
|
||||
|
||||
#include "hw_postprocess_cvars.h"
|
||||
#include "v_video.h"
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
// CVARs
|
||||
//
|
||||
//==========================================================================
|
||||
CVAR(Bool, gl_bloom, false, CVAR_ARCHIVE);
|
||||
CUSTOM_CVAR(Float, gl_bloom_amount, 1.4f, CVAR_ARCHIVE)
|
||||
{
|
||||
if (self < 0.1f) self = 0.1f;
|
||||
}
|
||||
|
||||
CVAR(Float, gl_exposure_scale, 1.3f, CVAR_ARCHIVE)
|
||||
CVAR(Float, gl_exposure_min, 0.35f, CVAR_ARCHIVE)
|
||||
CVAR(Float, gl_exposure_base, 0.35f, CVAR_ARCHIVE)
|
||||
CVAR(Float, gl_exposure_speed, 0.05f, CVAR_ARCHIVE)
|
||||
|
||||
CUSTOM_CVAR(Int, gl_tonemap, 0, CVAR_ARCHIVE)
|
||||
{
|
||||
if (self < 0 || self > 5)
|
||||
self = 0;
|
||||
}
|
||||
|
||||
CVAR(Bool, gl_lens, false, CVAR_ARCHIVE | CVAR_GLOBALCONFIG)
|
||||
|
||||
CVAR(Float, gl_lens_k, -0.12f, CVAR_ARCHIVE | CVAR_GLOBALCONFIG)
|
||||
CVAR(Float, gl_lens_kcube, 0.1f, CVAR_ARCHIVE | CVAR_GLOBALCONFIG)
|
||||
CVAR(Float, gl_lens_chromatic, 1.12f, CVAR_ARCHIVE | CVAR_GLOBALCONFIG)
|
||||
|
||||
CUSTOM_CVAR(Int, gl_fxaa, 0, CVAR_ARCHIVE | CVAR_GLOBALCONFIG)
|
||||
{
|
||||
if (self < 0 || self >= IFXAAShader::Count)
|
||||
{
|
||||
self = 0;
|
||||
}
|
||||
}
|
||||
|
||||
CUSTOM_CVAR(Int, gl_ssao, 0, CVAR_ARCHIVE | CVAR_GLOBALCONFIG)
|
||||
{
|
||||
if (self < 0 || self > 3)
|
||||
self = 0;
|
||||
}
|
||||
|
||||
CUSTOM_CVAR(Int, gl_ssao_portals, 1, CVAR_ARCHIVE | CVAR_GLOBALCONFIG)
|
||||
{
|
||||
if (self < 0)
|
||||
self = 0;
|
||||
}
|
||||
|
||||
CVAR(Float, gl_ssao_strength, 0.7f, CVAR_ARCHIVE | CVAR_GLOBALCONFIG)
|
||||
CVAR(Int, gl_ssao_debug, 0, 0)
|
||||
CVAR(Float, gl_ssao_bias, 0.2f, 0)
|
||||
CVAR(Float, gl_ssao_radius, 80.0f, 0)
|
||||
CUSTOM_CVAR(Float, gl_ssao_blur, 16.0f, 0)
|
||||
{
|
||||
if (self < 0.1f) self = 0.1f;
|
||||
}
|
||||
|
||||
CUSTOM_CVAR(Float, gl_ssao_exponent, 1.8f, 0)
|
||||
{
|
||||
if (self < 0.1f) self = 0.1f;
|
||||
}
|
||||
|
||||
CUSTOM_CVAR(Float, gl_paltonemap_powtable, 2.0f, CVAR_ARCHIVE | CVAR_NOINITCALL)
|
||||
{
|
||||
screen->UpdatePalette();
|
||||
}
|
||||
|
||||
CUSTOM_CVAR(Bool, gl_paltonemap_reverselookup, true, CVAR_ARCHIVE | CVAR_NOINITCALL)
|
||||
{
|
||||
screen->UpdatePalette();
|
||||
}
|
||||
|
||||
CVAR(Float, gl_menu_blur, -1.0f, CVAR_ARCHIVE)
|
||||
|
|
@ -0,0 +1,54 @@
|
|||
#pragma once
|
||||
|
||||
#include "c_cvars.h"
|
||||
|
||||
class IFXAAShader
|
||||
{
|
||||
public:
|
||||
enum Quality
|
||||
{
|
||||
None,
|
||||
Low,
|
||||
Medium,
|
||||
High,
|
||||
Extreme,
|
||||
Count
|
||||
};
|
||||
};
|
||||
|
||||
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
// CVARs
|
||||
//
|
||||
//==========================================================================
|
||||
EXTERN_CVAR(Bool, gl_bloom)
|
||||
EXTERN_CVAR(Float, gl_bloom_amount)
|
||||
EXTERN_CVAR(Float, gl_exposure_scale)
|
||||
EXTERN_CVAR(Float, gl_exposure_min)
|
||||
EXTERN_CVAR(Float, gl_exposure_base)
|
||||
EXTERN_CVAR(Float, gl_exposure_speed)
|
||||
EXTERN_CVAR(Int, gl_tonemap)
|
||||
EXTERN_CVAR(Int, gl_bloom_kernel_size)
|
||||
EXTERN_CVAR(Bool, gl_lens)
|
||||
EXTERN_CVAR(Float, gl_lens_k)
|
||||
EXTERN_CVAR(Float, gl_lens_kcube)
|
||||
EXTERN_CVAR(Float, gl_lens_chromatic)
|
||||
EXTERN_CVAR(Int, gl_fxaa)
|
||||
EXTERN_CVAR(Int, gl_ssao)
|
||||
EXTERN_CVAR(Int, gl_ssao_portals)
|
||||
EXTERN_CVAR(Float, gl_ssao_strength)
|
||||
EXTERN_CVAR(Int, gl_ssao_debug)
|
||||
EXTERN_CVAR(Float, gl_ssao_bias)
|
||||
EXTERN_CVAR(Float, gl_ssao_radius)
|
||||
EXTERN_CVAR(Float, gl_ssao_blur)
|
||||
EXTERN_CVAR(Float, gl_ssao_exponent)
|
||||
EXTERN_CVAR(Float, gl_paltonemap_powtable)
|
||||
EXTERN_CVAR(Bool, gl_paltonemap_reverselookup)
|
||||
EXTERN_CVAR(Float, gl_menu_blur)
|
||||
EXTERN_CVAR(Float, vid_brightness)
|
||||
EXTERN_CVAR(Float, vid_contrast)
|
||||
EXTERN_CVAR(Float, vid_saturation)
|
||||
EXTERN_CVAR(Int, gl_satformula)
|
||||
|
|
@ -0,0 +1,32 @@
|
|||
#pragma once
|
||||
|
||||
enum class PostProcessUniformType
|
||||
{
|
||||
Undefined,
|
||||
Int,
|
||||
Float,
|
||||
Vec2,
|
||||
Vec3
|
||||
};
|
||||
|
||||
struct PostProcessUniformValue
|
||||
{
|
||||
PostProcessUniformType Type = PostProcessUniformType::Undefined;
|
||||
double Values[4] = { 0.0, 0.0, 0.0, 0.0 };
|
||||
};
|
||||
|
||||
struct PostProcessShader
|
||||
{
|
||||
FString Target;
|
||||
FString ShaderLumpName;
|
||||
int ShaderVersion = 0;
|
||||
|
||||
FString Name;
|
||||
bool Enabled = false;
|
||||
|
||||
TMap<FString, PostProcessUniformValue> Uniforms;
|
||||
TMap<FString, FString> Textures;
|
||||
};
|
||||
|
||||
extern TArray<PostProcessShader> PostProcessShaders;
|
||||
|
Loading…
Add table
Add a link
Reference in a new issue