diff --git a/.gitmodules b/.gitmodules index 7d9eb34e..8be12a94 100644 --- a/.gitmodules +++ b/.gitmodules @@ -19,9 +19,9 @@ [submodule "dependencies/SafeMemory"] path = dependencies/SafeMemory url = https://github.com/ravi688/SafeMemory.git -[submodule "dependencies/MeshLib"] - path = dependencies/MeshLib - url = https://github.com/ravi688/MeshLib.git [submodule "dependencies/ttf2mesh"] path = dependencies/ttf2mesh url = https://github.com/ravi688/ttf2mesh.git +[submodule "dependencies/MeshLib"] + path = dependencies/MeshLib + url = https://github.com/ravi688/MeshLib.git diff --git a/dependencies/MeshLib b/dependencies/MeshLib index fae170f0..ca22bca2 160000 --- a/dependencies/MeshLib +++ b/dependencies/MeshLib @@ -1 +1 @@ -Subproject commit fae170f0285c1dd7e5490874ed7dc99709bcce25 +Subproject commit ca22bca25f658d4e94ea96e171b8e4d6000fcca7 diff --git a/dependencies/SafeMemory b/dependencies/SafeMemory index 9a9c32b5..42f2d346 160000 --- a/dependencies/SafeMemory +++ b/dependencies/SafeMemory @@ -1 +1 @@ -Subproject commit 9a9c32b566a41282aa182133a07b9af21b9d3039 +Subproject commit 42f2d346ffdc05827721c4caae77f36f1b096dc4 diff --git a/include/renderer/font.h b/include/renderer/font.h index 9f16dfee..13fa76fa 100644 --- a/include/renderer/font.h +++ b/include/renderer/font.h @@ -5,8 +5,30 @@ #include +enum +{ + FONT_GLYPH_MESH_QUALITY_LOW, + FONT_GLYPH_MESH_QUALITY_NORMAL, + FONT_GLYPH_MESH_QUALITY_HIGH +}; + typedef struct font_t font_t; +typedef struct mesh3d_t mesh3d_t; + +typedef struct font_glyph_info_t +{ + u32 index; + float min_x; + float max_x; + float min_y; + float max_y; + + float advance_width; + + float left_side_bearing; + float right_side_bearing; +} font_glyph_info_t; typedef struct font_t { @@ -19,3 +41,7 @@ font_t* font_create(void* bytes, u64 length); font_t* font_load_and_create(const char* file_name); void font_destroy(font_t* font); void font_release_resources(font_t* font); + +void font_get_glyph_mesh(font_t* font, u16 wide_char, u8 mesh_quality, mesh3d_t* out_mesh); +void font_get_glyph_info(font_t* font, u16 wide_char, font_glyph_info_t* out_info); +// void font_get_glyph_bitmap(font_t* font, void* out_bytes); diff --git a/include/renderer/internal/vulkan/vulkan_buffer.h b/include/renderer/internal/vulkan/vulkan_buffer.h index a6913247..e3f80c1a 100644 --- a/include/renderer/internal/vulkan/vulkan_buffer.h +++ b/include/renderer/internal/vulkan/vulkan_buffer.h @@ -23,7 +23,7 @@ typedef struct vulkan_buffer_t uint32_t count; } vulkan_buffer_t; - +void vulkan_buffer_init(vulkan_buffer_t* buffer); vulkan_buffer_t* vulkan_buffer_new(); vulkan_buffer_t* vulkan_buffer_create(renderer_t* renderer, vulkan_buffer_create_info_t* create_info); void vulkan_buffer_create_no_alloc(renderer_t* renderer, vulkan_buffer_create_info_t* create_info, vulkan_buffer_t* buffer); diff --git a/include/renderer/text_mesh.h b/include/renderer/text_mesh.h index 9bfc387a..fed7229a 100644 --- a/include/renderer/text_mesh.h +++ b/include/renderer/text_mesh.h @@ -2,6 +2,7 @@ #include #include +#include typedef struct renderer_t renderer_t; typedef struct font_t font_t; @@ -9,9 +10,10 @@ typedef struct mesh3d_t mesh3d_t; typedef struct text_mesh_t { - mesh3d_t* handle; - mesh_t* render_handle; font_t* font; + BUFFER/*typeof(mesh3d_t*)*/ meshes; + BUFFER/*typeof(mesh_t*)*/ render_meshes; + BUFFER/*typeof(u32)*/ instance_counts; } text_mesh_t; @@ -21,6 +23,6 @@ void text_mesh_release_resources(text_mesh_t* text); void text_mesh_draw(text_mesh_t* text, renderer_t* renderer); -void text_mesh_set_string(text_mesh_t* text, const char* string); +void text_mesh_set_string(text_mesh_t* text, renderer_t* renderer, const char* string); void text_mesh_set_size(text_mesh_t* text, u32 size); diff --git a/shared-dependencies/BufferLib b/shared-dependencies/BufferLib index 3cc7bc71..8bf0400b 160000 --- a/shared-dependencies/BufferLib +++ b/shared-dependencies/BufferLib @@ -1 +1 @@ -Subproject commit 3cc7bc71fb007b5a14436d3a423f7638f1c63201 +Subproject commit 8bf0400b194a481b3c2c2b03f247a4ba33feb93c diff --git a/source/renderer/font.c b/source/renderer/font.c index 631892a3..606431a5 100644 --- a/source/renderer/font.c +++ b/source/renderer/font.c @@ -1,10 +1,10 @@ #include -#include +#include #include #include - #include +#include font_t* font_load_and_create(const char* file_name) @@ -42,3 +42,63 @@ void font_release_resources(font_t* font) heap_free(font); } +void font_get_glyph_mesh(font_t* font, u16 wide_char, u8 mesh_quality, mesh3d_t* out_mesh) +{ + assert(out_mesh != NULL); + mesh3d_positions_new(out_mesh, 0); + // mesh3d_colors_new(out_mesh, 0); + mesh3d_triangles_new(out_mesh, 0); + font_glyph_info_t info; + font_get_glyph_info(font, wide_char, &info); + ttf_mesh_t* mesh; + u8 quality; + switch(mesh_quality) + { + case FONT_GLYPH_MESH_QUALITY_LOW: quality = TTF_QUALITY_LOW; break; + case FONT_GLYPH_MESH_QUALITY_NORMAL: quality = TTF_QUALITY_NORMAL; break; + case FONT_GLYPH_MESH_QUALITY_HIGH: quality = TTF_QUALITY_HIGH; break; + default: LOG_FETAL_ERR("Invalid font mesh quality: %u\n", mesh_quality); + } + int result = ttf_glyph2mesh(&font->handle->glyphs[info.index], &mesh, quality, TTF_FEATURES_DFLT); + assert(result == TTF_DONE); + + float max_y = 0, min_y = 0, max_x = 0, min_x = 0; + for(int i = 0; i < mesh->nvert; i++) + { + if(mesh->vert[i].y > max_y) + max_y = mesh->vert[i].y; + if(mesh->vert[i].y < min_y) + min_y = mesh->vert[i].y; + + if(mesh->vert[i].x > max_x) + max_x = mesh->vert[i].x; + if(mesh->vert[i].x < min_x) + min_x = mesh->vert[i].x; + + mesh3d_position_add(out_mesh, 0, mesh->vert[i].y, mesh->vert[i].x); + // mesh3d_color_add(out_mesh, 1, 1, 1); + } + for(int i = 0; i < mesh->nfaces; i++) + mesh3d_triangle_add(out_mesh, mesh->faces[i].v3, mesh->faces[i].v2, mesh->faces[i].v1); + mesh3d_optimize_buffer(out_mesh); + ttf_free_mesh(mesh); +} + + +void font_get_glyph_info(font_t* font, u16 wide_char, font_glyph_info_t* out_info) +{ + int index = ttf_find_glyph(font->handle, wide_char); + if(index < 0) + { + LOG_FETAL_ERR("Font error: couldn't find glyph \"%c\"\n", wide_char); + } + ttf_glyph_t info = font->handle->glyphs[index]; + out_info->left_side_bearing = info.lbearing; + out_info->right_side_bearing = info.rbearing; + out_info->advance_width = info.advance; + out_info->min_x = info.xbounds[0]; + out_info->max_x = info.xbounds[1]; + out_info->min_y = info.ybounds[0]; + out_info->max_y = info.ybounds[1]; + out_info->index = index; +} diff --git a/source/renderer/text_mesh.c b/source/renderer/text_mesh.c index 4becbe6a..3c19916a 100644 --- a/source/renderer/text_mesh.c +++ b/source/renderer/text_mesh.c @@ -1,33 +1,45 @@ #include -#include #include +#include #include +#include #include +#include +#include +static void build_meshes(BUFFER* meshes, font_t* font); text_mesh_t* text_mesh_create(font_t* font) { assert(font != NULL); - text_mesh_t* text_mesh = heap_new(text_mesh_t); - memset(text_mesh, 0, sizeof(text_mesh_t)); - text_mesh->handle = mesh3d_new(); - text_mesh->font = font; - return text_mesh; + text_mesh_t* text = heap_new(text_mesh_t); + memset(text, 0, sizeof(text_mesh_t)); + text->meshes = buf_create(sizeof(mesh3d_t*), 0, 0); + text->render_meshes = buf_create(sizeof(mesh_t*), 0, 0); + text->instance_counts = buf_create(sizeof(u32), 0, 0); + text->font = font; + build_meshes(&text->meshes, font); + return text; } void text_mesh_destroy(text_mesh_t* text, renderer_t* renderer) { assert(text != NULL); - mesh_destroy(text->render_handle, renderer); - mesh3d_destroy(text->handle); + for(u32 i = 0; i < text->meshes.element_count; i++) + mesh3d_destroy(*(mesh3d_t**)buf_get_ptr_at(&text->meshes, i)); + for(u32 i = 0; i < text->render_meshes.element_count; i++) + mesh_destroy(*(mesh_t**)buf_get_ptr_at(&text->render_meshes, i), renderer); } void text_mesh_release_resources(text_mesh_t* text) { assert(text != NULL); - mesh_release_resources(text->render_handle); + for(u32 i = 0; i < text->render_meshes.element_count; i++) + mesh_release_resources(*(mesh_t**)buf_get_ptr_at(&text->render_meshes, i)); + buf_free(&text->render_meshes); + buf_free(&text->meshes); heap_free(text); } @@ -35,14 +47,65 @@ void text_mesh_release_resources(text_mesh_t* text) void text_mesh_draw(text_mesh_t* text, renderer_t* renderer) { assert(text != NULL); - mesh_draw_indexed(text->render_handle, renderer); + for(u32 i = 0; i < text->render_meshes.element_count; i++) + mesh_draw_indexed_instanced(*(mesh_t**)buf_get_ptr_at(&text->render_meshes, i), renderer, *(u32*)buf_get_ptr_at(&text->instance_counts, i)); } -void text_mesh_set_string(text_mesh_t* text, const char* string) +void text_mesh_set_string(text_mesh_t* text, renderer_t* renderer, const char* string) { assert(text != NULL); + //maximum number of characters in the character set + u8 unique_char_count = 126 - 33 + 1; + + //create a count_mask, + u32 count_mask[unique_char_count]; + memset(count_mask, 0UL, sizeof(u32) * unique_char_count); + + //create instance buffers for each possible character in the character set + BUFFER instance_buffers[unique_char_count]; + for(u8 i = 0; i < unique_char_count; i++) + instance_buffers[i] = buf_create(sizeof(vec3_t(float)), 0, 0); + + float horizontal_pen = 0; + while(*string != 0) + { + char ch = *string; + assert((ch >= 32) && (ch <= 126)); + font_glyph_info_t info; + font_get_glyph_info(text->font, ch, &info); + + vec3_t(float) v = { 0, 0, horizontal_pen }; + horizontal_pen += info.advance_width; + + if(ch != 32) + { + BUFFER* buffer = &instance_buffers[ch - 33]; + count_mask[ch - 33]++; + buf_push(buffer, &v); + } + string++; + } + + for(u8 i = 0; i < unique_char_count; i++) + { + if(count_mask[i] == 0UL) continue; + mesh_t* mesh = mesh_create(renderer, *(mesh3d_t**)buf_get_ptr_at(&text->meshes, i)); + vulkan_vertex_buffer_create_info_t create_info = + { + .data = instance_buffers[i].bytes, + .stride = sizeof(vec3_t(float)), + .count = instance_buffers[i].element_count + }; + vulkan_mesh_create_and_add_vertex_buffer(mesh, renderer, &create_info); + buf_free(&instance_buffers[i]); + buf_push(&text->render_meshes, &mesh); + } + + for(u8 i = 0; i < unique_char_count; i++) + if(count_mask[i] != 0UL) + buf_push(&text->instance_counts, &count_mask[i]); } void text_mesh_set_size(text_mesh_t* text, const u32 size) @@ -50,3 +113,21 @@ void text_mesh_set_size(text_mesh_t* text, const u32 size) assert(text != NULL); } + + +static void build_meshes(BUFFER* meshes, font_t* font) +{ + /*NOTE: 32 is space, not printable character*/ + u16 A = 33; + buf_clear(meshes, NULL); + while(A <= 126) + { + font_glyph_info_t info; + font_get_glyph_info(font, A, &info); + mesh3d_t* mesh = mesh3d_new(); + font_get_glyph_mesh(font, A, FONT_GLYPH_MESH_QUALITY_LOW, mesh); + buf_push(meshes, &mesh); + A++; + } +} + diff --git a/source/renderer/vulkan/vulkan_buffer.c b/source/renderer/vulkan/vulkan_buffer.c index 5c30c23a..0568bdf4 100644 --- a/source/renderer/vulkan/vulkan_buffer.c +++ b/source/renderer/vulkan/vulkan_buffer.c @@ -4,17 +4,21 @@ #include #include +void vulkan_buffer_init(vulkan_buffer_t* buffer) +{ + memset(buffer, 0, sizeof(vulkan_buffer_t)); +} + vulkan_buffer_t* vulkan_buffer_new() { vulkan_buffer_t* buffer = heap_new(vulkan_buffer_t); - memset(buffer, 0, sizeof(vulkan_buffer_t)); + vulkan_buffer_init(buffer); return buffer; } vulkan_buffer_t* vulkan_buffer_create(renderer_t* renderer, vulkan_buffer_create_info_t* create_info) { - vulkan_buffer_t* buffer = vulkan_buffer_new(); vulkan_buffer_create_no_alloc(renderer, create_info, buffer); return buffer; diff --git a/source/renderer/vulkan/vulkan_mesh.c b/source/renderer/vulkan/vulkan_mesh.c index c152a080..84a87356 100644 --- a/source/renderer/vulkan/vulkan_mesh.c +++ b/source/renderer/vulkan/vulkan_mesh.c @@ -12,6 +12,7 @@ vulkan_mesh_t* vulkan_mesh_new() { vulkan_mesh_t* mesh = heap_new(vulkan_mesh_t); memset(mesh, 0, sizeof(vulkan_mesh_t)); + mesh->vertex_buffers = buf_create(sizeof(vulkan_buffer_t), 0, 0); return mesh; } @@ -20,9 +21,8 @@ void vulkan_mesh_create_no_alloc(renderer_t* renderer, vulkan_mesh_create_info_t ASSERT(renderer->vk_device != VK_NULL_HANDLE, "renderer->vk_device == VK_NULL_HANDLE\n"); assert(create_info != 0); assert(mesh != NULL); - + buf_clear(&mesh->vertex_buffers, NULL); //create vertex buffers - mesh->vertex_buffers = buf_create(sizeof(vulkan_buffer_t*), create_info->vertex_buffer_info_count, 0); if((create_info->vertex_buffer_info_count != 0) && (create_info->vertex_buffer_infos != NULL)) { uint32_t vertex_count = refp(vulkan_vertex_buffer_create_info_t, create_info->vertex_buffer_infos, 0)->count; @@ -52,7 +52,10 @@ void vulkan_mesh_create_no_alloc(renderer_t* renderer, vulkan_mesh_create_info_t .usage_flags = VK_BUFFER_USAGE_INDEX_BUFFER_BIT, .memory_property_flags = VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT | VK_MEMORY_PROPERTY_HOST_COHERENT_BIT }; - mesh->index_buffer = vulkan_buffer_create(renderer, &buffer_create_info); + if(mesh->index_buffer != NULL) + vulkan_buffer_create_no_alloc(renderer, &buffer_create_info, mesh->index_buffer); + else + mesh->index_buffer = vulkan_buffer_create(renderer, &buffer_create_info); mesh->index_type = create_info->index_buffer_info.index_type; } else @@ -74,7 +77,7 @@ void vulkan_mesh_destroy(vulkan_mesh_t* mesh, renderer_t* renderer) { assert(mesh != NULL); for(uint32_t i = 0; i < mesh->vertex_buffers.element_count; i++) - vulkan_buffer_destroy(*(vulkan_buffer_t**)buf_get_ptr_at(&mesh->vertex_buffers, i), renderer); + vulkan_buffer_destroy((vulkan_buffer_t*)buf_get_ptr_at(&mesh->vertex_buffers, i), renderer); if(mesh->index_buffer != NULL) vulkan_buffer_destroy(refp(vulkan_buffer_t, mesh->index_buffer, 0), renderer); } @@ -88,8 +91,11 @@ void vulkan_mesh_sync(vulkan_mesh_t* mesh, renderer_t* renderer, vulkan_mesh_cre void vulkan_mesh_release_resources(vulkan_mesh_t* mesh) { assert(mesh != NULL); - for(uint32_t i = 0; i < mesh->vertex_buffers.element_count; i++) - vulkan_buffer_release_resources(*(vulkan_buffer_t**)buf_get_ptr_at(&mesh->vertex_buffers, i)); + //NOTE: We are using BUFFER of vulkan_buffer_t itself, which is not allocated by safe_memory/memory_allocator + //so, no need to call release_resources kind of function because they call heap_free internally, which tries to + //free as if it was allocated by safe_memory/memory_allocator + // for(uint32_t i = 0; i < mesh->vertex_buffers.element_count; i++) + // vulkan_buffer_release_resources((vulkan_buffer_t*)buf_get_ptr_at(&mesh->vertex_buffers, i)); buf_free(&mesh->vertex_buffers); if(mesh->index_buffer != NULL) vulkan_buffer_release_resources(refp(vulkan_buffer_t, mesh->index_buffer, 0)); @@ -115,7 +121,7 @@ void vulkan_mesh_draw_indexed_instanced(vulkan_mesh_t* mesh, renderer_t* rendere uint32_t first_binding = 0; VkCommandBuffer command_buffer = renderer->vk_command_buffers.value2[renderer->swapchain->current_image_index]; for(uint32_t i = 0; i < mesh->vertex_buffers.element_count; i++, first_binding++) - vkCmdBindVertexBuffers(command_buffer, first_binding, 1, &((*(vulkan_buffer_t**)buf_get_ptr_at(&mesh->vertex_buffers, i))->handle), offsets); + vkCmdBindVertexBuffers(command_buffer, first_binding, 1, &(((vulkan_buffer_t*)buf_get_ptr_at(&mesh->vertex_buffers, i))->handle), offsets); vkCmdBindIndexBuffer(command_buffer, mesh->index_buffer->handle, 0, mesh->index_type); vkCmdDrawIndexed(command_buffer, mesh->index_buffer->count, instance_count, 0, 0, 0); } @@ -127,8 +133,8 @@ void vulkan_mesh_draw_instanced(vulkan_mesh_t* mesh, renderer_t* renderer, uint3 uint32_t first_binding = 0; VkCommandBuffer command_buffer = renderer->vk_command_buffers.value2[renderer->swapchain->current_image_index]; for(uint32_t i = 0; i < mesh->vertex_buffers.element_count; i++, first_binding++) - vkCmdBindVertexBuffers(command_buffer, first_binding, 1, &((*(vulkan_buffer_t**)buf_get_ptr_at(&mesh->vertex_buffers, i))->handle), offsets); - vkCmdDraw(command_buffer, (*(vulkan_buffer_t**)buf_get_ptr_at(&mesh->vertex_buffers, 0))->count, instance_count, 0, 0); + vkCmdBindVertexBuffers(command_buffer, first_binding, 1, &(((vulkan_buffer_t*)buf_get_ptr_at(&mesh->vertex_buffers, i))->handle), offsets); + vkCmdDraw(command_buffer, ((vulkan_buffer_t*)buf_get_ptr_at(&mesh->vertex_buffers, 0))->count, instance_count, 0, 0); } void vulkan_mesh_create_and_add_vertex_buffer(vulkan_mesh_t* mesh, renderer_t* renderer, vulkan_vertex_buffer_create_info_t* create_info) @@ -145,8 +151,25 @@ void vulkan_mesh_create_and_add_vertex_buffer(vulkan_mesh_t* mesh, renderer_t* r .usage_flags = VK_BUFFER_USAGE_VERTEX_BUFFER_BIT, .memory_property_flags = VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT | VK_MEMORY_PROPERTY_HOST_COHERENT_BIT }; - vulkan_buffer_t* buffer = vulkan_buffer_create(renderer, &buffer_create_info); - buf_push(&mesh->vertex_buffers, &buffer); + + vulkan_buffer_t* buffer; + //if there is already allocated memory, i.e. the buffer has enough capacity already + if(buf_get_capacity(&mesh->vertex_buffers) > buf_get_element_count(&mesh->vertex_buffers)) + { + //reuse the memory + buf_set_element_count(&mesh->vertex_buffers, buf_get_element_count(&mesh->vertex_buffers) + 1); + buffer = buf_peek_ptr(&mesh->vertex_buffers); + } + //otherwise, allocate new memory block and init the internal fields + else + { + //WARNING: buf_push_pseudo(&mesh->vertex_buffers, 1) doesn't seems to be working! + vulkan_buffer_t __buffer; + vulkan_buffer_init(&__buffer); + buf_push(&mesh->vertex_buffers, &__buffer); + buffer = buf_peek_ptr(&mesh->vertex_buffers); + } + vulkan_buffer_create_no_alloc(renderer, &buffer_create_info, buffer); } static uint32_t get_index_stride(VkIndexType index_type) diff --git a/source/renderer/vulkan/vulkan_renderer.c b/source/renderer/vulkan/vulkan_renderer.c index 14de4173..5a236f10 100644 --- a/source/renderer/vulkan/vulkan_renderer.c +++ b/source/renderer/vulkan/vulkan_renderer.c @@ -125,7 +125,7 @@ void renderer_terminate(renderer_t* renderer) vulkan_swapchain_release_resources(renderer->swapchain); vkDestroyDescriptorPool(renderer->vk_device, renderer->vk_descriptor_pool, NULL); vkDestroyRenderPass(renderer->vk_device, renderer->vk_render_pass, NULL); - vkFreeCommandBuffers(renderer->vk_device, renderer->vk_command_pool, renderer->swapchain->image_count, renderer->vk_command_buffers.value2); + vkFreeCommandBuffers(renderer->vk_device, renderer->vk_command_pool, renderer->vk_command_buffers.value1, renderer->vk_command_buffers.value2); vkDestroyCommandPool(renderer->vk_device, renderer->vk_command_pool, NULL); vkDestroyDevice(renderer->vk_device, NULL); vkDestroyInstance(renderer->vk_instance, NULL); diff --git a/testbed/resource/fonts/Pushster-Regular.ttf b/testbed/resource/fonts/Pushster-Regular.ttf new file mode 100644 index 00000000..21c0073f Binary files /dev/null and b/testbed/resource/fonts/Pushster-Regular.ttf differ diff --git a/testbed/resource/shaders/font_shader.glsl b/testbed/resource/shaders/font_shader.glsl index 0a38ada0..5049361c 100644 --- a/testbed/resource/shaders/font_shader.glsl +++ b/testbed/resource/shaders/font_shader.glsl @@ -9,10 +9,7 @@ layout(push_constant) uniform Push } push; layout(location = 0) in vec3 position; -layout(location = 1) in vec3 color; -layout(location = 2) in vec3 offset; - -layout(location = 0) out vec3 fragColor; +layout(location = 1) in vec3 offset; void main() { @@ -20,7 +17,6 @@ void main() v.x += offset.z; v.y += offset.y; gl_Position = push.mvp_matrix * vec4(0, v.y, v.x, 1); - fragColor = color; } @@ -30,9 +26,7 @@ void main() layout(location = 0) out vec3 color; -layout(location = 0) in vec3 fragColor; - void main() { - color = fragColor; + color = vec3(1, 1, 1); } diff --git a/testbed/resource/shaders/text_shader.glsl b/testbed/resource/shaders/text_shader.glsl new file mode 100644 index 00000000..20d54313 --- /dev/null +++ b/testbed/resource/shaders/text_shader.glsl @@ -0,0 +1,37 @@ + + +#stage vertex + +#version 450 + +layout(push_constant) uniform Push +{ + //model view project matrix + mat4 mvp; +} push; + + +//Inputs +//per vertex +layout(location = 0) in vec3 position; + +//per instance +layout(location = 1) in vec3 offset; + + +void main() +{ + gl_Position = push.mvp * vec4(position + offset, 1); +} + + +#stage fragment + +#version 450 + +layout(location = 0) out vec3 color; + +void main() +{ + color = vec3(1, 1, 1); +} diff --git a/testbed/source/main.c b/testbed/source/main.c index 31d2766e..f16afd5d 100644 --- a/testbed/source/main.c +++ b/testbed/source/main.c @@ -6,7 +6,6 @@ #include #include #include -#include //For handling text/font rendering #include @@ -52,8 +51,7 @@ static void recreate_matrix(render_window_t* window, void* user_data) static void offset_visitor(vec3_t(float)* position, void* user_data) { - vec3_t(float) center = *(vec3_t(float)*)user_data; - *position = vec3_sub(float)(*position, center); + *position = vec3_mul(float)(*position, vec3(float)(0, 100, 100)); } int main(int argc, char** argv) @@ -66,68 +64,38 @@ int main(int argc, char** argv) mat4_t(float) view_matrix = mat4_inverse(float)(camera_transform); mat4_t(float) clip_matrix = mat4_identity(float)(); clip_matrix.m11 = -1; - mesh3d_t* char_mesh = mesh3d_new(); - mesh3d_positions_new(char_mesh, 0); - mesh3d_colors_new(char_mesh, 0); - mesh3d_triangles_new(char_mesh, 0); - + /*------TEXT-----------------------------*/ + shader_t* text_shader = shader_load(renderer, "resource/shaders/text_shader.sb"); font_t* font = font_load_and_create("resource/fonts/arial.ttf"); text_mesh_t* text = text_mesh_create(font); - text_mesh_set_string(text, "Hello World"); - text_mesh_set_size(text, 100); - - int index = ttf_find_glyph(font->handle, L'&'); - assert(index >= 0); + text_mesh_set_string(text, renderer, "Vulkan 3D Engine"); + // text_mesh_set_size(text, 100); - ttf_mesh_t* mesh; - int result = ttf_glyph2mesh(&font->handle->glyphs[index], &mesh, TTF_QUALITY_LOW, TTF_FEATURES_DFLT); - assert(result == TTF_DONE); - - float max_y = 0, min_y = 0, max_x = 0, min_x = 0; - for(int i = 0; i < mesh->nvert; i++) + material_create_info_t text_material_info = { - if(mesh->vert[i].y > max_y) - max_y = mesh->vert[i].y; - if(mesh->vert[i].y < min_y) - min_y = mesh->vert[i].y; - - if(mesh->vert[i].x > max_x) - max_x = mesh->vert[i].x; - if(mesh->vert[i].x < min_x) - min_x = mesh->vert[i].x; - - mesh3d_position_add(char_mesh, 0, mesh->vert[i].y * 100, mesh->vert[i].x * 100 + 200); - mesh3d_color_add(char_mesh, 1, 1, 1); - } - for(int i = 0; i < mesh->nfaces; i++) - mesh3d_triangle_add(char_mesh, mesh->faces[i].v3, mesh->faces[i].v2, mesh->faces[i].v1); - mesh3d_optimize_buffer(char_mesh); - vec3_t(float) center = { .z = (max_x + min_x) * 800 * 0.5f, .y = (max_y + min_y) * 800 * 0.5f }; - mesh3d_positions_foreach(char_mesh, offset_visitor, ¢er); - ttf_free_mesh(mesh); - mesh_t* char_render_mesh = mesh_create(renderer, char_mesh); - - shader_t* font_shader = shader_load(renderer, "resource/shaders/font_shader.sb"); - material_create_info_t font_material_info = - { - .per_vertex_attributes = MATERIAL_ALIGN(MATERIAL_VEC3, 0) //position - | MATERIAL_ALIGN(MATERIAL_VEC3, 1), //color + .per_vertex_attributes = MATERIAL_ALIGN(MATERIAL_VEC3, 0), //position .per_instance_attributes = MATERIAL_ALIGN(MATERIAL_VEC3, 0), //offset - .shader = font_shader - }; - material_t* font_material = material_create(renderer, &font_material_info); - - vec3_t(float) offsets[2] = - { - { 0, 0, -200 }, { 0, 0, 200 }, + .shader = text_shader }; - vulkan_vertex_buffer_create_info_t offset_create_info = + material_t* text_material = material_create(renderer, &text_material_info); + /*---------------------------------------*/ + + /*------CUBE-----------------------------*/ + shader_t* albedo_shader = shader_load(renderer, "resource/shaders/albedo_shader.sb"); + mesh3d_t* cube_mesh3d = mesh3d_cube(1); + mesh_t* cube = mesh_create(renderer, cube_mesh3d); + texture_t* linux_texture = texture_load(renderer, "resource/textures/linuxlogo.bmp"); + material_create_info_t cube_material_info = { - .data = offsets, - .stride = sizeof(vec3_t(float)), - .count = 2 + .per_vertex_attributes = MATERIAL_ALIGN(MATERIAL_VEC3, 0) //position + | MATERIAL_ALIGN(MATERIAL_VEC3, 1) //normal + | MATERIAL_ALIGN(MATERIAL_VEC3, 2) //color + | MATERIAL_ALIGN(MATERIAL_VEC2, 3), //texture coordinates + .shader = albedo_shader }; - vulkan_mesh_create_and_add_vertex_buffer(char_render_mesh, renderer, &offset_create_info); + material_t* cube_material = material_create(renderer, &cube_material_info); + material_set_texture(cube_material,renderer, linux_texture); + /*---------------------------------------*/ time_handle_t frame_time_handle = time_get_handle(); time_handle_t second_time_handle = time_get_handle(); @@ -139,12 +107,18 @@ int main(int argc, char** argv) float delta_time = time_get_delta_time(&frame_time_handle); renderer_begin_frame(renderer, 0, 0, 0, 0); - material_bind(font_material, renderer); - mat4_t(float) canvas_transform = mat4_mul(float)(2, clip_matrix, screen_space_matrix); + material_bind(cube_material, renderer); + mat4_t(float) mvp = mat4_mul(float)(3, clip_matrix, projection_matrix, view_matrix); + mat4_move(float)(&mvp, mat4_transpose(float)(mvp)); + material_push_constants(cube_material, renderer, &mvp); + mesh_draw_indexed(cube, renderer); - mat4_move(float)(&canvas_transform, mat4_transpose(float)(canvas_transform)); - material_push_constants(font_material, renderer, &canvas_transform); - mesh_draw_indexed_instanced(char_render_mesh, renderer, 2); + material_bind(text_material, renderer); + mat4_t(float) canvas_transform = mat4_mul(float)(2, clip_matrix, screen_space_matrix); + mat4_t(float) model_matrix = mat4_mul(float)(2, mat4_translation(float)(0, 0, -700), mat4_scale(float)(0, 70, 70)); + mat4_move(float)(&canvas_transform, mat4_transpose(float)(mat4_mul(float)(2, canvas_transform, model_matrix))); + material_push_constants(text_material, renderer, &canvas_transform); + text_mesh_draw(text, renderer); renderer_end_frame(renderer); renderer_update(renderer); @@ -166,15 +140,20 @@ int main(int argc, char** argv) font_release_resources(font); text_mesh_destroy(text, renderer); text_mesh_release_resources(text); - - mesh_destroy(char_render_mesh, renderer); - mesh_release_resources(char_render_mesh); - mesh3d_destroy(char_mesh); - - shader_destroy(font_shader, renderer); - shader_release_resources(font_shader); - material_destroy(font_material, renderer); - material_release_resources(font_material); + shader_destroy(text_shader, renderer); + shader_release_resources(text_shader); + material_destroy(text_material, renderer); + material_release_resources(text_material); + + mesh_destroy(cube, renderer); + mesh_release_resources(cube); + mesh3d_destroy(cube_mesh3d); + shader_destroy(albedo_shader, renderer); + shader_release_resources(albedo_shader); + material_destroy(cube_material, renderer); + material_release_resources(cube_material); + texture_destroy(linux_texture, renderer); + texture_release_resources(linux_texture); renderer_terminate(renderer); memory_allocator_terminate();