- write OpenGL backend for hw_postprocess (FGLRenderBuffers::RenderEffect)

- remove old fxaa and lens shader classes
- render the fxaa and lens effects
This commit is contained in:
Magnus Norddahl 2018-06-20 19:56:30 +02:00
parent e3997d5f11
commit 151ed22967
13 changed files with 270 additions and 319 deletions

View file

@ -1072,8 +1072,6 @@ set (PCH_SOURCES
hwrenderer/postprocessing/hw_blurshader.cpp
hwrenderer/postprocessing/hw_colormapshader.cpp
hwrenderer/postprocessing/hw_tonemapshader.cpp
hwrenderer/postprocessing/hw_lensshader.cpp
hwrenderer/postprocessing/hw_fxaashader.cpp
hwrenderer/textures/hw_material.cpp
hwrenderer/textures/hw_precache.cpp
hwrenderer/utility/hw_clock.cpp

View file

@ -44,9 +44,9 @@
#include "hwrenderer/postprocessing/hw_blurshader.h"
#include "hwrenderer/postprocessing/hw_tonemapshader.h"
#include "hwrenderer/postprocessing/hw_colormapshader.h"
#include "hwrenderer/postprocessing/hw_lensshader.h"
#include "hwrenderer/postprocessing/hw_fxaashader.h"
#include "hwrenderer/postprocessing/hw_presentshader.h"
#include "hwrenderer/postprocessing/hw_postprocess.h"
#include "hwrenderer/postprocessing/hw_postprocess_cvars.h"
#include "gl/shaders/gl_postprocessshaderinstance.h"
#include "gl/stereo3d/gl_stereo3d.h"
#include "gl/textures/gl_hwtexture.h"
@ -74,6 +74,164 @@ void FGLRenderer::PostProcessScene(int fixedcm, const std::function<void()> &aft
mCustomPostProcessShaders->Run("scene");
}
void FGLRenderBuffers::RenderEffect(const FString &name)
{
// Create/update textures (To do: move out of RunEffect)
{
TMap<FString, PPTextureDesc>::Iterator it(hw_postprocess.Textures);
TMap<FString, PPTextureDesc>::Pair *pair;
while (it.NextPair(pair))
{
auto &gltexture = GLTextures[pair->Key];
auto &glframebuffer = GLTextureFBs[pair->Key];
int glformat;
switch (pair->Value.Format)
{
default:
case PixelFormat::Rgba8: glformat = GL_RGBA8; break;
case PixelFormat::Rgba16f: glformat = GL_RGBA16F; break;
}
if (gltexture && (gltexture.Width != pair->Value.Width || gltexture.Height != pair->Value.Height))
{
glDeleteTextures(1, &gltexture.handle);
glDeleteFramebuffers(1, &glframebuffer.handle);
gltexture.handle = 0;
glframebuffer.handle = 0;
}
if (!gltexture)
{
gltexture = Create2DTexture(name.GetChars(), glformat, pair->Value.Width, pair->Value.Height);
gltexture.Width = pair->Value.Width;
gltexture.Height = pair->Value.Height;
glframebuffer = CreateFrameBuffer(name.GetChars(), gltexture);
}
}
}
// Compile shaders (To do: move out of RunEffect)
{
TMap<FString, PPShader>::Iterator it(hw_postprocess.Shaders);
TMap<FString, PPShader>::Pair *pair;
while (it.NextPair(pair))
{
const auto &desc = pair->Value;
auto &glshader = GLShaders[pair->Key];
if (!glshader)
{
glshader = std::make_unique<FShaderProgram>();
FString prolog;
if (!desc.Uniforms.empty())
prolog = UniformBlockDecl::Create("Uniforms", desc.Uniforms, POSTPROCESS_BINDINGPOINT);
prolog += desc.Defines;
glshader->Compile(IShaderProgram::Vertex, desc.VertexShader, "", desc.Version);
glshader->Compile(IShaderProgram::Fragment, desc.FragmentShader, prolog, desc.Version);
glshader->Link(pair->Key.GetChars());
if (!desc.Uniforms.empty())
glshader->SetUniformBufferLocation(POSTPROCESS_BINDINGPOINT, "Uniforms");
}
}
}
// Render the effect
FGLDebug::PushGroup(name.GetChars());
FGLPostProcessState savedState;
savedState.SaveTextureBindings(3);
for (const PPStep &step : hw_postprocess.Effects[name])
{
// Bind input textures
for (unsigned int index = 0; index < step.Textures.Size(); index++)
{
const PPTextureInput &input = step.Textures[index];
int filter = (input.Filter == PPFilterMode::Nearest) ? GL_NEAREST : GL_LINEAR;
switch (input.Type)
{
default:
case PPTextureType::CurrentPipelineTexture:
BindCurrentTexture(index, filter);
break;
case PPTextureType::NextPipelineTexture:
I_FatalError("PPTextureType::NextPipelineTexture not allowed as input\n");
break;
case PPTextureType::PPTexture:
GLTextures[input.Texture].Bind(index, filter);
break;
}
}
// Set render target
switch (step.Output.Type)
{
default:
case PPTextureType::CurrentPipelineTexture:
BindCurrentFB();
break;
case PPTextureType::NextPipelineTexture:
BindNextFB();
break;
case PPTextureType::PPTexture:
GLTextureFBs[step.Output.Texture].Bind();
break;
}
// Set blend mode
if (step.BlendMode.BlendOp == STYLEOP_Add && step.BlendMode.SrcAlpha == STYLEALPHA_One && step.BlendMode.DestAlpha == STYLEALPHA_Zero && step.BlendMode.Flags == 0)
{
glDisable(GL_BLEND);
}
else
{
// To do: support all the modes
glEnable(GL_BLEND);
glBlendEquation(GL_FUNC_ADD);
if (step.BlendMode.SrcAlpha == STYLEALPHA_One && step.BlendMode.DestAlpha == STYLEALPHA_One)
glBlendFunc(GL_ONE, GL_ONE);
else
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
}
// Setup viewport
glViewport(step.Viewport.left, step.Viewport.top, step.Viewport.width, step.Viewport.height);
auto &shader = GLShaders[step.ShaderName];
// Set uniforms
if (step.Uniforms.Size > 0)
{
if (!shader->Uniforms)
shader->Uniforms.reset(screen->CreateUniformBuffer(step.Uniforms.Size));
shader->Uniforms->SetData(step.Uniforms.Data);
shader->Uniforms->Bind(POSTPROCESS_BINDINGPOINT);
}
// Set shader
shader->Bind(NOQUEUE);
// Draw the screen quad
GLRenderer->RenderScreenQuad();
// Advance to next PP texture if our output was sent there
if (step.Output.Type == PPTextureType::NextPipelineTexture)
NextTexture();
}
glViewport(screen->mScreenViewport.left, screen->mScreenViewport.top, screen->mScreenViewport.width, screen->mScreenViewport.height);
FGLDebug::PopGroup();
}
//-----------------------------------------------------------------------------
//
@ -304,6 +462,18 @@ static void RenderBlur(FGLRenderer *renderer, float blurAmount, PPTexture input,
void FGLRenderer::BloomScene(int fixedcm)
{
#if 0
if (mBuffers->GetSceneWidth() <= 0 || mBuffers->GetSceneHeight() <= 0)
return;
PPBloom bloom;
bloom.DeclareShaders();
bloom.UpdateTextures(mBuffers->GetSceneWidth(), mBuffers->GetSceneHeight());
bloom.UpdateSteps(fixedcm);
mBuffers->RenderEffect("Bloom");
#else
// Only bloom things if enabled and no special fixed light mode is active
if (!gl_bloom || fixedcm != CM_DEFAULT || gl_ssao_debug)
return;
@ -372,6 +542,7 @@ void FGLRenderer::BloomScene(int fixedcm)
glViewport(mScreenViewport.left, mScreenViewport.top, mScreenViewport.width, mScreenViewport.height);
FGLDebug::PopGroup();
#endif
}
//-----------------------------------------------------------------------------
@ -566,6 +737,14 @@ void FGLRenderer::ColormapScene(int fixedcm)
void FGLRenderer::LensDistortScene()
{
#if 1
PPLensDistort lens;
lens.DeclareShaders();
lens.UpdateSteps();
mBuffers->RenderEffect("LensDistortScene");
#else
if (gl_lens == 0)
return;
@ -610,6 +789,7 @@ void FGLRenderer::LensDistortScene()
mBuffers->NextTexture();
FGLDebug::PopGroup();
#endif
}
//-----------------------------------------------------------------------------
@ -620,6 +800,15 @@ void FGLRenderer::LensDistortScene()
void FGLRenderer::ApplyFXAA()
{
#if 1
PPFXAA fxaa;
fxaa.DeclareShaders();
fxaa.UpdateSteps();
mBuffers->RenderEffect("ApplyFXAA");
#else
if (0 == gl_fxaa)
{
return;
@ -644,6 +833,8 @@ void FGLRenderer::ApplyFXAA()
mBuffers->NextTexture();
FGLDebug::PopGroup();
#endif
}
//-----------------------------------------------------------------------------

View file

@ -2,6 +2,7 @@
#define __GL_RENDERBUFFERS_H
#include "gl/shaders/gl_shader.h"
#include "hwrenderer/postprocessing/hw_postprocess.h"
class PPTexture
{
@ -16,6 +17,11 @@ public:
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, wrap);
}
int Width = -1;
int Height = -1;
explicit operator bool() const { return handle != 0; }
private:
GLuint handle = 0;
@ -30,6 +36,8 @@ public:
glBindFramebuffer(GL_FRAMEBUFFER, handle);
}
explicit operator bool() const { return handle != 0; }
private:
GLuint handle = 0;
@ -41,6 +49,8 @@ class PPRenderBuffer
private:
GLuint handle = 0;
explicit operator bool() const { return handle != 0; }
friend class FGLRenderBuffers;
};
@ -64,6 +74,8 @@ public:
int Height = 0;
};
class FShaderProgram;
class FGLRenderBuffers
{
public:
@ -72,6 +84,12 @@ public:
bool Setup(int width, int height, int sceneWidth, int sceneHeight);
void RenderEffect(const FString &name);
TMap<PPTextureName, PPTexture> GLTextures;
TMap<PPTextureName, PPFrameBuffer> GLTextureFBs;
TMap<PPShaderName, std::shared_ptr<FShaderProgram>> GLShaders;
void BindSceneFB(bool sceneData);
void BindSceneColorTexture(int index);
void BindSceneFogTexture(int index);

View file

@ -55,8 +55,6 @@
#include "hwrenderer/postprocessing/hw_blurshader.h"
#include "hwrenderer/postprocessing/hw_tonemapshader.h"
#include "hwrenderer/postprocessing/hw_colormapshader.h"
#include "hwrenderer/postprocessing/hw_lensshader.h"
#include "hwrenderer/postprocessing/hw_fxaashader.h"
#include "hwrenderer/postprocessing/hw_presentshader.h"
#include "hwrenderer/postprocessing/hw_present3dRowshader.h"
#include "hwrenderer/postprocessing/hw_shadowmapshader.h"
@ -112,13 +110,10 @@ FGLRenderer::FGLRenderer(OpenGLFrameBuffer *fb)
mTonemapShader = nullptr;
mTonemapPalette = nullptr;
mColormapShader = nullptr;
mLensShader = nullptr;
mLinearDepthShader = nullptr;
mDepthBlurShader = nullptr;
mSSAOShader = nullptr;
mSSAOCombineShader = nullptr;
mFXAAShader = nullptr;
mFXAALumaShader = nullptr;
mShadowMapShader = nullptr;
mCustomPostProcessShaders = nullptr;
}
@ -141,9 +136,6 @@ void FGLRenderer::Initialize(int width, int height)
mTonemapShader = new FTonemapShader();
mColormapShader = new FColormapShader();
mTonemapPalette = nullptr;
mLensShader = new FLensShader();
mFXAAShader = new FFXAAShader;
mFXAALumaShader = new FFXAALumaShader;
mPresentShader = new FPresentShader();
mPresent3dCheckerShader = new FPresent3DCheckerShader();
mPresent3dColumnShader = new FPresent3DColumnShader();
@ -207,11 +199,8 @@ FGLRenderer::~FGLRenderer()
if (mTonemapShader) delete mTonemapShader;
if (mTonemapPalette) delete mTonemapPalette;
if (mColormapShader) delete mColormapShader;
if (mLensShader) delete mLensShader;
if (mShadowMapShader) delete mShadowMapShader;
delete mCustomPostProcessShaders;
delete mFXAAShader;
delete mFXAALumaShader;
}
//===========================================================================

