3#include "RenderPipelineManager.h"
5#include "Systems/Core/CameraSystem.h"
6#include "Systems/Core/LightSystem.h"
7#include "Systems/Core/CameraArraySystem.h"
9#include "Services/Time.h"
10#include "Services/Services.h"
11#include "Services/PipelineService.h"
14#include "ViewContext.h"
17#include "RenderPipelineFactory.h"
18#include "RenderTexture.h"
19#include "RenderTarget.h"
20#include "RenderList.h"
22#include "Serialization/RenderPipelineReader.h"
24#include "Tasks/RenderTaskFactory.h"
25#include "Tasks/RenderListTask.h"
26#include "Tasks/ReadbackTask.h"
28#include "Rendering/ICapabilities.h"
30#include "Foundation/HashSequence.h"
31#include "Foundation/Collections/SmallVector.h"
32#include "Foundation/Logging/Logger.h"
33#include "Foundation/ComponentModel/Entity.h"
34#include "Foundation/Platform/Mouse.h"
35#include "Foundation/Reflection/TypeDatabase.h"
45 const std::string forwardPath =
"Pipelines/Forward.pipeline";
46 const std::string shadowPath =
"Pipelines/Shadow.pipeline";
48 std::string toHexString(
size_t value)
50 constexpr size_t maxDigits = 2 *
sizeof(size_t);
51 static const char digits[16] = {
'0',
'1',
'2',
'3',
'4',
'5',
'6',
'7',
'8',
'9',
'A',
'B',
'C',
'D',
'E',
'F' };
54 rv.reserve(2 + maxDigits);
59 if (
size_t nibble = (value >> (4 * (o - 1)) & 0xF); nibble) {
65 size_t nibble = (value >> (4 * (o - 1)) & 0xF);
66 rv.push_back(digits[nibble]);
74 if (!texture)
return nullptr;
76 RenderTexture* renderTexture = renderContext->resources->getRenderTexture(texture);
78 if (useAsTarget && !renderTexture->renderTarget) {
80 assert(!renderTexture->depthTexture);
81 RenderTexture* depthTexture = renderContext->resources->createRenderTexture();
82 depthTexture->setName(name.
to_string() +
" DT");
83 depthTexture->description.target = (renderTexture->description.samples > 1) ? Cogs::ResourceDimensions::Texture2DMS : Cogs::ResourceDimensions::Texture2D;
85 depthTexture->description.format = Cogs::TextureFormat::R32_TYPELESS;
86 depthTexture->description.samples = renderTexture->description.samples;
87 depthTexture->sizeSource = renderTexture;
88 renderTexture->depthTexture = depthTexture;
90 assert(!renderTexture->renderTarget);
91 RenderTarget* renderTarget = renderContext->resources->createRenderTarget();
92 renderTarget->setName(name.
to_string() +
" RT");
93 renderTarget->textures.push_back(renderTexture);
94 renderTarget->depth = depthTexture;
95 renderTarget->width = renderTexture->description.width;
96 renderTarget->height = renderTexture->description.height;
97 renderTarget->samples = renderTexture->description.samples;
98 renderTexture->renderTarget = renderTarget;
101 reinterpret_cast<intptr_t
>(renderTexture),
102 reinterpret_cast<intptr_t
>(renderTexture->renderTarget),
103 reinterpret_cast<intptr_t
>(renderTexture->depthTexture));
106 return renderTexture;
111 releasePipeline(renderContext, instance->pipeline);
112 instance->options.clear();
113 instance->dataHash = 0;
114 instance->priority = 0;
115 instance->pipeline.updateResources.resources.clear();
119 size_t instanceKey,
size_t dataHash,
const Cogs::StringView& pipeline,
int priority,
122 auto [instance, wasCreated] = manager->instanceByKey(renderContext->context, instanceKey);
124 instance->priority = priority;
125 instance->sanityCheck = camData;
127 assert(instance->sanityCheck == camData);
136 if (wasCreated || instance->dataHash != dataHash || instance->priority != priority || !isPipelineFresh(renderContext, instance->pipeline)) {
137 releasePipelineInstance(renderContext, instance);
138 instance->dataHash = dataHash;
139 instance->priority = priority;
143 resources.add(&resource);
146 resources.add(renderList,
"Cogs.RenderList");
150 instance->options.push_back({
158 instance->pipeline.updateResources.add(renderTexture->depthTexture);
159 instance->pipeline.updateResources.add(renderTexture->renderTarget);
160 resources.add(renderTexture->renderTarget,
"Cogs.BackBuffer");
164 expressionContext.add(
"Cogs.BackBuffer.width", renderTexture->description.width);
165 expressionContext.add(
"Cogs.BackBuffer.height", renderTexture->description.height);
167 renderTexture->width = { &expressionContext,
"Cogs.BackBuffer.width", std::to_string(renderTexture->description.width), 0 };
168 renderTexture->height = { &expressionContext,
"Cogs.BackBuffer.height", std::to_string(renderTexture->description.height), 0 };
170 instance->options.push_back({
"Pass",
"Offscreen" });
175 initFunc(instance, resources, wasCreated);
179 createPipeline(renderContext, pipeDefinition, resources, instance->pipeline, pipeline, camData, instance->options);
196 instance->
name =
"Light@" + toHexString(
size_t(&light));
197 instance->priority = 100;
198 instance->sanityCheck = &light;
199 LOG_DEBUG(logger,
"Added light pipeline");
201 assert(instance->sanityCheck == &light);
203 auto renderTexture = renderContext->resources->getRenderTexture(shadowTexture);
204 if (!renderTexture)
return;
206 size_t dataHash =
Cogs::hash(
reinterpret_cast<intptr_t
>(renderTexture));
212 for (uint32_t i = 0; i < lightData.maxViewports; ++i) {
213 const uint32_t arrayIndex = i + lightData.arrayOffset;
214 if (!(arrayIndex < renderTexture->renderTargets.size())) {
215 LOG_ERROR(logger,
"Light shadow arrayIndex larger than renderTarget size");
218 if (!renderTexture->renderTargets[arrayIndex]) {
219 auto renderTarget = renderContext->resources->createRenderTarget();
220 renderTarget->setName(
"Light 0x" + toHexString(
size_t(&light)) +
" RT arrayIndex=" + std::to_string(arrayIndex));
221 renderTarget->depth = renderTexture;
222 renderTarget->depthLayerIndex = arrayIndex;
223 renderTexture->renderTargets[arrayIndex] = renderTarget;
225 dataHash =
Cogs::hashSequence(
reinterpret_cast<intptr_t
>(renderTexture->renderTargets[arrayIndex]), dataHash);
232 if (wasCreated || instance->dataHash != dataHash || !isPipelineFresh(renderContext, instance->pipeline)) {
233 releasePipelineInstance(renderContext, instance);
234 instance->dataHash = dataHash;
236 for (
size_t viewportIndex = 0; viewportIndex < lightData.maxViewports; viewportIndex++) {
237 const size_t arrayIndex = viewportIndex + lightData.arrayOffset;
239 instance->pipeline.updateResources.add(renderTexture->renderTargets[arrayIndex]);
242 resources.add(renderTexture->renderTargets[arrayIndex],
"Cogs.BackBuffer");
243 resources.add(renderList,
"Cogs.RenderList");
245 createPipeline(renderContext, manager->definitionByPath(renderContext->context, shadowPath), resources, instance->pipeline, shadowPath, &lightData.lightCameraData[viewportIndex], instance->options);
247 for (
size_t taskIndex = viewportIndex * 2; taskIndex < viewportIndex * 2 + 2; ++taskIndex) {
248 instance->pipeline.tasks[taskIndex]->frameMod = 0;
249 instance->pipeline.tasks[taskIndex]->frameOffset = 0;
250 if (lightData.shadowUpdate == ShadowUpdate::Static || lightData.shadowUpdate == ShadowUpdate::StaticPartial) {
251 instance->pipeline.tasks[taskIndex]->flags = (RenderTaskFlags::ERenderTaskFlags)((
int)instance->pipeline.tasks[taskIndex]->flags | (int)RenderTaskFlags::Static);
255 if (!wasCreated) LOG_DEBUG(logger,
"Updated light pipeline");
256 manager->dirty =
true;
262 std::vector<const Variable*> vars;
263 renderContext->context->
variables->getMatchingVariables(vars,
"renderer.auxiliaryPipelines.");
265 for (
const auto * var : vars) {
266 if (var->getValue().empty())
continue;
268 std::vector<Cogs::StringView> tokens;
269 split(var->getValue(),
":", tokens);
270 if (tokens.empty() || 2 < tokens.size()) {
271 LOG_ERROR_ONCE(logger,
"Failed to tokenize %.*s: '%.*s'", StringViewFormat(var->getName()), StringViewFormat(var->getValue()));
279 if (1 < tokens.size()) {
280 priority = std::stoi(tokens[1].to_string());
285 instance->name = var->getName().to_string();
286 instance->options.push_back( {
"Pass",
"Offscreen" });
287 LOG_DEBUG(logger,
"%s aux pipeline run for %s: %.*s", wasCreated ?
"Creating" :
"Updating", instance->name.c_str(), StringViewFormat(pipeline));
290 setupCameraPipeline(renderContext, manager,
291 instanceKey, dataHash, pipeline, priority,
292 initFunc,
nullptr,
nullptr,
nullptr, renderList);
300 if (run->enabled && !run->pipeline.empty()) {
305 if (run->renderTexture) {
306 renderTexture = getRenderTexture(renderContext, dataHash, run->renderTexture, run->name,
true);
312 instance->options.push_back( {
"Pass",
"Offscreen" });
313 if (!renderTexture) {
314 resources.add(renderContext->defaultRenderTarget,
"Cogs.BackBuffer");
315 instance->options.push_back({
"Pass",
"Onscreen" });
317 LOG_DEBUG(logger,
"%s extra pipeline run for %s: %s", wasCreated ?
"Creating" :
"Updating", instance->name.c_str(), run->pipeline.c_str());
320 setupCameraPipeline(renderContext, manager,
321 instanceKey, dataHash, run->pipeline, run->priority,
322 initFunc,
nullptr, run->cameraData, renderTexture, renderList);
329 for (
auto & light : renderContext->context->lightSystem->pool) {
330 auto & lightData = renderContext->context->lightSystem->getData(&light);
332 if (!lightData.enabled || !lightData.castShadows)
continue;
334 setupLightPipeline(renderContext, manager, light, lightData, lightData.shadowTexture, renderList);
339 size_t& dataHash,
RenderTexture* renderTexture,
size_t targetIndex,
340 uint32_t multiViewCount, uint32_t multiViewSamples,
344 if (1 < multiViewCount) {
345 camArrData.passOptions = camArrData.camData.passOptions ? *camArrData.camData.passOptions :
RenderPassOptions{};
346 camArrData.camData.passOptions = &camArrData.passOptions;
347 camArrData.passOptions.multiViews = multiViewCount;
350 if (!renderTexture->renderTargets[targetIndex]) {
351 RenderTarget* renderTarget = renderContext->resources->createRenderTarget();
352 renderTarget->setName(name.
to_string() +
" MV-RT[" + std::to_string(targetIndex) +
":" + std::to_string(multiViewCount) +
"]");
353 renderTarget->textures.push_back(renderTexture);
354 renderTarget->layerIndex = uint16_t(targetIndex);
355 renderTarget->depth = renderTexture->depthTexture;
356 renderTarget->depthLayerIndex = uint16_t(targetIndex);
357 if (1 < multiViewCount) {
358 renderTarget->multiViewBaseIndex = 0;
359 renderTarget->multiViewCount =
static_cast<uint8_t
>(multiViewCount);
360 renderTarget->multiViewSamples =
static_cast<uint8_t
>(std::min(255u, multiViewSamples));
362 renderTarget->width = renderTexture->description.width;
363 renderTarget->height = renderTexture->description.height;
364 renderTarget->samples = renderTexture->description.samples;
365 renderTarget->expectsSRGB = camArrComp.
expectsSRGB;
366 renderTexture->renderTargets[targetIndex] = renderTarget;
368 dataHash =
Cogs::hashSequence(dataHash,
reinterpret_cast<intptr_t
>(renderTexture->renderTarget));
372 size_t& dataHash,
RenderTexture* renderTexture,
size_t targetIndex,
375 switch (camArrData.depthMode) {
377 case CameraArrayData::DepthMode::None:
380 case CameraArrayData::DepthMode::Create:
381 if (!renderTexture->depthTexture) {
382 RenderTexture* depthTexture = renderContext->resources->createRenderTexture();
383 depthTexture->setName(name.
to_string() +
" DT");
384 depthTexture->description.target = renderTexture->description.target;
386 depthTexture->description.format = Cogs::TextureFormat::R32_TYPELESS;
387 depthTexture->layers = renderTexture->description.layers;
388 depthTexture->samples = renderTexture->description.samples;
389 depthTexture->sizeSource = renderTexture;
390 renderTexture->depthTexture = depthTexture;
392 dataHash =
Cogs::hashSequence(dataHash,
reinterpret_cast<intptr_t
>(renderTexture->depthTexture));
395 case CameraArrayData::DepthMode::Provided:
396 if (!renderTexture->depthTexture) {
397 renderTexture->depthTexture = getRenderTexture(renderContext, dataHash, camArrData.depthTextures[targetIndex], name,
false);
399 dataHash =
Cogs::hashSequence(dataHash,
reinterpret_cast<intptr_t
>(renderTexture->depthTexture));
403 assert(
false &&
"Illegal enum");
409 const size_t dataHash,
RenderTexture* renderTexture,
size_t targetIndex,
413 Cogs::StringView pipeline = camArrData.pipeline.empty() ? forwardPath : camArrData.pipeline;
415 PipeInitFunc initFunc = [targetIndex, &name, &pipeline, renderTexture, updateDepth = camArrData.depthMode == CameraArrayData::DepthMode::Create](
PipelineInstance* instance,
RenderTaskResources& resources,
bool wasCreated)
417 instance->
name = name.to_string();
420 instance->pipeline.updateResources.add(renderTexture->depthTexture);
422 instance->pipeline.updateResources.add(renderTexture->renderTargets[targetIndex]);
423 resources.add(renderTexture->renderTargets[targetIndex],
"Cogs.BackBuffer");
427 expressionContext.add(
"Cogs.BackBuffer.width", renderTexture->description.width);
428 expressionContext.add(
"Cogs.BackBuffer.height", renderTexture->description.height);
433 LOG_DEBUG(logger,
"%s offscreen camera pipeline for %s: %.*s", wasCreated ?
"Creating" :
"Updating", instance->
name.c_str(), StringViewFormat(pipeline));
436 setupCameraPipeline(renderContext, manager,
438 initFunc, &camComp, &camArrData.camData,
nullptr, renderList);
449 for (
const CameraArrayComponent& camArrComp : renderContext->context->cameraArraySystem->pool) {
451 CameraArrayData& camArrData = renderContext->context->cameraArraySystem->getData(&camArrComp);
452 if (camArrData.textureMode == CameraArrayData::TextureMode::None) {
459 name_ =
"CameraArray@" + std::to_string(entity->
getId());
463 assert(camArrData.camData.camera);
464 const CameraComponent& camComp = renderContext->context->cameraSystem->pool[camArrData.camData.camera.index];
467 switch (camArrData.textureMode) {
469 case CameraArrayData::TextureMode::TextureArray: {
471 if (
RenderTexture* renderTexture = getRenderTexture(renderContext, dataHash, camArrData.colorTextures[0], name,
false); renderTexture) {
474 setupCameraArrayDepthTarget(renderContext, dataHash, renderTexture, 0, camArrData, name);
477 if ((1 < renderTexture->description.layers) && multiView) {
478 setupCameraArrayRenderTarget(renderContext, dataHash, renderTexture, 0, renderTexture->description.layers, camArrComp.
samples, camArrComp, camArrData, name);
479 setupCameraArrayDraw(renderContext, manager, renderList, dataHash, renderTexture, 0, camArrData, camComp, name, instanceKey);
483 for (
size_t l = 0; l < renderTexture->description.layers; l++) {
484 setupCameraArrayRenderTarget(renderContext, dataHash, renderTexture, l, 1, 1, camArrComp, camArrData, name);
486 for (
size_t l = 0; l < renderTexture->description.layers; l++) {
487 setupCameraArrayDraw(renderContext, manager, renderList, dataHash, renderTexture, l, camArrData, camComp, name,
Cogs::hashSequence(instanceKey,
static_cast<intptr_t
>(l)));
494 case CameraArrayData::TextureMode::ArrayOfTextures:
495 for (
size_t l = 0; l < camArrData.numViews; l++) {
497 if (
RenderTexture* renderTexture = getRenderTexture(renderContext, dataHash, camArrData.colorTextures[l], name,
false); renderTexture) {
498 setupCameraArrayDepthTarget(renderContext, dataHash, renderTexture, l, camArrData, name);
499 setupCameraArrayRenderTarget(renderContext, dataHash, renderTexture, l, 1, 1, camArrComp, camArrData, name);
500 setupCameraArrayDraw(renderContext, manager, renderList, dataHash, renderTexture, l, camArrData, camComp, name,
Cogs::hashSequence(instanceKey,
static_cast<intptr_t
>(l)));
505 case CameraArrayData::TextureMode::None: [[fallthrough]];
507 assert(
false &&
"Illegal enum");
514 size_t cameraInstanceKey(
const CameraData& camData,
bool isMainCamera)
521 std::string nameTemp;
522 const bool defaultTargetRender = renderContext->context->
variables->get(
"renderer.defaultTarget.render",
true);
524 const CameraComponent* mainCamComp = renderContext->context->cameraSystem->getMainCamera();
525 for(
const CameraComponent& camComp : renderContext->context->cameraSystem->pool) {
527 if ((camComp.
flags & CameraFlags::EnableRender) == 0) {
continue; }
533 nameTemp =
"Camera, entity=" + std::to_string(entity->
getId());
542 bool isMainCamera = &camComp == mainCamComp;
546 if (
const Variable* var1 = renderContext->context->
variables->get(
"renderer.pipeline.override"); var1 && !var1->isEmpty() && !var1->getValue().empty()) {
547 pipeline = var1->getCString();
551 else if (
const Variable* var2 = renderContext->context->
variables->get(
"renderer.pipeline"); var2 && !var2->isEmpty() && !var2->getValue().empty()) {
552 pipeline = var2->getCString();
558 renderTexture = getRenderTexture(renderContext, dataHash, camComp.
renderTexture, name,
true);
562 if (renderTexture ==
nullptr && defaultTargetRender ==
false) {
570 if (!renderTexture) {
571 resources.add(renderContext->defaultRenderTarget,
"Cogs.BackBuffer");
573 LOG_DEBUG(logger,
"%s main camera pipeline for %s: %.*s", wasCreated ?
"Creating" :
"Updating", instance->name.c_str(), StringViewFormat(pipeline));
576 const CameraData& camData = renderContext->context->cameraSystem->getData(&camComp);
577 setupCameraPipeline(renderContext, manager,
578 cameraInstanceKey(camData, isMainCamera), dataHash, pipeline, (renderTexture ? 300 : 400) + camComp.
stackOrder,
579 initFunc, &camComp, &camData, renderTexture, renderList);
588void Cogs::Core::RenderPipelineManager::initialize(
RenderTaskContext* renderContext)
590 renderList = renderContext->resources->createRenderList();
591 renderList->setName(
"Cogs.RenderList");
593 std::list<std::unique_ptr<SubContext>> subContexts;
596 taskDefinition.name =
"Cogs.GenerateList";
597 taskDefinition.type =
"GenerateList";
598 generateListTask = createRenderTask(renderContext, taskDefinition, subContexts, &expressionContextRoot);
599 generateListTask->output.add(renderList);
600 generateListTask->flags = RenderTaskFlags::Persistent;
605 if (!renderList)
return;
607 assert(generateListTask);
608 destroyRenderTask(renderContext, generateListTask);
609 generateListTask =
nullptr;
611 assert(!renderList->isOwned());
612 renderContext->renderer->getRenderResources().releaseResource(renderList);
613 renderContext->renderer->getRenderResources().destroyResource(renderList);
614 renderList =
nullptr;
616 for (
auto& pipeline : pipelineInstances) {
617 releasePipelineInstance(renderContext, pipeline.second.get());
622Cogs::Core::RenderPipelineManager::definitionByPath(
Context* context,
const StringView& path)
626 auto p1 = definitions.emplace(
hash, std::make_unique<RenderPipelineDefinition>(parsePipeline(context, myPath)));
627 assert(p1.first->second.get());
628 auto& definition = *(p1.first->second.get());
629 if (!definition.name.empty()) {
630 nameMap.insert({ definition.name,
hash });
631 if (!p1.second) LOG_WARNING(logger,
"Collision in nameMap when inserting %s, hash=%zd.", definition.name.c_str(),
hash);
634 for (
auto& generator : definition.generators) {
635 if (!definition.name.empty()) {
638 auto pp1 = definitions.emplace(genHash, std::make_unique<RenderPipelineDefinition>(generator));
639 assert(pp1.first->second.get());
640 if (!pp1.second) LOG_WARNING(logger,
"Collision in hashes when inserting %s, hash=%zd.", generator.name.c_str(), genHash);
642 auto pp2 = nameMap.emplace(generator.name, genHash);
643 if (!pp2.second) LOG_WARNING(logger,
"Collision in nameMap when inserting %s, hash=%zd.", generator.name.c_str(), genHash);
650 auto queryLoc = path.find(
"?");
653 size_t hash1 = trimmedPath.hash();
654 if (
auto it = definitions.find(hash1); it != definitions.end()) {
655 return *(it->second.get());
658 auto& def1 = insert(hash1, trimmedPath);
662 std::vector<StringParameter> importStack = def1.imports;
664 while (!importStack.empty())
667 importStack.pop_back();
670 if (!definitions.contains(hash2)) {
671 const auto& def2 = insert(hash2, item.value);
672 for (
auto& importValue : def2.imports) {
673 importStack.push_back(importValue);
677 nameMap.insert({ item.key, hash2 });
680 for (
const auto& it : definitions) {
681 assert(it.second.get());
687std::pair< Cogs::Core::PipelineInstance*, bool> Cogs::Core::RenderPipelineManager::instanceByKey(
Context* context,
size_t key)
689 auto it = pipelineInstances.find(key);
690 if (it == pipelineInstances.end()) {
691 auto instance = pipelineInstances.emplace(key, std::make_unique<PipelineInstance>()).first->second.get();
692 instance->touched = context->
time->getFrame();
693 return std::make_pair(instance,
true);
695 auto* instance = it->second.get();
696 instance->touched = context->
time->getFrame();
697 return std::make_pair(instance,
false);
700void Cogs::Core::RenderPipelineManager::setupPipeline(
RenderTaskContext * renderContext)
702 Context* context = renderContext->context;
703 uint32_t frame = context->
time->getFrame();
705 renderList->viewportData = renderContext->cameraData;
707 expressionContextRoot.add(
"Cogs.Frame", frame);
708 expressionContextRoot.add(
"Cogs.Time", renderContext->context->
time->getAnimationTime());
709 expressionContextRoot.add(
"Cogs.TimeDelta", renderContext->context->
time->getAnimationTimeDelta());
710 expressionContextRoot.add(
"Cogs.BackBuffer.width", renderContext->renderer->
getSize().x);
711 expressionContextRoot.add(
"Cogs.BackBuffer.height", renderContext->renderer->
getSize().y);
712 expressionContextRoot.add(
"Cogs.Mouse.x", (
float)context->getDefaultView()->refMouse().getState().position.x);
713 expressionContextRoot.add(
"Cogs.Mouse.y", (
float)context->getDefaultView()->refMouse().getState().position.y);
715 renderContext->expressionContext = &expressionContextRoot;
717 setupAuxPipelines(renderContext,
this, renderList);
718 setupExtraPipelineRuns(renderContext,
this, renderList);
719 setupLightPipelines(renderContext,
this, renderList);
720 setupCameraArrayPipelines(renderContext,
this, renderList);
721 setupCameraPipelines(renderContext,
this, renderList);
724void Cogs::Core::RenderPipelineManager::initializeFrame(
RenderTaskContext * renderContext)
726 Context* context = renderContext->context;
727 const uint32_t frame = context->
time->getFrame();
734 SmallVector<size_t,50> killList;
735 for (
const auto& it : pipelineInstances) {
736 if (it.second->touched != frame) {
737 releasePipelineInstance(renderContext, it.second.get());
738 LOG_DEBUG(logger,
"Killing pipeline %s.", it.second->name.c_str());
739 killList.push_back(it.first);
742 for (
const auto& it : killList) {
743 pipelineInstances.erase(it);
746 assert(currentPipeline.empty());
748 currentPipeline.push_back(generateListTask);
751 static std::vector<PipelineInstance*> instances;
752 instances.reserve(pipelineInstances.size());
753 for (
auto& it : pipelineInstances) {
754 instances.push_back(it.second.get());
759 for (
auto & sc : instance->pipeline.subContexts) {
760 sc->pullVariables(context);
762 for (
RenderTask* task : instance->pipeline.tasks) {
763 currentPipeline.push_back(task);
769 if (instance->renderTarget ==
nullptr) {
771 renderContext->resources->updateResource(r.resource);
777 renderContext->resources->updateResource(r.resource);
779 if (instance->renderTarget !=
nullptr) {
781 renderContext->resources->updateResource(r.resource);
789void Cogs::Core::RenderPipelineManager::applyPipeline(
RenderTaskContext * renderContext)
791 auto frame = renderContext->context->
time->getFrame();
793 for (
auto & task : currentPipeline) {
794 if (task->frameMod != 0) {
795 if ((frame % task->frameMod) != task->frameOffset) {
799 task->apply(renderContext);
805 currentPipeline.clear();
class Entity * getContainer() const
Get the container currently owning this component instance.
Container for components, providing composition of dynamic entities.
constexpr size_t getId() const noexcept
Get the unique identifier of this entity.
const std::string & getName() const noexcept
Get the name of this entity.
Multi-view: Render a set of related views into array texture layers.
uint32_t samples
Number of multi-sampling samples, a value of 0 or 1 implies no multi-sampling.
bool expectsSRGB
Does the colorTexture expect values in sRGB color space.
CameraFlags flags
Camera behavior flags.
std::string renderPipeline
Render pipeline to apply when rendering to texture. Defaults to the built-in forward rendering pipeli...
TextureHandle renderTexture
The render texture to output the rendered scene from the camera to.
std::vector< std::string > renderPipelineOptions
Extra options passed when creating the render pipeline,.
int32_t stackOrder
Specifies the ordering of cameras when rendering to the same render target, lower numbers render befo...
A Context instance contains all the services, systems and runtime components needed to use Cogs.
std::unique_ptr< class Services > services
Services.
std::unique_ptr< class Variables > variables
Variables service instance.
std::unique_ptr< class Time > time
Time service instance.
Defines a single light source and its behavior.
glm::vec2 getSize() const override
Get the output surface size of the renderer.
virtual ICapabilities * getCapabilities()=0
Get a pointer to the capability management interface used to query the graphics device capability fla...
Log implementation class.
Provides a weakly referenced view over the contents of a string.
constexpr bool empty() const noexcept
Check if the string is empty.
static constexpr size_t NoPosition
No position.
std::string to_string() const
String conversion method.
constexpr size_t hash() const noexcept
Get the hash code of the string.
Contains the Engine, Renderer, resource managers and other systems needed to run Cogs....
constexpr Log getLogger(const char(&name)[LEN]) noexcept
constexpr size_t hash() noexcept
Simple getter function that returns the initial value for fnv1a hashing.
constexpr size_t hashSequence(const T &t, const U &u)
Hash the last two items in a sequence of objects.
Contains data describing a Camera instance and its derived data structured such as matrix data and vi...
Provides a context for evaluation of expressions.
Defines calculated light data.
std::string name
Friendly name used for debugging.
RenderTexture * renderTarget
Render-target that this pipeline outputs to, nullptr for default rendertarget.
Runtime control variable.
virtual const GraphicsDeviceCapabilities & getDeviceCapabilities() const
Gets the device capabilities in a structure.
@ DepthBuffer
The texture can be used as a depth target and have depth buffer values written into.