172 lines
5.7 KiB
C++
172 lines
5.7 KiB
C++
module;
|
|
|
|
#include <glm/gtc/matrix_transform.hpp>
|
|
|
|
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<const Rml::Vertex> vertices,
|
|
const Rml::Span<const std::int32_t> indices
|
|
) {
|
|
GeometryMesh *mesh = Allocate<GeometryMesh>();
|
|
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<Rml::CompiledGeometryHandle>(mesh);
|
|
}
|
|
|
|
void ee_rml::RmlVulkan::RenderGeometry(
|
|
const Rml::CompiledGeometryHandle geometry,
|
|
const Rml::Vector2f translation,
|
|
const Rml::TextureHandle texture
|
|
) {
|
|
GeometryMesh *geometryMesh = reinterpret_cast<GeometryMesh*>(geometry);
|
|
|
|
const Rml::TextureHandle cachedHandle = texture ? texture : static_cast<Rml::TextureHandle>(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<vulkan_render::RenderTexture*>(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<float>(renderer.surface.extent.width),
|
|
0.0f, static_cast<float>(renderer.surface.extent.height)
|
|
),
|
|
.translate = glm::vec2(translation.x, translation.y)
|
|
};
|
|
|
|
frameContext->renderCommand->handle.pushConstants<RmlTransformGeometry>(
|
|
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<GeometryMesh*>(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<const std::uint8_t> source,
|
|
const Rml::Vector2i source_dimensions
|
|
) {
|
|
vulkan_render::RenderTexture *texture =
|
|
Allocate<vulkan_render::RenderTexture>(
|
|
std::move(
|
|
vulkan_render::DataFactory::CreateRenderTexture(
|
|
renderer.context,
|
|
renderer.commands,
|
|
static_cast<std::uint32_t>(source_dimensions.x),
|
|
static_cast<std::uint32_t>(source_dimensions.y),
|
|
std::as_bytes(std::span{source.data(), source.size()}
|
|
)
|
|
)
|
|
)
|
|
);
|
|
|
|
return reinterpret_cast<Rml::TextureHandle>(texture);
|
|
}
|
|
|
|
void ee_rml::RmlVulkan::ReleaseTexture(const Rml::TextureHandle texture) {
|
|
textures.erase(texture);
|
|
Deallocate(reinterpret_cast<vulkan_render::RenderTexture*>(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;
|
|
}
|