#include "rse_graphics.h" #include "descriptor_builder.h" #include "graphics_context.h" #include "math.h" #include "mesh_controller.h" #include "pipeline_builder.h" #include "utilities/commons.h" #include "utilities/errors_common.h" #include "utilities/localization.h" #include "utilities/logger.h" #include "vulkan_base.h" #include "vulkan_commons.h" #include "window.h" struct rse_graphics_context_t { struct graphics_context_t* context; }; rse_err_t rse_graphics_init(struct rse_graphics_context_t** context) { rse_err_t status = RSE_ERROR_NO_ERROR; struct rse_graphics_context_t* ctx_ptr = NULL; if (*context != NULL) { LOGF(_("Graphics already initialized!\n")); return RSE_ERROR_ALREADY_INITIALIZED; } rse_malloc(*context, sizeof(struct rse_graphics_context_t)); ctx_ptr = *context; rse_malloc(ctx_ptr->context, sizeof(struct graphics_context_t)); rse_memset(ctx_ptr->context, 0, sizeof(struct graphics_context_t)); STATUS_CHECK(window_init(&ctx_ptr->context->window_handle, &ctx_ptr->context->is_framebuffer_resized)); STATUS_CHECK(init_vulkan(ctx_ptr->context)); return status; } void rse_graphics_test_function(struct rse_graphics_context_t* rse_context) { struct graphics_context_t* context = rse_context->context; // rse_err_t status = RSE_ERROR_NO_ERROR; uint16_t tex_id_2 = 0; size_t ubo_index = 0; size_t sampler_index = 0; struct pipeline_t* pipeline = NULL; struct descriptor_set_list_t* descriptor_set_list; struct descriptor_set_handle_t* descriptor_set_handle; struct pipeline_infos_list_t* pipeline_infos = NULL; // status = load_texture_from_file("../../test_image.jpg", &tex_id_2); // if (status != RSE_ERROR_NO_ERROR) { // LOGE("Failed to do something. Check error messages. Error: %d", status); // return; // } // fonts_initialize(); // FIXME: Temporary array of vertices, for testing purposes struct vertex_t vertices[] = {{{-0.5f, -0.5f, 0.0f}, {1.0f, 0.0f, 0.0f}, {0.0f, 0.0f}}, {{0.5f, -0.5f, 0.0f}, {0.0f, 1.0f, 0.0f}, {1.0f, 0.0f}}, {{0.5f, 0.5f, 0.0f}, {0.0f, 0.0f, 1.0f}, {1.0f, 1.0f}}, {{-0.5f, 0.5f, 0.0f}, {1.0f, 1.0f, 1.0f}, {0.0f, 1.0f}}}; struct vertex_t vertices2[] = {{{-0.5f, -0.5f, 0.0f}, {1.0f, 1.0f, 1.0f}, {0.0f, 0.0f}}, {{0.5f, -0.5f, 0.0f}, {1.0f, 1.0f, 1.0f}, {1.0f, 0.0f}}, {{0.5f, 0.5f, 0.0f}, {1.0f, 1.0f, 1.0f}, {1.0f, 1.0f}}, {{-0.5f, 0.5f, 0.0f}, {1.0f, 1.0f, 1.0f}, {0.0f, 1.0f}}}; // FIXME: Temporary array of vertices, for testing purposes uint16_t indices[] = {0, 1, 2, 2, 3, 0}; uint16_t mesh_id = create_mesh(context, vertices, indices, 6, 6); create_mesh_instance( context, mesh_id, (struct instance_data_t){{0.0f, 0.0f, 2.4f}, {0.0f, 0.0f, math_deg_to_radians(45.0f)}, 1.0f, tex_id_2}); create_mesh_instance( context, mesh_id, (struct instance_data_t){{-0.5f, 0.0f, -1.0f}, {0.0f, 0.0f, math_deg_to_radians(10.0f)}, 1.0f, tex_id_2}); mesh_id = create_mesh(context, vertices2, indices, 6, 6); create_mesh_instance( context, mesh_id, (struct instance_data_t){{2.0f, 1.0f, 0.0f}, {0.0f, 0.0f, math_deg_to_radians(0.0f)}, 1.0f, tex_id_2}); // fonts_load_from_file("/usr/share/fonts/JetBrainsMonoNerdFont/JetBrainsMonoNerdFont-Medium.ttf"); // print_text("Hello World!", (struct vec3_t){-1.0f, 0.0f, 0.9f}, 0.3f); /* Initialize pipeline */ pipeline_builder_init(&pipeline); pipeline_add_shader_stage(context, pipeline, "../graphics/shaders/shader.vert.num", VK_SHADER_STAGE_VERTEX_BIT); pipeline_add_shader_stage(context, pipeline, "../graphics/shaders/solid_objects.frag.num", VK_SHADER_STAGE_FRAGMENT_BIT); pipeline_add_vertex_input_binding(pipeline, 0, sizeof(struct vertex_t), VK_VERTEX_INPUT_RATE_VERTEX); pipeline_add_vertex_input_binding(pipeline, 1, sizeof(struct vertex_t), VK_VERTEX_INPUT_RATE_INSTANCE); pipeline_add_vertex_input_attribute(pipeline, 0, 0, VK_FORMAT_R32G32B32_SFLOAT, offsetof(struct vertex_t, pos)); pipeline_add_vertex_input_attribute(pipeline, 0, 1, VK_FORMAT_R32G32B32_SFLOAT, offsetof(struct vertex_t, color)); pipeline_add_vertex_input_attribute(pipeline, 0, 2, VK_FORMAT_R32G32_SFLOAT, offsetof(struct vertex_t, tex_coords)); pipeline_add_vertex_input_attribute(pipeline, 1, 3, VK_FORMAT_R32G32B32_SFLOAT, offsetof(struct instance_data_t, pos)); pipeline_add_vertex_input_attribute(pipeline, 1, 4, VK_FORMAT_R32G32B32_SFLOAT, offsetof(struct instance_data_t, rot)); pipeline_add_vertex_input_attribute(pipeline, 1, 5, VK_FORMAT_R32_SFLOAT, offsetof(struct instance_data_t, scale)); pipeline_add_vertex_input_attribute(pipeline, 1, 6, VK_FORMAT_R32_UINT, offsetof(struct instance_data_t, texture_id)); pipeline_add_dynamic_state(pipeline, VK_DYNAMIC_STATE_VIEWPORT); pipeline_add_dynamic_state(pipeline, VK_DYNAMIC_STATE_SCISSOR); VkSampler sampler = VK_NULL_HANDLE; create_sampler(context, sampler); descriptor_add_set(descriptor_set_list, 0, VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, 1, VK_SHADER_STAGE_VERTEX_BIT, NULL); descriptor_add_set(descriptor_set_list, 1, VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, 1, VK_SHADER_STAGE_FRAGMENT_BIT, sampler); descriptors_build(context, descriptor_set_list, descriptor_set_handle); add_pipeline(context, pipeline, &pipeline_infos); build_pipelines(context, pipeline_infos); // TODO: Add a shader for text rendering // pipeline_add_shader_stage("../graphics/shaders/on_screen_text.frag.num", VK_SHADER_STAGE_FRAGMENT_BIT); } rse_err_t rse_graphics_run(struct rse_graphics_context_t* rse_context) { rse_err_t status = RSE_ERROR_NO_ERROR; struct graphics_context_t* context = rse_context->context; STATUS_CHECK(run_vulkan(context)); STATUS_CHECK(window_loop(context)); deinit_vulkan(context); window_terminate(context->window_handle); return status; }