Added unproject
Broken and buggy font stuff Fixed some typos Fixed draw rect not using dim properly
This commit is contained in:
191
code/draw/core.c
191
code/draw/core.c
@@ -30,7 +30,8 @@ void D_End(D_Context *draw, Vk_Frame *frame) {
|
||||
rbo_info.offset = 0;
|
||||
rbo_info.range = VK_WHOLE_SIZE;
|
||||
|
||||
VkDescriptorImageInfo *image_info = M_ArenaPush(temp.arena, VkDescriptorImageInfo, .count = draw->n_images);
|
||||
U32 total = draw->n_images + draw->n_fonts;
|
||||
VkDescriptorImageInfo *image_info = M_ArenaPush(temp.arena, VkDescriptorImageInfo, .count = total);
|
||||
|
||||
for (U32 it = 0; it < draw->n_images; ++it) {
|
||||
image_info[it].imageView = draw->images[it].image.view;
|
||||
@@ -38,6 +39,15 @@ void D_End(D_Context *draw, Vk_Frame *frame) {
|
||||
image_info[it].imageLayout = VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL;
|
||||
}
|
||||
|
||||
U32 idx = draw->n_images;
|
||||
for (D_Font *it = draw->fonts; it != 0; it = it->next) {
|
||||
image_info[idx].imageView = it->image.view;
|
||||
image_info[idx].sampler = vk.sampler; // @Todo: probably want linear filtering on fonts
|
||||
image_info[idx].imageLayout = VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL;
|
||||
|
||||
idx += 1;
|
||||
}
|
||||
|
||||
writes[0].sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET;
|
||||
writes[0].dstSet = set;
|
||||
writes[0].dstBinding = 0;
|
||||
@@ -48,7 +58,7 @@ void D_End(D_Context *draw, Vk_Frame *frame) {
|
||||
writes[1].sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET;
|
||||
writes[1].dstSet = set;
|
||||
writes[1].dstBinding = 1;
|
||||
writes[1].descriptorCount = draw->n_images;
|
||||
writes[1].descriptorCount = total;
|
||||
writes[1].descriptorType = VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER;
|
||||
writes[1].pImageInfo = image_info;
|
||||
|
||||
@@ -111,8 +121,8 @@ void _D_Rect(D_Context *draw, D_RectOpts *opts) {
|
||||
}
|
||||
|
||||
if (opts->flags & D_RECT_IGNORE_ASPECT) {
|
||||
rect->w = opts->w;
|
||||
rect->h = opts->h;
|
||||
rect->w = opts->dim.w;
|
||||
rect->h = opts->dim.h;
|
||||
}
|
||||
else {
|
||||
Vk_Image *image = &draw->images[opts->texture].image;
|
||||
@@ -130,3 +140,176 @@ void _D_Rect(D_Context *draw, D_RectOpts *opts) {
|
||||
draw->n_rects += 1;
|
||||
}
|
||||
}
|
||||
|
||||
void D_Text(D_Context *draw, D_Font *font, Str8 text, F32 x, F32 y) {
|
||||
F32 xoff = x;
|
||||
local_persist B32 done = 0;
|
||||
|
||||
for (S64 it = 0; it < text.count; ++it) {
|
||||
if (text.data[it] >= ' ' && text.data[it] <= '~') {
|
||||
D_Glyph *glyph = &font->glyphs[text.data[it] - ' '];
|
||||
|
||||
V2f size;
|
||||
size.w = (glyph->box.max.x - glyph->box.min.x);
|
||||
size.h = (glyph->box.max.y - glyph->box.min.y);
|
||||
|
||||
V2f dim;
|
||||
|
||||
F32 scale = 150.0f / (font->ascent - font->descent);
|
||||
|
||||
if (size.w > size.h) {
|
||||
dim.w = scale * (size.w / size.h);
|
||||
dim.h = scale;
|
||||
}
|
||||
else {
|
||||
dim.w = scale;
|
||||
dim.h = scale * (size.h / size.w);
|
||||
}
|
||||
|
||||
// @Hardcode: need font index in font struct
|
||||
D_Rect(draw, xoff, y, .texture = 0, .c = V4F(0, 1, 1, 1), .dim = dim, .flags = D_RECT_IGNORE_ASPECT);
|
||||
D_Rect(draw, xoff, y, .texture = draw->n_images, .uv = glyph->box, .dim = dim, .flags = D_RECT_IGNORE_ASPECT);
|
||||
xoff += (1.05f * dim.w); // glyph->advance; //+ glyph->offset.x;
|
||||
|
||||
if (!done) { printf(" %f (%f, %f)", xoff, dim.w, dim.h); }
|
||||
}
|
||||
}
|
||||
|
||||
if (!done) { printf("\n"); }
|
||||
done = true;
|
||||
}
|
||||
|
||||
void D_FontLoad(D_Context *draw, Str8 name, F32 size) {
|
||||
M_TempScope(0, 0) {
|
||||
(void) draw;
|
||||
|
||||
Str8 exe_path = FS_SystemPath(temp.arena, FS_SYSTEM_PATH_EXE);
|
||||
Str8 path = Sf(temp.arena, "%.*s/assets/%.*s.ttf", Sv(exe_path), Sv(name));
|
||||
|
||||
Str8 font_data = FS_ReadEntireFile(temp.arena, path);
|
||||
|
||||
stbtt_fontinfo info = { 0 };
|
||||
stbtt_InitFont(&info, font_data.data, 0);
|
||||
|
||||
F32 scale = stbtt_ScaleForPixelHeight(&info, 20);
|
||||
|
||||
U32 w = 512;
|
||||
U32 h = 512;
|
||||
|
||||
U8 *pixels = M_ArenaPush(temp.arena, U8, .count = (w * h));
|
||||
|
||||
stbtt_pack_context pack = { 0 };
|
||||
stbtt_PackBegin(&pack, pixels, w, h, 0, 1, 0);
|
||||
|
||||
U32 count = '~' - ' ';
|
||||
stbtt_packedchar *packed = M_ArenaPush(temp.arena, stbtt_packedchar, .count = count);
|
||||
stbtt_PackFontRange(&pack, font_data.data, 0, size, ' ', count, packed);
|
||||
|
||||
D_Font *font = M_ArenaPush(draw->arena, D_Font);
|
||||
|
||||
font->px = size;
|
||||
|
||||
S32 asc, desc, line;
|
||||
stbtt_GetFontVMetrics(&info, &asc, &desc, &line);
|
||||
|
||||
font->line_advance = cast(F32) line;
|
||||
font->ascent = cast(F32) asc;
|
||||
font->descent = cast(F32) desc;
|
||||
|
||||
font->glyphs = M_ArenaPush(draw->arena, D_Glyph, .count = count);
|
||||
|
||||
for (U32 it = 0; it < count; ++it) {
|
||||
D_Glyph *glyph = &font->glyphs[it];
|
||||
stbtt_packedchar *chr = &packed[it];
|
||||
|
||||
S32 left, width;
|
||||
stbtt_GetCodepointHMetrics(&info, ' ' + it, &width, &left);
|
||||
|
||||
glyph->box = R2F(V2F(chr->x0 / (F32) w, chr->y0 / (F32) h), V2F(chr->x1 / (F32) w, chr->y1 / (F32) h));
|
||||
|
||||
glyph->advance = glyph->box.max.x - glyph->box.min.x; //chr->xadvance * scale;
|
||||
glyph->offset = V2F(chr->xoff * scale, chr->yoff * scale);
|
||||
}
|
||||
|
||||
Vk_Buffer *staging = &draw->staging;
|
||||
U32 *px = (U32 *) staging->data;
|
||||
for (U32 y = 0; y < h; ++y) {
|
||||
for (U32 x = 0; x < w; ++x) {
|
||||
*px++ = 0x0 | ((U32) pixels[(y * w) + x] << 24);
|
||||
}
|
||||
}
|
||||
|
||||
Vk_CommandBuffer *cmds = Vk_CommandBufferPush();
|
||||
|
||||
font->image.width = w;
|
||||
font->image.height = h;
|
||||
|
||||
font->image.format = VK_FORMAT_R8G8B8A8_SRGB;
|
||||
font->image.usage = VK_IMAGE_USAGE_SAMPLED_BIT;
|
||||
|
||||
Vk_ImageCreate(&font->image);
|
||||
|
||||
VkBufferImageCopy copy = { 0 };
|
||||
|
||||
copy.bufferOffset = 0;
|
||||
copy.bufferRowLength = 0;
|
||||
copy.bufferImageHeight = 0;
|
||||
|
||||
copy.imageSubresource.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
|
||||
copy.imageSubresource.mipLevel = 0;
|
||||
copy.imageSubresource.baseArrayLayer = 0;
|
||||
copy.imageSubresource.layerCount = 1;
|
||||
|
||||
copy.imageExtent.width = w;
|
||||
copy.imageExtent.height = h;
|
||||
copy.imageExtent.depth = 1;
|
||||
|
||||
VkImageMemoryBarrier2 transfer = { 0 };
|
||||
VkImageMemoryBarrier2 shader_read = { 0 };
|
||||
|
||||
transfer.sType = VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER_2;
|
||||
transfer.srcStageMask = VK_PIPELINE_STAGE_2_NONE;
|
||||
transfer.srcAccessMask = VK_ACCESS_2_NONE;
|
||||
transfer.dstStageMask = VK_PIPELINE_STAGE_2_TRANSFER_BIT;
|
||||
transfer.dstAccessMask = VK_ACCESS_2_TRANSFER_WRITE_BIT;
|
||||
transfer.oldLayout = VK_IMAGE_LAYOUT_UNDEFINED;
|
||||
transfer.newLayout = VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL;
|
||||
transfer.image = font->image.handle;
|
||||
|
||||
transfer.subresourceRange.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
|
||||
transfer.subresourceRange.layerCount = 1;
|
||||
transfer.subresourceRange.levelCount = 1;
|
||||
|
||||
shader_read.sType = VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER_2;
|
||||
shader_read.srcStageMask = VK_PIPELINE_STAGE_2_TRANSFER_BIT;
|
||||
shader_read.srcAccessMask = VK_ACCESS_2_TRANSFER_WRITE_BIT;
|
||||
shader_read.dstStageMask = VK_PIPELINE_STAGE_2_FRAGMENT_SHADER_BIT;
|
||||
shader_read.dstAccessMask = VK_ACCESS_2_SHADER_SAMPLED_READ_BIT;
|
||||
shader_read.oldLayout = VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL;
|
||||
shader_read.newLayout = VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL;
|
||||
shader_read.image = font->image.handle;
|
||||
|
||||
shader_read.subresourceRange.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
|
||||
shader_read.subresourceRange.layerCount = 1;
|
||||
shader_read.subresourceRange.levelCount = 1;
|
||||
|
||||
VkDependencyInfo dep = { 0 };
|
||||
dep.sType = VK_STRUCTURE_TYPE_DEPENDENCY_INFO;
|
||||
|
||||
dep.imageMemoryBarrierCount = 1;
|
||||
dep.pImageMemoryBarriers = &transfer;
|
||||
|
||||
vk.CmdPipelineBarrier2(cmds->handle, &dep);
|
||||
|
||||
vk.CmdCopyBufferToImage(cmds->handle, staging->handle, font->image.handle, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, 1, ©);
|
||||
|
||||
dep.pImageMemoryBarriers = &shader_read;
|
||||
|
||||
vk.CmdPipelineBarrier2(cmds->handle, &dep);
|
||||
|
||||
Vk_CommandBufferSubmit(cmds, true);
|
||||
|
||||
SLL_PushN(draw->fonts, font, next);
|
||||
draw->n_fonts += 1;
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user