Cogs.Core
ProcessTask.cpp
1#include "ProcessTask.h"
2
3#include "Rendering/IContext.h"
4
5#include "Foundation/Logging/Logger.h"
6
7#include "Context.h"
8
9#include "Renderer/Renderer.h"
10#include "Renderer/RenderBuffer.h"
11#include "Renderer/RenderTexture.h"
12#include "Renderer/RenderTarget.h"
13#include "Renderer/RenderList.h"
14#include "Resources/BasicBlueNoiseManager.h"
15#include "Services/Variables.h"
16#include "Systems/Core/EnvironmentSystem.h"
17#include "Systems/Appearance/BasicOceanSystem.h"
18#include "Utilities/ValueVariant.h"
19
20namespace
21{
22 Cogs::Logging::Log logger = Cogs::Logging::getLogger("ProcessTask");
23}
24
25Cogs::Core::EffectDescription Cogs::Core::ProcessTask::createEffectDesc(RenderTaskContext* context)
26{
27 const RenderSettings& renderSettings = context->renderer->getSettings();
28
29 EffectDescription desc{};
30
31 if (context->context->variables->get("renderer.reverseDepth", false)) {
32 desc.definitions.push_back({ "COGS_REVERSE_DEPTH", "1" });
33 }
34
35 // See Default.permutations for defines.
36 switch (renderSettings.sRGBConversion) {
37 case RenderSettings::SRGBConversion::Fast:
38 desc.definitions.push_back({ "COGS_SRGB_CONVERSION_FAST", "1" });
39 break;
40 case RenderSettings::SRGBConversion::Approx:
41 desc.definitions.push_back({ "COGS_SRGB_CONVERSION_APPROX", "1" });
42 break;
43 case RenderSettings::SRGBConversion::Exact:
44 desc.definitions.push_back({ "COGS_SRGB_CONVERSION_EXACT", "1" });
45 break;
46 default:
47 assert(false && "Invalid enum");
48 break;
49 }
50
51 // See Default.permutations for defines.
52 switch (renderSettings.tonemapper) {
53 case RenderSettings::Tonemapper::Reinhard:
54 desc.definitions.push_back({ "COGS_TONEMAP_REINHARD", "1" });
55 break;
56 case RenderSettings::Tonemapper::Filmic:
57 desc.definitions.push_back({ "COGS_TONEMAP_FILMIC", "1" });
58 break;
59 case RenderSettings::Tonemapper::ACESLuminance:
60 desc.definitions.push_back({ "COGS_TONEMAP_ACES_LUMINANCE", "1" });
61 break;
62 case RenderSettings::Tonemapper::PBRNeutral:
63 desc.definitions.push_back({ "COGS_TONEMAP_PBR_NEUTRAL", "1" });
64 break;
65 default:
66 assert(false && "Invalid enum");
67 break;
68 }
69
70 return desc;
71}
72
73
74void Cogs::Core::ProcessTask::cleanup(RenderTaskContext * context)
75{
76 if (effect) context->renderer->getEffectCache().release(context, effect);
77 for (auto & prop : properties) {
78 //for (auto & p : prop.expressions) {
79 // //delete p.second;
80 //}
81 prop.expressions.clear();
82 }
83}
84
85void Cogs::Core::ProcessTask::setProperties(RenderTaskContext * renderTaskContext, Cogs::Core::RenderTexture* targetSource)
86{
87 texUnit = 0;
88 auto * context = renderTaskContext->context;
89 auto * deviceContext = renderTaskContext->device->getImmediateContext();
90
91 deviceContext->setBlendState(renderTaskContext->states->blendStates[size_t(blendMode)].handle);
92
93 //auto * scope = renderTaskContext->expressionContext;
94 assert(scope);
95
96 //if (this->scope != nullptr) {
97 // scope = this->scope;
98 // for (auto & v : renderTaskContext->expressionContext->values) {
99 // scope->add(v.name, v.value);
100 // }
101
102 // for (auto & p : useVariables) {
103 // scope->add(p.first, context->variables->get(p.second)->get<double>());
104 // }
105 //}
106
107 for (auto & p : properties) {
108
109 switch (p.definition->type) {
110 case ParsedDataType::Float:
111 case ParsedDataType::Float2:
112 case ParsedDataType::Float3:
113 case ParsedDataType::Float4:
114 case ParsedDataType::Float4x4:
115 for (auto & q : p.expressions) {
116 (&p.floatValue)[q.first] = scope->update(q.second, (&p.definition->floatValue)[q.first]);
117 }
118 break;
119 case ParsedDataType::Int:
120 case ParsedDataType::Int2:
121 case ParsedDataType::Int3:
122 case ParsedDataType::Int4:
123 case ParsedDataType::UInt:
124 case ParsedDataType::UInt2:
125 case ParsedDataType::UInt3:
126 case ParsedDataType::UInt4:
127 for (auto & q : p.expressions) {
128 (&p.intValue)[q.first] = scope->update(q.second, (&p.definition->intValue)[q.first]);
129 }
130 break;
131 default:
132 break;
133 }
134 }
135
136 auto basicOceanSystem = context->basicOceanSystem;
137 if (basicOceanSystem && !basicOceanSystem->pool.size()) {
138 basicOceanSystem = nullptr;
139 }
140
141 auto renderList = input.get(RenderResourceType::RenderList);
142 const EnvironmentComponent * envComp = nullptr;
143 if (renderList) {
144 envComp = renderList->renderList->viewportData->environment.resolveComponent<EnvironmentComponent>();
145 }
146
147 auto binding = renderTaskContext->device->getEffects()->getTextureBinding(effect->handle, "blueNoise_LDR_RGBA", 0);
148 if(HandleIsValid(binding)){
149 auto& blueNoiseManager = renderTaskContext->context->blueNoiseManager;
150 blueNoiseManager->enable();
151 TextureHandle blueNoise = blueNoiseManager->getBlueNoiseHandle(false)->texture;
152 RenderTexture * blueNoiseTexture = renderTaskContext->renderer->getRenderResources().getRenderTexture(blueNoise);
153 if (blueNoiseTexture) {
154 deviceContext->setTexture(binding, blueNoiseTexture->textureHandle);
155 }
156 }
157
158 {
159 {
160 for (auto & p : properties) {
161 bool setSampler = true;
162 switch (p.definition->type)
163 {
164 case ParsedDataType::Texture2D:
165 {
166 switch (p.definition->valueHash)
167 {
168 case Cogs::hash("Cogs.EnvironmentRadiance.NoSampler"):
169 setSampler = false;
170 case Cogs::hash("Cogs.EnvironmentRadiance"):
171 case Cogs::hash("Cogs.EnvironmentRadiance.SetSampler"):
172 if (envComp && HandleIsValid(envComp->radiance)) {
173 RenderTexture * tex = renderTaskContext->renderer->getRenderResources().getRenderTexture(envComp->radiance);
174 if (tex) {
175 deviceContext->setTexture(p.definition->key, texUnit, tex->textureHandle);
176 if (setSampler) {
177 deviceContext->setSamplerState(p.definition->key + "Sampler", texUnit, renderTaskContext->states->getSamplerState(SamplerState::DefaultState()));
178 }
179 }
180 }
181 break;
182
183 case Cogs::hash("Cogs.SubseaRadiance.NoSampler"):
184 setSampler = false;
185 case Cogs::hash("Cogs.SubseaRadiance"):
186 case Cogs::hash("Cogs.SubseaRadiance.SetSampler"):
187 if (envComp && HandleIsValid(envComp->subseaRadiance)) {
188 RenderTexture * tex = renderTaskContext->renderer->getRenderResources().getRenderTexture(envComp->subseaRadiance);
189 if (tex) {
190 deviceContext->setTexture(p.definition->key, texUnit, tex->textureHandle);
191 if (setSampler) {
192 deviceContext->setSamplerState(p.definition->key + "Sampler", texUnit, renderTaskContext->states->getSamplerState(SamplerState::DefaultState()));
193 }
194 }
195 }
196 break;
197
198 case Cogs::hash("Cogs.BasicOceanSystem.Real"):
199 if (basicOceanSystem) {
200 RenderTexture * tex = renderTaskContext->renderer->getRenderResources().getRenderTexture(basicOceanSystem->getRealTex());
201 if (tex) {
202 deviceContext->setTexture(p.definition->key, texUnit, tex->textureHandle);
203 deviceContext->setSamplerState(p.definition->key + "Sampler", texUnit, renderTaskContext->states->getSamplerState(SamplerState::DefaultState()));
204 texUnit++;
205 }
206 }
207 break;
208 case Cogs::hash("Cogs.BasicOceanSystem.Imag"):
209 if (basicOceanSystem) {
210 RenderTexture * tex = renderTaskContext->renderer->getRenderResources().getRenderTexture(basicOceanSystem->getImagTex());
211 if (tex) {
212 deviceContext->setTexture(p.definition->key, texUnit, tex->textureHandle);
213 deviceContext->setSamplerState(p.definition->key + "Sampler", texUnit, renderTaskContext->states->getSamplerState(SamplerState::DefaultState()));
214 texUnit++;
215 }
216 }
217 break;
218 case Cogs::hash("Cogs.BasicOceanSystem.Tangent"):
219 if (basicOceanSystem) {
220 RenderTexture * tex = renderTaskContext->renderer->getRenderResources().getRenderTexture(basicOceanSystem->getTangentTex());
221 if (tex) {
222 deviceContext->setTexture(p.definition->key, texUnit, tex->textureHandle);
223 deviceContext->setSamplerState(p.definition->key + "Sampler", texUnit, renderTaskContext->states->getSamplerState(SamplerState::DefaultState()));
224 texUnit++;
225 }
226 }
227 break;
228 default:
229 auto inputSource = input.get(p.definition->value);
230
231 RenderTexture* tex = nullptr;
232 if (inputSource->type == RenderResourceType::RenderTexture) {
233 tex = inputSource->renderTexure;
234 } else if (inputSource->type == RenderResourceType::RenderTarget) {
235 tex = inputSource->renderTarget->textures[0];
236 }
237
238 if (tex == nullptr) {
239 // report error
240 }
241 else if (tex == targetSource) {
242 // ignore
243 }
244 else {
245 deviceContext->setTexture(p.definition->key, texUnit, tex->textureHandle);
246 deviceContext->setSamplerState(p.texture.samplerName, texUnit, p.texture.samplerState);
247 texUnit++;
248 }
249 }
250 }
251 break;
252 case ParsedDataType::Buffer:
253 {
254 auto inputSource = input.get(p.definition->value);
255
256 if (!inputSource) {
257 auto outputSource = output.get(p.definition->value);
258
259 deviceContext->setBuffer(p.definition->key, outputSource->renderBuffer->buffer);
260 } else {
261 deviceContext->setBuffer(p.definition->key, inputSource->renderBuffer->buffer);
262 }
263 }
264 break;
265 case ParsedDataType::ConstantBuffer:
266 switch (StringView(p.definition->value).hash()) {
267 case Cogs::hash("Cogs.SceneBuffer"):
268 deviceContext->setConstantBuffer(p.definition->key, renderTaskContext->engineBuffers->sceneBufferHandle);
269 break;
270 case Cogs::hash("Cogs.LightBuffer"):
271 deviceContext->setConstantBuffer(p.definition->key, renderTaskContext->engineBuffers->lightBufferHandle);
272 break;
273 }
274 break;
275 case ParsedDataType::Float4x4:
276 switch (StringView(p.definition->value).hash())
277 {
278 case Cogs::hash("inverseViewMatrix"):
279 if (renderList && renderList->renderList->viewportData) {
280 deviceContext->setMatrixVariable(p.definition->key, glm::value_ptr(renderList->renderList->viewportData->inverseViewMatrix));
281 }
282 break;
283 case Cogs::hash("inverseProjectionMatrix"):
284 if (renderList && renderList->renderList->viewportData) {
285 deviceContext->setMatrixVariable(p.definition->key, glm::value_ptr(renderList->renderList->viewportData->inverseProjectionMatrix));
286 }
287 break;
288 case Cogs::hash("projectionMatrix"):
289 if (renderList && renderList->renderList->viewportData) {
290 deviceContext->setMatrixVariable(p.definition->key, glm::value_ptr(renderList->renderList->viewportData->projectionMatrix));
291 }
292 break;
293 case Cogs::hash("inverseViewProjectionMatrix"):
294 if (renderList && renderList->renderList->viewportData) {
295 deviceContext->setMatrixVariable(p.definition->key, glm::value_ptr(renderList->renderList->viewportData->inverseViewProjectionMatrix));
296 }
297 break;
298 default:
299 deviceContext->setMatrixVariable(p.definition->key, glm::value_ptr(p.float4x4Value));
300 break;
301 }
302 break;
303 case ParsedDataType::Float:
304 switch (p.definition->valueHash)
305 {
306 case Cogs::hash("Cogs.BasicOceanSystem.SignificantWaveHeight"):
307 deviceContext->setScalarVariable(p.definition->key, context->basicOceanSystem->getSignificantWaveHeight());
308 break;
309 case Cogs::hash("Cogs.BasicOceanSystem.TileScale"):
310 deviceContext->setScalarVariable(p.definition->key, context->basicOceanSystem->getTileScale());
311 break;
312 case Cogs::hash("exposure"):
313 if (renderList && renderList->renderList->viewportData) {
314 deviceContext->setScalarVariable(p.definition->key, renderList->renderList->viewportData->exposure);
315 }
316 break;
317 default:
318 deviceContext->setScalarVariable(p.definition->key, p.floatValue);
319 break;
320 }
321 break;
322 case ParsedDataType::Float2:
323 switch (p.definition->valueHash)
324 {
325 case Cogs::hash("viewportSize"):
326 if (renderList && renderList->renderList->viewportData) {
327 deviceContext->setVector2Variable(p.definition->key, glm::value_ptr(renderList->renderList->viewportData->viewportSize));
328 }
329 break;
330 case Cogs::hash("viewportSizeReciprocal"):
331 if (renderList && renderList->renderList->viewportData) {
332 const glm::vec2 viewSizeRcp = 1.f / renderList->renderList->viewportData->viewportSize;
333 deviceContext->setVector2Variable(p.definition->key, glm::value_ptr(viewSizeRcp));
334 }
335 break;
336 default:
337 deviceContext->setVector2Variable(p.definition->key, glm::value_ptr(p.float2Value));
338 }
339 break;
340 case ParsedDataType::Float3:
341 deviceContext->setVector3Variable(p.definition->key, glm::value_ptr(p.float3Value));
342 break;
343 case ParsedDataType::Float4:
344 deviceContext->setVector4Variable(p.definition->key, glm::value_ptr(p.float4Value));
345 break;
346 case ParsedDataType::UInt:
347 deviceContext->setScalarVariable(p.definition->key, (int)p.uintValue);
348 break;
349 case ParsedDataType::Int:
350 deviceContext->setScalarVariable(p.definition->key, p.intValue);
351 break;
352 default:
353 break;
354 }
355 }
356 }
357 }
358}
Log implementation class.
Definition: LogManager.h:139
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:180
Contains all Cogs related functionality.
Definition: FieldSetter.h:23
constexpr size_t hash() noexcept
Simple getter function that returns the initial value for fnv1a hashing.
Definition: HashFunctions.h:62