Cogs.Core
RenderStateUpdater.cpp
1#include "Foundation/Logging/Logger.h"
2
3#include "Rendering/IBindGroups.h"
4#include "Rendering/ICapabilities.h"
5
6#include "Context.h"
7
8#include "Systems/Core/LightSystem.h"
9#include "Systems/Core/EnvironmentSystem.h"
10
11#include "Resources/Mesh.h"
12#include "Resources/Skeleton.h"
13#include "Resources/Animation.h"
14#include "Resources/BasicBlueNoiseManager.h"
15#include "RenderStateUpdater.h"
16#include "RenderList.h"
17
18#include "Tasks/RenderTask.h"
19#include "Tasks/GenerateListTask.h"
20#include "Tasks/FilterListTask.h"
21
22#include "Resources/TextureManager.h"
23#include "EngineBindGroups.h"
24
25namespace
26{
27 Cogs::Logging::Log logger = Cogs::Logging::getLogger("RenderStateUpdater");
28}
29
30void Cogs::Core::updateSceneBindings(const DrawContext * drawContext, const CameraData * /*cameraData*/, const EffectBinding * bindings)
31{
32 assert(drawContext->taskContext && "Invalid rendering context.");
33
34 updateSceneBindings(drawContext->taskContext, bindings);
35}
36
37void Cogs::Core::updateSceneBindings(const RenderTaskContext * taskContext, const EffectBinding * bindings)
38{
39 const EngineBuffers* engineBuffers = &taskContext->renderer->getEngineBuffers();
40 IGraphicsDevice* device = taskContext->renderer->getDevice();
41 IContext* deviceContext = device->getImmediateContext();
42
43 if (HandleIsValid(bindings->sceneBufferBinding)) {
44 deviceContext->setConstantBuffer(bindings->sceneBufferBinding, engineBuffers->sceneBufferHandle);
45 }
46 if (HandleIsValid(bindings->viewBufferBinding)) {
47 deviceContext->setConstantBuffer(bindings->viewBufferBinding, engineBuffers->viewBufferHandle);
48 }
49 if (HandleIsValid(bindings->linearSampler)) {
50 deviceContext->setSamplerState(bindings->linearSampler, taskContext->states->defaultSampler);
51 }
52
53 if (HandleIsValid(bindings->blueNoise)) {
54 auto& blueNoiseManager = taskContext->context->blueNoiseManager;
55 blueNoiseManager->enable();
56 TextureHandle blueNoise = blueNoiseManager->getBlueNoiseHandle(false)->texture;
57 RenderTexture * blueNoiseTexture = taskContext->renderer->getRenderResources().getRenderTexture(blueNoise);
58 if (blueNoiseTexture) {
59 deviceContext->setTexture(bindings->blueNoise, blueNoiseTexture->textureHandle);
60 }
61 }
62 if (HandleIsValid(bindings->blueNoiseStable)) {
63 auto& blueNoiseManager = taskContext->context->blueNoiseManager;
64 blueNoiseManager->enable();
65 TextureHandle blueNoise = blueNoiseManager->getBlueNoiseHandle(true)->texture;
66 RenderTexture * blueNoiseTexture = taskContext->renderer->getRenderResources().getRenderTexture(blueNoise);
67 if (blueNoiseTexture) {
68 deviceContext->setTexture(bindings->blueNoiseStable, blueNoiseTexture->textureHandle);
69 }
70 }
71}
72
73void Cogs::Core::updateEnvironmentBindings(const DrawContext * drawContext, const EffectBinding * bindings)
74{
75 IContext *deviceContext = drawContext->deviceContext;
76 LightSystem *lightSystem = drawContext->context->lightSystem;
77 if (drawContext->device->getBindGroups()) {
78 EngineBindGroups& engineBindGroups = drawContext->renderer->getEngineBindGroups();
79 deviceContext->setBindGroup(engineBindGroups.lightTextures, static_cast<uint32_t>(BindGroup::LightTextures));
80 return;
81 }
82
83 bool needSkyBinding = true;
84 bool needRadianceBinding = true;
85 bool needIrradianceBinding = true;
86 bool needAmbientIrradianceBinding = true;
87 bool needBrdfLUTBinding = true;
88 bool needShadowArrayBinding = true;
89 bool needShadowArrayBinding_1 = true;
90 bool needShadowCubeArrayBinding = true;
91 bool needShadowCubeArrayBinding_1 = true;
92
93 if (HandleIsValid(bindings->shadowSamplerBinding)) {
94 deviceContext->setSamplerState(bindings->shadowSamplerBinding, drawContext->taskContext->states->shadowSampler);
95 }
96
97
98 if (!drawContext->permutation->isShadowPass()) {
99 if (HandleIsValid(bindings->shadowArrayBinding)) {
100 RenderTexture * shadowTexture = drawContext->renderer->getRenderResources().getRenderTexture(lightSystem->cascadeArray);
101
102 if (shadowTexture) {
103 deviceContext->setTexture(bindings->shadowArrayBinding, shadowTexture->textureHandle);
104 deviceContext->setSamplerState("", 1, drawContext->taskContext->states->shadowSampler);
105 needShadowArrayBinding = false;
106 }
107 }
108 if (HandleIsValid(bindings->shadowArrayBinding_1)) {
109 RenderTexture * shadowTexture = drawContext->renderer->getRenderResources().getRenderTexture(lightSystem->cascadeArray);
110
111 if (shadowTexture) {
112 deviceContext->setTexture(bindings->shadowArrayBinding_1, shadowTexture->textureHandle);
113 deviceContext->setSamplerState("", 1, drawContext->taskContext->states->shadowSampler);
114 needShadowArrayBinding_1 = false;
115 }
116 }
117
118 if (HandleIsValid(bindings->shadowCubeArrayBinding)) {
119 RenderTexture * shadowTexture = drawContext->renderer->getRenderResources().getRenderTexture(lightSystem->cubeArray);
120
121 if (shadowTexture) {
122 deviceContext->setTexture(bindings->shadowCubeArrayBinding, shadowTexture->textureHandle);
123 deviceContext->setSamplerState("", 2, drawContext->taskContext->states->shadowSampler);
124 needShadowCubeArrayBinding = false;
125 }
126 }
127 if (HandleIsValid(bindings->shadowCubeArrayBinding_1)) {
128 auto shadowTexture = drawContext->renderer->getRenderResources().getRenderTexture(lightSystem->cubeArray);
129
130 if (shadowTexture) {
131 deviceContext->setTexture(bindings->shadowCubeArrayBinding_1, shadowTexture->textureHandle);
132 deviceContext->setSamplerState("", 2, drawContext->taskContext->states->shadowSampler);
133 needShadowCubeArrayBinding_1 = false;
134 }
135 }
136
137 if (HandleIsValid(bindings->shadowSamplerBinding)) {
138 deviceContext->setSamplerState(bindings->shadowSamplerBinding, drawContext->taskContext->states->shadowSampler);
139 }
140 if (HandleIsValid(bindings->shadowArraySamplerBinding)) {
141 deviceContext->setSamplerState(bindings->shadowArraySamplerBinding, drawContext->taskContext->states->shadowSampler);
142 }
143 if (HandleIsValid(bindings->shadowCubeArraySamplerBinding)) {
144 deviceContext->setSamplerState(bindings->shadowCubeArraySamplerBinding, drawContext->taskContext->states->shadowSampler);
145 }
146 }
147 else {
148 if (HandleIsValid(bindings->shadowSamplerBinding)) {
149 deviceContext->setSamplerState(bindings->shadowSamplerBinding, drawContext->taskContext->states->shadowSampler);
150 }
151 }
152
153 auto environmentComponent = drawContext->cameraData->environment.resolveComponent<EnvironmentComponent>();
154
155 if (environmentComponent) {
156 if (environmentComponent->isSubmerged(drawContext->cameraData)) {
157
158 if (environmentComponent->subseaRadiance) {
159 RenderTexture * subseaRadianceTexture = drawContext->renderer->getRenderResources().getRenderTexture(environmentComponent->subseaRadiance);
160 if (subseaRadianceTexture) {
161 if (subseaRadianceTexture->description.target != ResourceDimensions::TextureCube) {
162 static int count = 0;
163 if (count < 10) {
164 LOG_ERROR(logger, "environment.subseaRadiance is not a cube texture.");
165 count++;
166 }
167 }
168 else {
169 if (HandleIsValid(bindings->skyBinding)) {
170 deviceContext->setTexture(bindings->skyBinding, subseaRadianceTexture->textureHandle);
171 needSkyBinding = false;
172 }
173 if (HandleIsValid(bindings->radianceBinding)) {
174 deviceContext->setTexture(bindings->radianceBinding, subseaRadianceTexture->textureHandle);
175 needRadianceBinding = false;
176 }
177 if (HandleIsValid(bindings->irradianceBinding)) {
178 deviceContext->setTexture(bindings->irradianceBinding, subseaRadianceTexture->textureHandle);
179 needIrradianceBinding = false;
180 }
181 if (HandleIsValid(bindings->ambientIrradianceBinding)) {
182 deviceContext->setTexture(bindings->ambientIrradianceBinding, subseaRadianceTexture->textureHandle);
183 needAmbientIrradianceBinding = false;
184 }
185 }
186 }
187 }
188 } else {
189 if (environmentComponent->skyDome && HandleIsValid(bindings->skyBinding)) {
190
191 if (RenderTexture * skyTexture = drawContext->renderer->getRenderResources().getRenderTexture(environmentComponent->skyDome); skyTexture) {
192
193 if (skyTexture->description.target != ResourceDimensions::TextureCube) {
194 static int warningCount = 0;
195 if (warningCount < 10) {
196 LOG_ERROR(logger, "environment.skyDome is not a cube texture.");
197 warningCount++;
198 }
199 }
200 else {
201 deviceContext->setTexture(bindings->skyBinding, skyTexture->textureHandle);
202 needSkyBinding = false;
203 }
204 }
205 }
206
207 if (environmentComponent->radiance && HandleIsValid(bindings->radianceBinding)) {
208
209 if (RenderTexture * radianceTexture = drawContext->renderer->getRenderResources().getRenderTexture(environmentComponent->radiance); radianceTexture) {
210
211 if (radianceTexture->description.target != ResourceDimensions::TextureCube) {
212 static int warningCount = 0;
213 if (warningCount < 10) {
214 LOG_ERROR(logger, "environment.radiance is not a cube texture.");
215 warningCount++;
216 }
217 }
218 else {
219 deviceContext->setTexture(bindings->radianceBinding, radianceTexture->textureHandle);
220 needRadianceBinding = false;
221 }
222 }
223 }
224
225 if (environmentComponent->irradiance && HandleIsValid(bindings->irradianceBinding)) {
226
227 if (RenderTexture * irradianceTexture = drawContext->renderer->getRenderResources().getRenderTexture(environmentComponent->irradiance); irradianceTexture) {
228
229 if (irradianceTexture->description.target != ResourceDimensions::TextureCube) {
230 static int warningCount = 0;
231 if (warningCount < 10) {
232 LOG_ERROR(logger, "environment.irradiance is not a cube texture.");
233 warningCount++;
234 }
235 }
236 else {
237 deviceContext->setTexture(bindings->irradianceBinding, irradianceTexture->textureHandle);
238 needIrradianceBinding = false;
239 }
240 }
241 }
242
243 if (environmentComponent->ambientIrradiance && HandleIsValid(bindings->ambientIrradianceBinding)) {
244 RenderTexture * ambientIrradianceTexture = drawContext->renderer->getRenderResources().getRenderTexture(environmentComponent->ambientIrradiance);
245 if (ambientIrradianceTexture) {
246
247 if (ambientIrradianceTexture->description.target != ResourceDimensions::TextureCube) {
248 static int warningCount = 0;
249 if (warningCount < 10) {
250 LOG_ERROR(logger, "environment.ambientIrradiance is not a cube texture.");
251 warningCount++;
252 }
253 }
254 else {
255 deviceContext->setTexture(bindings->ambientIrradianceBinding, ambientIrradianceTexture->textureHandle);
256 needAmbientIrradianceBinding = false;
257 }
258 }
259 }
260
261 if (environmentComponent->brdfLUT && HandleIsValid(bindings->brdfLUTBinding)) {
262 RenderTexture* brdfLUTTexture = drawContext->renderer->getRenderResources().getRenderTexture(environmentComponent->brdfLUT);
263 if (brdfLUTTexture) {
264
265 if (brdfLUTTexture->description.target != ResourceDimensions::Texture2D) {
266 static int warningCount = 0;
267 if (warningCount < 10) {
268 LOG_ERROR(logger, "environment.brdfLUT is not a 2D texture.");
269 warningCount++;
270 }
271 }
272 else {
273 deviceContext->setTexture(bindings->brdfLUTBinding, brdfLUTTexture->textureHandle);
274 needBrdfLUTBinding = false;
275 }
276 }
277 } else if (HandleIsValid(bindings->brdfLUTBinding)) {
278 RenderTexture * white = drawContext->renderer->getRenderResources().getRenderTexture(drawContext->context->textureManager->white);
279 deviceContext->setTexture(bindings->brdfLUTBinding, white->textureHandle);
280 needBrdfLUTBinding = false;
281 }
282
283 }
284 }
285
286 if (drawContext->device->getType() == GraphicsDeviceType::WebGPU){
287 // Set Dymmy textures requered for WebGPU
288
289 // skyBinding
290 if(HandleIsValid(bindings->skyBinding) && needSkyBinding){
291 TextureHandle whiteCube = drawContext->context->textureManager->whiteCube;
292 RenderTexture* skyTexture = drawContext->renderer->getRenderResources().getRenderTexture(whiteCube);
293 if (skyTexture) {
294 LOG_INFO_ONCE(logger, "Setting dummy environment.skyDome.");
295 deviceContext->setTexture(bindings->skyBinding, skyTexture->textureHandle);
296 }
297 }
298
299 // radianceBinding
300 if(HandleIsValid(bindings->radianceBinding) && needRadianceBinding) {
301 TextureHandle whiteCube = drawContext->context->textureManager->whiteCube;
302 RenderTexture* radianceTexture = drawContext->renderer->getRenderResources().getRenderTexture(whiteCube);
303 if (radianceTexture) {
304 LOG_INFO_ONCE(logger, "Setting dummy environment.radiance.");
305 deviceContext->setTexture(bindings->radianceBinding, radianceTexture->textureHandle);
306 }
307 }
308
309 // irradianceBinding
310 if(HandleIsValid(bindings->irradianceBinding) && needIrradianceBinding) {
311 TextureHandle whiteCube = drawContext->context->textureManager->whiteCube;
312 RenderTexture* irradianceTexture = drawContext->renderer->getRenderResources().getRenderTexture(whiteCube);
313 if (irradianceTexture) {
314 LOG_INFO_ONCE(logger, "Setting dummy environment.irradiance.");
315 deviceContext->setTexture(bindings->irradianceBinding, irradianceTexture->textureHandle);
316 }
317 }
318
319 // ambientIrradianceBinding
320 if(HandleIsValid(bindings->ambientIrradianceBinding) && needAmbientIrradianceBinding) {
321 TextureHandle whiteCube = drawContext->context->textureManager->whiteCube;
322 RenderTexture* ambientIrradianceTexture = drawContext->renderer->getRenderResources().getRenderTexture(whiteCube);
323 if (ambientIrradianceTexture) {
324 LOG_INFO_ONCE(logger, "Setting dummy environment.ambientIrradiance.");
325 deviceContext->setTexture(bindings->ambientIrradianceBinding, ambientIrradianceTexture->textureHandle);
326 }
327 }
328
329 // brdfLUTBinding
330 if(HandleIsValid(bindings->brdfLUTBinding) && needBrdfLUTBinding) {
331 RenderTexture* white = drawContext->renderer->getRenderResources().getRenderTexture(drawContext->context->textureManager->white);
332 if (white) {
333 LOG_INFO_ONCE(logger, "Setting dummy environment.brdfLUT.");
334 deviceContext->setTexture(bindings->brdfLUTBinding, white->textureHandle);
335 }
336 }
337
338 // cascadedShadowMap
339 if(HandleIsValid(bindings->shadowArrayBinding) && needShadowArrayBinding) {
340 RenderTexture* dummy = drawContext->renderer->getRenderResources().getRenderTexture(drawContext->context->textureManager->whiteDepthArray);
341 if (dummy) {
342 LOG_INFO_ONCE(logger, "Setting dummy cascadedShadowMap.");
343 deviceContext->setTexture(bindings->shadowArrayBinding, dummy->textureHandle);
344 }
345 }
346 if(HandleIsValid(bindings->shadowArrayBinding_1) && needShadowArrayBinding_1) {
347 RenderTexture* dummy = drawContext->renderer->getRenderResources().getRenderTexture(drawContext->context->textureManager->whiteDepthArray);
348 if (dummy) {
349 deviceContext->setTexture(bindings->shadowArrayBinding_1, dummy->textureHandle);
350 }
351 }
352
353 // cubeShadowMap
354 if(HandleIsValid(bindings->shadowCubeArrayBinding) && needShadowCubeArrayBinding) {
355 RenderTexture* dummy = drawContext->renderer->getRenderResources().getRenderTexture(drawContext->context->textureManager->whiteDepthCube);
356 if (dummy) {
357 LOG_INFO_ONCE(logger, "Setting dummy cubeShadowMap.");
358 deviceContext->setTexture(bindings->shadowCubeArrayBinding, dummy->textureHandle);
359 }
360 }
361 if(HandleIsValid(bindings->shadowCubeArrayBinding_1) && needShadowCubeArrayBinding_1) {
362 RenderTexture* dummy = drawContext->renderer->getRenderResources().getRenderTexture(drawContext->context->textureManager->whiteDepthCube);
363 if (dummy) {
364 deviceContext->setTexture(bindings->shadowCubeArrayBinding_1, dummy->textureHandle);
365 }
366 }
367 }
368
369 SamplerState linearFiltering = {
370 SamplerState::AddressMode::Clamp,
371 SamplerState::AddressMode::Clamp,
372 SamplerState::AddressMode::Clamp,
373 SamplerState::FilterMode::MinMagMipLinear,
374 SamplerState::ComparisonFunction::Never,
375 1,
376 { 0, 0, 0, 1 }
377 };
378
379 if (HandleIsValid(bindings->skySamplerBinding)) {
380 deviceContext->setSamplerState(bindings->skySamplerBinding, drawContext->taskContext->states->getSamplerState(linearFiltering));
381 }
382
383
384 if (HandleIsValid(bindings->radianceSamplerBinding)) {
385 deviceContext->setSamplerState(bindings->radianceSamplerBinding, drawContext->taskContext->states->getSamplerState(linearFiltering));
386 }
387 if (HandleIsValid(bindings->irradianceSamplerBinding)) {
388 deviceContext->setSamplerState(bindings->irradianceSamplerBinding, drawContext->taskContext->states->getSamplerState(linearFiltering));
389 }
390 if (HandleIsValid(bindings->ambientIrradianceSamplerBinding)) {
391 deviceContext->setSamplerState(bindings->ambientIrradianceSamplerBinding, drawContext->taskContext->states->getSamplerState(SamplerState::DefaultState()));
392 }
393 if (HandleIsValid(bindings->brdfLUTSamplerBinding)) {
394 SamplerState lutSamplerState = {
395 SamplerState::AddressMode::Clamp,
396 SamplerState::AddressMode::Clamp,
397 SamplerState::AddressMode::Clamp,
398 SamplerState::FilterMode::MinMagMipLinear,
399 SamplerState::ComparisonFunction::Never,
400 1,
401 { 0, 0, 0, 1 }
402 };
403 deviceContext->setSamplerState(bindings->brdfLUTSamplerBinding, drawContext->taskContext->states->getSamplerState(lutSamplerState));
404 }
405}
406
407void Cogs::Core::updateMaterialBindings(const DrawContext * drawContext, const RenderMaterialInstance * renderMaterialInstance, const EffectBinding * bindings, bool perInstance)
408{
409 auto deviceContext = drawContext->deviceContext;
410
411 auto materialInstance = renderMaterialInstance->getResource();
412 auto material = materialInstance->material;
413
414 for (auto & buffer : material->constantBuffers.buffers) {
415 if (buffer.isPerInstance != perInstance) continue;
416
417 auto & bufferBinding = bindings->bufferBindings[buffer.index];
418
419 if (perInstance) {
420 if (HandleIsValid(bufferBinding)) {
421 deviceContext->setConstantBuffer(bufferBinding, renderMaterialInstance->buffers[buffer.index].handle);
422 }
423 }
424 else {
425 if (HandleIsValid(bufferBinding)) {
426 deviceContext->setConstantBuffer(bufferBinding, bindings->buffers[buffer.index].handle);
427 }
428 }
429 }
430
431 if (perInstance) {
432 for (const TextureValue& textureProperty : materialInstance->textureVariables) {
433 if (textureProperty.property->isPerInstance) {
434 const Cogs::TextureBindingHandle& textureBinding = bindings->textureBindings[textureProperty.key];
435 const Cogs::SamplerStateBindingHandle& samplerBinding = bindings->samplerBindings[textureProperty.key];
436
437 RenderTexture* renderTexture = drawContext->renderer->getRenderResources().getRenderTexture(textureProperty.texture.handle);
438
439 if (renderTexture) {
440 deviceContext->setTexture(textureBinding, renderTexture->textureHandle);
441 }
442 else {
443 if (HandleIsValid(textureProperty.property->texture.handle)) {
444 // Render texture is not ready, fall back to default value if available.
445 renderTexture = drawContext->renderer->getRenderResources().getRenderTexture(textureProperty.property->texture.handle);
446 deviceContext->setTexture(textureBinding, renderTexture ? renderTexture->textureHandle : Cogs::TextureHandle::NoHandle);
447 }
448 else {
449 deviceContext->setTexture(textureBinding, Cogs::TextureHandle::NoHandle);
450 }
451 }
452 if (HandleIsValid(renderMaterialInstance->samplerStates[textureProperty.key])) {
453 deviceContext->setSamplerState(samplerBinding, renderMaterialInstance->samplerStates[textureProperty.key]);
454 }
455 else {
456 deviceContext->setSamplerState(samplerBinding, Cogs::SamplerStateHandle::NoHandle);
457 }
458 }
459 }
460 }
461 else {
462 RenderMaterial* renderMaterial = renderMaterialInstance->renderMaterial;
463
464 for (size_t i = 0, N = material->textureProperties.size(); i < N; i++) {
465 const TextureProperty& textureProperty = material->textureProperties[i];
466 if (!textureProperty.isPerInstance) {
467
468 RenderTexture* renderTexture = drawContext->renderer->getRenderResources().getRenderTexture(textureProperty.texture.handle);
469 if (renderTexture) {
470 deviceContext->setTexture(bindings->textureBindings[textureProperty.key], renderTexture->textureHandle);
471 }
472 else {
473 deviceContext->setTexture(bindings->textureBindings[textureProperty.key], Cogs::TextureHandle::NoHandle);
474 }
475
476 const RenderMaterial::TexturePropertyState& state = renderMaterial->texturePropertyStates[i];
477 if (HandleIsValid(state.samplerState)) {
478 deviceContext->setSamplerState(bindings->samplerBindings[textureProperty.key], state.samplerState);
479 }
480 else {
481 deviceContext->setSamplerState(bindings->samplerBindings[textureProperty.key], Cogs::SamplerStateHandle::NoHandle);
482 }
483
484 }
485 }
486 }
487}
488
489void Cogs::Core::applyMaterialPermutation(RenderTaskContext * taskContext, const DrawContext * drawContext, const EffectBinding * bindings, const RenderMaterialInstance * renderMaterialInstance)
490{
491 drawContext->deviceContext->setEffect(bindings->renderEffect->effectHandle);
492 drawContext->deviceContext->setInputLayout(bindings->renderEffect->inputHandle);
493 updateSceneBindings(taskContext, bindings);
494 updateMaterialBindings(drawContext, renderMaterialInstance, bindings, false);
495}
496
497void Cogs::Core::applyMaterialInstance(const DrawContext * drawContext, const EffectBinding * bindings, const RenderMaterialInstance * renderMaterialInstance)
498{
499 updateMaterialBindings(drawContext, renderMaterialInstance, bindings, true);
500}
501
502size_t Cogs::Core::populateObjectBuffer(const DrawContext * drawContext, const RenderItem* items, size_t o, size_t n)
503{
504 auto deviceContext = drawContext->deviceContext;
505 auto & engineBuffers = *drawContext->engineBuffers;
506 assert(engineBuffers.objectBatch.count != 0);
507
508 const auto stride = engineBuffers.objectBatch.stride;
509 auto m = std::min(n - o, size_t(engineBuffers.objectBatch.count));
510 if (m) {
511 MappedBuffer<char> objectBatch(deviceContext, engineBuffers.objectBatch.bufferHandle, MapMode::WriteDiscard);
512
513 if (objectBatch) {
514 for (size_t i = 0; i < m; i++) {
515 if (items[o + i].isCustom()) continue;
516 auto * obj = (ObjectBuffer*)(objectBatch.get() + stride * i);
517 obj->encodeWorldMatrix(*items[o + i].worldMatrix);
518 obj->encodeObjectId(items[o + i].objectId);
519 }
520 }
521 }
522 return o + m;
523}
524
525void Cogs::Core::applyMaterialPerObjectBatched(const DrawContext * drawContext, const RenderMaterialInstance * /*renderMaterialInstance*/, const RenderItem & renderItem, size_t o, const EffectBinding * binding)
526{
527 auto deviceContext = drawContext->deviceContext;
528 auto & engineBuffers = *drawContext->engineBuffers;
529 auto & batch = engineBuffers.objectBatch;
530
531 const auto bindings = binding;
532
533 if (HandleIsValid(bindings->objectBufferBinding)) {
534 deviceContext->setConstantBuffer(bindings->objectBufferBinding,
535 batch.bufferHandle,
536 batch.stride * uint32_t(o),
537 batch.stride);
538 }
539
540 if (renderItem.poseData) {
541 if (HandleIsValid(bindings->animationBufferBinding)) {
542 deviceContext->updateBuffer(engineBuffers.animationBuffer, renderItem.poseData->transforms, sizeof(glm::mat4) * renderItem.poseData->numPoses);
543 deviceContext->setConstantBuffer(bindings->animationBufferBinding, engineBuffers.animationBuffer);
544 }
545 }
546}
547
548
549void Cogs::Core::applyMaterialPerObject(const DrawContext * drawContext, const RenderMaterialInstance * /*renderMaterialInstance*/, const RenderItem & renderItem, const EffectBinding * binding)
550{
551 auto deviceContext = drawContext->deviceContext;
552 auto & engineBuffers = *drawContext->engineBuffers;
553
554 const auto bindings = binding;
555
556 if (HandleIsValid(bindings->objectBufferBinding)) {
557 ArrayObjectBuffer* arrayObjectBuffer = drawContext->arrayObjectBuffer;
558 ListObjectBuffer* listObjectBuffer = drawContext->listObjectBuffer;
559
560 if (arrayObjectBuffer && renderItem.hasObjectArrayBufferSlot() && HandleIsValid(arrayObjectBuffer->gpu)){
561 uint32_t bind_offset = renderItem.objectArrayBufferSlot / ArrayObjectBuffer::arrayGranularity;
562 deviceContext->setConstantBuffer(bindings->objectBufferBinding,
563 arrayObjectBuffer->gpu,
564 ArrayObjectBuffer::bindSize*bind_offset,
565 ArrayObjectBuffer::bindSize);
566 }
567 else if (listObjectBuffer && renderItem.hasObjectBufferSlot() && HandleIsValid(listObjectBuffer->gpu)) {
568 deviceContext->setConstantBuffer(bindings->objectBufferBinding,
569 listObjectBuffer->gpu,
570 listObjectBuffer->stride * renderItem.objectBufferSlot,
571 listObjectBuffer->stride);
572 }
573 else {
574 MappedBuffer<ObjectBuffer> objectBuffer(deviceContext, engineBuffers.objectBufferHandle, MapMode::WriteDiscard);
575 if (objectBuffer) {
576 objectBuffer->encodeWorldMatrix(*renderItem.worldMatrix);
577 objectBuffer->encodeObjectId(renderItem.objectId);
578 }
579 deviceContext->setConstantBuffer(bindings->objectBufferBinding, engineBuffers.objectBufferHandle);
580 }
581 }
582
583 if (renderItem.poseData) {
584 if (HandleIsValid(bindings->animationBufferBinding)) {
585 deviceContext->updateBuffer(engineBuffers.animationBuffer, renderItem.poseData->transforms, sizeof(glm::mat4) * renderItem.poseData->numPoses);
586 deviceContext->setConstantBuffer(bindings->animationBufferBinding, engineBuffers.animationBuffer);
587 }
588 }
589}
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
static const Handle_t NoHandle
Represents a handle to nothing.
Definition: Common.h:78