module; #include module rmlui_vulkan; // ReSharper disable once CppPassValueParameterByConstReference ee_rml::RmlVulkan::RmlVulkan(RenderContext renderContext) : renderer(renderContext), sampler(vulkan_render::Sampler(renderContext.context)), defaultTexture( //std::move( vulkan_render::DataFactory::CreateRenderTexture( renderContext.context, renderContext.commands ) //) ) {} Rml::CompiledGeometryHandle ee_rml::RmlVulkan::CompileGeometry( const Rml::Span vertices, const Rml::Span indices ) { GeometryMesh *mesh = Allocate(); mesh->vertices.emplace(renderer.context, vertices.size()); mesh->indices.emplace(renderer.context, indices.size()); std::ranges::copy(vertices, mesh->vertices->content.data()); std::ranges::copy(indices, mesh->indices->content.data()); renderer.commands.SubmitStagingBuffer(*mesh->vertices); renderer.commands.SubmitStagingBuffer(*mesh->indices); return reinterpret_cast(mesh); } void ee_rml::RmlVulkan::RenderGeometry( const Rml::CompiledGeometryHandle geometry, const Rml::Vector2f translation, const Rml::TextureHandle texture ) { GeometryMesh *geometryMesh = reinterpret_cast(geometry); const Rml::TextureHandle cachedHandle = texture ? texture : static_cast(0); auto textureDescriptor = textures.find(cachedHandle); if (textureDescriptor == textures.end()) { textureDescriptor = textures.emplace(cachedHandle, renderer.pipeline.AllocateDescriptorSet()).first; const vulkan_render::RenderTexture *textureObject = texture ? reinterpret_cast(texture) : &defaultTexture; renderer.pipeline.UpdateDescriptors({ vulkan_render::DescriptorInfo{ .info = vk::DescriptorImageInfo{ .sampler = sampler.handle, .imageView = textureObject->view, .imageLayout = vk::ImageLayout::eShaderReadOnlyOptimal }, .bindingPosition = 1, .type = vk::DescriptorType::eCombinedImageSampler } }, textureDescriptor->second[0]); } frameContext->renderCommand->handle.bindDescriptorSets( vk::PipelineBindPoint::eGraphics, renderer.pipeline.layout, 0, {textureDescriptor->second[0]}, {} ); frameContext->renderCommand->handle.setViewport(0, {renderer.pipeline.viewport}); frameContext->renderCommand->handle.setScissor(0, {renderer.pipeline.scissors}); frameContext->renderCommand->handle.bindVertexBuffers( 0, {geometryMesh->vertices->handle}, {0} ); frameContext->renderCommand->handle.bindIndexBuffer( geometryMesh->indices->handle, 0, vk::IndexType::eUint32 ); RmlTransformGeometry transform { .mvp = glm::ortho( 0.0f, static_cast(renderer.surface.extent.width), 0.0f, static_cast(renderer.surface.extent.height) ), .translate = glm::vec2(translation.x, translation.y) }; frameContext->renderCommand->handle.pushConstants( renderer.pipeline.layout, vk::ShaderStageFlagBits::eVertex, 0, {transform} ); frameContext->renderCommand->handle.drawIndexed( geometryMesh->indices->content.size(), 1, 0, 0, 0 ); } void ee_rml::RmlVulkan::ReleaseGeometry(const Rml::CompiledGeometryHandle geometry) { Deallocate(reinterpret_cast(geometry)); } Rml::TextureHandle ee_rml::RmlVulkan::LoadTexture(Rml::Vector2i &texture_dimensions, const Rml::String &source) { return 1; } Rml::TextureHandle ee_rml::RmlVulkan::GenerateTexture( const Rml::Span source, const Rml::Vector2i source_dimensions ) { vulkan_render::RenderTexture *texture = Allocate( std::move( vulkan_render::DataFactory::CreateRenderTexture( renderer.context, renderer.commands, static_cast(source_dimensions.x), static_cast(source_dimensions.y), std::as_bytes(std::span{source.data(), source.size()} ) ) ) ); return reinterpret_cast(texture); } void ee_rml::RmlVulkan::ReleaseTexture(const Rml::TextureHandle texture) { textures.erase(texture); Deallocate(reinterpret_cast(texture)); } void ee_rml::RmlVulkan::EnableScissorRegion(const bool enable) { scissorEnabled = enable; if (enable) return; renderer.pipeline.scissors.extent = renderer.surface.extent; renderer.pipeline.scissors.offset = {.x = 0, .y = 0}; } void ee_rml::RmlVulkan::SetScissorRegion(const Rml::Rectanglei region) { if (!scissorEnabled) return; const std::int32_t x = std::max(0, region.Position().x); const std::int32_t y = std::max(0, region.Position().y); std::uint32_t width = std::max(0, region.Size().x); std::uint32_t height = std::max(0, region.Size().y); if (x + width > renderer.surface.extent.width)width = renderer.surface.extent.width - x; if (y + height > renderer.surface.extent.height) height = renderer.surface.extent.height - y; renderer.pipeline.scissors.offset = {x, y}; renderer.pipeline.scissors.extent = {width, height}; } void ee_rml::RmlVulkan::SetFrameContext(vulkan_render::FrameContext *frameContext) { this->frameContext = frameContext; }