View file

@ -37,9 +37,6 @@ class FExposureCombineShader;
class FBlurShader;
class FTonemapShader;
class FColormapShader;
class FLensShader;
class FFXAALumaShader;
class FFXAAShader;
class FPresentShader;
class FPresent3DCheckerShader;
class FPresent3DColumnShader;
@ -93,9 +90,6 @@ public:
FTonemapShader *mTonemapShader;
FColormapShader *mColormapShader;
FHardwareTexture *mTonemapPalette;
FLensShader *mLensShader;
FFXAALumaShader *mFXAALumaShader;
FFXAAShader *mFXAAShader;
FPresentShader *mPresentShader;
FPresent3DCheckerShader *mPresent3dCheckerShader;
FPresent3DColumnShader *mPresent3dColumnShader;

View file

@ -21,6 +21,8 @@ public:
GLuint Handle() { return mProgram; }
//explicit operator bool() const { return mProgram != 0; }
std::unique_ptr<IUniformBuffer> Uniforms;
private:
FShaderProgram(const FShaderProgram &) = delete;
FShaderProgram &operator=(const FShaderProgram &) = delete;

View file

@ -38,6 +38,54 @@ public:
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 (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 (const auto &field : fields)
{
decl.AppendFormat("\t%s %s;\n", GetTypeStr(field.Type), field.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
{
@ -61,25 +109,7 @@ public:
FString CreateDeclaration(const char *name, const std::vector<UniformFieldDesc> &fields)
{
mFields = fields;
FString decl;
FString layout;
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 (const auto &field : fields)
{
decl.AppendFormat("\t%s %s;\n", GetTypeStr(field.Type), field.Name);
}
decl += "};\n";
return decl;
return UniformBlockDecl::Create(name, fields, bindingpoint);
}
void Init()
@ -107,27 +137,6 @@ private:
ShaderUniforms(const ShaderUniforms &) = delete;
ShaderUniforms &operator=(const ShaderUniforms &) = delete;
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";
}
}
IUniformBuffer *mBuffer = nullptr;
std::vector<UniformFieldDesc> mFields;
};

View file

@ -1,95 +0,0 @@
//
//---------------------------------------------------------------------------
//
// Copyright(C) 2016 Alexey Lysiuk
// All rights reserved.
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU Lesser General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU Lesser General Public License for more details.
//
// You should have received a copy of the GNU Lesser General Public License
// along with this program. If not, see http://www.gnu.org/licenses/
//
//--------------------------------------------------------------------------
//
//
// Fast approXimate Anti-Aliasing (FXAA) post-processing
//
#include "hw_fxaashader.h"
EXTERN_CVAR(Int, gl_fxaa)
void FFXAALumaShader::Bind(IRenderQueue *q)
{
if (!mShader)
{
mShader.reset(screen->CreateShaderProgram());
mShader->Compile(IShaderProgram::Vertex, "shaders/glsl/screenquad.vp", "", 330);
mShader->Compile(IShaderProgram::Fragment, "shaders/glsl/fxaa.fp", "#define FXAA_LUMA_PASS\n", 330);
mShader->Link("shaders/glsl/fxaa");
}
mShader->Bind(q);
}
static int GetMaxVersion()
{
return screen->glslversion >= 4.f ? 400 : 330;
}
static FString GetDefines()
{
int quality;
switch (gl_fxaa)
{
default:
case FFXAAShader::Low: quality = 10; break;
case FFXAAShader::Medium: quality = 12; break;
case FFXAAShader::High: quality = 29; break;
case FFXAAShader::Extreme: quality = 39; break;
}
const int gatherAlpha = GetMaxVersion() >= 400 ? 1 : 0;
// TODO: enable FXAA_GATHER4_ALPHA on OpenGL earlier than 4.0
// when GL_ARB_gpu_shader5/GL_NV_gpu_shader5 extensions are supported
FString result;
result.Format(
"#define FXAA_QUALITY__PRESET %i\n"
"#define FXAA_GATHER4_ALPHA %i\n",
quality, gatherAlpha);
return result;
}
void FFXAAShader::Bind(IRenderQueue *q)
{
assert(gl_fxaa > 0 && gl_fxaa < Count);
auto &shader = mShaders[gl_fxaa];
if (!shader)
{
FString prolog = Uniforms.CreateDeclaration("Uniforms", UniformBlock::Desc()) + GetDefines();
const int maxVersion = GetMaxVersion();
shader.reset(screen->CreateShaderProgram());
shader->Compile(IShaderProgram::Vertex, "shaders/glsl/screenquad.vp", "", maxVersion);
shader->Compile(IShaderProgram::Fragment, "shaders/glsl/fxaa.fp", prolog, maxVersion);
shader->Link("shaders/glsl/fxaa");
shader->SetUniformBufferLocation(Uniforms.BindingPoint(), "Uniforms");
Uniforms.Init();
}
shader->Bind(q);
}

View file

@ -1,70 +0,0 @@
//
//---------------------------------------------------------------------------
//
// Copyright(C) 2016 Alexey Lysiuk
// All rights reserved.
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU Lesser General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU Lesser General Public License for more details.
//
// You should have received a copy of the GNU Lesser General Public License
// along with this program. If not, see http://www.gnu.org/licenses/
//
//--------------------------------------------------------------------------
//
//
// Fast approXimate Anti-Aliasing (FXAA) post-processing
//
#ifndef __GL_FXAASHADER_H__
#define __GL_FXAASHADER_H__
#include "hwrenderer/postprocessing/hw_shaderprogram.h"
#include "hwrenderer/postprocessing/hw_postprocess_cvars.h"
class FFXAALumaShader
{
public:
void Bind(IRenderQueue *q);
private:
std::unique_ptr<IShaderProgram> mShader;
};
class FFXAAShader : public IFXAAShader
{
public:
void Bind(IRenderQueue *q);
struct UniformBlock
{
FVector2 ReciprocalResolution;
float Padding0, Padding1;
static std::vector<UniformFieldDesc> Desc()
{
return
{
{ "ReciprocalResolution", UniformType::Vec2, offsetof(UniformBlock, ReciprocalResolution) },
{ "Padding0", UniformType::Float, offsetof(UniformBlock, Padding0) },
{ "Padding1", UniformType::Float, offsetof(UniformBlock, Padding1) }
};
}
};
ShaderUniforms<UniformBlock, POSTPROCESS_BINDINGPOINT> Uniforms;
private:
std::unique_ptr<IShaderProgram> mShaders[Count];
};
#endif // __GL_FXAASHADER_H__

View file

@ -1,45 +0,0 @@
//
//---------------------------------------------------------------------------
//
// Copyright(C) 2016 Magnus Norddahl
// All rights reserved.
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU Lesser General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU Lesser General Public License for more details.
//
// You should have received a copy of the GNU Lesser General Public License
// along with this program. If not, see http://www.gnu.org/licenses/
//
//--------------------------------------------------------------------------
//
/*
** gl_lensshader.cpp
** Lens distortion with chromatic aberration shader
**
*/
#include "v_video.h"
#include "hw_lensshader.h"
void FLensShader::Bind(IRenderQueue *q)
{
if (!mShader)
{
FString prolog = Uniforms.CreateDeclaration("Uniforms", UniformBlock::Desc());
mShader.reset(screen->CreateShaderProgram());
mShader->Compile(IShaderProgram::Vertex, "shaders/glsl/screenquad.vp", "", 330);
mShader->Compile(IShaderProgram::Fragment, "shaders/glsl/lensdistortion.fp", prolog, 330);
mShader->Link("shaders/glsl/lensdistortion");
mShader->SetUniformBufferLocation(Uniforms.BindingPoint(), "Uniforms");
Uniforms.Init();
}
mShader->Bind(q);
}

View file

@ -1,39 +0,0 @@
#ifndef __GL_LENSSHADER_H
#define __GL_LENSSHADER_H
#include "hwrenderer/postprocessing/hw_shaderprogram.h"
class FLensShader
{
public:
void Bind(IRenderQueue *q);
struct UniformBlock
{
float AspectRatio;
float Scale;
float Padding0, Padding1;
FVector4 LensDistortionCoefficient;
FVector4 CubicDistortionValue;
static std::vector<UniformFieldDesc> Desc()
{
return
{
{ "Aspect", UniformType::Float, offsetof(UniformBlock, AspectRatio) },
{ "Scale", UniformType::Float, offsetof(UniformBlock, Scale) },
{ "Padding0", UniformType::Float, offsetof(UniformBlock, Padding0) },
{ "Padding1", UniformType::Float, offsetof(UniformBlock, Padding1) },
{ "k", UniformType::Vec4, offsetof(UniformBlock, LensDistortionCoefficient) },
{ "kcube", UniformType::Vec4, offsetof(UniformBlock, CubicDistortionValue) }
};
}
};
ShaderUniforms<UniformBlock, POSTPROCESS_BINDINGPOINT> Uniforms;
private:
std::unique_ptr<IShaderProgram> mShader;
};
#endif

View file

@ -25,19 +25,17 @@ void PPBloom::UpdateTextures(int width, int height)
for (int i = 0; i < NumBloomLevels; i++)
{
FString vtexture, htexture;
vtexture.Format("Bloom.VTexture.%d", i);
htexture.Format("Bloom.HTexture.%d", i);
auto &level = levels[i];
level.VTexture.Format("Bloom.VTexture.%d", i);
level.HTexture.Format("Bloom.HTexture.%d", i);
level.Viewport.left = 0;
level.Viewport.top = 0;
level.Viewport.width = (bloomWidth + 1) / 2;
level.Viewport.height = (bloomHeight + 1) / 2;
PPTextureDesc texture = { level.Viewport.width, level.Viewport.height, PixelFormat::Rgba16f };
hw_postprocess.Textures[vtexture] = texture;
hw_postprocess.Textures[htexture] = texture;
hw_postprocess.Textures[level.VTexture] = texture;
hw_postprocess.Textures[level.HTexture] = texture;
bloomWidth = level.Viewport.width;
bloomHeight = level.Viewport.height;
@ -65,6 +63,7 @@ void PPBloom::UpdateSteps(int fixedcm)
// Extract blooming pixels from scene texture:
step.Viewport = level0.Viewport;
step.SetInputCurrent(0, PPFilterMode::Linear);
step.SetInputTexture(1, "ExposureTexture");
step.ShaderName = "BloomExtract";
step.Uniforms.Set(extractUniforms);
step.SetOutputTexture(level0.VTexture);

View file

@ -78,7 +78,7 @@ public:
Data = nullptr;
Size = 0;
Data = new uint8_t[Size];
Data = new uint8_t[sizeof(T)];
Size = sizeof(T);
memcpy(Data, &v, Size);
}
@ -93,7 +93,7 @@ class PPStep
public:
void SetInputTexture(int index, PPTextureName texture, PPFilterMode filter = PPFilterMode::Nearest)
{
if ((int)Textures.Size() < index)
if ((int)Textures.Size() < index + 1)
Textures.Resize(index + 1);
auto &tex = Textures[index];
tex.Filter = filter;
@ -103,7 +103,7 @@ public:
void SetInputCurrent(int index, PPFilterMode filter = PPFilterMode::Nearest)
{
if ((int)Textures.Size() < index)
if ((int)Textures.Size() < index + 1)
Textures.Resize(index + 1);
auto &tex = Textures[index];
tex.Filter = filter;