// Copyright (c) 2023 Dominic Masters // // This software is released under the MIT License. // https://opensource.org/licenses/MIT #include "UICanvas.hpp" #include "display/pass/RenderPass.hpp" #include "display/mesh/QuadMesh.hpp" #include "ui/UIComponent.hpp" using namespace Dawn; void UICanvas::onInit() { mesh = std::make_shared(); mesh->createBuffers( QUAD_VERTICE_COUNT * UI_SHADER_QUAD_COUNT, QUAD_INDICE_COUNT * UI_SHADER_QUAD_COUNT ); for(int32_t i = 0; i < UI_SHADER_QUAD_COUNT; i++) { QuadMesh::bufferWithIndex( mesh, glm::vec4(0, 0, 1, 1), glm::vec4(0, 0, 1, 1), i * QUAD_VERTICE_COUNT, i * QUAD_INDICE_COUNT, i * QUAD_VERTICE_COUNT ); } } void UICanvas::onDispose() { mesh = nullptr; } std::vector> UICanvas::getPasses( struct RenderPassContext &ctx ) { if(this->components.empty()) return {}; data.projection = ctx.camera->getProjection(); data.view = ctx.camera->getItem()->getWorldTransform(); data.model = this->getItem()->getWorldTransform(); this->passes.clear(); this->textureBindings.clear(); this->textures.clear(); quadCount = 0; nextBinding = 0; auto itComponents = components.begin(); auto self = std::ref(*this); while(itComponents != components.end()) { auto component = *itComponents; component->getQuads({ 0, 0 }, self); ++itComponents; } flushPass(); return passes; } void UICanvas::addQuad( const glm::vec4 quad, const glm::vec4 uvs, const struct Color color, const std::shared_ptr text ) { float_t fTexture; if(text == nullptr) { fTexture = -1; } else { shadertexturebinding_t texture; auto bindingIt = textureBindings.find(text); if(bindingIt == textureBindings.end()) { if(nextBinding >= UI_SHADER_TEXTURE_COUNT) { flushPass(); } textureBindings[text] = nextBinding; textures[nextBinding] = text; data.textures[nextBinding] = nextBinding; texture = nextBinding++; } else { texture = bindingIt->second; } fTexture = (float_t)texture; } data.quads[quadCount] = { quad, uvs, color, fTexture }; quadCount++; if(quadCount == UI_SHADER_QUAD_COUNT) flushPass(); } void UICanvas::flushPass() { if(quadCount == 0) return; auto pass = createRenderPass( std::ref(*this), data, textures, mesh, MeshDrawMode::TRIANGLES, 0, quadCount * QUAD_INDICE_COUNT ); passes.push_back(pass); quadCount = 0; nextBinding = 0; textures.clear(); textureBindings.clear(); }