Cogs.Core
TexAtlasRenderer.cpp
1#include "Context.h"
2#include "Foundation/Logging/Logger.h"
3
4#include "Rendering/IBuffers.h"
5#include "Rendering/ICapabilities.h"
6#include "Rendering/IRenderTargets.h"
7
8#include "Resources/MaterialManager.h"
9
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"
19
20namespace {
21 using namespace Cogs::Core;
22
24
25 struct ConstantsNone {
26 glm::vec4 corners[8];
27 glm::vec4 colorNone;
28 };
29
30 struct ConstantsEval {
31 glm::vec2 coefficents[4];
32 glm::vec2 domain[2];
33 glm::vec4 colorEval;
34 float elevationMin;
35 float elevationMax;
36 };
37
38 void fullScreenTriangleInit(Context* context, TexAtlasRenderer* texAtlasRenderer)
39 {
40 Cogs::IGraphicsDevice* device = context->device;
41 Cogs::IBuffers* buffers = device->getBuffers();
42
43
44 Cogs::VertexElement element{
46 };
47
48 auto& fullScreenTriangle = texAtlasRenderer->fullScreenTriangle;
49
50 fullScreenTriangle.streamsLayout.vertexFormats[0] = Cogs::VertexFormats::createVertexFormat(element);
51 fullScreenTriangle.streamsLayout.numStreams = 1;
52 fullScreenTriangle.streamsLayout.updateHash();
53
54 static const float fullScreenTriangleVertexData[] = {
55 -1.f, -1.f,
56 3.f, -1.f,
57 -1.f, 3.f
58 };
59 fullScreenTriangle.vertices = buffers->loadVertexBuffer(fullScreenTriangleVertexData,
60 sizeof(fullScreenTriangleVertexData) / sizeof(fullScreenTriangleVertexData[0]),
61 fullScreenTriangle.streamsLayout.vertexFormats[0]);
62 }
63
64 constexpr const char* atlasBlitVS_es30 = R"(#version 300 es
65precision highp float;
66in vec2 a_POSITION;
67void main()
68{
69 gl_Position = vec4(a_POSITION, 0, 1);
70}
71)";
72
73 constexpr const char* atlasBlitPS_es30 = R"(#version 300 es
74precision highp float;
75precision highp sampler2DArray;
76uniform Params {
77 int sourceLayer;
78};
79uniform sampler2DArray source;
80out vec4 destination;
81void main()
82{
83 destination = texelFetch(source, ivec3(floor(gl_FragCoord.xy), sourceLayer), 0);
84}
85)";
86
87 constexpr const char* atlasBlitVS_wgsl = R"(
88const a_POSITION0_LOC = 0;
89
90struct VertexOutput {
91 @builtin(position) position: vec4f,
92};
93
94@vertex
95fn main(@location(a_POSITION0_LOC) a_POSITION: vec2f) -> VertexOutput {
96 var output: VertexOutput;
97 output.position = vec4f(a_POSITION, 0.0, 1.0);
98 return output;
99}
100)";
101 constexpr const char* atlasBlitPS_wgsl = R"(
102struct ParamsType {
103 sourceLayer: i32,
104};
105@group(0) @binding(0) var<uniform> Params: ParamsType;
106@group(0) @binding(1) var source: texture_2d_array<f32>;
107
108@fragment
109fn main(@builtin(position) fragCoord: vec4f) -> @location(0) vec4f {
110 let coord = vec2i(floor(fragCoord.xy));
111 return textureLoad(source, coord, Params.sourceLayer, 0);
112}
113)";
114 void atlasBlitInit(Context* context, TexAtlasRenderer* texAtlasRenderer)
115 {
116 if (context->device->getType() != Cogs::GraphicsDeviceType::OpenGLES30 && context->device->getType() != Cogs::GraphicsDeviceType::WebGPU) {
117 return;
118 }
119 auto& atlasBlit = texAtlasRenderer->atlasBlit;
120
121 Cogs::IGraphicsDevice* device = context->device;
122 Cogs::IEffects* effects = device->getEffects();
123 Cogs::IBuffers* buffers = device->getBuffers();
124 Cogs::ITextures* textures = device->getTextures();
125 Cogs::IRenderTargets* renderTargets = device->getRenderTargets();
126
127 if (device->getType() == Cogs::GraphicsDeviceType::WebGPU) {
128 atlasBlit.effect = effects->loadEffectSource(atlasBlitVS_wgsl, atlasBlitPS_wgsl, Cogs::EffectFlags::WGSL);
129 } else {
130 atlasBlit.effect = effects->loadEffectSource(atlasBlitVS_es30, atlasBlitPS_es30);
131 }
132
133 atlasBlit.paramBuffer = buffers->loadBuffer(nullptr, std::max(sizeof(uint32_t), size_t(16)), Cogs::Usage::Dynamic, Cogs::AccessMode::Write, Cogs::BindFlags::ConstantBuffer);
134
135 atlasBlit.samplerState = textures->loadSamplerState({
140 .comparisonFunction = Cogs::SamplerState::ComparisonFunction::Never,
141 .maxAnisotropy = 1,
142 .borderColor = { 0, 0, 0, 1 }
143 });
144
145 atlasBlit.depthStencilState = renderTargets->loadDepthStencilState({
146 .depthEnabled = false,
147 .writeEnabled = true,
148 .depthFunction = Cogs::DepthStencilState::Always
149 });
150
151 atlasBlit.blendState = renderTargets->loadBlendState({
152 .enabled = 0,
153 .sourceBlend = Cogs::BlendState::Blend::One,
154 .destinationBlend = Cogs::BlendState::Blend::Zero,
155 .operation = Cogs::BlendState::BlendOperation::Add
156 });
157 }
158
159 bool atlasTileBlit(Context* context, const TexAtlasRenderer* texAtlasRenderer,
160 Cogs::TextureHandle dstTex, uint32_t dstLayer,
161 Cogs::TextureHandle srcTex, uint32_t srcLayer,
162 uint32_t w, uint32_t h)
163 {
164 Cogs::IGraphicsDevice* device = context->device;
165 Cogs::IRenderTargets* renderTargets = device->getRenderTargets();
166 Cogs::IContext* immediateContext = device->getImmediateContext();
167
169 .texture = dstTex,
170 .layerIndex = static_cast<uint16_t>(dstLayer),
171 .numLayers = 1,
172 .levelIndex = 0
173 };
174 Cogs::RenderTargetHandle renderTarget = renderTargets->createRenderTarget(&view, 1);
175
176 if (device->getCapabilities()->getDeviceCapabilities().RenderPass) {
178 info.renderTargetHandle = renderTarget;
179 info.depthStencilHandle = Cogs::DepthStencilHandle::NoHandle;
180 info.loadOp[0] = Cogs::LoadOp::Clear;
181 info.storeOp[0] = Cogs::StoreOp::Store;
182 info.clearValue[0][0] = 0.0;
183 info.clearValue[0][1] = 0.0;
184 info.clearValue[0][2] = 0.0;
185 info.clearValue[0][3] = 0.0;
186 info.depthLoadOp = Cogs::LoadOp::Undefined;
187 info.depthStoreOp = Cogs::StoreOp::Discard;
188 immediateContext->beginRenderPass(info);
189 }
190 else {
191 immediateContext->setRenderTarget(renderTarget, Cogs::DepthStencilHandle::NoHandle);
192 }
193 immediateContext->setViewport(0.f, 0.f, static_cast<float>(w), static_cast<float>(h));
194 immediateContext->updateBuffer(texAtlasRenderer->atlasBlit.paramBuffer, &srcLayer, sizeof(uint32_t));
195 immediateContext->setEffect(texAtlasRenderer->atlasBlit.effect);
196 immediateContext->setInputLayout(texAtlasRenderer->atlasBlit.inputLayout);
197 immediateContext->setConstantBuffer(texAtlasRenderer->atlasBlit.paramBinding, texAtlasRenderer->atlasBlit.paramBuffer);
198 immediateContext->setTexture(texAtlasRenderer->atlasBlit.srcTexBinding, srcTex);
199 immediateContext->setSamplerState(texAtlasRenderer->atlasBlit.srcSamplerBinding, texAtlasRenderer->atlasBlit.samplerState);
200 immediateContext->setVertexBuffers(&texAtlasRenderer->fullScreenTriangle.vertices, 1);
201 immediateContext->setDepthStencilState(texAtlasRenderer->atlasBlit.depthStencilState);
202 immediateContext->setBlendState(texAtlasRenderer->atlasBlit.blendState);
203 immediateContext->draw(Cogs::PrimitiveType::TriangleStrip, 0, 4);
204
205 if (device->getCapabilities()->getDeviceCapabilities().RenderPass) {
206 immediateContext->endRenderPass();
207 } else {
209 }
210 renderTargets->releaseRenderTarget(renderTarget);
211
212 return true;
213 }
214
215
216 bool renderCallbackSetup(RenderTaskContext* taskContext, DrawContext* drawContext, const RenderItem* renderItem)
217 {
218 const CameraData* camData = drawContext->cameraData;
219 if (camData == nullptr) return false;
220
221 bool useCamData = 2.f < std::min(camData->viewportSize.x, camData->viewportSize.y);
222
223 Renderer* renderer = taskContext->renderer;
224 float w = useCamData ? camData->viewportSize.x : (drawContext->renderTarget ? drawContext->renderTarget->width : renderer->getSize().x);
225 float h = useCamData ? camData->viewportSize.y : (drawContext->renderTarget ? drawContext->renderTarget->height : renderer->getSize().y);
226
227 Cogs::IGraphicsDevice* device = renderer->getDevice();
228 Cogs::IContext* iContext = device->getImmediateContext();
229 iContext->setViewport(camData->viewportOrigin.x, camData->viewportOrigin.y, w, h);
230 iContext->setDepthStencilState(taskContext->states->commonDepthStates[renderItem->depthState]);
231 iContext->setBlendState(taskContext->states->blendStates[renderItem->blendState].handle);
232
233 const RenderPassOptions passOptions = initRenderPassOptions(*camData, renderItem->materialInstance);
234 iContext->setRasterizerState(taskContext->states->rasterizerStateHandles[getRasterizerState(renderer, *renderItem, passOptions, camData->flipWindingOrder, true)]);
235
236 const ClipShapeCache::Item& clipShape = drawContext->clipShapeCache->data[renderItem->clipShapeIx];
237
238 // Invokes updateSceneBindings
239 updateViewportBuffer(taskContext, taskContext->engineBuffers->sceneBufferHandle, taskContext->engineBuffers->viewBufferHandle, drawContext->renderTarget, renderItem->viewportData ? renderItem->viewportData : drawContext->cameraData, &clipShape.clipEquations);
240
241 // Invokes updateMaterialBindings(instance=false)
242 applyMaterialPermutation(taskContext, drawContext, drawContext->binding, renderItem->renderMaterialInstance);
243
244 // Invokes updateEnvironmentBindings,
245 // Updates permutation->constant buffers
246 drawContext->task->applyMaterial(*drawContext, *renderItem, drawContext->binding);
247
248 // Invokes updateMaterialBindings -> applyMaterialProperties
249 applyMaterialInstance(drawContext, drawContext->binding, renderItem->renderMaterialInstance);
250
251 updateSceneBindings(drawContext, drawContext->cameraData, drawContext->binding);
252
253 updateMaterialBindings(drawContext, renderItem->renderMaterialInstance, drawContext->binding, true);
254
255 EngineBuffers& engineBuffers = *drawContext->engineBuffers;
256 const EffectBinding* bindings = drawContext->binding;
257 if (HandleIsValid(bindings->objectBufferBinding)) {
258 {
259 Cogs::MappedBuffer<ObjectBuffer> objectBuffer(iContext, engineBuffers.objectBufferHandle, Cogs::MapMode::WriteDiscard);
260 if (objectBuffer) {
261 objectBuffer->encodeWorldMatrix(glm::mat4(1.f, 0.f, 0.f, 0.f,
262 0.f, 1.f, 0.f, 0.f,
263 0.f, 0.f, 1.f, 0.f,
264 0.f, 0.f, 0.f, 1.f));
265 objectBuffer->encodeObjectId(renderItem->objectId);
266 }
267 }
268 iContext->setConstantBuffer(bindings->objectBufferBinding, engineBuffers.objectBufferHandle);
269 }
270
271 return true;
272 }
273
274 void renderCallbackBase(RenderTaskContext* taskContext, DrawContext* drawContext, const RenderItem* renderItem)
275 {
276 if (!renderCallbackSetup(taskContext, drawContext, renderItem)) return;
277
278 Renderer* renderer = taskContext->renderer;
279 Cogs::IGraphicsDevice* device = renderer->getDevice();
280 Cogs::IContext* iContext = device->getImmediateContext();
281 TexAtlasData* texAtlasData = renderItem->getCallbackData<TexAtlasData>();
282 TexAtlasRenderer* texAtlasRenderer = renderItem->getCallbackData2<TexAtlasRenderer>();
283
284
285 Cogs::IEffects* effects = device->getEffects();
286 iContext->setVertexBuffers(&texAtlasRenderer->wireBoxVertices, 1);
287 iContext->setIndexBuffer(texAtlasRenderer->wireBoxIndices, texAtlasRenderer->wireBoxIndexStride, 0);
288
289 const TexAtlas::Geometry& geo = texAtlasData->geometry;
290 if (Cogs::ConstantBufferBindingHandle constBinding = effects->getConstantBufferBinding(drawContext->binding->renderEffect->effectHandle, "ConstantsEval"); HandleIsValid(constBinding)) {
291 ConstantsEval constants{
292 .coefficents = {
293 geo.coefficients[0],
294 geo.coefficients[1],
295 geo.coefficients[2],
296 geo.coefficients[3]
297 },
298 .domain = {
299 glm::vec2(0.0, 0.0),
300 glm::vec2(1.0, 1.0)
301 },
302 .colorEval = glm::vec4(1,1,1,1),
303 .elevationMin = geo.elevationMin,
304 .elevationMax = geo.elevationMax
305 };
306 iContext->updateBuffer(texAtlasRenderer->wireBoxConstants, &constants, sizeof(constants));
307 iContext->setConstantBuffer(constBinding, texAtlasRenderer->wireBoxConstants);
308 iContext->drawIndexed(Cogs::PrimitiveType::LineList, 0, texAtlasRenderer->wireBoxIndexCount);
309 }
310 }
311
312
313 void renderCallbackTiles(RenderTaskContext* taskContext, DrawContext* drawContext, const RenderItem* renderItem)
314 {
315 if (!renderCallbackSetup(taskContext, drawContext, renderItem)) return;
316
317 Renderer* renderer = taskContext->renderer;
318 Cogs::IGraphicsDevice* device = renderer->getDevice();
319 Cogs::IContext* iContext = device->getImmediateContext();
320 TexAtlasData* texAtlasData = renderItem->getCallbackData<TexAtlasData>();
321 TexAtlasRenderer* texAtlasRenderer = renderItem->getCallbackData2<TexAtlasRenderer>();
322
323
324 Cogs::IEffects* effects = device->getEffects();
325 iContext->setVertexBuffers(&texAtlasRenderer->wireBoxVertices, 1);
326 iContext->setIndexBuffer(texAtlasRenderer->wireBoxIndices, texAtlasRenderer->wireBoxIndexStride, 0);
327
328 static const glm::vec4 colors[8] = {
329 glm::vec4(1,0,0,1),
330 glm::vec4(0,1,0,1),
331 glm::vec4(1,1,0,1),
332 glm::vec4(0,0,1,1),
333 glm::vec4(1,0,1,1),
334 glm::vec4(0,1,1,1),
335 glm::vec4(0.5f, 1, 0.5f, 1),
336 glm::vec4(1,0.5, 0.5f, 1),
337 };
338
339
340 if (Cogs::ConstantBufferBindingHandle constBinding = effects->getConstantBufferBinding(drawContext->binding->renderEffect->effectHandle, "ConstantsNone"); HandleIsValid(constBinding)) {
341 ConstantsNone constants;
342
343 const TexAtlas::LodTree& tree = texAtlasData->tree;
344 for (size_t i = 0, n = tree.tiles.size(); i < n; i++) {
345 texAtlasData->geometry.calcTileCorners(constants.corners, tree.tiles[i]);
346 glm::vec4 c = glm::vec4(0.f);
347 for (size_t k = 0; k < 8; k++) {
348 c += (1.f / 8.f) * constants.corners[k];
349 }
350 for (size_t k = 0; k < 8; k++) {
351 constants.corners[k] = glm::mix(constants.corners[k], c, (tree.tiles[i].level + 1) / 100.f);
352 }
353
354 constants.colorNone = glm::mix(colors[tree.tiles[i].level & 7u], glm::vec4(0.5f, 0.5f, 0.5f, 1.f), 0.5f);
355 iContext->updateBuffer(texAtlasRenderer->wireBoxConstants, &constants, sizeof(constants));
356 iContext->setConstantBuffer(constBinding, texAtlasRenderer->wireBoxConstants);
357 iContext->drawIndexed(Cogs::PrimitiveType::LineList, 0, texAtlasRenderer->wireBoxIndexCount);
358 }
359
360 }
361 }
362
363 void renderCallbackFrustum(RenderTaskContext* taskContext, DrawContext* drawContext, const RenderItem* renderItem)
364 {
365 if (!renderCallbackSetup(taskContext, drawContext, renderItem)) return;
366
367 Renderer* renderer = taskContext->renderer;
368 Cogs::IGraphicsDevice* device = renderer->getDevice();
369 Cogs::IContext* iContext = device->getImmediateContext();
370 TexAtlasRenderer* texAtlasRenderer = renderItem->getCallbackData2<TexAtlasRenderer>();
371
372
373 Cogs::IEffects* effects = device->getEffects();
374 iContext->setVertexBuffers(&texAtlasRenderer->wireBoxVertices, 1);
375 iContext->setIndexBuffer(texAtlasRenderer->wireBoxIndices, texAtlasRenderer->wireBoxIndexStride, 0);
376
377 if (Cogs::ConstantBufferBindingHandle constBinding = effects->getConstantBufferBinding(drawContext->binding->renderEffect->effectHandle, "ConstantsNone"); HandleIsValid(constBinding)) {
378 ConstantsNone constants;
379
380
381 constants.colorNone = glm::vec4(0.8f, 0.8f, 1.f, 1.f);
382 for (size_t i = 0; i < 8; i++) {
383 constants.corners[i] = texAtlasRenderer->frustumCorners[i];
384 }
385 iContext->updateBuffer(texAtlasRenderer->wireBoxConstants, &constants, sizeof(constants));
386 iContext->setConstantBuffer(constBinding, texAtlasRenderer->wireBoxConstants);
387 iContext->drawIndexed(Cogs::PrimitiveType::LineList, 0, texAtlasRenderer->wireBoxIndexCount);
388 }
389 }
390
391}
392
394{
395 this->device = device;
396
397 debugMaterial = context->materialManager->loadMaterial("Materials/TexAtlasDebug.material");
398 context->materialManager->processLoading();
399 debugMaterialNoneInstance = context->materialInstanceManager->createMaterialInstance(debugMaterial);
400 debugMaterialNoneInstance->setVariant("Mode", "None");
401
402 debugMaterialEvalInstance = context->materialInstanceManager->createMaterialInstance(debugMaterial);
403 debugMaterialEvalInstance->setVariant("Mode", "Eval");
404
405 const std::array<Cogs::VertexElement, 1> elements = {
406 Cogs::VertexElement{0, Cogs::DataFormat::R32G32B32_FLOAT, Cogs::ElementSemantic::Position, 0, Cogs::InputType::VertexData, 0}
407 };
408 wireStreamsLayout.vertexFormats[0] = VertexFormats::createVertexFormat(elements.data(), elements.size());
409 wireStreamsLayout.numStreams = 1;
410 wireStreamsLayout.updateHash();
411
412 Cogs::IBuffers* buffers = device->getBuffers();
413
414 // Create wireframe unit box geometry
415 static const float boxVertexData[] = {
416 0.f, 0.f, 0.f,
417 1.f, 0.f, 0.f,
418 1.f, 1.f, 0.f,
419 0.f, 1.f, 0.f,
420 0.f, 0.f, 1.f,
421 1.f, 0.f, 1.f,
422 1.f, 1.f, 1.f,
423 0.f, 1.f, 1.f,
424 };
425 wireBoxVertices = buffers->loadVertexBuffer(boxVertexData, sizeof(boxVertexData) / sizeof(boxVertexData[0]), wireStreamsLayout.vertexFormats[0]);
426
427 static const uint16_t boxEdgeIndexData[] = {
428 0, 1, 1, 2, 2, 3, 3, 0,
429 4, 5, 5, 6, 6, 7, 7, 4,
430 0, 4, 1, 5, 2, 6, 3, 7
431 };
432 wireBoxIndexStride = static_cast<uint32_t>(sizeof(boxEdgeIndexData[0]));
433 wireBoxIndexCount = static_cast<uint32_t>(sizeof(boxEdgeIndexData) / wireBoxIndexStride);
434 wireBoxIndices = buffers->loadIndexBuffer(boxEdgeIndexData, wireBoxIndexCount, wireBoxIndexStride);
435
436 wireBoxConstants = buffers->loadBuffer(nullptr, std::max(sizeof(ConstantsNone), sizeof(ConstantsEval)), Cogs::Usage::Dynamic, Cogs::AccessMode::Write, Cogs::BindFlags::ConstantBuffer, 0);
437
438 fullScreenTriangleInit(context, this);
439 atlasBlitInit(context, this);
440}
441
442bool Cogs::Core::TexAtlasRenderer::isReady()
443{
444 if (!HandleIsValid(atlasBlit.effect)) {
445 // atlasBlit isn't used on this device type (atlasBlitInit didn't load an effect), nothing to wait for.
446 return true;
447 }
448
449 Cogs::IEffects* effects = device->getEffects();
450 Cogs::ResourceStatus status = effects->checkEffect(atlasBlit.effect);
451
452 if (status == Cogs::ResourceStatus::Ready && atlasBlit.effectStatus != Cogs::ResourceStatus::Ready) {
453 Cogs::IBuffers* buffers = device->getBuffers();
454 atlasBlit.inputLayout = buffers->loadInputLayout(&fullScreenTriangle.streamsLayout.vertexFormats[0], 1, atlasBlit.effect);
455 atlasBlit.srcTexBinding = effects->getTextureBinding(atlasBlit.effect, "source", 0);
456 atlasBlit.srcSamplerBinding = effects->getSamplerStateBinding(atlasBlit.effect, "sourceSampler", 0);
457 atlasBlit.paramBinding = effects->getConstantBufferBinding(atlasBlit.effect, "Params");
458 }
459
460 if (status == Cogs::ResourceStatus::Error && atlasBlit.effectStatus != Cogs::ResourceStatus::Error) {
461 LOG_ERROR(logger, "TexAtlasRenderer: Invalid atlas blit effect handle.");
462 }
463
464 atlasBlit.effectStatus = status;
465 return status == Cogs::ResourceStatus::Ready;
466}
467
468TexAtlasRenderer::~TexAtlasRenderer()
469{
470 if (device) {
471 Cogs::IBuffers* buffers = device->getBuffers();
472
473 if (HandleIsValid(wireBoxVertices)) {
474 buffers->releaseVertexBuffer(wireBoxVertices);
475 wireBoxVertices = Cogs::VertexBufferHandle::NoHandle;
476 }
477 if (HandleIsValid(wireBoxIndices)) {
478 buffers->releaseIndexBuffer(wireBoxIndices);
479 wireBoxIndices = Cogs::IndexBufferHandle::NoHandle;
480 }
481 if (HandleIsValid(wireBoxConstants)) {
482 buffers->releaseBuffer(wireBoxConstants);
483 wireBoxConstants = Cogs::BufferHandle::NoHandle;
484 }
485 }
486}
487
488
489void Cogs::Core::TexAtlasRenderer::handleEvent(uint32_t eventId, const DrawContext* renderingContext)
490{
491 switch (eventId) {
493 Context* context = renderingContext->context;
494 IContext* deviceContext = renderingContext->deviceContext;
495
496 RenderResources& resources = renderingContext->renderer->getRenderResources();
497
498 for (const TexAtlasComponent& texAtlasComp : texAtlasSystem->pool) {
499 TexAtlasData& texAtlasData = texAtlasSystem->getData(&texAtlasComp);
500
501 if (texAtlasData.tilesOldTex) {
502 RenderTexture* tilesOldTex = resources.getRenderTexture(texAtlasData.tilesOldTex);
503 RenderTexture* tilesTex = resources.getRenderTexture(texAtlasData.tilesTex);
504 if (tilesOldTex && tilesTex) {
505
506 uint32_t tilesToCopy = std::min(tilesTex->description.layers,
507 tilesOldTex->description.layers);
508 for (uint32_t l = 0; l < tilesToCopy; l++) {
509 atlasTileBlit(context, this,
510 tilesTex->textureHandle, l,
511 tilesOldTex->textureHandle, l,
512 tilesTex->description.width, tilesTex->description.height);
513 }
514 texAtlasData.tilesOldTex = TextureHandle::NoHandle;
515 }
516 }
517
518
519 if (!texAtlasData.fetcher.loaded.empty()) {
520
521 RenderTexture* tilesTex = resources.getRenderTexture(texAtlasData.tilesTex);
522 if (!tilesTex || !tilesTex->textureHandle) {
523 LOG_ERROR(logger, "Failed to get tile texture");
524 continue;
525 }
526
527 for (TexAtlas::Fetcher::LoadItem& loadItem : texAtlasData.fetcher.loaded) {
528 RenderTexture* itemTex = resources.getRenderTexture(loadItem.texture);
529 if (!itemTex || !itemTex->textureHandle) {
530 LOG_ERROR(logger, "Failed to get item texture");
531 continue;
532 }
533
534 deviceContext->copyTexture(tilesTex->textureHandle, loadItem.slotIx, 0, 0, 0, itemTex->textureHandle, 0);
535 }
536 texAtlasData.fetcher.loaded.clear();
537 }
538
539 }
540 }
541 default:
542 break;
543 }
544}
545
546void Cogs::Core::TexAtlasRenderer::generateCommands(const RenderTaskContext* renderingContext, RenderList* renderList)
547{
548 assert(renderingContext);
549
550 MaterialInstance* debugMaterialNoneInstance = this->debugMaterialNoneInstance.resolve();
551 if (!debugMaterialNoneInstance) return;
552
553 MaterialInstance* debugMaterialEvalInstance = this->debugMaterialEvalInstance.resolve();
554 if (!debugMaterialEvalInstance) return;
555
556 if (renderFrustum) {
557 {
558 RenderItem& renderItem = renderList->createCustom(&wireStreamsLayout);
559 renderItem.layer = RenderLayers::Overlay;
560 renderItem.cullingIndex = ~0u;
561 renderItem.materialInstance = debugMaterialNoneInstance;
562 getTransparencyState(renderingContext->renderer->getRenderStates(), debugMaterialNoneInstance, renderItem);
563 renderItem.drawOrder = debugMaterialEvalInstance->options.drawOrder;
564 renderItem.setCallbackData2(this);
565 renderItem.callback = renderCallbackFrustum;
566 }
567 }
568
569 for (const TexAtlasComponent& texAtlasComp : texAtlasSystem->pool) {
570
571 if (!texAtlasComp.debugBox) continue;
572
573 TexAtlasData& texAtlasData = texAtlasSystem->getData(&texAtlasComp);
574
575 {
576 RenderItem& renderItem = renderList->createCustom(&wireStreamsLayout);
577 renderItem.layer = RenderLayers::Overlay;
578 renderItem.cullingIndex = ~0u;
579 renderItem.materialInstance = debugMaterialEvalInstance;
580 getTransparencyState(renderingContext->renderer->getRenderStates(), debugMaterialEvalInstance, renderItem);
581 renderItem.drawOrder = debugMaterialEvalInstance->options.drawOrder;
582 renderItem.setCallbackData(&texAtlasData);
583 renderItem.setCallbackData2(this);
584 renderItem.callback = renderCallbackBase;
585 }
586
587 {
588 RenderItem& renderItem = renderList->createCustom(&wireStreamsLayout);
589 renderItem.layer = RenderLayers::Overlay;
590 renderItem.cullingIndex = ~0u;
591 renderItem.materialInstance = debugMaterialNoneInstance;
592 getTransparencyState(renderingContext->renderer->getRenderStates(), debugMaterialNoneInstance, renderItem);
593 renderItem.drawOrder = debugMaterialNoneInstance->options.drawOrder;
594 renderItem.setCallbackData(&texAtlasData);
595 renderItem.setCallbackData2(this);
596 renderItem.callback = renderCallbackTiles;
597 }
598
599 }
600}
A Context instance contains all the services, systems and runtime components needed to use Cogs.
Definition: Context.h:83
Contains render resources used by the renderer.
Core renderer system.
Definition: Renderer.h:29
RenderStates & getRenderStates() override
Get the reference to the RenderStates structure.
Definition: Renderer.h:70
IGraphicsDevice * getDevice() override
Get the graphics device used by the renderer.
Definition: Renderer.h:46
glm::vec2 getSize() const override
Get the output surface size of the renderer.
Definition: Renderer.h:45
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.
Definition: LogManager.h:140
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
Definition: LogManager.h:181
@ OpenGLES30
Graphics device using the OpenGLES 3.0 API.
@ WebGPU
Graphics device using the WebGPU API Backend.
ResourceStatus
Status of an asynchronously loaded resource, such as an effect or a pipeline.
Definition: Common.h:198
@ Error
The resource failed to load.
@ Ready
The resource has loaded successfully and is ready for use.
@ VertexData
Per vertex data.
@ TriangleStrip
Triangle strip.
@ LineList
List of lines.
@ Position
Position semantic.
@ Write
The buffer can be mapped and written to by the CPU after creation.
Definition: Flags.h:50
@ ConstantBuffer
The buffer can be bound as input to effects as a constant buffer.
Definition: Flags.h:72
Contains data describing a Camera instance and its derived data structured such as matrix data and vi...
Definition: CameraSystem.h:67
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.
Definition: RenderList.h:174
uint32_t objectId
Lower 6 of upper 8 bits are instance id bits, lower 24 bits are object id.
Definition: RenderList.h:176
RenderLayers layer
Visibility mask.
Definition: RenderList.h:172
@ PreRender
Pre rendering happening for a given rendering context.
Definition: IRenderer.h:93
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.
Definition: IEffects.h:43
static const Handle_t NoHandle
Represents a handle to nothing.
Definition: Common.h:78
Provides buffer management functionality.
Definition: IBuffers.h:13
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.
Definition: IContext.h:43
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.
Definition: IEffects.h:158
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.
virtual ResourceStatus checkEffect(EffectHandle effectHandle)=0
Check the load status of the effect with the given effectHandle.
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.
Definition: ITextures.h:40
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.
Definition: Flags.h:103
Provides RAII style mapping of a buffer resource.
Definition: IBuffers.h:160
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.
Definition: SamplerState.h:17
@ MinMagMipPoint
Point sampling for both minification and magnification.
Definition: SamplerState.h:33
@ Dynamic
Buffer will be loaded and modified with some frequency.
Definition: Flags.h:30
Vertex element structure used to describe a single data element in a vertex for the input assembler.
Definition: VertexFormat.h:38