Found a serious flaw in Lucy design. A very very serious flaw. Gonna rewrite everything
This commit is contained in:
parent
91f6b8e2f6
commit
284b0b711b
@ -80,6 +80,10 @@ struct LucyGlyphCache {
|
||||
VecRefListNodeLucyImage to_be_copied_to_device_next_cycle;
|
||||
/* deletion will be performed last */
|
||||
VecRefListNodeLucyImage to_be_deleted;
|
||||
/* This filed is actually used in later stages of 'another_frame' sequence. It is used by font renderer
|
||||
* to know if sus stuff had occurred. At the beginning of my _another_frame method it gets turned false
|
||||
* automatically, but during my _another_frame it can get raised true to indicate reshuffling of images */
|
||||
bool changes_happened;
|
||||
};
|
||||
|
||||
|
||||
@ -98,7 +102,10 @@ LucyGlyphCache LucyGlyphCache_new(MargaretEngineReference ve){
|
||||
VkDescriptorSet descriptor_set = margaret_allocate_descriptor_set(ve.device, ve.descriptor_pool,
|
||||
my_desc_set_layout);
|
||||
return (LucyGlyphCache){.ve = ve, .images = ListLucyImage_new(),
|
||||
.descriptor_set_layout = my_desc_set_layout, .descriptor_set = descriptor_set};
|
||||
.descriptor_set_layout = my_desc_set_layout, .descriptor_set = descriptor_set,
|
||||
.to_be_freed_of_old_staging_next_cycle = VecRefListNodeLucyImage_new(),
|
||||
.to_be_copied_to_device_next_cycle = VecRefListNodeLucyImage_new(),
|
||||
.to_be_deleted = VecRefListNodeLucyImage_new(), .changes_happened = false};
|
||||
}
|
||||
|
||||
void LucyFaceFixedSize_get_rid_of_myself(LucyFaceFixedSize* self){
|
||||
@ -302,7 +309,10 @@ void LucyGlyphCache_drop(LucyGlyphCache self){
|
||||
VecRefListNodeLucyImage_drop(self.to_be_deleted);
|
||||
}
|
||||
|
||||
void
|
||||
|
||||
void LucyGlyphCache_another_frame(LucyGlyphCache* self){
|
||||
self->changes_happened = false;
|
||||
for (size_t i = 0; i < self->to_be_freed_of_old_staging_next_cycle.len; i++) {
|
||||
LucyImage* img = &self->to_be_freed_of_old_staging_next_cycle.buf[i]->el;
|
||||
assert(img->staging_buffer.len != 0);
|
||||
@ -355,6 +365,7 @@ void LucyGlyphCache_another_frame(LucyGlyphCache* self){
|
||||
.pImageInfo = desc_elements.buf
|
||||
}, 0, NULL);
|
||||
VecVkDescriptorImageInfo_drop(desc_elements);
|
||||
self->changes_happened = true;
|
||||
}
|
||||
self->to_be_freed_of_old_staging_next_cycle.len = 0;
|
||||
self->to_be_copied_to_device_next_cycle.len = 0;
|
||||
|
||||
@ -13,13 +13,32 @@ typedef struct{
|
||||
U32 tex_ind;
|
||||
} LucyVertex;
|
||||
|
||||
typedef struct {
|
||||
ListNodeLucyImage* img;
|
||||
vec4 color;
|
||||
ivec2 positioned;
|
||||
uvec2 pos_on_atlas;
|
||||
U32 w;
|
||||
U32 h;
|
||||
} LucyRenderedGlyphRecord;
|
||||
|
||||
#include "../../../gen/l1/eve/lucy/VecLucyRenderedGlyphRecord.h"
|
||||
|
||||
typedef struct {
|
||||
vec4 color;
|
||||
vec2 lt_pos;
|
||||
vec2 br_pos;
|
||||
vec2 lt_tex;
|
||||
vec2 br_tex;
|
||||
} LucyGlyphInstance;
|
||||
|
||||
typedef struct {
|
||||
MargaretEngineReference ve;
|
||||
LucyGlyphCache* cache;
|
||||
VkPipelineLayout pipeline_layout;
|
||||
VkPipeline pipeline;
|
||||
|
||||
U64 vertex_count;
|
||||
VecLucyRenderedGlyphRecord rendered_glyphs;
|
||||
MargaretSubbuf staging_vbo;
|
||||
MargaretSubbuf vbo;
|
||||
bool need_to_transfer;
|
||||
@ -67,7 +86,7 @@ LucyRenderer LucyRenderer_new(
|
||||
});
|
||||
|
||||
return (LucyRenderer){.ve = ve, .cache = cache, .pipeline_layout = pipeline_layout, .pipeline = pipeline,
|
||||
.vertex_count = 0, .staging_vbo = MargaretBufAllocator_alloc(ve.staging_buffers, 67),
|
||||
.rendered_glyphs = VecLucyRenderedGlyphRecord_new(), .staging_vbo = MargaretBufAllocator_alloc(ve.staging_buffers, 67),
|
||||
.vbo = MargaretBufAllocator_alloc(ve.dev_local_buffers, 67)
|
||||
};
|
||||
}
|
||||
@ -76,14 +95,7 @@ LucyRenderer LucyRenderer_new(
|
||||
* before LucyRenderer_another_frame
|
||||
*/
|
||||
void LucyRenderer_clear(LucyRenderer* self){
|
||||
self->vertex_count = 0;
|
||||
}
|
||||
|
||||
void LucyRenderer__append_vertex_to_vao(LucyRenderer* self, LucyVertex vert_data){
|
||||
self->vertex_count++;
|
||||
assert(self->vertex_count * sizeof(LucyVertex) <= self->staging_vbo.len);
|
||||
LucyVertex* staging = (LucyVertex*)MargaretSubbuf_get_mapped(&self->staging_vbo);
|
||||
staging[self->vertex_count - 1] = vert_data;
|
||||
self->rendered_glyphs.len = 0;
|
||||
}
|
||||
|
||||
/* When another_frame starts, you are safe to call this function, but you also have to call it
|
||||
@ -113,10 +125,40 @@ void LucyRenderer_add_text(
|
||||
assert(map_it > 0 && map_it < glyphs->tree.len);
|
||||
LucyStoredGlyph* glyph = &glyphs->el.buf[map_it - 1].value;
|
||||
if (glyph->w > 0 && glyph->h > 0) {
|
||||
VecLucyRenderedGlyphRecord_append(&self->rendered_glyphs, (LucyRenderedGlyphRecord){
|
||||
.color = color, .img = glyph->img,
|
||||
.positioned = ivec2_add_ivec2(pos, glyph->bearing),
|
||||
.pos_on_atlas = glyph->pos_on_atlas, .w = glyph->w, .h = glyph->h
|
||||
});
|
||||
}
|
||||
pos.x += (S32)glyph->advance_x;
|
||||
}
|
||||
}
|
||||
|
||||
/* It only records transfer commands (transfer command buffer is passed in MargaretEngineReference object) */
|
||||
void LucyRenderer_another_frame(LucyRenderer* self){
|
||||
U64 needed_vbo_length = self->rendered_glyphs.len * 6 * sizeof(LucyVertex);
|
||||
if (self->staging_vbo.len < needed_vbo_length) {
|
||||
printf("LucyRenderer Staging Buffer: Gotta replace %lu with %lu\n",
|
||||
self->staging_vbo.len, needed_vbo_length);
|
||||
MargaretBufAllocator_expand_or_move_old_host_visible(
|
||||
self->ve.staging_buffers, &self->staging_vbo, needed_vbo_length);
|
||||
}
|
||||
if (self->vbo.len < needed_vbo_length) {
|
||||
MargaretBufAllocator_expand_or_free_old(self->ve.dev_local_buffers, &self->vbo, needed_vbo_length);
|
||||
}
|
||||
size_t vertex_id = 0; // todo: rewrite using instances
|
||||
LucyVertex* vbo_data = (LucyVertex*)MargaretSubbuf_get_mapped(&self->staging_vbo);
|
||||
if ((self->cache->changes_happened || self->need_to_transfer) && self->rendered_glyphs.len > 0) {
|
||||
printf("LucyRenderer: we are doing copying\n");
|
||||
|
||||
for (size_t i = 0; i < self->rendered_glyphs.len; i++) {
|
||||
LucyRenderedGlyphRecord* glyph = &self->rendered_glyphs.buf[i];
|
||||
float atlas_w = (float)glyph->img->el.img.width;
|
||||
float atlas_h = (float)glyph->img->el.img.height;
|
||||
U32 desc_elem_id = glyph->img->el.pos_in_desc_array;
|
||||
ivec2 positioned = ivec2_add_ivec2(pos, glyph->bearing);
|
||||
vec4 color = glyph->color;
|
||||
ivec2 positioned = glyph->positioned;
|
||||
LucyVertex v0 = {
|
||||
.color = color, .pos = (vec2){(float)positioned.x, (float)positioned.y},
|
||||
.tex_cord = (vec2){
|
||||
@ -145,36 +187,17 @@ void LucyRenderer_add_text(
|
||||
(float)(glyph->pos_on_atlas.y + glyph->h) / atlas_h
|
||||
}, .tex_ind = desc_elem_id
|
||||
};
|
||||
/* What if we run out of space? */
|
||||
U64 needed_vbo_length = (self->vertex_count + 6) * sizeof(LucyVertex);
|
||||
if (self->staging_vbo.len < needed_vbo_length) {
|
||||
printf("LucyRenderer Staging Buffer: Gotta replace %lu with %lu\n",
|
||||
self->staging_vbo.len, needed_vbo_length);
|
||||
MargaretBufAllocator_expand_or_move_old_host_visible(
|
||||
self->ve.staging_buffers, &self->staging_vbo, needed_vbo_length);
|
||||
}
|
||||
LucyRenderer__append_vertex_to_vao(self, v1);
|
||||
LucyRenderer__append_vertex_to_vao(self, v0);
|
||||
LucyRenderer__append_vertex_to_vao(self, v2);
|
||||
LucyRenderer__append_vertex_to_vao(self, v1);
|
||||
LucyRenderer__append_vertex_to_vao(self, v2);
|
||||
LucyRenderer__append_vertex_to_vao(self, v3);
|
||||
|
||||
vbo_data[vertex_id++] = v1;
|
||||
vbo_data[vertex_id++] = v0;
|
||||
vbo_data[vertex_id++] = v2;
|
||||
vbo_data[vertex_id++] = v1;
|
||||
vbo_data[vertex_id++] = v2;
|
||||
vbo_data[vertex_id++] = v3;
|
||||
}
|
||||
pos.x += (S32)glyph->advance_x;
|
||||
}
|
||||
}
|
||||
|
||||
/* It only records transfer commands (transfer command buffer is passed in MargaretEngineReference object) */
|
||||
void LucyRenderer_another_frame(LucyRenderer* self){
|
||||
if (self->vbo.len < self->vertex_count * sizeof(LucyVertex)) {
|
||||
MargaretBufAllocator_expand_or_free_old(self->ve.dev_local_buffers, &self->vbo,
|
||||
self->vertex_count * sizeof(LucyVertex));
|
||||
}
|
||||
if (self->need_to_transfer && self->vertex_count > 0) {
|
||||
self->need_to_transfer = false;
|
||||
margaret_rec_cmd_copy_buffer_one_to_one_part(self->ve.transfer_cmd_buffer,
|
||||
&self->staging_vbo, &self->vbo, 0, self->vertex_count * sizeof(LucyVertex));
|
||||
&self->staging_vbo, &self->vbo, 0, needed_vbo_length);
|
||||
}
|
||||
}
|
||||
|
||||
@ -189,7 +212,7 @@ void LucyRenderer_another_frame_rec_drawing(
|
||||
(VkBuffer[]){MargaretSubbuf_get_buffer(&self->vbo)}, (VkDeviceSize[]){self->vbo.start});
|
||||
vkCmdBindDescriptorSets(drawing_cmd_buf, VK_PIPELINE_BIND_POINT_GRAPHICS, self->pipeline_layout, 0,
|
||||
1, (VkDescriptorSet[]){self->cache->descriptor_set}, 0, NULL);
|
||||
vkCmdDraw(drawing_cmd_buf, self->vertex_count, 1, 0, 0);
|
||||
vkCmdDraw(drawing_cmd_buf, self->rendered_glyphs.len * 6, 1, 0, 0);
|
||||
}
|
||||
|
||||
#endif
|
||||
@ -6,9 +6,9 @@ import Data.IORef (newIORef, readIORef, writeIORef, modifyIORef)
|
||||
import Data.Word(Word32, Word64)
|
||||
|
||||
lucyFaceAddGlyphRange :: LucyFaceFixedSize -> Char -> Char -> IO ()
|
||||
lucyFaceAddGlyphRange ffs a b = lucyFaceAddGlyphs ffs A (B - A + 1) where
|
||||
A = ((fromIntegral $ ord a) :: Word32)
|
||||
B = ((fromIntegral $ ord b) :: Word32)
|
||||
lucyFaceAddGlyphRange ffs a b = lucyFaceAddGlyphs ffs aInt (bInt - aInt + 1)
|
||||
where aInt = ((fromIntegral $ ord a) :: Word32)
|
||||
bInt = ((fromIntegral $ ord b) :: Word32)
|
||||
|
||||
-- Game configurable
|
||||
|
||||
@ -40,8 +40,9 @@ main = do
|
||||
aliceSetCamPos alice (Vec3 0 heroHeight 0)
|
||||
face <- aliceNewLucyFace alice "src/l3/fonts/DMSerifText-Regular.ttf"
|
||||
faceOf40 <- aliceLucyFaceOfSize face 40
|
||||
lucyFaceAddGlyphs faceOf40 32 (126 - 32 + 1)
|
||||
lucyFaceAddGlyphs faceOf40 (fromIntegral) (126 - 32 + 1)
|
||||
lucyFaceAddGlyphRange faceOf40 ' ' '~'
|
||||
lucyFaceAddGlyphRange faceOf40 'а' 'я'
|
||||
lucyFaceAddGlyphRange faceOf40 'А' 'Я'
|
||||
aliceAddText alice faceOf40 (Vec4 1 1 0 1) "Privet" 100 200
|
||||
|
||||
weirdStructure <- aliceAddGenericMeshHand alice "gen/l2/models/log_10_2_6.AliceGenericMesh"
|
||||
|
||||
@ -18,33 +18,55 @@ AliceGenericMeshPath AliceGenericMeshPath_for_puck(){
|
||||
};
|
||||
}
|
||||
|
||||
void main_h_on_wayland_keyboard_key(void* data, U32 keysym, U32 act){
|
||||
typedef struct{
|
||||
Alice* alice;
|
||||
LucyFace* font_face;
|
||||
RBTreeNodeLucyFaceFixedSize* font_face_of_size_40;
|
||||
} R4AlphaStuff;
|
||||
|
||||
void main_h_on_wayland_keyboard_key(void* data, U32 keysym, U32 act){
|
||||
}
|
||||
|
||||
void main_h_on_another_frame(void* data, float fl){
|
||||
|
||||
R4AlphaStuff *st = data;
|
||||
Alice* alice = st->alice;
|
||||
margaret_ns_time TIME = margaret_clock_gettime_monotonic_raw();
|
||||
printf("Updating text\n");
|
||||
LucyRenderer_clear(&alice->lucy_renderer);
|
||||
VecU8 text = VecU8_fmt("Time is %u.%u\nHave a good day sir\n", (U64)TIME.tv_sec, (U64)TIME.tv_nsec);
|
||||
LucyRenderer_add_text(&alice->lucy_renderer, st->font_face_of_size_40, (vec4){0.1f, 0.2f, 0, 1}, 0,
|
||||
VecU8_to_span(&text), (ivec2){100, 100});
|
||||
}
|
||||
|
||||
int main(){
|
||||
R4AlphaStuff st;
|
||||
Alice* alice = Alice_new();
|
||||
st.alice = alice;
|
||||
st.alice->guest = &st;
|
||||
|
||||
LucyFace* font_face = LucyFace_new(alice->ft_library, &alice->lucy_cache,
|
||||
st.font_face = LucyFace_new(st.alice->ft_library, &st.alice->lucy_cache,
|
||||
VecU8_fmt("%s/src/l3/fonts/DMSerifText-Regular.ttf", cstr(".")));
|
||||
RBTreeNodeLucyFaceFixedSize* font_face_of_size_40 = LucyFace_of_size(font_face, 40);
|
||||
st.font_face_of_size_40 = LucyFace_of_size(st.font_face, 13);
|
||||
VecLucyGlyphCachingRequest lucy_requests = VecLucyGlyphCachingRequest_new();
|
||||
VecU32Segment ranges_needed = VecU32Segment_new();
|
||||
VecU32Segment_append(&ranges_needed, (U32Segment){.start = 32, .len = 126 - 32 + 1});
|
||||
VecLucyGlyphCachingRequest_append(&lucy_requests, (LucyGlyphCachingRequest){
|
||||
.sized_face = font_face_of_size_40, .codepoint_ranges = ranges_needed,
|
||||
.sized_face = st.font_face_of_size_40, .codepoint_ranges = ranges_needed,
|
||||
});
|
||||
LucyGlyphCache_add_glyphs(lucy_requests);
|
||||
lucy_requests = VecLucyGlyphCachingRequest_new();
|
||||
ranges_needed = VecU32Segment_new();
|
||||
VecU32Segment_append(&ranges_needed, (U32Segment){.start = 0x430, .len = 0x44f - 0x430 + 1});
|
||||
VecLucyGlyphCachingRequest_append(&lucy_requests, (LucyGlyphCachingRequest){
|
||||
.sized_face = st.font_face_of_size_40, .codepoint_ranges = ranges_needed,
|
||||
});
|
||||
|
||||
LucyRenderer_add_text(&alice->lucy_renderer, font_face_of_size_40, (vec4){1, 0, 0, 1}, 0,
|
||||
LucyGlyphCache_add_glyphs(lucy_requests);
|
||||
LucyRenderer_add_text(&st.alice->lucy_renderer, st.font_face_of_size_40, (vec4){1, 0, 0, 1}, 0,
|
||||
cstr("Bebra budet\notnyahana"), (ivec2){10, 10});
|
||||
|
||||
ListNodeAliceGenericMeshHand* model_gen = Alice_add_generic_mesh(alice, AliceGenericMeshPath_for_log(cstr("."), 10, 2, 6));
|
||||
AliceGenericMeshHand_resize_instance_arr(alice, &model_gen->el, 1);
|
||||
ListNodeAliceGenericMeshHand* model_gen = Alice_add_generic_mesh(st.alice, AliceGenericMeshPath_for_log(cstr("."), 10, 2, 6));
|
||||
AliceGenericMeshHand_resize_instance_arr(st.alice, &model_gen->el, 1);
|
||||
|
||||
for (int X = 0; X < 1; X++) {
|
||||
for (int Z = 0; Z < 1; Z++) {
|
||||
@ -54,8 +76,8 @@ int main(){
|
||||
}
|
||||
}
|
||||
|
||||
// ListNodeAliceShinyMeshHand *model_sh = Alice_add_shiny_mesh(alice, vcstr("./gen/l2/models/cube.AliceShinyMesh"));
|
||||
// AliceShinyMeshHand_resize_instance_arr(alice, &model_sh->el, 100);
|
||||
// ListNodeAliceShinyMeshHand *model_sh = Alice_add_shiny_mesh(st->alice, vcstr("./gen/l2/models/cube.AliceShinyMesh"));
|
||||
// AliceShinyMeshHand_resize_instance_arr(st->alice, &model_sh->el, 100);
|
||||
|
||||
// for (int X = 0; X < 10; X++) {
|
||||
// for (int Z = 0; Z < 10; Z++) {
|
||||
@ -66,7 +88,7 @@ int main(){
|
||||
// }
|
||||
// }
|
||||
|
||||
// Pipeline0UBO* ubo = (Pipeline0UBO*)MargaretSubbuf_get_mapped(&alice->pipeline0_ubo.staging);
|
||||
// Pipeline0UBO* ubo = (Pipeline0UBO*)MargaretSubbuf_get_mapped(&st->alice->pipeline0_ubo.staging);
|
||||
// assert(pipeline_0_ubo_point_light_max_count >= 100);
|
||||
// ubo->point_light_count = 100;
|
||||
// ubo->spotlight_count = 0;
|
||||
@ -81,8 +103,8 @@ int main(){
|
||||
// ubo->point_light_arr[0].color = (vec3){100, 100, 100};
|
||||
|
||||
|
||||
// ListNodeAliceGenericMeshHand* model_puck = Alice_add_generic_mesh(alice, AliceGenericMeshPath_for_puck());
|
||||
// AliceGenericMeshHand_resize_instance_arr(alice, &model_puck->el, 100);
|
||||
// ListNodeAliceGenericMeshHand* model_puck = Alice_add_generic_mesh(st->alice, AliceGenericMeshPath_for_puck());
|
||||
// AliceGenericMeshHand_resize_instance_arr(st->alice, &model_puck->el, 100);
|
||||
// for (int X = 0; X < 10; X++) {
|
||||
// for (int Z = 0; Z < 10; Z++) {
|
||||
// AliceGenericMeshHand_set_inst(&model_puck->el, X * 10 + Z, (GenericMeshInstanceInc){
|
||||
@ -90,7 +112,7 @@ int main(){
|
||||
// });
|
||||
// }
|
||||
// }
|
||||
Alice_mainloop(alice, &(AliceCallbacks){
|
||||
Alice_mainloop(st.alice, &(AliceCallbacks){
|
||||
.on_wl_keyboard_key = main_h_on_wayland_keyboard_key,
|
||||
.on_another_frame = main_h_on_another_frame,
|
||||
});
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user