Add Text rendering

- Add FreeType as dependency
- Add MsdfGen as dependency
- Add MsdfAtlasGen as dependency
This commit is contained in:
Thraix
2023-05-08 22:12:19 +02:00
parent ad69293faa
commit 4e466a1fce
190 changed files with 44693 additions and 46 deletions
+31 -10
View File
@@ -1,16 +1,17 @@
#include "copium/core/Application.h"
#include "copium/asset/AssetManager.h"
#include "copium/core/Vulkan.h"
#include "copium/event/EventDispatcher.h"
#include "copium/event/MouseMoveEvent.h"
#include "copium/event/MouseScrollEvent.h"
#include "copium/event/MousePressEvent.h"
#include "copium/event/KeyPressEvent.h"
#include "copium/event/MouseMoveEvent.h"
#include "copium/event/MousePressEvent.h"
#include "copium/event/MouseScrollEvent.h"
#include "copium/event/WindowFocusEvent.h"
#include "copium/event/WindowResizeEvent.h"
#include "copium/mesh/Vertex.h"
#include "copium/mesh/VertexPassthrough.h"
#include "copium/asset/AssetManager.h"
#include "copium/sampler/Font.h"
#include <glm/gtc/matrix_transform.hpp>
@@ -60,6 +61,7 @@ namespace Copium
vkDeviceWaitIdle(Vulkan::GetDevice());
AssetManager::UnloadAsset(texture2D);
AssetManager::UnloadAsset(texture2D2);
AssetManager::UnloadAsset(font);
AssetManager::UnloadAsset(graphicsPipeline);
AssetManager::UnloadAsset(graphicsPipelinePassthrough);
AssetManager::UnloadAsset(framebuffer);
@@ -68,6 +70,8 @@ namespace Copium
bool Application::Update()
{
static Copium::Timer timer;
if (!Vulkan::GetSwapChain().BeginPresent())
return true;
@@ -75,6 +79,14 @@ namespace Copium
Vulkan::GetSwapChain().SubmitToGraphicsQueue(*commandBuffer);
Vulkan::GetSwapChain().EndPresent();
if (timer.Elapsed() >= 1.0)
{
fps = frameCounter;
frameCounter = 0;
timer.Start(); // Not quite accurate since the elapsed time might me 1.1, then we lose 0.1 precision
}
frameCounter++;
return !glfwWindowShouldClose(Vulkan::GetWindow().GetWindow());
}
@@ -93,7 +105,10 @@ namespace Copium
case EventType::MouseMove:
{
const MouseMoveEvent& mouseMoveEvent = static_cast<const MouseMoveEvent&>(event);
mousePos = {mouseMoveEvent.GetPos().x / Vulkan::GetSwapChain().GetExtent().width, mouseMoveEvent.GetPos().y / Vulkan::GetSwapChain().GetExtent().height};
float aspect = Vulkan::GetSwapChain().GetExtent().width / (float)Vulkan::GetSwapChain().GetExtent().height;
mousePos = {(mouseMoveEvent.GetPos().x / Vulkan::GetSwapChain().GetExtent().width - 0.5) * 2.0 * aspect,
-(mouseMoveEvent.GetPos().y / Vulkan::GetSwapChain().GetExtent().height - 0.5) * 2.0};
return EventResult::Continue;
}
@@ -144,6 +159,7 @@ namespace Copium
{
texture2D = AssetManager::LoadAsset<Texture2D>("fox.meta");
texture2D2 = AssetManager::LoadAsset<Texture2D>("fox2.meta");
font = AssetManager::LoadAsset<Font>("font.meta");
}
void Application::InitializeDescriptorSets()
@@ -202,9 +218,12 @@ namespace Copium
renderer->Quad(glm::vec2{-1 + x * 0.2 + 0.05, -1 + y * 0.2 + 0.05}, glm::vec2{0.1, 0.1}, glm::vec3{x * 0.1, y * 0.1, 1.0});
}
}
renderer->Quad(glm::vec2{-0.9, -0.4}, glm::vec2{0.8, 0.8}, AssetManager::GetAsset<Texture2D>(texture2D));
renderer->Quad(glm::vec2{ 0.1, -0.4}, glm::vec2{0.8, 0.8}, AssetManager::GetAsset<Texture2D>(texture2D2));
renderer->Quad(mousePos, glm::vec2{0.8, 0.8}, AssetManager::GetAsset<Texture2D>(texture2D2));
float aspect = fb.GetWidth() / (float)fb.GetHeight();
renderer->Quad(glm::vec2{-0.8, -0.4}, glm::vec2{0.8, 0.8}, AssetManager::GetAsset<Texture2D>(texture2D));
renderer->Quad(glm::vec2{ 0.1, -0.4}, glm::vec2{0.8, 0.8}, AssetManager::GetAsset<Font>(font));
renderer->Quad(mousePos - glm::vec2(0.1), glm::vec2{0.2}, AssetManager::GetAsset<Texture2D>(texture2D2));
std::string s = std::to_string(fps) + " fps";
renderer->Text(s, glm::vec2{-aspect + 0.01, 0.94}, AssetManager::GetAsset<Font>(font), 0.06, glm::vec3{0.3, 0.2, 0.8});
renderer->End();
fb.Unbind(*commandBuffer);
@@ -230,6 +249,7 @@ namespace Copium
float time = startTimer.Elapsed();
Framebuffer& fb = AssetManager::GetAsset<Framebuffer>(framebuffer);
float aspect = fb.GetWidth() / (float)fb.GetHeight();
time = 0;
{
glm::mat4 projection = glm::perspective(glm::radians(45.0f), aspect, 0.1f, 10.0f);
@@ -245,8 +265,9 @@ namespace Copium
{
UniformBuffer& uniformBuffer = descriptorSetRenderer->GetUniformBuffer("ubo");
uniformBuffer.Set("projection", glm::ortho(-aspect, aspect, -1.0f, 1.0f));
uniformBuffer.Set("view", glm::translate(glm::mat4(1), glm::vec3(0.1 * glm::sin(4 * time), 0.1 * glm::cos(4 * time), 0.0)));
uniformBuffer.Set("projection", glm::ortho(-aspect, aspect, 1.0f, -1.0f));
// uniformBuffer.Set("view", glm::translate(glm::mat4(1), glm::vec3(0.1 * glm::sin(4 * time), 0.1 * glm::cos(4 * time), 0.0)));
uniformBuffer.Set("view", glm::mat4(1));
uniformBuffer.Update();
}
}
@@ -19,6 +19,7 @@ namespace Copium
AssetHandle framebuffer;
AssetHandle texture2D;
AssetHandle texture2D2;
AssetHandle font;
AssetHandle graphicsPipeline;
AssetHandle graphicsPipelinePassthrough;
std::unique_ptr<DescriptorPool> descriptorPool;
@@ -28,7 +29,10 @@ namespace Copium
std::unique_ptr<Mesh> mesh;
std::unique_ptr<Mesh> meshPassthrough;
std::unique_ptr<CommandBuffer> commandBuffer;
glm::vec2 mousePos;
int fps;
int frameCounter;
public:
Application();
+2
View File
@@ -3,6 +3,7 @@
#include "copium/asset/AssetManager.h"
#include "copium/sampler/Texture2D.h"
#include "copium/sampler/ColorAttachment.h"
#include "copium/sampler/Font.h"
#include "copium/pipeline/Pipeline.h"
#include "copium/buffer/Framebuffer.h"
@@ -24,6 +25,7 @@ namespace Copium
AssetManager::RegisterAssetType<ColorAttachment>("RenderTexture");
AssetManager::RegisterAssetType<Pipeline>("Pipeline");
AssetManager::RegisterAssetType<Framebuffer>("Framebuffer");
AssetManager::RegisterAssetType<Font>("Font");
// TODO: Make the working directory always be relative to the assets folder
// By looking at where the executable is, since that should always be in the bin folder (it currently isn't though)
-9
View File
@@ -13,19 +13,10 @@ int main(int argc, char** argv)
Copium::Vulkan::Initialize();
{
Copium::Application application;
Copium::Timer timer;
int frames = 0;
while (application.Update())
{
glfwPollEvents();
Copium::EventDispatcher::Dispatch();
if (timer.Elapsed() >= 1.0)
{
CP_DEBUG("%d fps", frames);
frames = 0;
timer.Start();
}
frames++;
}
}
Copium::Vulkan::Destroy();
@@ -32,6 +32,7 @@ namespace Copium
{
creator.SetVertexDescriptor(RendererVertex::GetDescriptor());
creator.SetDepthTest(false);
creator.SetBlending(true);
}
else if (type == "Passthrough")
{
@@ -196,7 +197,7 @@ namespace Copium
depthStencilCreateInfo.sType = VK_STRUCTURE_TYPE_PIPELINE_DEPTH_STENCIL_STATE_CREATE_INFO;
depthStencilCreateInfo.depthTestEnable = creator.depthTest ? VK_TRUE : VK_FALSE;
depthStencilCreateInfo.depthWriteEnable = creator.depthTest ? VK_TRUE : VK_FALSE;
depthStencilCreateInfo.depthCompareOp = VK_COMPARE_OP_LESS;
depthStencilCreateInfo.depthCompareOp = VK_COMPARE_OP_LESS_OR_EQUAL;
depthStencilCreateInfo.depthBoundsTestEnable = VK_FALSE;
depthStencilCreateInfo.minDepthBounds = 0.0f;
depthStencilCreateInfo.maxDepthBounds = 1.0f;
@@ -210,9 +211,9 @@ namespace Copium
VK_COLOR_COMPONENT_G_BIT |
VK_COLOR_COMPONENT_B_BIT |
VK_COLOR_COMPONENT_A_BIT;
colorBlendAttachment.blendEnable = VK_FALSE;
colorBlendAttachment.srcColorBlendFactor = VK_BLEND_FACTOR_ONE;
colorBlendAttachment.dstColorBlendFactor = VK_BLEND_FACTOR_ZERO;
colorBlendAttachment.blendEnable = creator.blending ? VK_TRUE : VK_FALSE;
colorBlendAttachment.srcColorBlendFactor = VK_BLEND_FACTOR_SRC_ALPHA;
colorBlendAttachment.dstColorBlendFactor = VK_BLEND_FACTOR_ONE_MINUS_SRC_ALPHA;
colorBlendAttachment.colorBlendOp = VK_BLEND_OP_ADD;
colorBlendAttachment.srcAlphaBlendFactor = VK_BLEND_FACTOR_ONE;
colorBlendAttachment.dstAlphaBlendFactor = VK_BLEND_FACTOR_ZERO;
@@ -38,6 +38,11 @@ namespace Copium
this->depthTest = depthTest;
}
void PipelineCreator::SetBlending(bool blending)
{
this->blending = blending;
}
void PipelineCreator::AddShaderDescription()
{
for (auto& binding : shaderReflector.bindings)
@@ -33,6 +33,7 @@ namespace Copium
VkFrontFace frontFace = VK_FRONT_FACE_CLOCKWISE;
VkRenderPass renderPass = VK_NULL_HANDLE;
bool depthTest = true;
bool blending = false;
public:
PipelineCreator(VkRenderPass renderPass, const std::string& vertexShader, const std::string& fragmentShader);
@@ -42,6 +43,7 @@ namespace Copium
void SetCullMode(VkCullModeFlags flags);
void SetCullFrontFace(VkFrontFace cullFrontFace);
void SetDepthTest(bool depthTest);
void SetBlending(bool blending);
private:
void AddShaderDescription();
static VkDescriptorType GetDescriptorType(BindingType type);
+45 -9
View File
@@ -31,10 +31,10 @@ namespace Copium
void Renderer::Quad(const glm::vec2& pos, const glm::vec2& size, const glm::vec3& color)
{
AllocateQuad();
AddVertex(glm::vec2{pos.x, pos.y + size.y}, color, -1, glm::vec2{0, 0});
AddVertex(pos + size, color, -1, glm::vec2{0, 0});
AddVertex(glm::vec2{pos.x + size.x, pos.y}, color, -1, glm::vec2{0, 0});
AddVertex(pos, color, -1, glm::vec2{0, 0});
AddVertex(pos, color, -1, glm::vec2{0, 0}, RendererVertex::TYPE_QUAD);
AddVertex(glm::vec2{pos.x + size.x, pos.y}, color, -1, glm::vec2{0, 0}, RendererVertex::TYPE_QUAD);
AddVertex(pos + size, color, -1, glm::vec2{0, 0}, RendererVertex::TYPE_QUAD);
AddVertex(glm::vec2{pos.x, pos.y + size.y}, color, -1, glm::vec2{0, 0}, RendererVertex::TYPE_QUAD);
}
@@ -42,19 +42,55 @@ namespace Copium
{
AllocateQuad();
int texIndex = AllocateSampler(sampler);
AddVertex(glm::vec2{pos.x, pos.y + size.y}, glm::vec3{1, 1, 1}, texIndex, glm::vec2{texCoord1.x, texCoord2.y});
AddVertex(pos + size, glm::vec3{1,1,1}, texIndex, texCoord2);
AddVertex(glm::vec2{pos.x + size.x, pos.y}, glm::vec3{1, 1, 1}, texIndex, glm::vec2{texCoord2.x, texCoord1.y});
AddVertex(pos, glm::vec3{1,1,1}, texIndex, texCoord1);
AddVertex(pos, glm::vec3{1,1,1}, texIndex, texCoord1, RendererVertex::TYPE_QUAD);
AddVertex(glm::vec2{pos.x + size.x, pos.y}, glm::vec3{1, 1, 1}, texIndex, glm::vec2{texCoord2.x, texCoord1.y}, RendererVertex::TYPE_QUAD);
AddVertex(pos + size, glm::vec3{1,1,1}, texIndex, texCoord2, RendererVertex::TYPE_QUAD);
AddVertex(glm::vec2{pos.x, pos.y + size.y}, glm::vec3{1, 1, 1}, texIndex, glm::vec2{texCoord1.x, texCoord2.y}, RendererVertex::TYPE_QUAD);
}
void Renderer::AddVertex(const glm::vec2& position, const glm::vec3& color, int texindex, const glm::vec2& texCoord)
glm::vec2 Renderer::Text(const std::string& str, const glm::vec2& position, const Font& font, float size, const glm::vec3& color)
{
glm::vec2 offset = position;
for (char c : str)
{
if(c == ' ')
{
const Glyph& glyph = font.GetGlyph(c);
offset.x += glyph.advance * size;
continue;
}
else if (c == '\t')
{
const Glyph& glyph = font.GetGlyph(' ');
offset.x += glyph.advance * size * 4;
continue;
}
else if (c == '\n')
{
offset.y -= font.GetLineHeight() * size;
offset.x = position.x;
continue;
}
const Glyph& glyph = font.GetGlyph(c);
AllocateQuad();
int texIndex = AllocateSampler(font);
AddVertex(offset + glm::vec2{glyph.pos1.x * size, glyph.pos1.y * size}, color, texIndex, glyph.texCoord1, RendererVertex::TYPE_TEXT);
AddVertex(offset + glm::vec2{glyph.pos2.x * size, glyph.pos1.y * size}, color, texIndex, glm::vec2{glyph.texCoord2.x, glyph.texCoord1.y}, RendererVertex::TYPE_TEXT);
AddVertex(offset + glm::vec2{glyph.pos2.x * size, glyph.pos2.y * size}, color, texIndex, glyph.texCoord2, RendererVertex::TYPE_TEXT);
AddVertex(offset + glm::vec2{glyph.pos1.x * size, glyph.pos2.y * size}, color, texIndex, glm::vec2{glyph.texCoord1.x, glyph.texCoord2.y}, RendererVertex::TYPE_TEXT);
offset.x += glyph.advance * size;
}
return offset;
}
void Renderer::AddVertex(const glm::vec2& position, const glm::vec3& color, int texindex, const glm::vec2& texCoord, int type)
{
RendererVertex* vertex = (RendererVertex*)mappedVertexBuffer;
vertex->position = position;
vertex->color = color;
vertex->texCoord = texCoord;
vertex->texIndex = texindex;
vertex->type = type;
mappedVertexBuffer = (RendererVertex*)mappedVertexBuffer + 1;
}
+4 -1
View File
@@ -7,6 +7,7 @@
#include "copium/pipeline/Pipeline.h"
#include "copium/renderer/Batch.h"
#include "copium/sampler/Texture2D.h"
#include "copium/sampler/Font.h"
#include "copium/util/Common.h"
#include <glm/glm.hpp>
@@ -37,6 +38,8 @@ namespace Copium
void Quad(const glm::vec2& from, const glm::vec2& to, const glm::vec3& color = glm::vec3{1, 1, 1});
void Quad(const glm::vec2& from, const glm::vec2& to, const Sampler& sampler, const glm::vec2& texCoord1 = glm::vec2{0, 0}, const glm::vec2& texCoord2 = glm::vec2{1, 1});
// Returns the position where the text rendering ended
glm::vec2 Text(const std::string& str, const glm::vec2& position, const Font& font, float size, const glm::vec3& color = glm::vec3(1, 1, 1));
void Begin(CommandBuffer& commandBuffer);
void End();
@@ -52,6 +55,6 @@ namespace Copium
void Flush();
void NextBatch();
void AddVertex(const glm::vec2& position, const glm::vec3& color, int texindex, const glm::vec2& texCoord);
void AddVertex(const glm::vec2& position, const glm::vec3& color, int texindex, const glm::vec2& texCoord, int type);
};
}
@@ -9,6 +9,7 @@ namespace Copium
descriptor.AddAttribute(0, 1, VK_FORMAT_R32G32B32_SFLOAT, offsetof(RendererVertex, color), sizeof(RendererVertex));
descriptor.AddAttribute(0, 2, VK_FORMAT_R32G32_SFLOAT, offsetof(RendererVertex, texCoord), sizeof(RendererVertex));
descriptor.AddAttribute(0, 3, VK_FORMAT_R8_SINT, offsetof(RendererVertex, texIndex), sizeof(RendererVertex));
descriptor.AddAttribute(0, 4, VK_FORMAT_R8_SINT, offsetof(RendererVertex, type), sizeof(RendererVertex));
return descriptor;
}
}
@@ -8,10 +8,13 @@ namespace Copium
{
struct RendererVertex
{
static const int TYPE_QUAD = 0;
static const int TYPE_TEXT = 1;
glm::vec2 position;
glm::vec3 color;
glm::vec2 texCoord;
int8_t texIndex;
int8_t type = TYPE_QUAD; // TODO: Should maybe have different Renderers for quad vs text instead of a flag
static VertexDescriptor GetDescriptor();
};
+120
View File
@@ -0,0 +1,120 @@
#include "copium/sampler/Font.h"
#include "copium/buffer/Buffer.h"
#include "copium/core/Vulkan.h"
#include "copium/sampler/Image.h"
#define MSDF_ATLAS_PUBLIC
#define MSDFGEN_PUBLIC
#include <msdf-atlas-gen/msdf-atlas-gen.h>
namespace Copium
{
Font::Font(const MetaFile& metaFile)
{
msdfgen::FreetypeHandle* ft = msdfgen::initializeFreetype();
CP_ASSERT(ft, "Failed to initialize FreeType"); // TODO: Move to Vulkan singleton class?
std::string fontPath = metaFile.GetMetaClass("Font").GetValue("filepath");
msdfgen::FontHandle* font = msdfgen::loadFont(ft, fontPath.c_str());
CP_ASSERT(font, "Failed to initialize font: %s", fontPath.c_str());
std::vector<msdf_atlas::GlyphGeometry> glyphs;
msdf_atlas::FontGeometry fontGeometry(&glyphs);
fontGeometry.loadCharset(font, 1.0, msdf_atlas::Charset::ASCII);
const double maxCornerAngle = 3.0;
for (msdf_atlas::GlyphGeometry& glyph : glyphs)
{
glyph.edgeColoring(&msdfgen::edgeColoringInkTrap, maxCornerAngle, 0);
}
msdf_atlas::TightAtlasPacker packer;
packer.setDimensionsConstraint(msdf_atlas::TightAtlasPacker::DimensionsConstraint::SQUARE);
packer.setMinimumScale(64.0);
packer.setPixelRange(2.0);
packer.setMiterLimit(1.0);
packer.setPadding(2);
packer.pack(glyphs.data(), glyphs.size());
int width = 0, height = 0;
packer.getDimensions(width, height);
msdf_atlas::ImmediateAtlasGenerator<float, 3, msdf_atlas::msdfGenerator, msdf_atlas::BitmapAtlasStorage<msdf_atlas::byte, 3>> generator(width, height);
msdf_atlas::GeneratorAttributes attributes;
generator.setAttributes(attributes);
generator.setThreadCount(4);
generator.generate(glyphs.data(), glyphs.size());
msdf_atlas::BitmapAtlasStorage<msdf_atlas::byte, 3> pixels = generator.atlasStorage();
std::vector<uint8_t> data;
data.resize(width * height * 4);
msdfgen::Bitmap<msdf_atlas::byte, 3> bitmap = (msdfgen::Bitmap<msdf_atlas::byte, 3>)pixels;
for (int i = 0; i < width * height; i++)
{
data[i * 4] = bitmap[i * 3];
data[i * 4 + 1] = bitmap[i * 3 + 1];
data[i * 4 + 2] = bitmap[i * 3 + 2];
data[i * 4 + 3] = 255;
}
InitializeTextureImageFromData(data.data(), width, height);
for (msdf_atlas::GlyphGeometry& glyphGeom : glyphs)
{
Glyph glyph;
glyph.advance = glyphGeom.getAdvance();
double l, b, r, t;
glyphGeom.getQuadPlaneBounds(l, b, r, t);
glyph.pos1 = glm::vec2{l, b};
glyph.pos2 = glm::vec2{r, t};
glyphGeom.getQuadAtlasBounds(l, b, r, t);
glyph.texCoord1 = glm::vec2{l / width, b / height};
glyph.texCoord2 = glm::vec2{r / width, t / height};
this->glyphs.emplace((char)glyphGeom.getCodepoint(), glyph);
}
lineHeight = fontGeometry.getMetrics().lineHeight;
msdfgen::destroyFont(font);
msdfgen::deinitializeFreetype(ft);
}
Font::~Font()
{
vkDestroyImage(Vulkan::GetDevice(), image, nullptr);
vkFreeMemory(Vulkan::GetDevice(), imageMemory, nullptr);
vkDestroyImageView(Vulkan::GetDevice(), imageView, nullptr);
}
VkDescriptorImageInfo Font::GetDescriptorImageInfo(int index) const
{
VkDescriptorImageInfo imageInfo{};
imageInfo.imageLayout = VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL;
imageInfo.sampler = sampler;
imageInfo.imageView = imageView;
return imageInfo;
}
const Glyph& Font::GetGlyph(char c) const
{
CP_ASSERT(glyphs.find(c) != glyphs.end(), "Glyph not found: %c", c);
return glyphs.find(c)->second;
}
float Font::GetLineHeight() const
{
return lineHeight;
}
void Font::InitializeTextureImageFromData(const uint8_t* rgbaData, int width, int height)
{
VkDeviceSize bufferSize = width * height * 4;
Buffer stagingBuffer{VK_BUFFER_USAGE_TRANSFER_SRC_BIT, VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT | VK_MEMORY_PROPERTY_HOST_COHERENT_BIT, bufferSize, 1};
void* data = stagingBuffer.Map();
memcpy(data, rgbaData, bufferSize);
stagingBuffer.Unmap();
Image::InitializeImage(width, height, VK_FORMAT_R8G8B8A8_SRGB, VK_IMAGE_TILING_OPTIMAL, VK_IMAGE_USAGE_TRANSFER_DST_BIT | VK_IMAGE_USAGE_SAMPLED_BIT, VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT, &image, &imageMemory);
Image::TransitionImageLayout(image, VK_FORMAT_R8G8B8A8_SRGB, VK_IMAGE_LAYOUT_UNDEFINED, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL);
Image::CopyBufferToImage(stagingBuffer, image, width, height);
Image::TransitionImageLayout(image, VK_FORMAT_R8G8B8A8_SRGB, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL);
imageView = Image::InitializeImageView(image, VK_FORMAT_R8G8B8A8_SRGB, VK_IMAGE_ASPECT_COLOR_BIT);
}
}
+34
View File
@@ -0,0 +1,34 @@
#pragma once
#include "copium/sampler/Sampler.h"
#include "copium/sampler/Glyph.h"
namespace Copium
{
class Font : public Sampler
{
CP_DELETE_COPY_AND_MOVE_CTOR(Font);
struct GlyphData
{
};
private:
VkImage image;
VkDeviceMemory imageMemory;
VkImageView imageView;
std::map<char, Glyph> glyphs;
float lineHeight;
public:
Font(const MetaFile& metaFile);
~Font() override;
VkDescriptorImageInfo GetDescriptorImageInfo(int index) const override;
const Glyph& GetGlyph(char c) const;
float GetLineHeight() const;
private:
void InitializeTextureImageFromFile(const std::string& filename);
void InitializeTextureImageFromData(const uint8_t* rgbaData, int width, int height);
};
}
+15
View File
@@ -0,0 +1,15 @@
#pragma once
#include <glm/glm.hpp>
namespace Copium
{
struct Glyph
{
float advance;
glm::vec2 pos1;
glm::vec2 pos2;
glm::vec2 texCoord1;
glm::vec2 texCoord2;
};
}
@@ -1,6 +1,7 @@
#include "copium/sampler/Texture2D.h"
#include "copium/core/Vulkan.h"
#include "copium/sampler/Image.h"
#define STB_IMAGE_IMPLEMENTATION
#include <stb/stb_image.h>
@@ -19,7 +20,7 @@ namespace Copium
Texture2D::Texture2D(const std::vector<uint8_t>& rgbaData, int width, int height)
{
CP_ASSERT(rgbaData.size() == width * height * 4, "rgbaData has invalid size, should be equal to width * height * 4 (%d) actually is %d", width * height * 4, rgbaData.size());
InitializeTextureImageFromData((void*)rgbaData.data(), width, height);
InitializeTextureImageFromData(rgbaData.data(), width, height);
}
Texture2D::~Texture2D()
@@ -41,6 +42,7 @@ namespace Copium
void Texture2D::InitializeTextureImageFromFile(const std::string& filename)
{
stbi_set_flip_vertically_on_load(true);
int texWidth;
int texHeight;
int texChannels;
@@ -48,12 +50,12 @@ namespace Copium
CP_ASSERT(pixels, "Failed to load texture image");
InitializeTextureImageFromData((void*)pixels, texWidth, texHeight);
InitializeTextureImageFromData(pixels, texWidth, texHeight);
stbi_image_free(pixels);
}
void Texture2D::InitializeTextureImageFromData(void* rgbaData, int width, int height)
void Texture2D::InitializeTextureImageFromData(const uint8_t* rgbaData, int width, int height)
{
VkDeviceSize bufferSize = width * height * 4;
Buffer stagingBuffer{VK_BUFFER_USAGE_TRANSFER_SRC_BIT, VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT | VK_MEMORY_PROPERTY_HOST_COHERENT_BIT, bufferSize, 1};
+1 -5
View File
@@ -1,12 +1,8 @@
#pragma once
#include "copium/buffer/CommandBufferScoped.h"
#include "copium/sampler/Image.h"
#include "copium/sampler/Sampler.h"
#include "copium/util/Common.h"
#include <cstring>
namespace Copium
{
class Texture2D final : public Sampler
@@ -24,6 +20,6 @@ namespace Copium
VkDescriptorImageInfo GetDescriptorImageInfo(int index) const override;
private:
void InitializeTextureImageFromFile(const std::string& filename);
void InitializeTextureImageFromData(void* rgbaData, int width, int height);
void InitializeTextureImageFromData(const uint8_t* rgbaData, int width, int height);
};
}