2#include "Foundation/Logging/Logger.h"
4#include "Rendering/IBuffers.h"
5#include "Rendering/ICapabilities.h"
6#include "Rendering/IRenderTargets.h"
8#include "Resources/MaterialManager.h"
10#include "Renderer/Renderer.h"
11#include "Renderer/RenderStateUpdater.h"
12#include "Renderer/RenderList.h"
13#include "Renderer/RenderTarget.h"
14#include "Renderer/Tasks/RenderListTask.h"
15#include "Renderer/Tasks/GenerateListTask.h"
16#include "Renderer/Tasks/FilterListTask.h"
17#include "TexAtlasRenderer.h"
18#include "TexAtlasSystem.h"
25 struct ConstantsNone {
30 struct ConstantsEval {
31 glm::vec2 coefficents[4];
48 auto& fullScreenTriangle = texAtlasRenderer->fullScreenTriangle;
50 fullScreenTriangle.streamsLayout.
vertexFormats[0] = Cogs::VertexFormats::createVertexFormat(element);
51 fullScreenTriangle.streamsLayout.numStreams = 1;
52 fullScreenTriangle.streamsLayout.updateHash();
54 static const float fullScreenTriangleVertexData[] = {
59 fullScreenTriangle.vertices = buffers->
loadVertexBuffer(fullScreenTriangleVertexData,
60 sizeof(fullScreenTriangleVertexData) /
sizeof(fullScreenTriangleVertexData[0]),
61 fullScreenTriangle.streamsLayout.vertexFormats[0]);
64 constexpr const char* atlasBlitVS_es30 = R
"(#version 300 es
69 gl_Position = vec4(a_POSITION, 0, 1);
73 constexpr const char* atlasBlitPS_es30 = R
"(#version 300 es
75precision highp sampler2DArray;
79uniform sampler2DArray source;
83 destination = texelFetch(source, ivec3(floor(gl_FragCoord.xy), sourceLayer), 0);
87 constexpr const char* atlasBlitVS_wgsl = R
"(
88const a_POSITION0_LOC = 0;
91 @builtin(position) position: vec4f,
95fn main(@location(a_POSITION0_LOC) a_POSITION: vec2f) -> VertexOutput {
96 var output: VertexOutput;
97 output.position = vec4f(a_POSITION, 0.0, 1.0);
101 constexpr const char* atlasBlitPS_wgsl = R
"(
105@group(0) @binding(0) var<uniform> Params: ParamsType;
106@group(0) @binding(1) var source: texture_2d_array<f32>;
109fn main(@builtin(position) fragCoord: vec4f) -> @location(0) vec4f {
110 let coord = vec2i(floor(fragCoord.xy));
111 return textureLoad(source, coord, Params.sourceLayer, 0);
119 auto& atlasBlit = texAtlasRenderer->atlasBlit;
130 atlasBlit.effect = effects->
loadEffectSource(atlasBlitVS_es30, atlasBlitPS_es30);
133 atlasBlit.inputLayout = buffers->
loadInputLayout(&texAtlasRenderer->fullScreenTriangle.streamsLayout.
vertexFormats[0], 1, atlasBlit.effect);
134 atlasBlit.srcTexBinding = effects->
getTextureBinding(atlasBlit.effect,
"source", 0);
146 .comparisonFunction = Cogs::SamplerState::ComparisonFunction::Never,
148 .borderColor = { 0, 0, 0, 1 }
152 .depthEnabled =
false,
153 .writeEnabled =
true,
159 .sourceBlend = Cogs::BlendState::Blend::One,
160 .destinationBlend = Cogs::BlendState::Blend::Zero,
161 .operation = Cogs::BlendState::BlendOperation::Add
168 uint32_t w, uint32_t h)
176 .layerIndex =
static_cast<uint16_t
>(dstLayer),
184 info.renderTargetHandle = renderTarget;
186 info.loadOp[0] = Cogs::LoadOp::Clear;
187 info.storeOp[0] = Cogs::StoreOp::Store;
188 info.clearValue[0][0] = 0.0;
189 info.clearValue[0][1] = 0.0;
190 info.clearValue[0][2] = 0.0;
191 info.clearValue[0][3] = 0.0;
192 info.depthLoadOp = Cogs::LoadOp::Undefined;
193 info.depthStoreOp = Cogs::StoreOp::Discard;
199 immediateContext->
setViewport(0.f, 0.f,
static_cast<float>(w),
static_cast<float>(h));
200 immediateContext->
updateBuffer(texAtlasRenderer->atlasBlit.paramBuffer, &srcLayer,
sizeof(uint32_t));
201 immediateContext->
setEffect(texAtlasRenderer->atlasBlit.effect);
202 immediateContext->
setInputLayout(texAtlasRenderer->atlasBlit.inputLayout);
203 immediateContext->
setConstantBuffer(texAtlasRenderer->atlasBlit.paramBinding, texAtlasRenderer->atlasBlit.paramBuffer);
204 immediateContext->
setTexture(texAtlasRenderer->atlasBlit.srcTexBinding, srcTex);
205 immediateContext->
setSamplerState(texAtlasRenderer->atlasBlit.srcSamplerBinding, texAtlasRenderer->atlasBlit.samplerState);
206 immediateContext->
setVertexBuffers(&texAtlasRenderer->fullScreenTriangle.vertices, 1);
208 immediateContext->
setBlendState(texAtlasRenderer->atlasBlit.blendState);
224 const CameraData* camData = drawContext->cameraData;
225 if (camData ==
nullptr)
return false;
227 bool useCamData = 2.f < std::min(camData->viewportSize.x, camData->viewportSize.y);
229 Renderer* renderer = taskContext->renderer;
230 float w = useCamData ? camData->viewportSize.x : (drawContext->renderTarget ? drawContext->renderTarget->width : renderer->
getSize().x);
231 float h = useCamData ? camData->viewportSize.y : (drawContext->renderTarget ? drawContext->renderTarget->height : renderer->
getSize().y);
235 iContext->
setViewport(camData->viewportOrigin.x, camData->viewportOrigin.y, w, h);
237 iContext->
setBlendState(taskContext->states->blendStates[renderItem->blendState].handle);
239 const RenderPassOptions passOptions = initRenderPassOptions(*camData, renderItem->materialInstance);
240 iContext->
setRasterizerState(taskContext->states->rasterizerStateHandles[getRasterizerState(renderer, *renderItem, passOptions, camData->flipWindingOrder,
true)]);
242 const ClipShapeCache::Item& clipShape = drawContext->clipShapeCache->data[renderItem->clipShapeIx];
243 updateViewportBuffer(taskContext, taskContext->engineBuffers->sceneBufferHandle, taskContext->engineBuffers->viewBufferHandle, drawContext->renderTarget, renderItem->viewportData ? renderItem->viewportData : drawContext->cameraData, &clipShape.clipEquations);
247 applyMaterialPermutation(taskContext, drawContext, renderItem->binding, renderItem->renderMaterialInstance);
251 drawContext->task->applyMaterial(*drawContext, *renderItem);
254 applyMaterialInstance(drawContext, renderItem->binding, renderItem->renderMaterialInstance);
256 updateSceneBindings(drawContext, drawContext->cameraData, renderItem->binding);
258 updateMaterialBindings(drawContext, renderItem->renderMaterialInstance, renderItem->binding,
true);
266 objectBuffer->worldMatrix = glm::mat4(1.f, 0.f, 0.f, 0.f,
270 objectBuffer->objectId = renderItem->
objectId;
273 iContext->
setConstantBuffer(bindings->objectBufferBinding, engineBuffers.objectBufferHandle);
281 if (!renderCallbackSetup(taskContext, drawContext, renderItem))
return;
283 Renderer* renderer = taskContext->renderer;
292 iContext->
setIndexBuffer(texAtlasRenderer->wireBoxIndices, texAtlasRenderer->wireBoxIndexStride, 0);
296 ConstantsEval constants{
307 .colorEval = glm::vec4(1,1,1,1),
308 .elevationMin = geo.elevationMin,
309 .elevationMax = geo.elevationMax
311 iContext->
updateBuffer(texAtlasRenderer->wireBoxConstants, &constants,
sizeof(constants));
320 if (!renderCallbackSetup(taskContext, drawContext, renderItem))
return;
322 Renderer* renderer = taskContext->renderer;
331 iContext->
setIndexBuffer(texAtlasRenderer->wireBoxIndices, texAtlasRenderer->wireBoxIndexStride, 0);
333 static const glm::vec4 colors[8] = {
340 glm::vec4(0.5f, 1, 0.5f, 1),
341 glm::vec4(1,0.5, 0.5f, 1),
346 ConstantsNone constants;
349 for (
size_t i = 0, n = tree.tiles.size(); i < n; i++) {
350 texAtlasData->geometry.calcTileCorners(constants.corners, tree.tiles[i]);
351 glm::vec4 c = glm::vec4(0.f);
352 for (
size_t k = 0; k < 8; k++) {
353 c += (1.f / 8.f) * constants.corners[k];
355 for (
size_t k = 0; k < 8; k++) {
356 constants.corners[k] = glm::mix(constants.corners[k], c, (tree.tiles[i].level + 1) / 100.f);
359 constants.colorNone = glm::mix(colors[tree.tiles[i].level & 7u], glm::vec4(0.5f, 0.5f, 0.5f, 1.f), 0.5f);
360 iContext->
updateBuffer(texAtlasRenderer->wireBoxConstants, &constants,
sizeof(constants));
370 if (!renderCallbackSetup(taskContext, drawContext, renderItem))
return;
372 Renderer* renderer = taskContext->renderer;
380 iContext->
setIndexBuffer(texAtlasRenderer->wireBoxIndices, texAtlasRenderer->wireBoxIndexStride, 0);
383 ConstantsNone constants;
386 constants.colorNone = glm::vec4(0.8f, 0.8f, 1.f, 1.f);
387 for (
size_t i = 0; i < 8; i++) {
388 constants.corners[i] = texAtlasRenderer->frustumCorners[i];
390 iContext->
updateBuffer(texAtlasRenderer->wireBoxConstants, &constants,
sizeof(constants));
400 this->device = device;
402 debugMaterial = context->materialManager->loadMaterial(
"Materials/TexAtlasDebug.material");
403 context->materialManager->processLoading();
404 debugMaterialNoneInstance = context->materialInstanceManager->createMaterialInstance(debugMaterial);
405 debugMaterialNoneInstance->setVariant(
"Mode",
"None");
407 debugMaterialEvalInstance = context->materialInstanceManager->createMaterialInstance(debugMaterial);
408 debugMaterialEvalInstance->setVariant(
"Mode",
"Eval");
410 const std::array<Cogs::VertexElement, 1> elements = {
413 wireStreamsLayout.
vertexFormats[0] = VertexFormats::createVertexFormat(elements.data(), elements.size());
420 static const float boxVertexData[] = {
430 wireBoxVertices = buffers->
loadVertexBuffer(boxVertexData,
sizeof(boxVertexData) /
sizeof(boxVertexData[0]), wireStreamsLayout.
vertexFormats[0]);
432 static const uint16_t boxEdgeIndexData[] = {
433 0, 1, 1, 2, 2, 3, 3, 0,
434 4, 5, 5, 6, 6, 7, 7, 4,
435 0, 4, 1, 5, 2, 6, 3, 7
437 wireBoxIndexStride =
static_cast<uint32_t
>(
sizeof(boxEdgeIndexData[0]));
438 wireBoxIndexCount =
static_cast<uint32_t
>(
sizeof(boxEdgeIndexData) / wireBoxIndexStride);
439 wireBoxIndices = buffers->
loadIndexBuffer(boxEdgeIndexData, wireBoxIndexCount, wireBoxIndexStride);
443 fullScreenTriangleInit(context,
this);
444 atlasBlitInit(context,
this);
447TexAtlasRenderer::~TexAtlasRenderer()
472 Context* context = renderingContext->context;
473 IContext* deviceContext = renderingContext->deviceContext;
475 RenderResources& resources = renderingContext->renderer->getRenderResources();
478 TexAtlasData& texAtlasData = texAtlasSystem->getData(&texAtlasComp);
480 if (texAtlasData.tilesOldTex) {
481 RenderTexture* tilesOldTex = resources.getRenderTexture(texAtlasData.tilesOldTex);
482 RenderTexture* tilesTex = resources.getRenderTexture(texAtlasData.tilesTex);
483 if (tilesOldTex && tilesTex) {
485 uint32_t tilesToCopy = std::min(tilesTex->description.layers,
486 tilesOldTex->description.layers);
487 for (uint32_t l = 0; l < tilesToCopy; l++) {
488 atlasTileBlit(context,
this,
489 tilesTex->textureHandle, l,
490 tilesOldTex->textureHandle, l,
491 tilesTex->description.width, tilesTex->description.height);
498 if (!texAtlasData.fetcher.loaded.empty()) {
500 RenderTexture* tilesTex = resources.getRenderTexture(texAtlasData.tilesTex);
501 if (!tilesTex || !tilesTex->textureHandle) {
502 LOG_ERROR(logger,
"Failed to get tile texture");
507 RenderTexture* itemTex = resources.getRenderTexture(loadItem.texture);
508 if (!itemTex || !itemTex->textureHandle) {
509 LOG_ERROR(logger,
"Failed to get item texture");
513 deviceContext->copyTexture(tilesTex->textureHandle, loadItem.slotIx, 0, 0, 0, itemTex->textureHandle, 0);
515 texAtlasData.fetcher.loaded.clear();
527 assert(renderingContext);
529 MaterialInstance* debugMaterialNoneInstance = this->debugMaterialNoneInstance.resolve();
530 if (!debugMaterialNoneInstance)
return;
532 MaterialInstance* debugMaterialEvalInstance = this->debugMaterialEvalInstance.resolve();
533 if (!debugMaterialEvalInstance)
return;
537 RenderItem& renderItem = renderList->createCustom(&wireStreamsLayout);
538 renderItem.
layer = RenderLayers::Overlay;
539 renderItem.cullingIndex = ~0u;
540 renderItem.materialInstance = debugMaterialNoneInstance;
541 getTransparencyState(renderingContext->renderer->
getRenderStates(), debugMaterialNoneInstance, renderItem);
543 renderItem.setCallbackData2(
this);
544 renderItem.callback = renderCallbackFrustum;
550 if (!texAtlasComp.
debugBox)
continue;
552 TexAtlasData& texAtlasData = texAtlasSystem->getData(&texAtlasComp);
555 RenderItem& renderItem = renderList->createCustom(&wireStreamsLayout);
556 renderItem.
layer = RenderLayers::Overlay;
557 renderItem.cullingIndex = ~0u;
558 renderItem.materialInstance = debugMaterialEvalInstance;
559 getTransparencyState(renderingContext->renderer->
getRenderStates(), debugMaterialEvalInstance, renderItem);
561 renderItem.setCallbackData(&texAtlasData);
562 renderItem.setCallbackData2(
this);
563 renderItem.callback = renderCallbackBase;
567 RenderItem& renderItem = renderList->createCustom(&wireStreamsLayout);
568 renderItem.
layer = RenderLayers::Overlay;
569 renderItem.cullingIndex = ~0u;
570 renderItem.materialInstance = debugMaterialNoneInstance;
571 getTransparencyState(renderingContext->renderer->
getRenderStates(), debugMaterialNoneInstance, renderItem);
573 renderItem.setCallbackData(&texAtlasData);
574 renderItem.setCallbackData2(
this);
575 renderItem.callback = renderCallbackTiles;
A Context instance contains all the services, systems and runtime components needed to use Cogs.
Contains render resources used by the renderer.
RenderStates & getRenderStates() override
Get the reference to the RenderStates structure.
IGraphicsDevice * getDevice() override
Get the graphics device used by the renderer.
glm::vec2 getSize() const override
Get the output surface size of the renderer.
Represents a graphics device used to manage graphics resources and issue drawing commands.
virtual IEffects * getEffects()=0
Get a pointer to the effect management interface.
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 IBuffers * getBuffers()=0
Get a pointer to the buffer management interface.
virtual GraphicsDeviceType getType() const
Get the type of the graphics device.
virtual IRenderTargets * getRenderTargets()=0
Get a pointer to the render target management interface.
Log implementation class.
Contains the Engine, Renderer, resource managers and other systems needed to run Cogs....
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
@ OpenGLES30
Graphics device using the OpenGLES 3.0 API.
@ WebGPU
Graphics device using the WebGPU API Backend.
@ VertexData
Per vertex data.
@ TriangleStrip
Triangle strip.
@ Position
Position semantic.
@ Write
The buffer can be mapped and written to by the CPU after creation.
@ ConstantBuffer
The buffer can be bound as input to effects as a constant buffer.
Contains data describing a Camera instance and its derived data structured such as matrix data and vi...
Material instances represent a specialized Material combined with state for all its buffers and prope...
MaterialOptions options
Material rendering options used by this instance.
VertexFormatHandle vertexFormats[maxStreams]
COGSCORE_DLL_API void updateHash()
int32_t drawOrder
Ordering of draw items within a bucket.
uint32_t objectId
Lower 6 of upper 8 bits are instance id bits, lower 24 bits are object id.
RenderLayers layer
Visibility mask.
@ PreRender
Pre rendering happening for a given rendering context.
static const ResourceHandle_t NoHandle
Handle representing a default (or none if default not present) resource.
bool debugBox
Render wireframe box that outlines texture position in world.
void handleEvent(uint32_t eventId, const DrawContext *renderingContext) override
Called when rendering events occur.
void initialize(Context *context, IGraphicsDevice *device) override
Initialize the extension using the given context and device.
glm::vec2 coefficients[4]
Coefficients wrt engine origin.
@ Always
Always evaluates to true.
@ WGSL
Effect source is WGSL.
static const Handle_t NoHandle
Represents a handle to nothing.
Provides buffer management functionality.
virtual void releaseVertexBuffer(VertexBufferHandle vertexBufferHandle)=0
Release the vertex buffer with the given handle.
virtual InputLayoutHandle loadInputLayout(const VertexFormatHandle *vertexFormats, const size_t count, EffectHandle effectHandle)=0
Loads a new input layout to map vertex flow between vertex buffers with the given vertexFormats to ef...
virtual IndexBufferHandle loadIndexBuffer(const void *indexData, const size_t count, const size_t indexSize)=0
Loads a new index buffer and populates it with the given indexData.
virtual void releaseIndexBuffer(IndexBufferHandle indexBufferHandle)=0
Releases the index buffer with the given handle.
virtual BufferHandle loadBuffer(const void *data, const size_t size, Usage::EUsage usage, uint32_t accessMode, uint32_t bindFlags, uint32_t stride=0)=0
Loads a new buffer using the given data to populate the buffer.
virtual void releaseBuffer(BufferHandle bufferHandle)=0
Releases the buffer with the given bufferHandle.
virtual VertexBufferHandle loadVertexBuffer(const void *vertexData, const size_t count, const VertexFormat &vertexFormat)=0
Loads a new vertex buffer and populates it with the given data.
virtual const GraphicsDeviceCapabilities & getDeviceCapabilities() const
Gets the device capabilities in a structure.
Represents a graphics device context which can receive rendering commands.
virtual void setTexture(const StringView &name, unsigned int unit, TextureHandle textureHandle)=0
Sets the texture slot given by unit with the given name to contain the given texture.
virtual void setRasterizerState(const RasterizerStateHandle handle)=0
Set the current rasterizer state.
virtual void drawIndexed(PrimitiveType primitiveType, const size_t startIndex, const size_t numIndexes, const size_t startVertex=0)=0
Draws indexed, non-instanced primitives.
virtual void setBlendState(const BlendStateHandle handle, const float *constant=nullptr)=0
Set the current blend state.
virtual void setInputLayout(const InputLayoutHandle inputLayoutHandle)=0
Sets the current input layout.
virtual void endRenderPass()=0
End a render pass.
virtual void setIndexBuffer(IndexBufferHandle bufferHandle, uint32_t stride=4, uint32_t offset=0)=0
Sets the current index buffer.
virtual void setDepthStencilState(const DepthStencilStateHandle handle)=0
Set the current depth stencil state.
virtual void setConstantBuffer(const StringView &name, const BufferHandle bufferHandle, const uint32_t offset=0, const uint32_t size=~0u)=0
Sets a constant buffer to be bound to the given name and slot.
virtual void updateBuffer(BufferHandle bufferHandle, const void *data, size_t size)=0
Replace contents of buffer with new data.
virtual void setViewport(const float x, const float y, const float width, const float height)=0
Sets the current viewport to the given location and dimensions.
virtual void draw(PrimitiveType primitiveType, const size_t startVertex, const size_t numVertexes)=0
Draws non-indexed, non-instanced primitives.
virtual void beginRenderPass(const RenderPassInfo &info)=0
Begin a render pass.
virtual void setSamplerState(const StringView &name, unsigned int unit, SamplerStateHandle samplerStateHandle)=0
Sets the sampler slot given by unit with the given name to contain the given sampler state.
virtual void setVertexBuffers(const VertexBufferHandle *vertexBufferHandles, const size_t count, const uint32_t *strides, const uint32_t *offsets)=0
Sets the current vertex buffers.
virtual void setEffect(EffectHandle handle)=0
Set the current effect.
virtual void setRenderTarget(const RenderTargetHandle handle, const DepthStencilHandle depthStencilHandle)=0
Sets the current render target and an associated depth stencil target.
Provides effects and shader management functionality.
virtual SamplerStateBindingHandle getSamplerStateBinding(EffectHandle effectHandle, const StringView &name, const unsigned int slot)=0
Get a handle to a sampler state object binding, mapping how to bind the sampler state to the given ef...
virtual ConstantBufferBindingHandle getConstantBufferBinding(EffectHandle effectHandle, const StringView &name)=0
Get a handle to a constant buffer binding, mapping how to bind a constant buffer to the given effect.
virtual TextureBindingHandle getTextureBinding(EffectHandle effectHandle, const StringView &name, const unsigned int slot)=0
Get a handle to a texture object binding, mapping how to bind textures to the given effect.
virtual EffectHandle loadEffectSource(const StringView &vsSource, const StringView &psSource, EffectFlags::EEffectFlags effectFlags=EffectFlags::None)=0
Load an effect created from the vertex and pixel shader sources given.
Provides render target management functionality.
virtual BlendStateHandle loadBlendState(const BlendState &blendState)=0
Load a blend state object.
virtual DepthStencilStateHandle loadDepthStencilState(const DepthStencilState &depthStencilState)=0
Load a depth stencil state object.
virtual void releaseRenderTarget(RenderTargetHandle renderTargetHandle)=0
Release the render target with the given renderTargetHandle.
virtual RenderTargetHandle createRenderTarget(TextureHandle textureHandle)
Create a render target using the given texture to render into.
Provides texture management functionality.
virtual SamplerStateHandle loadSamplerState(const SamplerState &state)=0
Load a sampler state object.
@ WriteDiscard
Write access. When unmapping the graphics system will discard the old contents of the resource.
Provides RAII style mapping of a buffer resource.
Describes a single render target view and which resources to use from the underlying texture.
TextureHandle texture
Texture handle.
@ Clamp
Texture coordinates are clamped to the [0, 1] range.
@ MinMagMipPoint
Point sampling for both minification and magnification.
@ Dynamic
Buffer will be loaded and modified with some frequency.
Vertex element structure used to describe a single data element in a vertex for the input assembler.