Cogs.Core
TransparencyMergeTask.cpp
1#include "TransparencyMergeTask.h"
2
3#include "Rendering/IGraphicsDevice.h"
4#include "Rendering/IBuffers.h"
5#include "Rendering/IEffects.h"
6#include "Rendering/IContext.h"
7
8#include "Renderer/Renderer.h"
9#include "Renderer/RenderBuffer.h"
10#include "Renderer/RenderTarget.h"
11#include "Renderer/RenderStateUpdater.h"
12
13#include "Resources/VertexFormats.h"
14
15#include "Context.h"
16
17#include "Services/Variables.h"
18
19#include "Systems/Core/CameraSystem.h"
20#include "Systems/Core/LightSystem.h"
21#include "Systems/Core/EnvironmentSystem.h"
22
23#include "DeferredLightingTask.h"
24
25#include "Foundation/Logging/Logger.h"
26
27#include <cassert>
28
29using namespace Cogs;
30
31namespace
32{
33 struct MergeParameters
34 {
35 uint32_t alloc;
36 uint32_t width;
37 uint32_t WidthDivisor;
38 uint32_t HeightDivisor;
39 float beersScaleFactor;
40 };
41
42 Cogs::Logging::Log logger = Cogs::Logging::getLogger("TransparencyMergeTask");
43}
44
46{
47 IGraphicsDevice* device = context->renderer->getDevice();
48 IBuffers* buffers = device->getBuffers();
49
50 EffectDescription desc = {};
51 desc.vs = "Engine/FullscreenV3T2VS.hlsl";
52
53 const char * pixelShaders[] = {
54 "Engine/TransparencyBlendAlphaPS.hlsl",
55 "Engine/TransparencyBlendMaxPS.hlsl",
56 "Engine/TransparencyBlendMax2PS.hlsl",
57 "Engine/TransparencyBlendDepthWeightedPS.hlsl",
58 "Engine/TransparencyBlendBeersPS.hlsl"
59 };
60
61 desc.ps = pixelShaders[(int)context->renderer->getSettings().blendKernel];
62
63 desc.definitions.push_back({ "COGS_FORWARD_SHADOWS_ENABLED", "1" });
64 desc.definitions.push_back({ "COGS_NUM_DIRECTIONAL_SHADOW_LIGHTS", std::to_string(context->renderer->getActiveLights().numDirectionalShadowLights) });
65 desc.definitions.push_back({ "COGS_NUM_DIRECTIONAL_LIGHTS", std::to_string(context->renderer->getActiveLights().numDirectionalLights) });
66 desc.definitions.push_back({ "COGS_NUM_POINT_SHADOW_LIGHTS", std::to_string(context->renderer->getActiveLights().numPointShadowLights) });
67 desc.definitions.push_back({ "COGS_NUM_POINT_LIGHTS", std::to_string(context->renderer->getActiveLights().numPointLights) });
68
69 desc.definitions.push_back({ "COGS_DISABLE_DIRECTIONAL_SHADOWS", "1" });
70
71 if(context->context->variables->get("renderer.reverseDepth", false)){
72 desc.definitions.push_back({ "COGS_REVERSE_DEPTH", "1" });
73 }
74
75 if (auto ec = context->context->environmentSystem->getGlobalEnvironment(); ec != nullptr) {
76 if (ec->subseaSupport) {
77 desc.definitions.push_back({ "COGS_SUBSEA_SUPPORT", "1" });
78 }
79 if (ec->imageBasedLighting) {
80 desc.definitions.push_back({ "COGS_IMAGE_BASED_LIGHTING", "1" });
81 }
82 }
83 effect = context->renderer->getEffectCache().loadEffect(context, desc);
84
85 IEffects* effects = device->getEffects();
86 Cogs::ResourceStatus status = HandleIsValid(effect->handle) ? effects->checkEffect(effect->handle) : Cogs::ResourceStatus::Error;
87
88 if (status == Cogs::ResourceStatus::Ready && (effectPrev != effect || effectStatus != Cogs::ResourceStatus::Ready)) {
89 if (HandleIsValid(parameterHandle)) {
90 buffers->releaseBuffer(parameterHandle);
91 }
92 parameterHandle = device->getBuffers()->loadBuffer(nullptr, sizeof(MergeParameters), Usage::Dynamic, AccessMode::Write, BindFlags::ConstantBuffer);
93 buffers->annotate(parameterHandle, "MergeParameters");
94 DeferredLightingTask::initializeGlobalBindings(context, effect, bindings);
95 }
96
97 if (status == Cogs::ResourceStatus::Error && effectStatus != Cogs::ResourceStatus::Error) {
98 LOG_ERROR(logger, "Invalid transparency merge effect handle.");
99 }
100
101 effectPrev = effect;
102 effectStatus = status;
103 return effectStatus;
104}
105
106void Cogs::Core::TransparencyMergeTask::cleanup(RenderTaskContext * context)
107{
108 auto device = context->renderer->getDevice();
109 auto buffers = device->getBuffers();
110 context->renderer->getEffectCache().release(context, effect);
111 if (HandleIsValid(parameterHandle)) {
112 buffers->releaseBuffer(parameterHandle);
113 }
114}
115
116void Cogs::Core::TransparencyMergeTask::apply(RenderTaskContext * taskContext)
117{
118 RenderInstrumentationScope(taskContext->device->getImmediateContext(), SCOPE_RENDERING, "TransparencyMergeTask::apply");
119
120 assert(effectStatus == Cogs::ResourceStatus::Ready);
121
122 RenderTarget* deferredRenderTarget = input.get(RenderResourceType::RenderTarget)->renderTarget;
123 RenderTarget* renderTarget = output.get(RenderResourceType::RenderTarget)->renderTarget;
124
125 RenderBuffer* listTarget = input.get("ListBuffer")->renderBuffer;
126 RenderBuffer* nodeTarget = input.get("NodeBuffer")->renderBuffer;
127 RenderBuffer* dataTarget = input.get("DataBuffer")->renderBuffer;
128
129 IGraphicsDevice* device = taskContext->renderer->getDevice();
130 IContext* deviceContext = device->getImmediateContext();
131
132 deviceContext->setEffect(effect->handle);
133
134 deviceContext->setRenderTarget(renderTarget->renderTargetHandle, renderTarget->depthTargetHandle);
135
136 if (clear) {
137 deviceContext->clearRenderTarget(glm::value_ptr(renderTarget->getClearColor()));
138 deviceContext->clearDepth(taskContext->context->renderer->getClearDepth());
139 }
140
141 deviceContext->setViewport(0, 0, static_cast<float>(renderTarget->width), static_cast<float>(renderTarget->height));
142
143 deviceContext->setDepthStencilState(taskContext->states->commonDepthStates[RenderStates::noTestDepthStencilState]);
144 deviceContext->setRasterizerState(taskContext->states->defaultRasterizerStateHandle);
145
146 if(deferredRenderTarget->textures.size())
147 deviceContext->setTexture("colorTexture", 0, deferredRenderTarget->textures[0]->textureHandle);
148 deviceContext->setTexture("depthTexture", 1, deferredRenderTarget->depth->textureHandle);
149
150 DeferredLightingTask::applyGlobalBindings(taskContext, bindings);
151
152 uint32_t widthDivisor = 1;//taskContext->context->variables->get("renderer.oit.UpscaleWidth", 1);
153 uint32_t heightDivisor = 1;//taskContext->context->variables->get("renderer.oit.UpscaleHeight", 1);
154
155 {
156 MappedBuffer<MergeParameters> parameters(deviceContext, parameterHandle, MapMode::WriteDiscard);
157
158 if (parameters) {
159 parameters->alloc = static_cast<int>(nodeTarget->bufferSize);
160 parameters->width = renderTarget->width/widthDivisor;
161 parameters->WidthDivisor = widthDivisor;
162 parameters->HeightDivisor = heightDivisor;
163 parameters->beersScaleFactor = taskContext->renderer->getSettings().beersScaleFactor;
164 }
165 }
166
167 deviceContext->setConstantBuffer("TransparencyParameters", parameterHandle);
168
169 deviceContext->setBuffer("List", listTarget->buffer);
170 deviceContext->setBuffer("Node", nodeTarget->buffer);
171 deviceContext->setBuffer("Data", dataTarget->buffer);
172
173 deviceContext->setVertexBuffers(nullptr, 0, nullptr, nullptr);
176 deviceContext->draw(PrimitiveType::TriangleList, 0, 3);
177}
std::unique_ptr< class Variables > variables
Variables service instance.
Definition: Context.h:180
ActiveLights & getActiveLights() override
Get the reference to the ActiveLights structure.
Definition: Renderer.h:74
IGraphicsDevice * getDevice() override
Get the graphics device used by the renderer.
Definition: Renderer.h:46
const RenderSettings & getSettings() const override
Get the settings of the renderer.
Definition: Renderer.h:47
EffectCache & getEffectCache() override
Get the reference to the EffectCache structure.
Definition: Renderer.h:72
Represents a graphics device used to manage graphics resources and issue drawing commands.
virtual IEffects * getEffects()=0
Get a pointer to the effect management interface.
virtual IContext * getImmediateContext()=0
Get a pointer to the immediate context used to issue commands to the graphics device.
virtual IBuffers * getBuffers()=0
Get a pointer to the buffer management interface.
Log implementation class.
Definition: LogManager.h:140
bool HandleIsValid(const ResourceHandle_t< T > &handle)
Check if the given resource is valid, that is not equal to NoHandle or InvalidHandle.
constexpr Log getLogger(const char(&name)[LEN]) noexcept
Definition: LogManager.h:181
Contains all Cogs related functionality.
Definition: FieldSetter.h:23
ResourceStatus
Status of an asynchronously loaded resource, such as an effect or a pipeline.
Definition: Common.h:198
@ Error
The resource failed to load.
@ Ready
The resource has loaded successfully and is ready for use.
@ TriangleList
List of triangles.
@ Write
The buffer can be mapped and written to by the CPU after creation.
Definition: Flags.h:50
@ ConstantBuffer
The buffer can be bound as input to effects as a constant buffer.
Definition: Flags.h:72
Cogs::ResourceStatus checkReady(RenderTaskContext *context) override
Check if the task is ready to be applied, e.g.
static const Handle_t NoHandle
Represents a handle to nothing.
Definition: Common.h:78
Provides buffer management functionality.
Definition: IBuffers.h:13
virtual void annotate(BufferHandle handle, const StringView &name)
Associate a name with an object for use in graphics debugging.
Definition: IBuffers.h:17
virtual BufferHandle loadBuffer(const void *data, const size_t size, Usage::EUsage usage, uint32_t accessMode, uint32_t bindFlags, uint32_t stride=0)=0
Loads a new buffer using the given data to populate the buffer.
virtual void releaseBuffer(BufferHandle bufferHandle)=0
Releases the buffer with the given bufferHandle.
Represents a graphics device context which can receive rendering commands.
Definition: IContext.h:43
virtual void setTexture(const StringView &name, unsigned int unit, TextureHandle textureHandle)=0
Sets the texture slot given by unit with the given name to contain the given texture.
virtual void setRasterizerState(const RasterizerStateHandle handle)=0
Set the current rasterizer state.
virtual void setInputLayout(const InputLayoutHandle inputLayoutHandle)=0
Sets the current input layout.
virtual void clearRenderTarget(const float *value)=0
Clear the currently set render target to the given value (4 component floating point RGBA).
virtual void setIndexBuffer(IndexBufferHandle bufferHandle, uint32_t stride=4, uint32_t offset=0)=0
Sets the current index buffer.
virtual void setDepthStencilState(const DepthStencilStateHandle handle)=0
Set the current depth stencil state.
virtual void clearDepth(const float depth=1.0f)=0
Clear the currently set depth/stencil target to the given depth.
virtual void setConstantBuffer(const StringView &name, const BufferHandle bufferHandle, const uint32_t offset=0, const uint32_t size=~0u)=0
Sets a constant buffer to be bound to the given name and slot.
virtual void setViewport(const float x, const float y, const float width, const float height)=0
Sets the current viewport to the given location and dimensions.
virtual void setBuffer(const StringView &name, BufferHandle bufferHandle)=0
Sets the given buffer to the buffer binding slot with the given name.
virtual void draw(PrimitiveType primitiveType, const size_t startVertex, const size_t numVertexes)=0
Draws non-indexed, non-instanced primitives.
virtual void setVertexBuffers(const VertexBufferHandle *vertexBufferHandles, const size_t count, const uint32_t *strides, const uint32_t *offsets)=0
Sets the current vertex buffers.
virtual void setEffect(EffectHandle handle)=0
Set the current effect.
virtual void setRenderTarget(const RenderTargetHandle handle, const DepthStencilHandle depthStencilHandle)=0
Sets the current render target and an associated depth stencil target.
Provides effects and shader management functionality.
Definition: IEffects.h:158
virtual ResourceStatus checkEffect(EffectHandle effectHandle)=0
Check the load status of the effect with the given effectHandle.
@ WriteDiscard
Write access. When unmapping the graphics system will discard the old contents of the resource.
Definition: Flags.h:103
Provides RAII style mapping of a buffer resource.
Definition: IBuffers.h:160
@ Dynamic
Buffer will be loaded and modified with some frequency.
Definition: Flags.h:30