25#include "shaders/textVert.hpp"
26#include "shaders/textFrag.hpp"
30 VkSampler textureSampler, VkRenderPass* renderPass,
46 fontpixels =
new unsigned char[fontHeight][256];
56 static_cast<size_t>(fontWidth),
static_cast<size_t>(fontHeight),
57 static_cast<VkDeviceSize
>(fontWidth * fontHeight), VK_FORMAT_R8_UNORM,
63 VK_BUFFER_USAGE_VERTEX_BUFFER_BIT,
64 VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT
65 | VK_MEMORY_PROPERTY_HOST_COHERENT_BIT,
76 textVert_spv, textVert_spv_len,
77 textFrag_spv, textFrag_spv_len);
82 return std::vector<VkDescriptorType> {
83 VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER,
84 VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER
90 return std::vector<VkShaderStageFlagBits> { VK_SHADER_STAGE_FRAGMENT_BIT,
91 VK_SHADER_STAGE_VERTEX_BIT, VK_SHADER_STAGE_FRAGMENT_BIT };
96 std::vector<VkDescriptorSetLayout> layouts(
98 VkDescriptorSetAllocateInfo allocInfo {};
99 allocInfo.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO;
100 allocInfo.descriptorPool = descriptorPool;
102 allocInfo.pSetLayouts = layouts.data();
104 if (vkAllocateDescriptorSets(
105 device->device, &allocInfo, descriptorSets.data())
107 throw std::runtime_error(
"failed to allocate descriptor sets!");
111 VkDescriptorImageInfo imageInfo {};
112 imageInfo.imageLayout = VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL;
113 imageInfo.imageView = fontTexture.textureImageView;
114 imageInfo.sampler = textureSampler;
116 VkDescriptorBufferInfo bufferInfo {};
117 bufferInfo.buffer = uniformBuffers[i].buffer;
118 bufferInfo.offset = 0;
121 VkDescriptorBufferInfo bufferInfo2 {};
122 bufferInfo2.buffer = colorBuffers[i].buffer;
123 bufferInfo2.offset = 0;
126 std::array<VkWriteDescriptorSet, 3> descriptorWrites {};
128 descriptorWrites[0].sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET;
129 descriptorWrites[0].dstSet = descriptorSets[i];
130 descriptorWrites[0].dstBinding = 0;
131 descriptorWrites[0].dstArrayElement = 0;
132 descriptorWrites[0].descriptorType
133 = VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER;
134 descriptorWrites[0].descriptorCount = 1;
135 descriptorWrites[0].pImageInfo = &imageInfo;
137 descriptorWrites[1].sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET;
138 descriptorWrites[1].dstSet = descriptorSets[i];
139 descriptorWrites[1].dstBinding = 1;
140 descriptorWrites[1].dstArrayElement = 0;
141 descriptorWrites[1].descriptorType = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER;
142 descriptorWrites[1].descriptorCount = 1;
143 descriptorWrites[1].pBufferInfo = &bufferInfo;
145 descriptorWrites[2].sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET;
146 descriptorWrites[2].dstSet = descriptorSets[i];
147 descriptorWrites[2].dstBinding = 2;
148 descriptorWrites[2].dstArrayElement = 0;
149 descriptorWrites[2].descriptorType = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER;
150 descriptorWrites[2].descriptorCount = 1;
151 descriptorWrites[2].pBufferInfo = &bufferInfo2;
153 vkUpdateDescriptorSets(device->device,
154 static_cast<uint32_t
>(descriptorWrites.size()),
155 descriptorWrites.data(), 0,
nullptr);
164 = std::vector<VkVertexInputBindingDescription> { 2 };
168 = VK_VERTEX_INPUT_RATE_VERTEX;
173 = VK_VERTEX_INPUT_RATE_VERTEX;
176 = std::vector<VkVertexInputAttributeDescription> { 2 };
180 = VK_FORMAT_R32G32_SFLOAT;
186 = VK_FORMAT_R32G32_SFLOAT;
189 pipelineAttributes.
topology = VK_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP;
190 pipelineAttributes.
frontFace = VK_FRONT_FACE_CLOCKWISE;
194 = VK_COLOR_COMPONENT_R_BIT | VK_COLOR_COMPONENT_G_BIT
195 | VK_COLOR_COMPONENT_B_BIT | VK_COLOR_COMPONENT_A_BIT;
197 = VK_BLEND_FACTOR_SRC_ALPHA;
199 = VK_BLEND_FACTOR_ONE_MINUS_SRC_ALPHA;
202 = VK_BLEND_FACTOR_ONE_MINUS_SRC_ALPHA;
204 = VK_BLEND_FACTOR_ZERO;
207 return pipelineAttributes;
213 vkDestroyBuffer(device->device, vertexBuffer,
nullptr);
214 vkFreeMemory(device->device, vertexBufferMemory,
nullptr);
216 colorBuffers[i].destroy();
218 fontTexture.destroy();
225 if (vkMapMemory(device->device, vertexBufferMemory, 0, VK_WHOLE_SIZE, 0,
226 (
void**)&mappedMemory)
228 throw std::runtime_error(
"failed to map memory!");
233 assert(mappedMemory !=
nullptr);
235 const float charW = 1.5f * params.scale / swapChain->swapChainExtent.width;
236 const float charH = 1.5f * params.scale / swapChain->swapChainExtent.height;
238 float fbW = (float)swapChain->swapChainExtent.width;
239 float fbH = (float)swapChain->swapChainExtent.height;
240 float x = (0 / fbW * 2.0f);
241 float y = (0 / fbH * 2.0f);
245 for (
auto letter : params.text) {
246 stb_fontchar* charData = &stbFontData[(uint32_t)letter - firstChar];
247 textWidth += charData->advance * charW;
254 x -= textWidth / 2.0f;
261 for (
auto letter : params.text) {
262 stb_fontchar* charData = &stbFontData[(uint32_t)letter - firstChar];
264 mappedMemory->x = (x + (float)charData->x0 * charW);
265 mappedMemory->y = (y + (float)charData->y0 * charH);
266 mappedMemory->z = charData->s0;
267 mappedMemory->w = charData->t0;
270 mappedMemory->x = (x + (float)charData->x1 * charW);
271 mappedMemory->y = (y + (float)charData->y0 * charH);
272 mappedMemory->z = charData->s1;
273 mappedMemory->w = charData->t0;
276 mappedMemory->x = (x + (float)charData->x0 * charW);
277 mappedMemory->y = (y + (float)charData->y1 * charH);
278 mappedMemory->z = charData->s0;
279 mappedMemory->w = charData->t1;
282 mappedMemory->x = (x + (float)charData->x1 * charW);
283 mappedMemory->y = (y + (float)charData->y1 * charH);
284 mappedMemory->z = charData->s1;
285 mappedMemory->w = charData->t1;
288 x += charData->advance * charW;
292 vkUnmapMemory(device->device, vertexBufferMemory);
293 mappedMemory =
nullptr;
298 if (vkMapMemory(device->device, vertexBufferMemory, 0, VK_WHOLE_SIZE, 0,
299 (
void**)&mappedMemory)
301 throw std::runtime_error(
"failed to map memory!");
304 mappedMemory =
nullptr;
306 vkUnmapMemory(device->device, vertexBufferMemory);
307 mappedMemory =
nullptr;
313 uniformBuffers[currentFrame].update(swapChain->swapChainExtent, params.x,
314 params.y, params.rotation + 90, 1.0f, -1.0f);
315 colorBuffers[currentFrame].update(
316 { params.color[0], params.color[1], params.color[2] });
320 float bgColor[3], VkViewport& viewport, VkRect2D& scissor,
321 std::vector<VkCommandBuffer>& commandBuffers)
323 vkCmdBindPipeline(commandBuffers[currentFrame],
324 VK_PIPELINE_BIND_POINT_GRAPHICS, this->graphicsPipeline);
325 vkCmdSetViewport(commandBuffers[currentFrame], 0, 1, &viewport);
326 vkCmdSetScissor(commandBuffers[currentFrame], 0, 1, &scissor);
327 VkBuffer vertexBuffers[] = { this->vertexBuffer };
328 VkDeviceSize offsets[] = { 0 };
329 vkCmdBindVertexBuffers(
330 commandBuffers[currentFrame], 0, 1, vertexBuffers, offsets);
331 vkCmdBindVertexBuffers(
332 commandBuffers[currentFrame], 1, 1, vertexBuffers, offsets);
333 vkCmdBindDescriptorSets(commandBuffers[currentFrame],
334 VK_PIPELINE_BIND_POINT_GRAPHICS, this->pipelineLayout, 0, 1,
335 &this->descriptorSets[currentFrame], 0,
nullptr);
336 for (uint32_t j = 0; j < this->numLetters; j++) {
337 vkCmdDraw(commandBuffers[currentFrame], 4, 1, j * 4, 0);
This initializes, manages and destroys the logical and physical devices(GPU).
virtual void destroy()=0
Destroys the object and releases associated resources.
VkCommandPool commandPool
Chronos::Engine::SwapChain * swapChain
Chronos::Engine::Device * device
void init(Chronos::Engine::Device *device, VkCommandPool commandPool, SwapChain *swapChain, VkSampler textureSampler, VkRenderPass *renderPass, ObjectType objectType, unsigned char *vertShaderCode, int vertShaderCodeSize, unsigned char *fragShaderCode, int fragShaderCodeSize)
Initializes the object.
VkRenderPass * renderPass
void destroy() override
Destroys the font object and frees the memory.
Chronos::Engine::Texture fontTexture
std::vector< VkShaderStageFlagBits > getDescriptorStages() override
Gets the descriptor stages in which the descriptor sets are used.
uint32_t maxTextLength
Maximum number of characters that can be rendered.
std::vector< VkDescriptorType > getDescriptorTypes() override
Gets the descriptor types needed for rendering the text.
VkDeviceMemory vertexBufferMemory
The vertex buffer memory.
std::vector< Chronos::Engine::ColorBuffer > colorBuffers
void clear()
Clears the text stored in the font object.
void update(uint32_t currentFrame) override
Updates the attributes(like position, color, etc) of the text.
void init(Chronos::Engine::Device *device, VkCommandPool commandPool, Chronos::Engine::SwapChain *swapChain, VkSampler textureSampler, VkRenderPass *renderPass, Chronos::Engine::FontTypes fontStyle)
Initializes the font object and creates the necessary objects.
stb_fontchar stbFontData[STB_FONT_consolas_24_latin1_NUM_CHARS]
void createDescriptorSets() override
Creates the descriptor sets needed for rendering the text.
unsigned char(* fontpixels)[256]
PipelineAttributes getPipelineAttributes() override
Returns the pipeline attributes that are set for the graphics pipeline.
VkBuffer vertexBuffer
The vertices of each character used for rendering.
void render(uint32_t currentFrame, uint32_t imageIndex, float bgColor[3], VkViewport &viewport, VkRect2D &scissor, std::vector< VkCommandBuffer > &commandBuffers) override
Records the commands needed for rendering the text .
void updateBuffer()
Updates the buffer with the new text.
void create(Chronos::Engine::Device device, VkCommandPool commandPool, std::string texturePath, std::string textureName)
Create the texture by loading the texture from the given path. Only supports jpg and png images.
Contains various common functions used by other classes in the Engine namespace.
void createBuffer(Chronos::Engine::Device device, VkDeviceSize size, VkBufferUsageFlags usage, VkMemoryPropertyFlags properties, VkBuffer *buffer, VkDeviceMemory *bufferMemory)
Creates a buffer of a given size, usage and properties.
The parameters needed for the font style.
void(* getFontData)(stb_fontchar *, unsigned char[][256], int)
Structure defining attributes required for creating a graphics pipeline.
VkPrimitiveTopology topology
VkPipelineColorBlendAttachmentState colorBlendAttachment
std::vector< VkVertexInputBindingDescription > bindingDescriptions
std::vector< VkVertexInputAttributeDescription > attributeDescriptions