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