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 if (HandleIsValid(atlasBlit.effect)) {
133 atlasBlit.inputLayout = buffers->loadInputLayout(&texAtlasRenderer->fullScreenTriangle.streamsLayout.vertexFormats[0], 1, atlasBlit.effect);
134 atlasBlit.srcTexBinding = effects->getTextureBinding(atlasBlit.effect, "source", 0);
135 atlasBlit.srcSamplerBinding = effects->getSamplerStateBinding(atlasBlit.effect, "sourceSampler", 0);
136 atlasBlit.paramBinding = effects->getConstantBufferBinding(atlasBlit.effect, "Params");
137 }
138
139 atlasBlit.paramBuffer = buffers->loadBuffer(nullptr, std::max(sizeof(uint32_t), size_t(16)), Cogs::Usage::Dynamic, Cogs::AccessMode::Write, Cogs::BindFlags::ConstantBuffer);
140
141 atlasBlit.samplerState = textures->loadSamplerState({
146 .comparisonFunction = Cogs::SamplerState::ComparisonFunction::Never,
147 .maxAnisotropy = 1,
148 .borderColor = { 0, 0, 0, 1 }
149 });
150
151 atlasBlit.depthStencilState = renderTargets->loadDepthStencilState({
152 .depthEnabled = false,
153 .writeEnabled = true,
154 .depthFunction = Cogs::DepthStencilState::Always
155 });
156
157 atlasBlit.blendState = renderTargets->loadBlendState({
158 .enabled = 0,
159 .sourceBlend = Cogs::BlendState::Blend::One,
160 .destinationBlend = Cogs::BlendState::Blend::Zero,
161 .operation = Cogs::BlendState::BlendOperation::Add
162 });
163 }
164
165 bool atlasTileBlit(Context* context, const TexAtlasRenderer* texAtlasRenderer,
166 Cogs::TextureHandle dstTex, uint32_t dstLayer,
167 Cogs::TextureHandle srcTex, uint32_t srcLayer,
168 uint32_t w, uint32_t h)
169 {
170 Cogs::IGraphicsDevice* device = context->device;
171 Cogs::IRenderTargets* renderTargets = device->getRenderTargets();
172 Cogs::IContext* immediateContext = device->getImmediateContext();
173
175 .texture = dstTex,
176 .layerIndex = static_cast<uint16_t>(dstLayer),
177 .numLayers = 1,
178 .levelIndex = 0
179 };
180 Cogs::RenderTargetHandle renderTarget = renderTargets->createRenderTarget(&view, 1);
181
182 if (device->getCapabilities()->getDeviceCapabilities().RenderPass) {
184 info.renderTargetHandle = renderTarget;
185 info.depthStencilHandle = Cogs::DepthStencilHandle::NoHandle;
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;
194 immediateContext->beginRenderPass(info);
195 }
196 else {
197 immediateContext->setRenderTarget(renderTarget, Cogs::DepthStencilHandle::NoHandle);
198 }
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);
207 immediateContext->setDepthStencilState(texAtlasRenderer->atlasBlit.depthStencilState);
208 immediateContext->setBlendState(texAtlasRenderer->atlasBlit.blendState);
209 immediateContext->draw(Cogs::PrimitiveType::TriangleStrip, 0, 4);
210
211 if (device->getCapabilities()->getDeviceCapabilities().RenderPass) {
212 immediateContext->endRenderPass();
213 } else {
215 }
216 renderTargets->releaseRenderTarget(renderTarget);
217
218 return true;
219 }
220
221
222 bool renderCallbackSetup(RenderTaskContext* taskContext, DrawContext* drawContext, const RenderItem* renderItem)
223 {
224 const CameraData* camData = drawContext->cameraData;
225 if (camData == nullptr) return false;
226
227 bool useCamData = 2.f < std::min(camData->viewportSize.x, camData->viewportSize.y);
228
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);
232
233 Cogs::IGraphicsDevice* device = renderer->getDevice();
234 Cogs::IContext* iContext = device->getImmediateContext();
235 iContext->setViewport(camData->viewportOrigin.x, camData->viewportOrigin.y, w, h);
236 iContext->setDepthStencilState(taskContext->states->commonDepthStates[renderItem->depthState]);
237 iContext->setBlendState(taskContext->states->blendStates[renderItem->blendState].handle);
238
239 const RenderPassOptions passOptions = initRenderPassOptions(*camData, renderItem->materialInstance);
240 iContext->setRasterizerState(taskContext->states->rasterizerStateHandles[getRasterizerState(renderer, *renderItem, passOptions, camData->flipWindingOrder, true)]);
241
242 const ClipShapeCache::Item& clipShape = drawContext->clipShapeCache->data[renderItem->clipShapeIx];
243
244 // Invokes updateSceneBindings
245 updateViewportBuffer(taskContext, taskContext->engineBuffers->sceneBufferHandle, taskContext->engineBuffers->viewBufferHandle, drawContext->renderTarget, renderItem->viewportData ? renderItem->viewportData : drawContext->cameraData, &clipShape.clipEquations);
246
247 // Invokes updateMaterialBindings(instance=false)
248 applyMaterialPermutation(taskContext, drawContext, renderItem->binding, renderItem->renderMaterialInstance);
249
250 // Invokes updateEnvironmentBindings,
251 // Updates permutation->constant buffers
252 drawContext->task->applyMaterial(*drawContext, *renderItem);
253
254 // Invokes updateMaterialBindings -> applyMaterialProperties
255 applyMaterialInstance(drawContext, renderItem->binding, renderItem->renderMaterialInstance);
256
257 updateSceneBindings(drawContext, drawContext->cameraData, renderItem->binding);
258
259 updateMaterialBindings(drawContext, renderItem->renderMaterialInstance, renderItem->binding, true);
260
261 EngineBuffers& engineBuffers = *drawContext->engineBuffers;
262 const EffectBinding* bindings = renderItem->binding;
263 if (HandleIsValid(bindings->objectBufferBinding)) {
264 {
265 Cogs::MappedBuffer<ObjectBuffer> objectBuffer(iContext, engineBuffers.objectBufferHandle, Cogs::MapMode::WriteDiscard);
266 if (objectBuffer) {
267 objectBuffer->worldMatrix = glm::mat4(1.f, 0.f, 0.f, 0.f,
268 0.f, 1.f, 0.f, 0.f,
269 0.f, 0.f, 1.f, 0.f,
270 0.f, 0.f, 0.f, 1.f);
271 objectBuffer->objectId = renderItem->objectId;
272 }
273 }
274 iContext->setConstantBuffer(bindings->objectBufferBinding, engineBuffers.objectBufferHandle);
275 }
276
277 return true;
278 }
279
280 void renderCallbackBase(RenderTaskContext* taskContext, DrawContext* drawContext, const RenderItem* renderItem)
281 {
282 if (!renderCallbackSetup(taskContext, drawContext, renderItem)) return;
283
284 Renderer* renderer = taskContext->renderer;
285 Cogs::IGraphicsDevice* device = renderer->getDevice();
286 Cogs::IContext* iContext = device->getImmediateContext();
287 TexAtlasData* texAtlasData = renderItem->getCallbackData<TexAtlasData>();
288 TexAtlasRenderer* texAtlasRenderer = renderItem->getCallbackData2<TexAtlasRenderer>();
289
290
291 Cogs::IEffects* effects = device->getEffects();
292 iContext->setVertexBuffers(&texAtlasRenderer->wireBoxVertices, 1);
293 iContext->setIndexBuffer(texAtlasRenderer->wireBoxIndices, texAtlasRenderer->wireBoxIndexStride, 0);
294
295 const TexAtlas::Geometry& geo = texAtlasData->geometry;
296 if (Cogs::ConstantBufferBindingHandle constBinding = effects->getConstantBufferBinding(renderItem->binding->renderEffect->effectHandle, "ConstantsEval"); HandleIsValid(constBinding)) {
297 ConstantsEval constants{
298 .coefficents = {
299 geo.coefficients[0],
300 geo.coefficients[1],
301 geo.coefficients[2],
302 geo.coefficients[3]
303 },
304 .domain = {
305 glm::vec2(0.0, 0.0),
306 glm::vec2(1.0, 1.0)
307 },
308 .colorEval = glm::vec4(1,1,1,1),
309 .elevationMin = geo.elevationMin,
310 .elevationMax = geo.elevationMax
311 };
312 iContext->updateBuffer(texAtlasRenderer->wireBoxConstants, &constants, sizeof(constants));
313 iContext->setConstantBuffer(constBinding, texAtlasRenderer->wireBoxConstants);
314 iContext->drawIndexed(Cogs::PrimitiveType::LineList, 0, texAtlasRenderer->wireBoxIndexCount);
315 }
316 }
317
318
319 void renderCallbackTiles(RenderTaskContext* taskContext, DrawContext* drawContext, const RenderItem* renderItem)
320 {
321 if (!renderCallbackSetup(taskContext, drawContext, renderItem)) return;
322
323 Renderer* renderer = taskContext->renderer;
324 Cogs::IGraphicsDevice* device = renderer->getDevice();
325 Cogs::IContext* iContext = device->getImmediateContext();
326 TexAtlasData* texAtlasData = renderItem->getCallbackData<TexAtlasData>();
327 TexAtlasRenderer* texAtlasRenderer = renderItem->getCallbackData2<TexAtlasRenderer>();
328
329
330 Cogs::IEffects* effects = device->getEffects();
331 iContext->setVertexBuffers(&texAtlasRenderer->wireBoxVertices, 1);
332 iContext->setIndexBuffer(texAtlasRenderer->wireBoxIndices, texAtlasRenderer->wireBoxIndexStride, 0);
333
334 static const glm::vec4 colors[8] = {
335 glm::vec4(1,0,0,1),
336 glm::vec4(0,1,0,1),
337 glm::vec4(1,1,0,1),
338 glm::vec4(0,0,1,1),
339 glm::vec4(1,0,1,1),
340 glm::vec4(0,1,1,1),
341 glm::vec4(0.5f, 1, 0.5f, 1),
342 glm::vec4(1,0.5, 0.5f, 1),
343 };
344
345
346 if (Cogs::ConstantBufferBindingHandle constBinding = effects->getConstantBufferBinding(renderItem->binding->renderEffect->effectHandle, "ConstantsNone"); HandleIsValid(constBinding)) {
347 ConstantsNone constants;
348
349 const TexAtlas::LodTree& tree = texAtlasData->tree;
350 for (size_t i = 0, n = tree.tiles.size(); i < n; i++) {
351 texAtlasData->geometry.calcTileCorners(constants.corners, tree.tiles[i]);
352 glm::vec4 c = glm::vec4(0.f);
353 for (size_t k = 0; k < 8; k++) {
354 c += (1.f / 8.f) * constants.corners[k];
355 }
356 for (size_t k = 0; k < 8; k++) {
357 constants.corners[k] = glm::mix(constants.corners[k], c, (tree.tiles[i].level + 1) / 100.f);
358 }
359
360 constants.colorNone = glm::mix(colors[tree.tiles[i].level & 7u], glm::vec4(0.5f, 0.5f, 0.5f, 1.f), 0.5f);
361 iContext->updateBuffer(texAtlasRenderer->wireBoxConstants, &constants, sizeof(constants));
362 iContext->setConstantBuffer(constBinding, texAtlasRenderer->wireBoxConstants);
363 iContext->drawIndexed(Cogs::PrimitiveType::LineList, 0, texAtlasRenderer->wireBoxIndexCount);
364 }
365
366 }
367 }
368
369 void renderCallbackFrustum(RenderTaskContext* taskContext, DrawContext* drawContext, const RenderItem* renderItem)
370 {
371 if (!renderCallbackSetup(taskContext, drawContext, renderItem)) return;
372
373 Renderer* renderer = taskContext->renderer;
374 Cogs::IGraphicsDevice* device = renderer->getDevice();
375 Cogs::IContext* iContext = device->getImmediateContext();
376 TexAtlasRenderer* texAtlasRenderer = renderItem->getCallbackData2<TexAtlasRenderer>();
377
378
379 Cogs::IEffects* effects = device->getEffects();
380 iContext->setVertexBuffers(&texAtlasRenderer->wireBoxVertices, 1);
381 iContext->setIndexBuffer(texAtlasRenderer->wireBoxIndices, texAtlasRenderer->wireBoxIndexStride, 0);
382
383 if (Cogs::ConstantBufferBindingHandle constBinding = effects->getConstantBufferBinding(renderItem->binding->renderEffect->effectHandle, "ConstantsNone"); HandleIsValid(constBinding)) {
384 ConstantsNone constants;
385
386
387 constants.colorNone = glm::vec4(0.8f, 0.8f, 1.f, 1.f);
388 for (size_t i = 0; i < 8; i++) {
389 constants.corners[i] = texAtlasRenderer->frustumCorners[i];
390 }
391 iContext->updateBuffer(texAtlasRenderer->wireBoxConstants, &constants, sizeof(constants));
392 iContext->setConstantBuffer(constBinding, texAtlasRenderer->wireBoxConstants);
393 iContext->drawIndexed(Cogs::PrimitiveType::LineList, 0, texAtlasRenderer->wireBoxIndexCount);
394 }
395 }
396
397}
398
400{
401 this->device = device;
402
403 debugMaterial = context->materialManager->loadMaterial("Materials/TexAtlasDebug.material");
404 context->materialManager->processLoading();
405 debugMaterialNoneInstance = context->materialInstanceManager->createMaterialInstance(debugMaterial);
406 debugMaterialNoneInstance->setVariant("Mode", "None");
407
408 debugMaterialEvalInstance = context->materialInstanceManager->createMaterialInstance(debugMaterial);
409 debugMaterialEvalInstance->setVariant("Mode", "Eval");
410
411 const std::array<Cogs::VertexElement, 1> elements = {
412 Cogs::VertexElement{0, Cogs::DataFormat::R32G32B32_FLOAT, Cogs::ElementSemantic::Position, 0, Cogs::InputType::VertexData, 0}
413 };
414 wireStreamsLayout.vertexFormats[0] = VertexFormats::createVertexFormat(elements.data(), elements.size());
415 wireStreamsLayout.numStreams = 1;
416 wireStreamsLayout.updateHash();
417
418 Cogs::IBuffers* buffers = device->getBuffers();
419
420 // Create wireframe unit box geometry
421 static const float boxVertexData[] = {
422 0.f, 0.f, 0.f,
423 1.f, 0.f, 0.f,
424 1.f, 1.f, 0.f,
425 0.f, 1.f, 0.f,
426 0.f, 0.f, 1.f,
427 1.f, 0.f, 1.f,
428 1.f, 1.f, 1.f,
429 0.f, 1.f, 1.f,
430 };
431 wireBoxVertices = buffers->loadVertexBuffer(boxVertexData, sizeof(boxVertexData) / sizeof(boxVertexData[0]), wireStreamsLayout.vertexFormats[0]);
432
433 static const uint16_t boxEdgeIndexData[] = {
434 0, 1, 1, 2, 2, 3, 3, 0,
435 4, 5, 5, 6, 6, 7, 7, 4,
436 0, 4, 1, 5, 2, 6, 3, 7
437 };
438 wireBoxIndexStride = static_cast<uint32_t>(sizeof(boxEdgeIndexData[0]));
439 wireBoxIndexCount = static_cast<uint32_t>(sizeof(boxEdgeIndexData) / wireBoxIndexStride);
440 wireBoxIndices = buffers->loadIndexBuffer(boxEdgeIndexData, wireBoxIndexCount, wireBoxIndexStride);
441
442 wireBoxConstants = buffers->loadBuffer(nullptr, std::max(sizeof(ConstantsNone), sizeof(ConstantsEval)), Cogs::Usage::Dynamic, Cogs::AccessMode::Write, Cogs::BindFlags::ConstantBuffer, 0);
443
444 fullScreenTriangleInit(context, this);
445 atlasBlitInit(context, this);
446}
447
448TexAtlasRenderer::~TexAtlasRenderer()
449{
450 if (device) {
451 Cogs::IBuffers* buffers = device->getBuffers();
452
453 if (HandleIsValid(wireBoxVertices)) {
454 buffers->releaseVertexBuffer(wireBoxVertices);
455 wireBoxVertices = Cogs::VertexBufferHandle::NoHandle;
456 }
457 if (HandleIsValid(wireBoxIndices)) {
458 buffers->releaseIndexBuffer(wireBoxIndices);
459 wireBoxIndices = Cogs::IndexBufferHandle::NoHandle;
460 }
461 if (HandleIsValid(wireBoxConstants)) {
462 buffers->releaseBuffer(wireBoxConstants);
463 wireBoxConstants = Cogs::BufferHandle::NoHandle;
464 }
465 }
466}
467
468
469void Cogs::Core::TexAtlasRenderer::handleEvent(uint32_t eventId, const DrawContext* renderingContext)
470{
471 switch (eventId) {
473 Context* context = renderingContext->context;
474 IContext* deviceContext = renderingContext->deviceContext;
475
476 RenderResources& resources = renderingContext->renderer->getRenderResources();
477
478 for (const TexAtlasComponent& texAtlasComp : texAtlasSystem->pool) {
479 TexAtlasData& texAtlasData = texAtlasSystem->getData(&texAtlasComp);
480
481 if (texAtlasData.tilesOldTex) {
482 RenderTexture* tilesOldTex = resources.getRenderTexture(texAtlasData.tilesOldTex);
483 RenderTexture* tilesTex = resources.getRenderTexture(texAtlasData.tilesTex);
484 if (tilesOldTex && tilesTex) {
485
486 uint32_t tilesToCopy = std::min(tilesTex->description.layers,
487 tilesOldTex->description.layers);
488 for (uint32_t l = 0; l < tilesToCopy; l++) {
489 atlasTileBlit(context, this,
490 tilesTex->textureHandle, l,
491 tilesOldTex->textureHandle, l,
492 tilesTex->description.width, tilesTex->description.height);
493 }
494 texAtlasData.tilesOldTex = TextureHandle::NoHandle;
495 }
496 }
497
498
499 if (!texAtlasData.fetcher.loaded.empty()) {
500
501 RenderTexture* tilesTex = resources.getRenderTexture(texAtlasData.tilesTex);
502 if (!tilesTex || !tilesTex->textureHandle) {
503 LOG_ERROR(logger, "Failed to get tile texture");
504 continue;
505 }
506
507 for (TexAtlas::Fetcher::LoadItem& loadItem : texAtlasData.fetcher.loaded) {
508 RenderTexture* itemTex = resources.getRenderTexture(loadItem.texture);
509 if (!itemTex || !itemTex->textureHandle) {
510 LOG_ERROR(logger, "Failed to get item texture");
511 continue;
512 }
513
514 deviceContext->copyTexture(tilesTex->textureHandle, loadItem.slotIx, 0, 0, 0, itemTex->textureHandle, 0);
515 }
516 texAtlasData.fetcher.loaded.clear();
517 }
518
519 }
520 }
521 default:
522 break;
523 }
524}
525
526void Cogs::Core::TexAtlasRenderer::generateCommands(const RenderTaskContext* renderingContext, RenderList* renderList)
527{
528 assert(renderingContext);
529
530 MaterialInstance* debugMaterialNoneInstance = this->debugMaterialNoneInstance.resolve();
531 if (!debugMaterialNoneInstance) return;
532
533 MaterialInstance* debugMaterialEvalInstance = this->debugMaterialEvalInstance.resolve();
534 if (!debugMaterialEvalInstance) return;
535
536 if (renderFrustum) {
537 {
538 RenderItem& renderItem = renderList->createCustom(&wireStreamsLayout);
539 renderItem.layer = RenderLayers::Overlay;
540 renderItem.cullingIndex = ~0u;
541 renderItem.materialInstance = debugMaterialNoneInstance;
542 getTransparencyState(renderingContext->renderer->getRenderStates(), debugMaterialNoneInstance, renderItem);
543 renderItem.drawOrder = debugMaterialEvalInstance->options.drawOrder;
544 renderItem.setCallbackData2(this);
545 renderItem.callback = renderCallbackFrustum;
546 }
547 }
548
549 for (const TexAtlasComponent& texAtlasComp : texAtlasSystem->pool) {
550
551 if (!texAtlasComp.debugBox) continue;
552
553 TexAtlasData& texAtlasData = texAtlasSystem->getData(&texAtlasComp);
554
555 {
556 RenderItem& renderItem = renderList->createCustom(&wireStreamsLayout);
557 renderItem.layer = RenderLayers::Overlay;
558 renderItem.cullingIndex = ~0u;
559 renderItem.materialInstance = debugMaterialEvalInstance;
560 getTransparencyState(renderingContext->renderer->getRenderStates(), debugMaterialEvalInstance, renderItem);
561 renderItem.drawOrder = debugMaterialEvalInstance->options.drawOrder;
562 renderItem.setCallbackData(&texAtlasData);
563 renderItem.setCallbackData2(this);
564 renderItem.callback = renderCallbackBase;
565 }
566
567 {
568 RenderItem& renderItem = renderList->createCustom(&wireStreamsLayout);
569 renderItem.layer = RenderLayers::Overlay;
570 renderItem.cullingIndex = ~0u;
571 renderItem.materialInstance = debugMaterialNoneInstance;
572 getTransparencyState(renderingContext->renderer->getRenderStates(), debugMaterialNoneInstance, renderItem);
573 renderItem.drawOrder = debugMaterialNoneInstance->options.drawOrder;
574 renderItem.setCallbackData(&texAtlasData);
575 renderItem.setCallbackData2(this);
576 renderItem.callback = renderCallbackTiles;
577 }
578
579 }
580}
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:28
RenderStates & getRenderStates() override
Get the reference to the RenderStates structure.
Definition: Renderer.h:68
IGraphicsDevice * getDevice() override
Get the graphics device used by the renderer.
Definition: Renderer.h:45
glm::vec2 getSize() const override
Get the output surface size of the renderer.
Definition: Renderer.h:44
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.
@ 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:36
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:148
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.
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