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->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);
234 if (wasCreated || instance->dataHash != dataHash || !isPipelineFresh(renderContext, instance->pipeline)) {
235 releasePipelineInstance(renderContext, instance);
236 instance->dataHash = dataHash;
238 for (
size_t viewportIndex = 0; viewportIndex < lightData.maxViewports; viewportIndex++) {
239 const size_t arrayIndex = viewportIndex + lightData.arrayOffset;
241 instance->pipeline.updateResources.add(renderTexture->renderTargets[arrayIndex]);
244 resources.add(renderTexture->renderTargets[arrayIndex],
"Cogs.BackBuffer");
245 resources.add(renderList,
"Cogs.RenderList");
247 createPipeline(renderContext, manager->definitionByPath(renderContext->context, shadowPath), resources, instance->pipeline, shadowPath, &lightData.lightCameraData[viewportIndex], instance->options);
249 for (
size_t taskIndex = viewportIndex * 2; taskIndex < viewportIndex * 2 + 2; ++taskIndex) {
250 instance->pipeline.tasks[taskIndex]->frameMod = 0;
251 instance->pipeline.tasks[taskIndex]->frameOffset = 0;
252 if (lightData.shadowUpdate == ShadowUpdate::Static || lightData.shadowUpdate == ShadowUpdate::StaticPartial) {
253 instance->pipeline.tasks[taskIndex]->flags = (RenderTaskFlags::ERenderTaskFlags)((
int)instance->pipeline.tasks[taskIndex]->flags | (int)RenderTaskFlags::Static);
257 if (!wasCreated) LOG_DEBUG(logger,
"Updated light pipeline");
258 manager->dirty =
true;
264 std::vector<const Variable*> vars;
265 renderContext->context->
variables->getMatchingVariables(vars,
"renderer.auxiliaryPipelines.");
267 for (
const auto * var : vars) {
268 if (var->getValue().empty())
continue;
270 std::vector<Cogs::StringView> tokens;
271 split(var->getValue(),
":", tokens);
272 if (tokens.empty() || 2 < tokens.size()) {
273 LOG_ERROR_ONCE(logger,
"Failed to tokenize %.*s: '%.*s'", StringViewFormat(var->getName()), StringViewFormat(var->getValue()));
281 if (1 < tokens.size()) {
282 priority = std::stoi(tokens[1].to_string());
287 instance->name = var->getName().to_string();
288 instance->options.push_back( {
"Pass",
"Offscreen" });
289 LOG_DEBUG(logger,
"%s aux pipeline run for %s: %.*s", wasCreated ?
"Creating" :
"Updating", instance->name.c_str(), StringViewFormat(pipeline));
292 setupCameraPipeline(renderContext, manager,
293 instanceKey, dataHash, pipeline, priority,
294 initFunc,
nullptr,
nullptr,
nullptr, renderList);
302 if (run->enabled && !run->pipeline.empty()) {
307 if (run->renderTexture) {
308 renderTexture = getRenderTexture(renderContext, dataHash, run->renderTexture, run->name,
true);
314 instance->options.push_back( {
"Pass",
"Offscreen" });
315 if (!renderTexture) {
316 resources.add(renderContext->defaultRenderTarget,
"Cogs.BackBuffer");
317 instance->options.push_back({
"Pass",
"Onscreen" });
319 LOG_DEBUG(logger,
"%s extra pipeline run for %s: %s", wasCreated ?
"Creating" :
"Updating", instance->name.c_str(), run->pipeline.c_str());
322 setupCameraPipeline(renderContext, manager,
323 instanceKey, dataHash, run->pipeline, run->priority,
324 initFunc,
nullptr, run->cameraData, renderTexture, renderList);
331 for (
auto & light : renderContext->context->lightSystem->pool) {
332 auto & lightData = renderContext->context->lightSystem->getData(&light);
334 if (!lightData.enabled || !lightData.castShadows)
continue;
336 setupLightPipeline(renderContext, manager, light, lightData, lightData.shadowTexture, renderList);
341 size_t& dataHash,
RenderTexture* renderTexture,
size_t targetIndex,
342 uint32_t multiViewCount, uint32_t multiViewSamples,
346 if (1 < multiViewCount) {
347 camArrData.passOptions = camArrData.camData.passOptions ? *camArrData.camData.passOptions :
RenderPassOptions{};
348 camArrData.camData.passOptions = &camArrData.passOptions;
349 camArrData.passOptions.multiViews = multiViewCount;
352 if (!renderTexture->renderTargets[targetIndex]) {
353 RenderTarget* renderTarget = renderContext->resources->createRenderTarget();
354 renderTarget->setName(name.
to_string() +
" MV-RT[" + std::to_string(targetIndex) +
":" + std::to_string(multiViewCount) +
"]");
355 renderTarget->textures.push_back(renderTexture);
356 renderTarget->layerIndex = uint16_t(targetIndex);
357 renderTarget->depth = renderTexture->depthTexture;
358 renderTarget->depthLayerIndex = uint16_t(targetIndex);
359 if (1 < multiViewCount) {
360 renderTarget->multiViewBaseIndex = 0;
361 renderTarget->multiViewCount =
static_cast<uint8_t
>(multiViewCount);
362 renderTarget->multiViewSamples =
static_cast<uint8_t
>(std::min(255u, multiViewSamples));
364 renderTarget->width = renderTexture->description.width;
365 renderTarget->height = renderTexture->description.height;
366 renderTarget->samples = renderTexture->description.samples;
367 renderTarget->expectsSRGB = camArrComp.
expectsSRGB;
368 renderTexture->renderTargets[targetIndex] = renderTarget;
370 dataHash =
Cogs::hashSequence(dataHash,
reinterpret_cast<intptr_t
>(renderTexture->renderTarget));
374 size_t& dataHash,
RenderTexture* renderTexture,
size_t targetIndex,
377 switch (camArrData.depthMode) {
379 case CameraArrayData::DepthMode::None:
382 case CameraArrayData::DepthMode::Create:
383 if (!renderTexture->depthTexture) {
384 RenderTexture* depthTexture = renderContext->resources->createRenderTexture();
385 depthTexture->setName(name.
to_string() +
" DT");
386 depthTexture->description.target = renderTexture->description.target;
388 depthTexture->description.format = Cogs::TextureFormat::R32_TYPELESS;
389 depthTexture->layers = renderTexture->description.layers;
390 depthTexture->samples = renderTexture->description.samples;
391 depthTexture->sizeSource = renderTexture;
392 renderTexture->depthTexture = depthTexture;
394 dataHash =
Cogs::hashSequence(dataHash,
reinterpret_cast<intptr_t
>(renderTexture->depthTexture));
397 case CameraArrayData::DepthMode::Provided:
398 if (!renderTexture->depthTexture) {
399 renderTexture->depthTexture = getRenderTexture(renderContext, dataHash, camArrData.depthTextures[targetIndex], name,
false);
401 dataHash =
Cogs::hashSequence(dataHash,
reinterpret_cast<intptr_t
>(renderTexture->depthTexture));
405 assert(
false &&
"Illegal enum");
411 const size_t dataHash,
RenderTexture* renderTexture,
size_t targetIndex,
415 Cogs::StringView pipeline = camArrData.pipeline.empty() ? forwardPath : camArrData.pipeline;
417 PipeInitFunc initFunc = [targetIndex, &name, &pipeline, renderTexture, updateDepth = camArrData.depthMode == CameraArrayData::DepthMode::Create](
PipelineInstance* instance,
RenderTaskResources& resources,
bool wasCreated)
419 instance->
name = name.to_string();
422 instance->pipeline.updateResources.add(renderTexture->depthTexture);
424 instance->pipeline.updateResources.add(renderTexture->renderTargets[targetIndex]);
425 resources.add(renderTexture->renderTargets[targetIndex],
"Cogs.BackBuffer");
429 expressionContext.add(
"Cogs.BackBuffer.width", renderTexture->description.width);
430 expressionContext.add(
"Cogs.BackBuffer.height", renderTexture->description.height);
435 LOG_DEBUG(logger,
"%s offscreen camera pipeline for %s: %.*s", wasCreated ?
"Creating" :
"Updating", instance->
name.c_str(), StringViewFormat(pipeline));
438 setupCameraPipeline(renderContext, manager,
440 initFunc, &camComp, &camArrData.camData,
nullptr, renderList);
451 for (
const CameraArrayComponent& camArrComp : renderContext->context->cameraArraySystem->pool) {
453 CameraArrayData& camArrData = renderContext->context->cameraArraySystem->getData(&camArrComp);
454 if (camArrData.textureMode == CameraArrayData::TextureMode::None) {
461 name_ =
"CameraArray@" + std::to_string(entity->
getId());
465 assert(camArrData.camData.camera);
466 const CameraComponent& camComp = renderContext->context->cameraSystem->pool[camArrData.camData.camera.index];
469 switch (camArrData.textureMode) {
471 case CameraArrayData::TextureMode::TextureArray: {
473 if (
RenderTexture* renderTexture = getRenderTexture(renderContext, dataHash, camArrData.colorTextures[0], name,
false); renderTexture) {
476 setupCameraArrayDepthTarget(renderContext, dataHash, renderTexture, 0, camArrData, name);
479 if ((1 < renderTexture->description.layers) && multiView) {
480 setupCameraArrayRenderTarget(renderContext, dataHash, renderTexture, 0, renderTexture->description.layers, camArrComp.
samples, camArrComp, camArrData, name);
481 setupCameraArrayDraw(renderContext, manager, renderList, dataHash, renderTexture, 0, camArrData, camComp, name, instanceKey);
485 for (
size_t l = 0; l < renderTexture->description.layers; l++) {
486 setupCameraArrayRenderTarget(renderContext, dataHash, renderTexture, l, 1, 1, camArrComp, camArrData, name);
488 for (
size_t l = 0; l < renderTexture->description.layers; l++) {
489 setupCameraArrayDraw(renderContext, manager, renderList, dataHash, renderTexture, l, camArrData, camComp, name,
Cogs::hashSequence(instanceKey,
static_cast<intptr_t
>(l)));
496 case CameraArrayData::TextureMode::ArrayOfTextures:
497 for (
size_t l = 0; l < camArrData.numViews; l++) {
499 if (
RenderTexture* renderTexture = getRenderTexture(renderContext, dataHash, camArrData.colorTextures[l], name,
false); renderTexture) {
500 setupCameraArrayDepthTarget(renderContext, dataHash, renderTexture, l, camArrData, name);
501 setupCameraArrayRenderTarget(renderContext, dataHash, renderTexture, l, 1, 1, camArrComp, camArrData, name);
502 setupCameraArrayDraw(renderContext, manager, renderList, dataHash, renderTexture, l, camArrData, camComp, name,
Cogs::hashSequence(instanceKey,
static_cast<intptr_t
>(l)));
507 case CameraArrayData::TextureMode::None: [[fallthrough]];
509 assert(
false &&
"Illegal enum");
516 size_t cameraInstanceKey(
const CameraData& camData,
bool isMainCamera)
523 std::string nameTemp;
524 const bool defaultTargetRender = renderContext->context->
variables->get(
"renderer.defaultTarget.render",
true);
526 const CameraComponent* mainCamComp = renderContext->context->cameraSystem->getMainCamera();
527 for(
const CameraComponent& camComp : renderContext->context->cameraSystem->pool) {
529 if ((camComp.
flags & CameraFlags::EnableRender) == 0) {
continue; }
535 nameTemp =
"Camera, entity=" + std::to_string(entity->
getId());
544 bool isMainCamera = &camComp == mainCamComp;
548 if (
const Variable* var1 = renderContext->context->
variables->get(
"renderer.pipeline.override"); var1 && !var1->isEmpty() && !var1->getValue().empty()) {
549 pipeline = var1->getCString();
553 else if (
const Variable* var2 = renderContext->context->
variables->get(
"renderer.pipeline"); var2 && !var2->isEmpty() && !var2->getValue().empty()) {
554 pipeline = var2->getCString();
560 renderTexture = getRenderTexture(renderContext, dataHash, camComp.
renderTexture, name,
true);
564 if (renderTexture ==
nullptr && defaultTargetRender ==
false) {
572 if (!renderTexture) {
573 resources.add(renderContext->defaultRenderTarget,
"Cogs.BackBuffer");
576 LOG_DEBUG(logger,
"Creating main camera pipeline for %s: %.*s", instance->name.c_str(), StringViewFormat(pipeline));
580 const CameraData& camData = renderContext->context->cameraSystem->getData(&camComp);
581 setupCameraPipeline(renderContext, manager,
582 cameraInstanceKey(camData, isMainCamera), dataHash, pipeline, (renderTexture ? 300 : 400) + camComp.
stackOrder,
583 initFunc, &camComp, &camData, renderTexture, renderList);
592void Cogs::Core::RenderPipelineManager::initialize(
RenderTaskContext* renderContext)
594 renderList = renderContext->resources->createRenderList();
595 renderList->setName(
"Cogs.RenderList");
597 std::list<std::unique_ptr<SubContext>> subContexts;
600 taskDefinition.name =
"Cogs.GenerateList";
601 taskDefinition.type =
"GenerateList";
602 generateListTask = createRenderTask(renderContext, taskDefinition, subContexts, &expressionContextRoot);
603 generateListTask->output.add(renderList);
604 generateListTask->flags = RenderTaskFlags::Persistent;
609 if (!renderList)
return;
611 assert(generateListTask);
612 destroyRenderTask(renderContext, generateListTask);
613 generateListTask =
nullptr;
615 assert(!renderList->isOwned());
616 renderContext->renderer->getRenderResources().releaseResource(renderList);
617 renderContext->renderer->getRenderResources().destroyResource(renderList);
618 renderList =
nullptr;
620 for (
auto& pipeline : pipelineInstances) {
621 releasePipelineInstance(renderContext, pipeline.second.get());
626Cogs::Core::RenderPipelineManager::definitionByPath(
Context* context,
const StringView& path)
630 auto p1 = definitions.emplace(
hash, std::make_unique<RenderPipelineDefinition>(parsePipeline(context, myPath)));
631 assert(p1.first->second.get());
632 auto& definition = *(p1.first->second.get());
633 if (!definition.name.empty()) {
634 nameMap.insert({ definition.name,
hash });
635 if (!p1.second) LOG_WARNING(logger,
"Collision in nameMap when inserting %s, hash=%zd.", definition.name.c_str(),
hash);
638 for (
auto& generator : definition.generators) {
639 if (!definition.name.empty()) {
642 auto pp1 = definitions.emplace(genHash, std::make_unique<RenderPipelineDefinition>(generator));
643 assert(pp1.first->second.get());
644 if (!pp1.second) LOG_WARNING(logger,
"Collision in hashes when inserting %s, hash=%zd.", generator.name.c_str(), genHash);
646 auto pp2 = nameMap.emplace(generator.name, genHash);
647 if (!pp2.second) LOG_WARNING(logger,
"Collision in nameMap when inserting %s, hash=%zd.", generator.name.c_str(), genHash);
654 auto queryLoc = path.find(
"?");
657 size_t hash1 = trimmedPath.hash();
658 if (
auto it = definitions.find(hash1); it != definitions.end()) {
659 return *(it->second.get());
662 auto& def1 = insert(hash1, trimmedPath);
666 std::vector<StringParameter> importStack = def1.imports;
668 while (!importStack.empty())
671 importStack.pop_back();
674 if (!definitions.contains(hash2)) {
675 const auto& def2 = insert(hash2, item.value);
676 for (
auto& importValue : def2.imports) {
677 importStack.push_back(importValue);
681 nameMap.insert({ item.key, hash2 });
684 for (
const auto& it : definitions) {
685 assert(it.second.get());
691std::pair< Cogs::Core::PipelineInstance*, bool> Cogs::Core::RenderPipelineManager::instanceByKey(
Context* context,
size_t key)
693 auto it = pipelineInstances.find(key);
694 if (it == pipelineInstances.end()) {
695 auto instance = pipelineInstances.emplace(key, std::make_unique<PipelineInstance>()).first->second.get();
696 instance->touched = context->
time->getFrame();
697 return std::make_pair(instance,
true);
699 auto* instance = it->second.get();
700 instance->touched = context->
time->getFrame();
701 return std::make_pair(instance,
false);
704void Cogs::Core::RenderPipelineManager::setupPipeline(
RenderTaskContext * renderContext)
706 Context* context = renderContext->context;
707 uint32_t frame = context->
time->getFrame();
709 renderList->viewportData = renderContext->cameraData;
711 expressionContextRoot.add(
"Cogs.Frame", frame);
712 expressionContextRoot.add(
"Cogs.Time", renderContext->context->
time->getAnimationTime());
713 expressionContextRoot.add(
"Cogs.TimeDelta", renderContext->context->
time->getAnimationTimeDelta());
714 expressionContextRoot.add(
"Cogs.BackBuffer.width", renderContext->renderer->
getSize().x);
715 expressionContextRoot.add(
"Cogs.BackBuffer.height", renderContext->renderer->
getSize().y);
716 expressionContextRoot.add(
"Cogs.Mouse.x", (
float)context->getDefaultView()->refMouse().getState().position.x);
717 expressionContextRoot.add(
"Cogs.Mouse.y", (
float)context->getDefaultView()->refMouse().getState().position.y);
719 renderContext->expressionContext = &expressionContextRoot;
721 setupAuxPipelines(renderContext,
this, renderList);
722 setupExtraPipelineRuns(renderContext,
this, renderList);
723 setupLightPipelines(renderContext,
this, renderList);
724 setupCameraArrayPipelines(renderContext,
this, renderList);
725 setupCameraPipelines(renderContext,
this, renderList);
728void Cogs::Core::RenderPipelineManager::initializeFrame(
RenderTaskContext * renderContext)
730 Context* context = renderContext->context;
731 const uint32_t frame = context->
time->getFrame();
738 SmallVector<size_t,50> killList;
739 for (
const auto& it : pipelineInstances) {
740 if (it.second->touched != frame) {
741 releasePipelineInstance(renderContext, it.second.get());
742 LOG_DEBUG(logger,
"Killing pipeline %s.", it.second->name.c_str());
743 killList.push_back(it.first);
746 for (
const auto& it : killList) {
747 pipelineInstances.erase(it);
750 assert(currentPipeline.empty());
752 currentPipeline.push_back(generateListTask);
755 static std::vector<PipelineInstance*> instances;
756 instances.reserve(pipelineInstances.size());
757 for (
auto& it : pipelineInstances) {
758 instances.push_back(it.second.get());
763 for (
auto & sc : instance->pipeline.subContexts) {
764 sc->pullVariables(context);
766 for (
RenderTask* task : instance->pipeline.tasks) {
767 currentPipeline.push_back(task);
773 if (instance->renderTarget ==
nullptr) {
775 renderContext->resources->updateResource(r.resource);
781 renderContext->resources->updateResource(r.resource);
783 if (instance->renderTarget !=
nullptr) {
785 renderContext->resources->updateResource(r.resource);
793void Cogs::Core::RenderPipelineManager::applyPipeline(
RenderTaskContext * renderContext)
795 auto frame = renderContext->context->
time->getFrame();
797 for (
auto & task : currentPipeline) {
798 if (task->frameMod != 0) {
799 if ((frame % task->frameMod) != task->frameOffset) {
803 task->apply(renderContext);
809 currentPipeline.clear();
Vector with inline storage for up to Size elements, avoiding heap allocation for small collections.
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.