3#include "Foundation/Logging/Logger.h"
6#include "MemoryContext.h"
9#include "RenderPipelineManager.h"
10#include "RenderStateUpdater.h"
11#include "RenderTarget.h"
13#include "CustomRenderer/BoundsRenderer.h"
14#include "CustomRenderer/DebugGeometryRenderers.h"
16#include "Rendering/Factory.h"
17#include "Rendering/ICapabilities.h"
18#include "Rendering/IContext.h"
19#include "Rendering/IGraphicsDevice.h"
20#include "Rendering/ITextures.h"
21#include "Rendering/IRenderTargets.h"
23#include "Resources/ResourceStore.h"
24#include "Resources/Texture.h"
25#include "Services/Variables.h"
26#include "Systems/Core/CameraSystem.h"
27#include "Systems/Core/EnvironmentSystem.h"
28#include "Systems/Core/LightSystem.h"
29#include "Utilities/Parsing.h"
31#include "InspectorGui/InspectorGuiRenderer.h"
33#include <glm/gtc/color_space.hpp>
39 void addLights(std::vector<const LightComponent*>& dst,
size_t& freeSlots, uint32_t& srcCount,
const std::vector<const LightComponent*>& src)
41 srcCount =
static_cast<uint32_t
>(std::min(freeSlots, src.size()));
42 freeSlots -= srcCount;
44 for (
size_t i = 0; i < srcCount; i++) {
45 dst.push_back(src[i]);
49 void buildSortedListOfActiveLights(
Context* context,
ActiveLights& activeLights,
const size_t maxLights)
54 std::vector<const LightComponent*> directionalShadowLights;
55 std::vector<const LightComponent*> pointShadowLights;
56 std::vector<const LightComponent*> directionalLights;
57 std::vector<const LightComponent*> pointLights;
58 const bool shadowsEnabled = context->
variables->get(
"renderer.shadowsEnabled",
false);
64 if (light.
lightType == LightType::Directional) {
65 directionalShadowLights.push_back(&light);
67 else if (light.
lightType == LightType::Point) {
68 pointShadowLights.push_back(&light);
72 if (light.
lightType == LightType::Directional) {
73 directionalLights.push_back(&light);
75 else if (light.
lightType == LightType::Point) {
76 pointLights.push_back(&light);
81 size_t numLightsTotal = directionalShadowLights.size() + directionalLights.size() + pointShadowLights.size() + pointLights.size();
82 if (maxLights < numLightsTotal) {
83 LOG_WARNING_ONCE(logger,
"More active lights (=%zu) than supported (=%zu)", numLightsTotal, maxLights);
86 activeLights.lights.clear();
87 size_t freeLightSlots = maxLights;
88 addLights(activeLights.lights, freeLightSlots, activeLights.numDirectionalShadowLights, directionalShadowLights);
89 addLights(activeLights.lights, freeLightSlots, activeLights.numDirectionalLights, directionalLights);
90 addLights(activeLights.lights, freeLightSlots, activeLights.numPointShadowLights, pointShadowLights);
91 addLights(activeLights.lights, freeLightSlots, activeLights.numPointLights, pointLights);
93 assert(activeLights.lights.size() <= maxLights);
115 renderContext.context = renderer->context;
116 renderContext.renderer = renderer;
117 renderContext.device = renderer->device;
118 renderContext.resources = &renderer->resources;
119 renderContext.states = &renderer->renderStates;
120 renderContext.engineBuffers = &renderer->engineBuffers;
121 renderContext.defaultRenderTarget = renderer->defaultTarget;
123 return renderContext;
130 drawContext.context = renderContext->context;
131 drawContext.renderer = renderContext->renderer;
132 drawContext.device = renderContext->device;
134 drawContext.cameraData = renderContext->cameraData;
135 drawContext.renderTarget = renderContext->defaultRenderTarget;
136 drawContext.engineBuffers = renderContext->engineBuffers;
137 drawContext.taskContext = renderContext;
138 drawContext.permutationIndex = 0;
145Cogs::Core::Renderer::Renderer(
Context * context) :
148 enginePermutations(context),
149 effectBindings(context->memory.get()),
156Cogs::Core::Renderer::~Renderer()
163 LOG_FATAL(logger,
"Cannot initialize renderer with nullptr device.");
167 Instrumentation::initializeGpu(context);
170 this->device = device;
172 auto backColor = context->
variables->get(
"renderer.backgroundColor", glm::vec4(0.5, 0.5, 0.5, 1));
173 setBackgroundColor(backColor);
178 context->
variables->set(
"renderer.DedicatedVideoMemoryMB", (
int)(device_capabilities.DedicatedVideoMemory/(1024*1024)));
179 context->
variables->set(
"renderer.DedicatedSystemMemoryMB", (
int)(device_capabilities.DedicatedSystemMemory/(1024*1024)));
180 context->
variables->set(
"renderer.SharedSystemMemoryMB", (
int)(device_capabilities.SharedSystemMemory/(1024*1024)));
183 enginePermutations.initialize(context);
184 renderStates.initialize(device);
186 resources.initialize(context,
this);
188 defaultTarget = resources.createRenderTarget();
191 initializeEngineBindGroups(device->getBindGroups(), engineBindGroups);
193 renderContext = getRenderTaskContext(
this);
194 pipelineManager->initialize(&renderContext);
196 renderers->boundsRenderer.initialize(
this, device);
197 renderers->debugGeometryRenderer.initialize(
this, device);
198 renderers->imguiRenderer.initialize(context);
199 renderers->engineInspectorGuiRenderer.initialize(context,
this);
202 settings.anisotropicFiltering = context->
variables->get(
"renderer.anisotropicFiltering");
204 for (
auto & extension : extensions) {
205 extension->initialize(context, device);
211 renderers->debugGeometryRenderer.cleanup();
214 resources.releaseResource(defaultTarget);
217 pipelineManager->cleanup(&renderContext);
219 renderers->engineInspectorGuiRenderer.cleanup(context,
this);
220 renderers->imguiRenderer.cleanup();
222 if (context && context->
variables->get(
"renderer.reportLeaks",
false)) {
223 resources.cleanup(context);
226 renderStates.cleanup();
237 bool reverseDepth = context->
variables->get(
"renderer.reverseDepth",
false);
238 if(renderStates.reverseDepth != reverseDepth){
239 renderStates.reverseDepth = reverseDepth;
240 pipelineManager->dirty =
true;
242 renderStates.setupDepthStates(device);
248 if(reverseDepth) comparisonSamplerState.comparisonFunction = SamplerState::GreaterEqual;
249 else comparisonSamplerState.comparisonFunction = SamplerState::LessEqual;
251 for (
unsigned i = 0; i < 4; i++) {
252 if(reverseDepth) comparisonSamplerState.borderColor[i] = 0.f;
253 else comparisonSamplerState.borderColor[i] = 1.f;
256 renderStates.shadowSampler = textures->loadSamplerState(comparisonSamplerState);
262 renderContext.cameraData = &context->cameraSystem->getMainCameraData();
264 defaultTarget->setName(
"Cogs.BackBuffer");
265 defaultTarget->setOverride();
268 defaultTarget->width =
static_cast<int>(renderContext.cameraData->viewportSize.x);
269 defaultTarget->height =
static_cast<int>(renderContext.cameraData->viewportSize.y);
270 defaultTarget->samples = device->getSettings().
numSamples;
271 defaultTarget->clearColors = { backgroundColor };
273 const bool reloadEffects = context->
variables->get(
"renderer.reloadEffects",
false);
276 effectCache.reload(&renderContext);
277 context->
variables->set(
"renderer.reloadEffects",
false);
280 pipelineManager->setupPipeline(&renderContext);
282 buildSortedListOfActiveLights(context, activeLights, maxLights);
285 const auto eventContext = getDrawContext(&renderContext);
291 int samples = context->
variables->get(
"renderer.samples", 1);
292 context->
variables->set(
"impl.multiSample", samples > 1);
295 pipelineManager->initializeFrame(&renderContext);
296 updateLightTexturesBindGroup(&renderContext);
297 pipelineManager->applyPipeline(&renderContext);
302 renderers->boundsRenderer.renderBounds(
this, context, *pipelineManager->getRenderList());
306 const auto eventContext = getDrawContext(&renderContext);
311 renderers->engineInspectorGuiRenderer.beginRender(context,
this);
312 renderers->engineInspectorGuiRenderer.render(context,
this);
314 if (context->callbacks.postRenderCallback) {
315 context->callbacks.postRenderCallback(context);
318 renderers->engineInspectorGuiRenderer.endRender(context,
this);
321 const DrawContext eventContext = getDrawContext(&renderContext);
323 context->cameraSystem->postRender(context);
326 pipelineManager->cleanupFrame(&renderContext);
332 this->backgroundColor = glm::vec4(glm::convertSRGBToLinear(glm::vec3(backgroundColor)),
336void Cogs::Core::Renderer::updateEffectFlags()
339 if (context->
variables->get(
"effects.logShaderInfo",
false)) {
342 if (context->
variables->get(
"effects.logShaderSource",
false)) {
348void Cogs::Core::Renderer::updateSettings()
351 if(context->
variables->exist(
"renderer.enableDeferred")){
352 static uint32_t t = 0;
355 LOG_WARNING(logger,
"Variable \"renderer.enableDeferred\" deprecated. Use \"renderer.pipeline\": \"Pipelines/Deferred.pipeline\".");
357 if(context->
variables->get(
"renderer.enableDeferred",
false))
358 context->
variables->set(
"renderer.pipeline",
"Pipelines/Deferred.pipeline");
364 default: settings.transparencyAlgorithm = RenderSettings::TransparencyAlgorithm::Regular;
break;
373 default: settings.blendKernel = RenderSettings::BlendKernel::Alpha;
break;
376 settings.defaultRenderTargetClear = context->
variables->get(
"renderer.backBuffer.clear.enable",
true);
378 if (
Variable* var = context->
variables->get(
"renderer.backBuffer.sRGB"); var->isEmpty()) {
379 switch (context->device->getType()) {
381 settings.defaultRenderTargetExpectsSRGB =
true;
384 settings.defaultRenderTargetExpectsSRGB =
false;
387 var->setBool(settings.defaultRenderTargetExpectsSRGB);
390 settings.defaultRenderTargetExpectsSRGB = var->getBool();
395 if (var->isEmpty()) {
396 var->setValue(
"Exact");
409 settings.sRGBConversion = RenderSettings::SRGBConversion::Exact;
415 if (var->isEmpty()) {
416 var->setValue(
"Filmic");
432 settings.tonemapper = RenderSettings::Tonemapper::Filmic;
436 settings.beersScaleFactor = context->
variables->get(
"renderer.beers.scaleFactor", 1.f);
438 settings.ambientIntensity = context->
variables->get(
"renderer.ambientLightIntensity", 0.f);
439 std::string acStr = context->
variables->get(
"renderer.ambientLightColor",
"1 1 1");
440 static std::string prev;
443 auto acTokens = tokenize(acStr);
444 parseValues(glm::value_ptr(settings.ambientColor), acTokens, 3);
447 settings.ambientColor = glm::convertSRGBToLinear(settings.ambientColor);
455 return projectionMatrix;
458 if(context->
variables->get(
"renderer.reverseDepth",
false)){
459 static glm::mat4 reverse(
465 projectionMatrix = reverse * projectionMatrix;
474 static glm::mat4 depthScale = glm::scale(glm::mat4(1.0f), glm::vec3(1, 1, 0.5f));
475 static glm::mat4 bias(
482 glm::mat4 projection = depthScale * bias * projectionMatrix;
488 static glm::mat4 depthScale = glm::scale(glm::mat4(1.0f), glm::vec3(1, -1, 0.5f));
489 static glm::mat4 bias(
496 glm::mat4 projection = depthScale * bias * projectionMatrix;
503 return projectionMatrix;
506 static glm::mat4 depthScale = glm::scale(glm::mat4(1.0f), glm::vec3(1, 1, 0.5f));
507 static glm::mat4 bias(
514 glm::mat4 projection = depthScale * bias * projectionMatrix;
519 return projectionMatrix;
522 LOG_WARNING(logger,
"Unknown device type.");
523 return projectionMatrix;
529 return inverseProjectionMatrix;
537 glm::vec4 x = glm::vec4(0.1, 0.2, 0.3, 1.0);
538 glm::mat4 clipFromViewport (
544 return inverseProjectionMatrix * clipFromViewport;
549 return inverseProjectionMatrix;
554 glm::mat4 scale = glm::scale(glm::mat4(1.0), glm::vec3(2.0, 2.0, 2.0));
555 static glm::mat4 bias(
561 return inverseProjectionMatrix * bias * scale;
564 glm::mat4 scale = glm::scale(glm::mat4(1.0), glm::vec3(2.0, 2.0, 1.0));
565 static glm::mat4 bias(
571 return inverseProjectionMatrix * bias * scale;
574 return inverseProjectionMatrix;
577 LOG_WARNING(logger,
"Unknown device type.");
578 return inverseProjectionMatrix;
583 if(context->
variables->get(
"renderer.reverseDepth",
false)) {
590 if(context->
variables->get(
"renderer.reverseDepth",
false)) {
612 device->
endFrame(syncInterval, presentFlags);
622 extensions.push_back(extension);
625 extension->initialize(context, device);
631 auto it = std::find(extensions.begin(), extensions.end(), extension);
632 assert(it != extensions.end() &&
"Unregistering unknown IRendererExtension");
633 if (it != extensions.end()) {
634 extensions.erase(it);
645 auto format = TextureFormat::R8G8B8A8_UNORM_SRGB;
647 const size_t size = (size_t)settings.width * (
size_t)settings.height * Cogs::getBlockSize(format);
654 if(settings.numSamples > 1)
655 desc.target = ResourceDimensions::Texture2DMS;
657 desc.target = ResourceDimensions::Texture2D;
658 desc.width = settings.width;
659 desc.height = settings.height;
660 desc.format = format;
661 desc.samples = settings.numSamples;
663 texture = textures->loadTexture(desc,
nullptr);
666 auto renderTarget = renderTargets->createRenderTarget(&texture, 1);
667 auto depthStencilTarget = renderTargets->createDepthStencilTarget(renderTarget);
669 auto camera = context->cameraSystem->getMainCamera();
670 auto restoreViewport = camera->viewportSize;
671 camera->viewportSize = glm::vec2(settings.width, settings.height);
672 context->cameraSystem->update(context);
674 renderContext.cameraData = &context->cameraSystem->getMainCameraData();
676 pipelineManager->setupPipeline(&renderContext);
678 auto restoreRenderTargetHandle = defaultTarget->renderTargetHandle;
679 auto restoreDepthTargetHandle = defaultTarget->depthTargetHandle;
680 auto restoreWidth = defaultTarget->width;
681 auto restoreHeight = defaultTarget->height;
682 auto restoreSamples = defaultTarget->samples;
683 auto restoreColors = std::move(defaultTarget->clearColors);
685 defaultTarget->renderTargetHandle = renderTarget;
686 defaultTarget->depthTargetHandle = depthStencilTarget;
687 defaultTarget->width = settings.width;
688 defaultTarget->height = settings.height;
689 defaultTarget->samples = settings.numSamples;
690 defaultTarget->clearColors = { backgroundColor };
692 pipelineManager->initializeFrame(&renderContext);
693 pipelineManager->applyPipeline(&renderContext);
694 pipelineManager->cleanupFrame(&renderContext);
696 if (settings.numSamples > 1) {
698 auto resolveRt = renderTargets->createRenderTarget(&resolveTexture, 1);
699 auto resolveDt = renderTargets->createDepthStencilTarget(resolveRt);
701 deviceContext->resolveResource(texture, resolveTexture);
703 deviceContext->setRenderTarget(resolveRt, resolveDt);
705 deviceContext->readColorBuffer(readBuffer, 0, 0, settings.width, settings.height,
Framebuffer::Front);
707 renderTargets->releaseDepthStencilTarget(resolveDt);
708 renderTargets->releaseRenderTarget(resolveRt);
709 textures->releaseTexture(resolveTexture);
711 deviceContext->setRenderTarget(renderTarget, depthStencilTarget);
713 deviceContext->readColorBuffer(readBuffer, 0, 0, settings.width, settings.height,
Framebuffer::Front);
720 const size_t bufferSize = data.getStride() ? data.getStride() * settings.height : size;
721 bytes.assign(data.get(), data.get() + bufferSize);
724 *stride = data.getStride();
729 defaultTarget->renderTargetHandle = restoreRenderTargetHandle;
730 defaultTarget->depthTargetHandle = restoreDepthTargetHandle;
731 defaultTarget->width = restoreWidth;
732 defaultTarget->height = restoreHeight;
733 defaultTarget->samples = restoreSamples;
734 defaultTarget->clearColors = std::move(restoreColors);
736 camera->viewportSize = restoreViewport;
738 buffers->releaseBuffer(readBuffer);
739 renderTargets->releaseDepthStencilTarget(depthStencilTarget);
740 renderTargets->releaseRenderTarget(renderTarget);
741 textures->releaseTexture(texture);
746 for (
auto extension : extensions) {
747 extension->handleEvent(eventId, renderingContext);
753 const bool ditherEnabled = context->
variables->get(
"renderer.ditherEnabled",
false);
754 if(permutation->hasVariant(
"Dither"))
755 permutation->setVariant(
"Dither", ditherEnabled);
757 const bool reverseDepth = context->
variables->get(
"renderer.reverseDepth",
false);
758 if(permutation->hasVariant(
"ReverseDepth"))
759 permutation->setVariant(
"ReverseDepth", reverseDepth);
761 if(permutation->hasVariant(
"DepthNegativeOneToOne"))
764 if (!permutation->hasBuiltins())
return;
765 if (!permutation->isShadingPass() || permutation->isDepthOnly())
return;
767 if (
auto ec = context->environmentSystem->getGlobalEnvironment(); ec !=
nullptr) {
768 permutation->setVariant(
"SubseaSupport", ec->subseaSupport);
769 if(ec->imageBasedLighting) {
771 permutation->setVariant(
"ImageBasedLighting",
"PBR");
773 permutation->setVariant(
"ImageBasedLighting",
"Phong");
776 permutation->setVariant(
"ImageBasedLighting",
"Disabled");
781 const bool shadowsEnabled = (activeLights.numDirectionalShadowLights != 0) || (activeLights.numPointShadowLights != 0);
782 permutation->setVariant(
"NumDirectionalShadowLights",
static_cast<int>(activeLights.numDirectionalShadowLights));
783 permutation->setVariant(
"NumPointShadowLights",
static_cast<int>(activeLights.numPointShadowLights));
784 permutation->setVariant(
"NumDirectionalLights",
static_cast<int>(activeLights.numDirectionalLights));
785 permutation->setVariant(
"NumPointLights",
static_cast<int>(activeLights.numPointLights));
786 permutation->setVariant(
"ShadowsEnabled", shadowsEnabled);
787 if (shadowsEnabled) {
788 const Cogs::Core::SoftShadows softShadows = parseEnum<SoftShadows>(context->
variables->get(
"shadows.softShadows",
"Default"));
789 permutation->setVariant(
"SoftShadows", (
int)softShadows);
792 if(permutation->hasVariant(
"sRGBConversion")) {
793 switch (settings.sRGBConversion) {
794 case RenderSettings::SRGBConversion::Fast:
795 permutation->setVariant(
"sRGBConversion",
"Fast");
797 case RenderSettings::SRGBConversion::Approx:
798 permutation->setVariant(
"sRGBConversion",
"Approx");
800 case RenderSettings::SRGBConversion::Exact:
801 permutation->setVariant(
"sRGBConversion",
"Exact");
804 assert(
false &&
"Invalid enum");
809 if (permutation->hasVariant(
"Tonemapper")) {
810 switch (settings.tonemapper) {
811 case RenderSettings::Tonemapper::Reinhard:
812 permutation->setVariant(
"Tonemapper",
"Reinhard");
814 case RenderSettings::Tonemapper::Filmic:
815 permutation->setVariant(
"Tonemapper",
"Filmic");
817 case RenderSettings::Tonemapper::ACESLuminance:
818 permutation->setVariant(
"Tonemapper",
"ACESLuminance");
820 case RenderSettings::Tonemapper::PBRNeutral:
821 permutation->setVariant(
"Tonemapper",
"PBRNeutral");
824 assert(
false &&
"Invalid enum");
832 return &renderers->imguiRenderer;
837 return &renderers->engineInspectorGuiRenderer;
ComponentPool< ComponentType > pool
Pool of components managed by the system.
A Context instance contains all the services, systems and runtime components needed to use Cogs.
std::unique_ptr< class Variables > variables
Variables service instance.
Interface to the render resources.
Defines an extension to the renderer, capable of doing custom rendering.
Defines a single light source and its behavior.
LightType lightType
The type of light.
bool castShadows
If this light should cast shadows.
bool enabled
If the light is enabled.
Holds all LightComponent instances in the system.
void updatePermutation(EnginePermutation *permutation) override
Updates the EnginePermutation.
float getNearDepth() override
Get adjusted near plane depth.
IRenderResources * getResources() override
Get the render resources interface.
void registerExtension(IRendererExtension *extension) override
Registers the given extension with the renderer. Doesn not take ownership of pointer.
void setBackgroundColor(const glm::vec4 &backgroundColor) override
Set the background color applied to the output surface before rendering.
void renderScreenshot(const ScreenshotSettings &settings, std::vector< uint8_t > &bytes, uint32_t *stride=nullptr) override
Render screenshot.
glm::mat4 getViewFromViewportMatrix(glm::mat4 inverseProjectionMatrix) override
Get an adjusted inverse projection matrix mainly used in post processing.
void emitEvent(uint32_t eventId, const DrawContext *renderingContext)
Emits the given render event to all registered extensions.
void endFrame(uint32_t syncInterval=0, Cogs::PresentFlags presentFlags=PresentFlags::None) override
Signals the end of the current frame.
void unregisterExtension(IRendererExtension *extension) override
Unregister an extension with the renderer.
void cleanup() override
Cleanup the renderer, releasing all resources held.
float getClearDepth() override
Get adjusted clear depth used to render.
glm::mat4 getProjectionMatrix(const glm::mat4 projectionMatrix) override
Get an adjusted projection matrix used to render.
void render() override
Kick off the actual rendering, allowing the renderer to produce its output.
void beginFrame() override
Signals the beginning of a new frame.
Represents a graphics device used to manage graphics resources and issue drawing commands.
virtual ITextures * getTextures()=0
Get a pointer to the texture management interface.
virtual ICapabilities * getCapabilities()=0
Get a pointer to the capability management interface used to query the graphics device capability fla...
virtual IContext * getImmediateContext()=0
Get a pointer to the immediate context used to issue commands to the graphics device.
virtual void beginFrame()=0
Signal the beginning of a new frame to the graphics device.
virtual IBuffers * getBuffers()=0
Get a pointer to the buffer management interface.
virtual std::string getIdentifier() const
Get the graphics device identifier.
virtual GraphicsDeviceType getType() const
Get the type of the graphics device.
virtual void endFrame(uint32_t syncInterval=0, PresentFlags presentFlags=PresentFlags::None)=0
Signal the end of a frame to the graphics device.
virtual IRenderTargets * getRenderTargets()=0
Get a pointer to the render target management interface.
Log implementation class.
Provides a weakly referenced view over the contents of a string.
size_t hashLowercase(size_t hashValue=Cogs::hash()) const noexcept
Get the hash code of the string converted to lowercase.
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....
@ Box
Bounding-box rendering over regular rendering.
constexpr Log getLogger(const char(&name)[LEN]) noexcept
Contains all Cogs related functionality.
@ Direct3D12
Graphics device using the Direct3D 12 API.
@ OpenGLES30
Graphics device using the OpenGLES 3.0 API.
@ Vulkan
Graphics device using the Vulkan API.
@ Direct3D11
Graphics device using the Direct3D 11 API.
@ OpenGL20
Graphics device using OpenGL, supporting at least OpenGL 2.0.
@ Null
Null device that implements no rendering functionality.
@ WebGPU
Graphics device using the WebGPU API Backend.
constexpr size_t hash() noexcept
Simple getter function that returns the initial value for fnv1a hashing.
PresentFlags
Flags controlling presentation.
@ Read
The buffer can be mapped and read from by the CPU after creation.
@ None
The buffer will not be bound to the graphics pipeline. Suitable for staging resources.
Render settings variables.
@ RenderGui
Rendering GUI elements.
@ PostRender
Rendering has finished for a given rendering context.
@ PreRender
Pre rendering happening for a given rendering context.
Screenshot render settings.
Runtime control variable.
EEffectFlags
Effect source flags.
@ LogShaderSource
Log the contents of the shader on error.
@ LogShaderInfo
Log detailed info about shaders.
Contains device capabilities.
bool DepthNegativeOneToOne
If true, min z depth=-1 otherwise it is min z depth = 0 (max z depth = 1).
int numSamples
Number of samples to use for back buffer MSAA.
static const Handle_t NoHandle
Represents a handle to nothing.
virtual const GraphicsDeviceCapabilities & getDeviceCapabilities() const
Gets the device capabilities in a structure.
virtual void setRenderTarget(const RenderTargetHandle handle, const DepthStencilHandle depthStencilHandle)=0
Sets the current render target and an associated depth stencil target.
Provides RAII style mapping of a buffer resource.
Encapsulates state for texture sampling in a state object.
AddressMode addressModeS
Specifies the addressing mode along the S axis in texture coordinate space.
@ Border
Texture color is set to the border color when outside [0, 1] range.
@ ComparisonMinMagMipLinear
Comparison filter for depth sample comparisons using linear interpolation sampling.
@ RenderTarget
The texture can be used as a render target and drawn into.