From 8b9094ff517126ed102b79425e5fe4c67c589e47 Mon Sep 17 00:00:00 2001 From: omnisci3nce <17525998+omnisci3nce@users.noreply.github.com> Date: Sun, 24 Mar 2024 15:50:47 +1100 Subject: swapchain creation and main renderpass --- src/maths/maths.h | 2 ++ 1 file changed, 2 insertions(+) (limited to 'src/maths/maths.h') diff --git a/src/maths/maths.h b/src/maths/maths.h index d832739..6816415 100644 --- a/src/maths/maths.h +++ b/src/maths/maths.h @@ -52,6 +52,8 @@ static inline vec3 vec3_cross(vec3 a, vec3 b) { static inline vec2 vec2_create(f32 x, f32 y) { return (vec2){ x, y }; } // TODO: Dimension 4 +static inline vec4 vec4_create(f32 x, f32 y, f32 z, f32 w) { return (vec4){ x, y, z, w }; } +#define vec4(x, y, z, w) (vec4_create(x, y, z, w)) #define VEC4_ZERO ((vec4){ .x = 0.0, .y = 0.0, .z = 0.0, .w = 0.0 }) // --- Quaternion Implementations -- cgit v1.2.3-70-g09d2 From fe83372519e3ae8dd88ecfb4c67d484a1a5f13af Mon Sep 17 00:00:00 2001 From: omniscient <17525998+omnisci3nce@users.noreply.github.com> Date: Wed, 27 Mar 2024 23:07:16 +1100 Subject: brainsforming refined layout for renderer --- assets/shaders/triangle.frag | 4 +-- assets/shaders/triangle.vert | 4 +-- src/maths/maths.h | 6 ++++ src/platform/file.c | 50 +++++++++++++-------------- src/platform/file.h | 6 ++-- src/renderer/backends/backend_vulkan.c | 15 +++----- src/renderer/cleanroom/README.md | 1 + src/renderer/cleanroom/types.h | 63 ++++++++++++++++++++++++++++++++++ src/renderer/render_types.h | 3 +- src/std/containers/darray.h | 3 +- 10 files changed, 109 insertions(+), 46 deletions(-) create mode 100644 src/renderer/cleanroom/README.md create mode 100644 src/renderer/cleanroom/types.h (limited to 'src/maths/maths.h') diff --git a/assets/shaders/triangle.frag b/assets/shaders/triangle.frag index d26e5c4..44c1eb3 100644 --- a/assets/shaders/triangle.frag +++ b/assets/shaders/triangle.frag @@ -3,6 +3,4 @@ layout(location = 0) out vec4 out_colour; -void main() { - out_colour = vec4(1.0); -} \ No newline at end of file +void main() { out_colour = vec4(1.0); } \ No newline at end of file diff --git a/assets/shaders/triangle.vert b/assets/shaders/triangle.vert index 0518c62..f253d9b 100644 --- a/assets/shaders/triangle.vert +++ b/assets/shaders/triangle.vert @@ -3,6 +3,4 @@ layout(location = 0) in vec3 in_position; -void main() { - gl_Position = vec4(in_position, 1.0); -} \ No newline at end of file +void main() { gl_Position = vec4(in_position, 1.0); } \ No newline at end of file diff --git a/src/maths/maths.h b/src/maths/maths.h index 6816415..db63072 100644 --- a/src/maths/maths.h +++ b/src/maths/maths.h @@ -236,3 +236,9 @@ typedef struct u32x3 { }; } u32x3; #define u32x3(x, y, z) ((u32x3){ x, y, z }) + +typedef struct u32x2 { + u32 x; + u32 y; +} u32x2; +#define u32x2(x, y) ((u32x3){ x, y }) \ No newline at end of file diff --git a/src/platform/file.c b/src/platform/file.c index ac5014d..6030620 100644 --- a/src/platform/file.c +++ b/src/platform/file.c @@ -63,31 +63,31 @@ str8_opt str8_from_file(arena *a, str8 path) { } FileData load_spv_file(const char *path) { - FILE *f = fopen(path, "rb"); - if (f == NULL) { - perror("Error opening file"); - return (FileData){NULL, 0}; - } - - fseek(f, 0, SEEK_END); - long fsize = ftell(f); - rewind(f); - - char *data = (char *)malloc(fsize); - if (data == NULL) { - perror("Memory allocation failed"); - fclose(f); - return (FileData){NULL, 0}; - } - - size_t bytesRead = fread(data, 1, fsize, f); - if (bytesRead < fsize) { - perror("Failed to read the entire file"); - free(data); - fclose(f); - return (FileData){NULL, 0}; - } + FILE *f = fopen(path, "rb"); + if (f == NULL) { + perror("Error opening file"); + return (FileData){ NULL, 0 }; + } + + fseek(f, 0, SEEK_END); + long fsize = ftell(f); + rewind(f); + char *data = (char *)malloc(fsize); + if (data == NULL) { + perror("Memory allocation failed"); fclose(f); - return (FileData){data, bytesRead}; + return (FileData){ NULL, 0 }; + } + + size_t bytesRead = fread(data, 1, fsize, f); + if (bytesRead < fsize) { + perror("Failed to read the entire file"); + free(data); + fclose(f); + return (FileData){ NULL, 0 }; + } + + fclose(f); + return (FileData){ data, bytesRead }; } \ No newline at end of file diff --git a/src/platform/file.h b/src/platform/file.h index 83d1317..a8aa8ea 100644 --- a/src/platform/file.h +++ b/src/platform/file.h @@ -19,8 +19,8 @@ const char* string_from_file(const char* path); str8_opt str8_from_file(arena* a, str8 path); typedef struct { - char *data; - size_t size; + char* data; + size_t size; } FileData; -FileData load_spv_file(const char *path); \ No newline at end of file +FileData load_spv_file(const char* path); \ No newline at end of file diff --git a/src/renderer/backends/backend_vulkan.c b/src/renderer/backends/backend_vulkan.c index c57da9d..d78d4d2 100644 --- a/src/renderer/backends/backend_vulkan.c +++ b/src/renderer/backends/backend_vulkan.c @@ -173,20 +173,15 @@ typedef struct vulkan_state { } vulkan_state; // pipeline stuff -bool vulkan_graphics_pipeline_create( - vulkan_context* context, - vulkan_renderpass* renderpass, - u32 attribute_count, - VkVertexInputAttributeDescription* attributes, - // ... https://youtu.be/OmPmftW7Kjg?si=qn_777v_ppHKzswK&t=568 -) { - -} +bool vulkan_graphics_pipeline_create(vulkan_context* context, vulkan_renderpass* renderpass, + u32 attribute_count, + VkVertexInputAttributeDescription* attributes, + // ... https://youtu.be/OmPmftW7Kjg?si=qn_777v_ppHKzswK&t=568 +) {} bool create_shader_module(vulkan_context* context, const char* filename, const char* type_str, VkShaderStageFlagBits flag, u32 stage_index, vulkan_shader_stage* shader_stages) { - memset(&shader_stages[stage_index].create_info, 0, sizeof(VkShaderModuleCreateInfo)); memset(&shader_stages[stage_index].stage_create_info, 0, sizeof(VkPipelineShaderStageCreateInfo)); diff --git a/src/renderer/cleanroom/README.md b/src/renderer/cleanroom/README.md new file mode 100644 index 0000000..d510f16 --- /dev/null +++ b/src/renderer/cleanroom/README.md @@ -0,0 +1 @@ +# Cleanroom / Re-jig of the renderer structure \ No newline at end of file diff --git a/src/renderer/cleanroom/types.h b/src/renderer/cleanroom/types.h new file mode 100644 index 0000000..cd51fca --- /dev/null +++ b/src/renderer/cleanroom/types.h @@ -0,0 +1,63 @@ +#pragma once +#include "defines.h" + +typedef int texture_handle; +typedef int buffer_handle; +typedef int model_handle; + +/** @brief Texture Description - used by texture creation functions */ +typedef struct texture_desc { + // gpu_texture_type tex_type; + // gpu_texture_format format; + // u32x2 extents; +} texture_desc; + +/* + - render_types.h + - ral_types.h + - ral.h + - render.h ? +*/ + +/* render_types */ +typedef struct mesh mesh; +typedef struct model model; +typedef struct model pbr_material; +typedef struct model bp_material; // blinn-phong + +// Three registers +// 1. low level graphics api calls "ral" +// 2. higher level render calls +// 3. simplified immediate mode API + +/* render.h */ +// frontend -- these can be called from say a loop in an example, or via FFI +texture_handle texture_create(const char* debug_name, texture_desc description); +void texture_data_upload(texture_handle texture); +buffer_handle buffer_create(const char* debug_name, u64 size); + +// models and meshes are implemented **in terms of the above** +mesh mesh_create(); +model_handle model_load(const char* filepath); + +/* ral.h */ +// backend -- these are not seen by the higher-level code +void gpu_texture_init(); +void gpu_texture_upload(); +void gpu_buffer_init(); +void gpu_buffer_upload(); + +// command buffer gubbins + +// 3. SIMA (simplified immediate mode api) +// - dont need to worry about uploading mesh data +void debug_draw_cuboid(); +void debug_draw_sphere(); +void debug_draw_camera_frustum(); +static void imm_draw_model(const char* model_filepath); // tracks internally whether the model is loaded + +static void imm_draw_model(const char* model_filepath) { + // check that model is loaded + // if not loaded, load model and upload to gpu - LRU cache for models + // else submit draw call +} \ No newline at end of file diff --git a/src/renderer/render_types.h b/src/renderer/render_types.h index 7bb6e60..2cc321c 100644 --- a/src/renderer/render_types.h +++ b/src/renderer/render_types.h @@ -8,6 +8,7 @@ #pragma once #include "darray.h" +#include "maths.h" #include "maths_types.h" #include "str.h" @@ -178,4 +179,4 @@ typedef enum gpu_texture_format { TEXTURE_FORMAT_8_8_8_8_RGBA_UNORM, TEXTURE_FORMAT_DEPTH_DEFAULT, TEXTURE_FORMAT_COUNT -} gpu_texture_format; +} gpu_texture_format; \ No newline at end of file diff --git a/src/std/containers/darray.h b/src/std/containers/darray.h index 45d92e2..b15d269 100644 --- a/src/std/containers/darray.h +++ b/src/std/containers/darray.h @@ -6,7 +6,8 @@ // COPIED FROM KITC WITH SOME MINOR ADJUSTMENTS /* TODO: - - a 'find' function that takes a predicate (maybe wrap with a macro so we dont have to define a new function?) + - a 'find' function that takes a predicate (maybe wrap with a macro so we dont have to define a + new function?) */ #ifndef KITC_TYPED_ARRAY_H -- cgit v1.2.3-70-g09d2 From f7b91c2eae24ecb7a20b638246fb849d6c63615a Mon Sep 17 00:00:00 2001 From: Omniscient <17525998+omnisci3nce@users.noreply.github.com> Date: Sat, 30 Mar 2024 21:39:31 +1100 Subject: start adding mouse input processing --- assets/shaders/object.vert | 10 ++- examples/input/ex_input.c | 113 +++++++++++++++++++++++++++++++++ examples/main_loop/ex_main_loop.c | 6 +- src/core.c | 13 ++++ src/core.h | 1 + src/maths/maths.h | 5 ++ src/renderer/backends/backend_vulkan.c | 63 +++++++++++------- src/renderer/render.c | 2 + src/renderer/render_backend.h | 6 +- src/systems/input.c | 19 ++++++ src/systems/keys.h | 15 ++++- xmake.lua | 11 +++- 12 files changed, 235 insertions(+), 29 deletions(-) create mode 100644 examples/input/ex_input.c (limited to 'src/maths/maths.h') diff --git a/assets/shaders/object.vert b/assets/shaders/object.vert index 9aaefed..a5097d4 100644 --- a/assets/shaders/object.vert +++ b/assets/shaders/object.vert @@ -9,4 +9,12 @@ layout(set = 0, binding = 0) uniform global_object_uniform { } global_ubo; -void main() { gl_Position = global_ubo.projection * global_ubo.view * vec4(in_position, 1.0); } \ No newline at end of file +layout(push_constant) uniform push_constants { + mat4 model; // 64 bytes +} +u_push_constants; + +void main() { + gl_Position = + global_ubo.projection * global_ubo.view * u_push_constants.model * vec4(in_position, 1.0); +} \ No newline at end of file diff --git a/examples/input/ex_input.c b/examples/input/ex_input.c new file mode 100644 index 0000000..d3d1fbd --- /dev/null +++ b/examples/input/ex_input.c @@ -0,0 +1,113 @@ +#include + +#include "camera.h" +#include "core.h" +#include "input.h" +#include "keys.h" +#include "maths.h" +#include "maths_types.h" +#include "render.h" +#include "render_backend.h" + +typedef struct game_state { + camera camera; + vec3 camera_euler; + bool first_mouse_update; +} game_state; + +void update_camera_rotation(input_state* input, game_state* game, camera* cam); + +int main() { + core* core = core_bringup(); + + game_state game = { + .camera = camera_create(vec3_create(0, 0, 30), vec3_create(0, 0, -1), VEC3_Y, deg_to_rad(45.0)), + .camera_euler = vec3_create(90, 0, 0), + .first_mouse_update = true, + }; + + printf("Starting look direction: "); + print_vec3(game.camera.front); + + // Main loop + const f32 camera_speed = 0.4; + + while (!should_exit(core)) { + input_update(&core->input); + + vec3 translation = VEC3_ZERO; + if (key_is_pressed(KEYCODE_W) || key_is_pressed(KEYCODE_KEY_UP)) { + printf("Move Forwards\n"); + translation = vec3_mult(game.camera.front, camera_speed); + } else if (key_is_pressed(KEYCODE_S) || key_is_pressed(KEYCODE_KEY_DOWN)) { + printf("Move Backwards\n"); + translation = vec3_mult(game.camera.front, -camera_speed); + } else if (key_is_pressed(KEYCODE_A) || key_is_pressed(KEYCODE_KEY_LEFT)) { + printf("Move Left\n"); + vec3 lateral = vec3_normalise(vec3_cross(game.camera.front, game.camera.up)); + translation = vec3_mult(lateral, -camera_speed); + } else if (key_is_pressed(KEYCODE_D) || key_is_pressed(KEYCODE_KEY_RIGHT)) { + printf("Move Right\n"); + vec3 lateral = vec3_normalise(vec3_cross(game.camera.front, game.camera.up)); + translation = vec3_mult(lateral, camera_speed); + } + game.camera.position = vec3_add(game.camera.position, translation); + update_camera_rotation(&core->input, &game, &game.camera); + + // UNUSED: threadpool_process_results(&core->threadpool, 1); + + render_frame_begin(&core->renderer); + + mat4 model = mat4_translation(VEC3_ZERO); + + gfx_backend_draw_frame(&core->renderer, &game.camera, model); + + render_frame_end(&core->renderer); + } + + core_shutdown(core); + + return 0; +} + +void update_camera_rotation(input_state* input, game_state* game, camera* cam) { + float xoffset = -input->mouse.x_delta; // xpos - lastX; + float yoffset = -input->mouse.y_delta; // reversed since y-coordinates go from bottom to top + if (game->first_mouse_update) { + xoffset = 0.0; + yoffset = 0.0; + game->first_mouse_update = false; + } + + printf("x offset: %f y offset %f\n", xoffset, yoffset); + + float sensitivity = 0.1f; // change this value to your liking + xoffset *= sensitivity; + yoffset *= sensitivity; + + // x = yaw + game->camera_euler.x += xoffset; + // y = pitch + game->camera_euler.y += yoffset; + // we dont update roll + + f32 yaw = game->camera_euler.x; + f32 pitch = game->camera_euler.y; + + // make sure that when pitch is out of bounds, screen doesn't get flipped + if (game->camera_euler.y > 89.0f) game->camera_euler.y = 89.0f; + if (game->camera_euler.y < -89.0f) game->camera_euler.y = -89.0f; + + vec3 front = cam->front; + front.x = cos(deg_to_rad(yaw) * cos(deg_to_rad(pitch))); + front.y = sin(deg_to_rad(pitch)); + front.z = sin(deg_to_rad(yaw)) * cos(deg_to_rad(pitch)); + + front = vec3_normalise(front); + // save it back + cam->front.x = front.x; + cam->front.y = front.y; + // cam->front.z = front.z; + + print_vec3(cam->front); +} diff --git a/examples/main_loop/ex_main_loop.c b/examples/main_loop/ex_main_loop.c index 9a6f98c..25dbf4a 100644 --- a/examples/main_loop/ex_main_loop.c +++ b/examples/main_loop/ex_main_loop.c @@ -15,7 +15,11 @@ int main() { render_frame_begin(&core->renderer); - gfx_backend_draw_frame(&core->renderer); + static f32 x = 0.0; + x += 0.01; + mat4 model = mat4_translation(vec3(x, 0, 0)); + + gfx_backend_draw_frame(&core->renderer, model); // insert work here diff --git a/src/core.c b/src/core.c index 4b3bd1b..0db8962 100644 --- a/src/core.c +++ b/src/core.c @@ -2,6 +2,9 @@ #include +#include "glfw3.h" +#include "input.h" +#include "keys.h" #include "log.h" #include "render.h" #include "render_types.h" @@ -49,3 +52,13 @@ core* core_bringup() { return c; } + +void core_shutdown(core* core) { + // threadpool_destroy(&core->threadpool); + input_system_shutdown(&core->input); + renderer_shutdown(&core->renderer); +} + +bool should_exit(core* core) { + return key_just_released(KEYCODE_ESCAPE) || glfwWindowShouldClose(core->renderer.window); +} \ No newline at end of file diff --git a/src/core.h b/src/core.h index f54631e..05e3aed 100644 --- a/src/core.h +++ b/src/core.h @@ -20,5 +20,6 @@ typedef struct core { // --- Lifecycle core* core_bringup(); void core_shutdown(core* core); +bool should_exit(core* core); void core_input_update(core* core); diff --git a/src/maths/maths.h b/src/maths/maths.h index 6816415..baa75e9 100644 --- a/src/maths/maths.h +++ b/src/maths/maths.h @@ -9,6 +9,7 @@ #pragma once #include +#include #include "maths_types.h" // --- Helpers @@ -48,6 +49,10 @@ static inline vec3 vec3_cross(vec3 a, vec3 b) { #define VEC3_Z ((vec3){ .x = 0.0, .y = 0.0, .z = 1.0 }) #define VEC3_NEG_Z ((vec3){ .x = 0.0, .y = 0.0, .z = -1.0 }) +static inline void print_vec3(vec3 v) { + printf("{ x: %f, y: %f, z: %f )\n", v.x, v.y, v.z); +} + // TODO: Dimension 2 static inline vec2 vec2_create(f32 x, f32 y) { return (vec2){ x, y }; } diff --git a/src/renderer/backends/backend_vulkan.c b/src/renderer/backends/backend_vulkan.c index 7be5918..43ea658 100644 --- a/src/renderer/backends/backend_vulkan.c +++ b/src/renderer/backends/backend_vulkan.c @@ -1,3 +1,4 @@ +#include "camera.h" #define CDEBUG #define CEL_PLATFORM_LINUX // ^ Temporary @@ -337,6 +338,16 @@ bool vulkan_graphics_pipeline_create(vulkan_context* context, vulkan_renderpass* VkPipelineLayoutCreateInfo pipeline_layout_create_info = { VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO }; + + // Pushconstants + VkPushConstantRange push_constant; + push_constant.stageFlags = VK_SHADER_STAGE_VERTEX_BIT; + push_constant.offset = sizeof(mat4) * 0; + push_constant.size = sizeof(mat4) * 2; + + pipeline_layout_create_info.pushConstantRangeCount = 1; + pipeline_layout_create_info.pPushConstantRanges = &push_constant; + pipeline_layout_create_info.setLayoutCount = descriptor_set_layout_count; pipeline_layout_create_info.pSetLayouts = descriptor_set_layouts; @@ -600,9 +611,6 @@ void vulkan_object_shader_update_global_state(vulkan_context* context, vulkan_sh VkCommandBuffer cmd_buffer = context->gfx_command_buffers->data[image_index].handle; VkDescriptorSet global_descriptors = shader->descriptor_sets[image_index]; - vkCmdBindDescriptorSets(cmd_buffer, VK_PIPELINE_BIND_POINT_GRAPHICS, shader->pipeline.layout, 0, - 1, &global_descriptors, 0, 0); - u32 range = sizeof(global_object_uniform); u64 offset = 0; @@ -624,6 +632,28 @@ void vulkan_object_shader_update_global_state(vulkan_context* context, vulkan_sh descriptor_write.pBufferInfo = &buffer_info; vkUpdateDescriptorSets(context->device.logical_device, 1, &descriptor_write, 0, 0); + + vkCmdBindDescriptorSets(cmd_buffer, VK_PIPELINE_BIND_POINT_GRAPHICS, shader->pipeline.layout, 0, + 1, &global_descriptors, 0, 0); +} + +void vulkan_object_shader_update_object(vulkan_context* context, vulkan_shader* shader, + mat4 model) { + u32 image_index = context->image_index; + VkCommandBuffer cmd_buffer = context->gfx_command_buffers->data[image_index].handle; + // vulkan_command_buffer* cmd_buffer = &context->gfx_command_buffers->data[context.image_index]; + + vkCmdPushConstants(cmd_buffer, shader->pipeline.layout, VK_SHADER_STAGE_VERTEX_BIT, 0, + sizeof(mat4), &model); + + // vulkan_object_shader_use(context, &context->object_shader); + VkDeviceSize offsets[1] = { 0 }; + vkCmdBindVertexBuffers(cmd_buffer, 0, 1, &context->object_vertex_buffer.handle, + (VkDeviceSize*)offsets); + + vkCmdBindIndexBuffer(cmd_buffer, context->object_index_buffer.handle, 0, VK_INDEX_TYPE_UINT32); + + vkCmdDrawIndexed(cmd_buffer, 6, 1, 0, 0, 0); } bool select_physical_device(vulkan_context* ctx) { @@ -1555,13 +1585,13 @@ bool gfx_backend_init(renderer* ren) { const f32 s = 10.0; - verts[0].pos.x = 0.0 * s; + verts[0].pos.x = -0.5 * s; verts[0].pos.y = -0.5 * s; verts[1].pos.x = 0.5 * s; verts[1].pos.y = 0.5 * s; - verts[2].pos.x = 0.0 * s; + verts[2].pos.x = -0.5 * s; verts[2].pos.y = 0.5 * s; verts[3].pos.x = 0.5 * s; @@ -1688,39 +1718,28 @@ void backend_end_frame(renderer* ren, f32 delta_time) { context.queue_complete_semaphores[context.current_frame], context.image_index); } -void gfx_backend_draw_frame(renderer* ren) { +void gfx_backend_draw_frame(renderer* ren, camera* cam, mat4 model) { backend_begin_frame(ren, 16.0); - static f32 z = -1.0; - z -= 0.2; - mat4 proj = mat4_perspective(deg_to_rad(45.0), 1000 / 1000.0, 0.1, 1000.0); - mat4 view = mat4_translation(vec3(0, 0, z)); + mat4 proj; + mat4 view; + + camera_view_projection(cam, SCR_HEIGHT, SCR_WIDTH, &view, &proj); gfx_backend_update_global_state(proj, view, VEC3_ZERO, vec4(1.0, 1.0, 1.0, 1.0), 0); + vulkan_object_shader_update_object(&context, &context.object_shader, model); backend_end_frame(ren, 16.0); } void gfx_backend_update_global_state(mat4 projection, mat4 view, vec3 view_pos, vec4 ambient_colour, i32 mode) { - vulkan_command_buffer* cmd_buffer = &context.gfx_command_buffers->data[context.image_index]; vulkan_object_shader_use(&context, &context.object_shader); vulkan_object_shader_update_global_state(&context, &context.object_shader); context.object_shader.global_ubo.projection = projection; context.object_shader.global_ubo.view = view; // TODO: other UBO properties - - // vulkan_object_shader_use(&context, &context.object_shader); - - VkDeviceSize offsets[1] = { 0 }; - vkCmdBindVertexBuffers(cmd_buffer->handle, 0, 1, &context.object_vertex_buffer.handle, - (VkDeviceSize*)offsets); - - vkCmdBindIndexBuffer(cmd_buffer->handle, context.object_index_buffer.handle, 0, - VK_INDEX_TYPE_UINT32); - - vkCmdDrawIndexed(cmd_buffer->handle, 6, 1, 0, 0, 0); } void clear_screen(vec3 colour) {} diff --git a/src/renderer/render.c b/src/renderer/render.c index 74b98cf..54b63b6 100644 --- a/src/renderer/render.c +++ b/src/renderer/render.c @@ -61,6 +61,8 @@ bool renderer_init(renderer* ren) { return true; } +void renderer_shutdown(renderer* ren) {} + void render_frame_begin(renderer* ren) { vec3 color = ren->config.clear_colour; clear_screen(color); diff --git a/src/renderer/render_backend.h b/src/renderer/render_backend.h index 69d14d8..ea84b27 100644 --- a/src/renderer/render_backend.h +++ b/src/renderer/render_backend.h @@ -3,6 +3,7 @@ */ #pragma once +#include "camera.h" #include "maths_types.h" #include "render_types.h" @@ -12,8 +13,9 @@ bool gfx_backend_init(renderer* ren); void gfx_backend_shutdown(renderer* ren); -void gfx_backend_draw_frame(renderer* ren); -void gfx_backend_update_global_state(mat4 projection, mat4 view, vec3 view_pos, vec4 ambient_colour, i32 mode); +void gfx_backend_draw_frame(renderer* ren, camera* camera, mat4 model); +void gfx_backend_update_global_state(mat4 projection, mat4 view, vec3 view_pos, vec4 ambient_colour, + i32 mode); void clear_screen(vec3 colour); diff --git a/src/systems/input.c b/src/systems/input.c index 292d438..fc62db8 100644 --- a/src/systems/input.c +++ b/src/systems/input.c @@ -1,11 +1,17 @@ #include "input.h" +#include #include +#include #include "log.h" +static input_state *g_input; // Use a global to simplify caller code + bool input_system_init(input_state *input, GLFWwindow *window) { INFO("Input init"); + memset(input, 0, sizeof(input_state)); + input->window = window; // Set everything to false. Could just set memory to zero but where's the fun in that for (int i = 0; i < KEYCODE_MAX; i++) { @@ -14,9 +20,16 @@ bool input_system_init(input_state *input, GLFWwindow *window) { input->just_released_keys[i] = false; } + g_input = input; + + assert(input->mouse.x_delta == 0); + assert(input->mouse.y_delta == 0); + return true; } +void input_system_shutdown(input_state *input) {} + void input_update(input_state *input) { // --- update keyboard input @@ -75,3 +88,9 @@ void input_update(input_state *input) { input->mouse = new_mouse_state; } + +bool key_is_pressed(keycode key) { return g_input->depressed_keys[key]; } + +bool key_just_pressed(keycode key) { return g_input->just_pressed_keys[key]; } + +bool key_just_released(keycode key) { return g_input->just_released_keys[key]; } \ No newline at end of file diff --git a/src/systems/keys.h b/src/systems/keys.h index 090bb49..a76e101 100644 --- a/src/systems/keys.h +++ b/src/systems/keys.h @@ -2,5 +2,18 @@ typedef enum keycode { // TODO: add all keycodes - KEYCODE_MAX + KEYCODE_SPACE = 32, + KEYCODE_A = 65, + KEYCODE_D = 68, + KEYCODE_S = 83, + KEYCODE_W = 87, + KEYCODE_ESCAPE = 256, + KEYCODE_ENTER = 257, + KEYCODE_TAB = 258, + KEYCODE_BACKSPACE = 259, + KEYCODE_KEY_RIGHT = 262, + KEYCODE_KEY_LEFT = 263, + KEYCODE_KEY_DOWN = 264, + KEYCODE_KEY_UP = 265, + KEYCODE_MAX = 348 } keycode; \ No newline at end of file diff --git a/xmake.lua b/xmake.lua index cb6d98a..29c1de0 100644 --- a/xmake.lua +++ b/xmake.lua @@ -71,7 +71,7 @@ rule("compile_glsl_vert_shaders") print("Compiling shader: %s to %s", sourcefile, targetfile) batchcmds:vrunv('glslc', {sourcefile, "-o", targetfile}) - batchcmds:add_depfiles(sourcefile) + -- batchcmds:add_depfiles(sourcefile) end) rule("compile_glsl_frag_shaders") set_extensions(".frag") @@ -80,7 +80,7 @@ rule("compile_glsl_frag_shaders") print("Compiling shader: %s to %s", sourcefile, targetfile) batchcmds:vrunv('glslc', {sourcefile, "-o", targetfile}) - batchcmds:add_depfiles(sourcefile) + -- batchcmds:add_depfiles(sourcefile) end) -- TODO: Metal shaders compilation @@ -144,6 +144,13 @@ target("obj") add_files("examples/obj_loading/ex_obj_loading.c") set_rundir("$(projectdir)") +target("input") + set_kind("binary") + set_group("examples") + add_deps("core_static") + add_files("examples/input/ex_input.c") + set_rundir("$(projectdir)") + target("demo") set_kind("binary") set_group("examples") -- cgit v1.2.3-70-g09d2 From 2c55e9a73ae1321c14f5186ecc75ac949ad19bbd Mon Sep 17 00:00:00 2001 From: Omniscient <17525998+omnisci3nce@users.noreply.github.com> Date: Sat, 30 Mar 2024 21:46:10 +1100 Subject: chore: format --- examples/input/ex_input.c | 4 +--- src/maths/maths.h | 4 +--- 2 files changed, 2 insertions(+), 6 deletions(-) (limited to 'src/maths/maths.h') diff --git a/examples/input/ex_input.c b/examples/input/ex_input.c index d3d1fbd..4bbf76a 100644 --- a/examples/input/ex_input.c +++ b/examples/input/ex_input.c @@ -79,8 +79,6 @@ void update_camera_rotation(input_state* input, game_state* game, camera* cam) { game->first_mouse_update = false; } - printf("x offset: %f y offset %f\n", xoffset, yoffset); - float sensitivity = 0.1f; // change this value to your liking xoffset *= sensitivity; yoffset *= sensitivity; @@ -107,7 +105,7 @@ void update_camera_rotation(input_state* input, game_state* game, camera* cam) { // save it back cam->front.x = front.x; cam->front.y = front.y; - // cam->front.z = front.z; + // roll is static print_vec3(cam->front); } diff --git a/src/maths/maths.h b/src/maths/maths.h index baa75e9..6fbdfdf 100644 --- a/src/maths/maths.h +++ b/src/maths/maths.h @@ -49,9 +49,7 @@ static inline vec3 vec3_cross(vec3 a, vec3 b) { #define VEC3_Z ((vec3){ .x = 0.0, .y = 0.0, .z = 1.0 }) #define VEC3_NEG_Z ((vec3){ .x = 0.0, .y = 0.0, .z = -1.0 }) -static inline void print_vec3(vec3 v) { - printf("{ x: %f, y: %f, z: %f )\n", v.x, v.y, v.z); -} +static inline void print_vec3(vec3 v) { printf("{ x: %f, y: %f, z: %f )\n", v.x, v.y, v.z); } // TODO: Dimension 2 static inline vec2 vec2_create(f32 x, f32 y) { return (vec2){ x, y }; } -- cgit v1.2.3-70-g09d2 From c4bf1916fe219324e14384fc938e767daeab26c9 Mon Sep 17 00:00:00 2001 From: Omniscient <17525998+omnisci3nce@users.noreply.github.com> Date: Sun, 31 Mar 2024 00:48:11 +1100 Subject: working on cube (hardcoded) --- assets/shaders/object.frag | 5 ++- assets/shaders/object.vert | 10 ++++- examples/gltf_loading/ex_gltf_loading.c | 0 examples/input/ex_input.c | 10 ++++- src/maths/maths.h | 19 ++++++++++ src/maths/primitives.h | 67 +++++++++++++++++++++++++++++++++ src/renderer/backends/backend_vulkan.c | 62 ++++++++++++++++++------------ src/renderer/cleanroom/types.h | 7 +++- 8 files changed, 149 insertions(+), 31 deletions(-) create mode 100644 examples/gltf_loading/ex_gltf_loading.c create mode 100644 src/maths/primitives.h (limited to 'src/maths/maths.h') diff --git a/assets/shaders/object.frag b/assets/shaders/object.frag index 44c1eb3..11b33e1 100644 --- a/assets/shaders/object.frag +++ b/assets/shaders/object.frag @@ -1,6 +1,9 @@ #version 450 #extension GL_ARB_separate_shader_objects : enable +layout(location = 0) in vec3 in_normal; +layout(location = 1) in vec3 in_position; + layout(location = 0) out vec4 out_colour; -void main() { out_colour = vec4(1.0); } \ No newline at end of file +void main() { out_colour = vec4(in_normal, 1.0); } \ No newline at end of file diff --git a/assets/shaders/object.vert b/assets/shaders/object.vert index a5097d4..a7237bb 100644 --- a/assets/shaders/object.vert +++ b/assets/shaders/object.vert @@ -2,6 +2,10 @@ #extension GL_ARB_separate_shader_objects : enable layout(location = 0) in vec3 in_position; +layout(location = 1) in vec3 in_normal; + +layout(location = 0) out vec3 out_normal; +layout(location = 1) out vec3 out_position; layout(set = 0, binding = 0) uniform global_object_uniform { mat4 projection; @@ -15,6 +19,8 @@ layout(push_constant) uniform push_constants { u_push_constants; void main() { - gl_Position = - global_ubo.projection * global_ubo.view * u_push_constants.model * vec4(in_position, 1.0); + out_position = in_position; + gl_Position = global_ubo.projection * global_ubo.view * u_push_constants.model * + vec4(in_position.x, in_position.y, in_position.z, 1.0); + out_normal = in_normal; // forward normal vectors } \ No newline at end of file diff --git a/examples/gltf_loading/ex_gltf_loading.c b/examples/gltf_loading/ex_gltf_loading.c new file mode 100644 index 0000000..e69de29 diff --git a/examples/input/ex_input.c b/examples/input/ex_input.c index 0e72c16..f102fad 100644 --- a/examples/input/ex_input.c +++ b/examples/input/ex_input.c @@ -6,8 +6,10 @@ #include "keys.h" #include "maths.h" #include "maths_types.h" +#include "primitives.h" #include "render.h" #include "render_backend.h" +#include "render_types.h" typedef struct game_state { camera camera; @@ -21,12 +23,15 @@ void update_camera_rotation(input_state* input, game_state* game, camera* cam); int main() { core* core = core_bringup(); + vec3 cam_pos = vec3_create(-15, 20.0, 13); game_state game = { - .camera = camera_create(vec3_create(0, 0, 30), vec3_create(0, 0, -1), VEC3_Y, deg_to_rad(45.0)), + .camera = camera_create(cam_pos, vec3_negate(cam_pos), VEC3_Y, deg_to_rad(45.0)), .camera_euler = vec3_create(90, 0, 0), .first_mouse_update = true, }; + // model_handle cube_handle = prim_cube_new(core); + printf("Starting look direction: "); print_vec3(game.camera.front); @@ -53,12 +58,13 @@ int main() { translation = vec3_mult(lateral, camera_speed); } game.camera.position = vec3_add(game.camera.position, translation); - update_camera_rotation(&core->input, &game, &game.camera); + // update_camera_rotation(&core->input, &game, &game.camera); // UNUSED: threadpool_process_results(&core->threadpool, 1); render_frame_begin(&core->renderer); + // model cube = core->models->data[cube_handle.raw]; mat4 model = mat4_translation(VEC3_ZERO); gfx_backend_draw_frame(&core->renderer, &game.camera, model); diff --git a/src/maths/maths.h b/src/maths/maths.h index 41fbdfc..9206c5c 100644 --- a/src/maths/maths.h +++ b/src/maths/maths.h @@ -132,6 +132,24 @@ static inline mat4 mat4_mult(mat4 lhs, mat4 rhs) { return out_matrix; } +#if defined(CEL_REND_BACKEND_VULKAN) +/** @brief Creates a perspective projection matrix compatible with Vulkan */ +static inline mat4 mat4_perspective(f32 fov_radians, f32 aspect_ratio, f32 near_clip, f32 far_clip) { + // near_clip *= -1.0; + // far_clip *= -1.0; + + f32 half_tan_fov = tanf(fov_radians * 0.5f); + mat4 out_matrix = { .data = { 0 } }; + + out_matrix.data[0] = 1.0f / (aspect_ratio * half_tan_fov); + out_matrix.data[5] = -1.0f / half_tan_fov; // Flip Y-axis for Vulkan + out_matrix.data[10] = -((far_clip + near_clip) / (far_clip - near_clip)); + out_matrix.data[11] = -1.0f; + out_matrix.data[14] = -((2.0f * far_clip * near_clip) / (far_clip - near_clip)); + + return out_matrix; +} +#else /** @brief Creates a perspective projection matrix */ static inline mat4 mat4_perspective(f32 fov_radians, f32 aspect_ratio, f32 near_clip, f32 far_clip) { @@ -144,6 +162,7 @@ static inline mat4 mat4_perspective(f32 fov_radians, f32 aspect_ratio, f32 near_ out_matrix.data[14] = -((2.0f * far_clip * near_clip) / (far_clip - near_clip)); return out_matrix; } +#endif /** @brief Creates an orthographic projection matrix */ static inline mat4 mat4_orthographic(f32 left, f32 right, f32 bottom, f32 top, f32 near_clip, diff --git a/src/maths/primitives.h b/src/maths/primitives.h new file mode 100644 index 0000000..60d36da --- /dev/null +++ b/src/maths/primitives.h @@ -0,0 +1,67 @@ +#pragma once + +#include +#include "core.h" +#include "render_types.h" + +static float cube_vertices[] = { + // positions // normals // texture coords + -0.5f, -0.5f, -0.5f, 0.0f, 0.0f, -1.0f, 0.0f, 0.0f, 0.5f, -0.5f, -0.5f, 0.0f, + 0.0f, -1.0f, 1.0f, 0.0f, 0.5f, 0.5f, -0.5f, 0.0f, 0.0f, -1.0f, 1.0f, 1.0f, + 0.5f, 0.5f, -0.5f, 0.0f, 0.0f, -1.0f, 1.0f, 1.0f, -0.5f, 0.5f, -0.5f, 0.0f, + 0.0f, -1.0f, 0.0f, 1.0f, -0.5f, -0.5f, -0.5f, 0.0f, 0.0f, -1.0f, 0.0f, 0.0f, + + -0.5f, -0.5f, 0.5f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f, 0.5f, -0.5f, 0.5f, 0.0f, + 0.0f, 1.0f, 1.0f, 0.0f, 0.5f, 0.5f, 0.5f, 0.0f, 0.0f, 1.0f, 1.0f, 1.0f, + 0.5f, 0.5f, 0.5f, 0.0f, 0.0f, 1.0f, 1.0f, 1.0f, -0.5f, 0.5f, 0.5f, 0.0f, + 0.0f, 1.0f, 0.0f, 1.0f, -0.5f, -0.5f, 0.5f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f, + + -0.5f, 0.5f, 0.5f, -1.0f, 0.0f, 0.0f, 1.0f, 0.0f, -0.5f, 0.5f, -0.5f, -1.0f, + 0.0f, 0.0f, 1.0f, 1.0f, -0.5f, -0.5f, -0.5f, -1.0f, 0.0f, 0.0f, 0.0f, 1.0f, + -0.5f, -0.5f, -0.5f, -1.0f, 0.0f, 0.0f, 0.0f, 1.0f, -0.5f, -0.5f, 0.5f, -1.0f, + 0.0f, 0.0f, 0.0f, 0.0f, -0.5f, 0.5f, 0.5f, -1.0f, 0.0f, 0.0f, 1.0f, 0.0f, + + 0.5f, 0.5f, 0.5f, 1.0f, 0.0f, 0.0f, 1.0f, 0.0f, 0.5f, 0.5f, -0.5f, 1.0f, + 0.0f, 0.0f, 1.0f, 1.0f, 0.5f, -0.5f, -0.5f, 1.0f, 0.0f, 0.0f, 0.0f, 1.0f, + 0.5f, -0.5f, -0.5f, 1.0f, 0.0f, 0.0f, 0.0f, 1.0f, 0.5f, -0.5f, 0.5f, 1.0f, + 0.0f, 0.0f, 0.0f, 0.0f, 0.5f, 0.5f, 0.5f, 1.0f, 0.0f, 0.0f, 1.0f, 0.0f, + + -0.5f, -0.5f, -0.5f, 0.0f, -1.0f, 0.0f, 0.0f, 1.0f, 0.5f, -0.5f, -0.5f, 0.0f, + -1.0f, 0.0f, 1.0f, 1.0f, 0.5f, -0.5f, 0.5f, 0.0f, -1.0f, 0.0f, 1.0f, 0.0f, + 0.5f, -0.5f, 0.5f, 0.0f, -1.0f, 0.0f, 1.0f, 0.0f, -0.5f, -0.5f, 0.5f, 0.0f, + -1.0f, 0.0f, 0.0f, 0.0f, -0.5f, -0.5f, -0.5f, 0.0f, -1.0f, 0.0f, 0.0f, 1.0f, + + -0.5f, 0.5f, -0.5f, 0.0f, 1.0f, 0.0f, 0.0f, 1.0f, 0.5f, 0.5f, -0.5f, 0.0f, + 1.0f, 0.0f, 1.0f, 1.0f, 0.5f, 0.5f, 0.5f, 0.0f, 1.0f, 0.0f, 1.0f, 0.0f, + 0.5f, 0.5f, 0.5f, 0.0f, 1.0f, 0.0f, 1.0f, 0.0f, -0.5f, 0.5f, 0.5f, 0.0f, + 1.0f, 0.0f, 0.0f, 0.0f, -0.5f, 0.5f, -0.5f, 0.0f, 1.0f, 0.0f, 0.0f, 1.0f +}; + +static mesh prim_cube_mesh_create() { + mesh cube = { 0 }; + cube.vertices = vertex_darray_new(36); + + for (int i = 0; i < 36; i++) { + vertex vert = { .position = vec3_create(cube_vertices[(i * 8) + 0], cube_vertices[(i * 8) + 1], + cube_vertices[(i * 8) + 2]), + .normal = vec3_create(cube_vertices[(i * 8) + 3], cube_vertices[(i * 8) + 4], + cube_vertices[(i * 8) + 5]), + .uv = (vec2){ .x = cube_vertices[(i * 8) + 6], + .y = cube_vertices[(i * 8) + 7] } }; + vertex_darray_push(cube.vertices, vert); + } + return cube; +} + +/** @brief create a new model with the shape of a cube */ +static model_handle prim_cube_new(core* core) { + model model = { 0 }; + mesh cube = prim_cube_mesh_create(); + + mesh_darray_push(model.meshes, cube); + assert(mesh_darray_len(model.meshes) == 1); + + u32 index = (u32)model_darray_len(core->models); + model_darray_push_copy(core->models, &model); + return (model_handle){ .raw = index }; +} \ No newline at end of file diff --git a/src/renderer/backends/backend_vulkan.c b/src/renderer/backends/backend_vulkan.c index 43ea658..f83b271 100644 --- a/src/renderer/backends/backend_vulkan.c +++ b/src/renderer/backends/backend_vulkan.c @@ -1,4 +1,5 @@ #include "camera.h" +#include "primitives.h" #define CDEBUG #define CEL_PLATFORM_LINUX // ^ Temporary @@ -226,6 +227,7 @@ typedef struct vulkan_state { typedef struct vertex_pos { vec3 pos; + vec3 normal; } vertex_pos; // pipeline stuff @@ -530,9 +532,9 @@ bool vulkan_object_shader_create(vulkan_context* context, vulkan_shader* out_sha // Pipeline creation VkViewport viewport; viewport.x = 0; - viewport.y = (f32)context->framebuffer_height; + viewport.y = 0; viewport.width = (f32)context->framebuffer_width; - viewport.height = -(f32)context->framebuffer_height; + viewport.height = (f32)context->framebuffer_height; viewport.minDepth = 0.0; viewport.maxDepth = 1.0; @@ -543,12 +545,12 @@ bool vulkan_object_shader_create(vulkan_context* context, vulkan_shader* out_sha // Attributes u32 offset = 0; - const i32 attribute_count = 1; - VkVertexInputAttributeDescription attribute_descs[1]; + const i32 attribute_count = 2; + VkVertexInputAttributeDescription attribute_descs[2]; // Position - VkFormat formats[1] = { VK_FORMAT_R32G32B32_SFLOAT }; + VkFormat formats[2] = { VK_FORMAT_R32G32B32_SFLOAT, VK_FORMAT_R32G32B32_SFLOAT }; - u64 sizes[1] = { sizeof(vec3) }; + u64 sizes[2] = { sizeof(vec3), sizeof(vec3) }; for (u32 i = 0; i < attribute_count; i++) { attribute_descs[i].binding = 0; @@ -651,9 +653,10 @@ void vulkan_object_shader_update_object(vulkan_context* context, vulkan_shader* vkCmdBindVertexBuffers(cmd_buffer, 0, 1, &context->object_vertex_buffer.handle, (VkDeviceSize*)offsets); - vkCmdBindIndexBuffer(cmd_buffer, context->object_index_buffer.handle, 0, VK_INDEX_TYPE_UINT32); + // vkCmdBindIndexBuffer(cmd_buffer, context->object_index_buffer.handle, 0, VK_INDEX_TYPE_UINT32); - vkCmdDrawIndexed(cmd_buffer, 6, 1, 0, 0, 0); + // vkCmdDrawIndexed(cmd_buffer, 6, 1, 0, 0, 0); + vkCmdDraw(cmd_buffer, 36, 1, 0, 0); } bool select_physical_device(vulkan_context* ctx) { @@ -1580,22 +1583,33 @@ bool gfx_backend_init(renderer* ren) { INFO("Created buffers"); // TODO: temporary test code - const u32 vert_count = 4; - vertex_pos verts[4] = { 0 }; - const f32 s = 10.0; + mesh cube = prim_cube_mesh_create(); - verts[0].pos.x = -0.5 * s; - verts[0].pos.y = -0.5 * s; + const u32 vert_count = 36; + // vertex_pos verts[4] = { 0 }; - verts[1].pos.x = 0.5 * s; - verts[1].pos.y = 0.5 * s; + vertex_pos verts[36] = { 0 }; - verts[2].pos.x = -0.5 * s; - verts[2].pos.y = 0.5 * s; + f32 scale = 3.0; + for (size_t i = 0; i < 36; i++) { + verts[i].pos = vec3_mult(cube.vertices->data[i].position, scale); + verts[i].normal = cube.vertices->data[i].normal; + } + + // const f32 s = 10.0; + + // verts[0].pos.x = -0.5 * s; + // verts[0].pos.y = -0.5 * s; - verts[3].pos.x = 0.5 * s; - verts[3].pos.y = -0.5 * s; + // verts[1].pos.x = 0.5 * s; + // verts[1].pos.y = 0.5 * s; + + // verts[2].pos.x = -0.5 * s; + // verts[2].pos.y = 0.5 * s; + + // verts[3].pos.x = 0.5 * s; + // verts[3].pos.y = -0.5 * s; const u32 index_count = 6; u32 indices[6] = { 0, 1, 2, 0, 3, 1 }; @@ -1603,9 +1617,9 @@ bool gfx_backend_init(renderer* ren) { upload_data_range(&context, context.device.gfx_command_pool, 0, context.device.graphics_queue, &context.object_vertex_buffer, 0, sizeof(vertex_pos) * vert_count, verts); TRACE("Uploaded vertex data"); - upload_data_range(&context, context.device.gfx_command_pool, 0, context.device.graphics_queue, - &context.object_index_buffer, 0, sizeof(u32) * index_count, indices); - TRACE("Uploaded index data"); + // upload_data_range(&context, context.device.gfx_command_pool, 0, context.device.graphics_queue, + // &context.object_index_buffer, 0, sizeof(u32) * index_count, indices); + // TRACE("Uploaded index data"); // --- End test code INFO("Vulkan renderer initialisation succeeded"); @@ -1646,9 +1660,9 @@ void backend_begin_frame(renderer* ren, f32 delta_time) { VkViewport viewport; viewport.x = 0.0; - viewport.y = (f32)context.framebuffer_height; + viewport.y = 0.0; viewport.width = (f32)context.framebuffer_width; - viewport.height = -(f32)context.framebuffer_height; + viewport.height = (f32)context.framebuffer_height; viewport.minDepth = 0.0; viewport.maxDepth = 1.0; diff --git a/src/renderer/cleanroom/types.h b/src/renderer/cleanroom/types.h index 23f2348..0a26120 100644 --- a/src/renderer/cleanroom/types.h +++ b/src/renderer/cleanroom/types.h @@ -77,10 +77,12 @@ typedef union vertex { } vertex; KITC_DECL_TYPED_ARRAY(vertex) +KITC_DECL_TYPED_ARRAY(u32) typedef struct geometry_data { vertex_format format; vertex_darray vertices; + u32_darray indices; } geometry_data; typedef struct mesh { @@ -110,7 +112,7 @@ void texture_data_upload(texture_handle texture); buffer_handle buffer_create(const char* debug_name, u64 size); // models and meshes are implemented **in terms of the above** -mesh mesh_create(); +mesh mesh_create(geometry_data* geometry); model_handle model_load(const char* filepath); /* ral.h */ @@ -123,10 +125,11 @@ void gpu_texture_init(); void gpu_texture_upload(); void gpu_buffer_init(); void gpu_buffer_upload(); +void gpu_buffer_bind(); // command buffer gubbins -// 3. SIMA (simplified immediate mode api) +// 3. SIMA (simplified immediate mode api) / render.h // - dont need to worry about uploading mesh data // - very useful for debugging void imm_draw_cuboid(); -- cgit v1.2.3-70-g09d2 From 6463c6c1090644438d8449f7ae1a152a4a196123 Mon Sep 17 00:00:00 2001 From: omniscient <17525998+omnisci3nce@users.noreply.github.com> Date: Sun, 31 Mar 2024 02:34:19 +1100 Subject: more api design --- src/maths/maths.h | 23 ++++----- src/maths/maths_types.h | 6 ++- src/maths/primitives.h | 2 +- src/renderer/backends/backend_vulkan.c | 1 + src/renderer/cleanroom/types.h | 88 +++++++++++++++++++++++++++------- 5 files changed, 91 insertions(+), 29 deletions(-) (limited to 'src/maths/maths.h') diff --git a/src/maths/maths.h b/src/maths/maths.h index 9206c5c..6fa2f9b 100644 --- a/src/maths/maths.h +++ b/src/maths/maths.h @@ -134,20 +134,21 @@ static inline mat4 mat4_mult(mat4 lhs, mat4 rhs) { #if defined(CEL_REND_BACKEND_VULKAN) /** @brief Creates a perspective projection matrix compatible with Vulkan */ -static inline mat4 mat4_perspective(f32 fov_radians, f32 aspect_ratio, f32 near_clip, f32 far_clip) { - // near_clip *= -1.0; - // far_clip *= -1.0; - - f32 half_tan_fov = tanf(fov_radians * 0.5f); - mat4 out_matrix = { .data = { 0 } }; - - out_matrix.data[0] = 1.0f / (aspect_ratio * half_tan_fov); - out_matrix.data[5] = -1.0f / half_tan_fov; // Flip Y-axis for Vulkan - out_matrix.data[10] = -((far_clip + near_clip) / (far_clip - near_clip)); +static inline mat4 mat4_perspective(f32 fov_radians, f32 aspect_ratio, f32 near_clip, + f32 far_clip) { + // near_clip *= -1.0; + // far_clip *= -1.0; + + f32 half_tan_fov = tanf(fov_radians * 0.5f); + mat4 out_matrix = { .data = { 0 } }; + + out_matrix.data[0] = 1.0f / (aspect_ratio * half_tan_fov); + out_matrix.data[5] = -1.0f / half_tan_fov; // Flip Y-axis for Vulkan + out_matrix.data[10] = -((far_clip + near_clip) / (far_clip - near_clip)); out_matrix.data[11] = -1.0f; out_matrix.data[14] = -((2.0f * far_clip * near_clip) / (far_clip - near_clip)); - return out_matrix; + return out_matrix; } #else /** @brief Creates a perspective projection matrix */ diff --git a/src/maths/maths_types.h b/src/maths/maths_types.h index ba741b9..6d38fc7 100644 --- a/src/maths/maths_types.h +++ b/src/maths/maths_types.h @@ -60,4 +60,8 @@ typedef struct transform { quat rotation; f32 scale; bool is_dirty; -} transform; \ No newline at end of file +} transform; + +typedef struct vec4i { + i32 x, y, z, w; +} vec4i; \ No newline at end of file diff --git a/src/maths/primitives.h b/src/maths/primitives.h index 60d36da..fd798c1 100644 --- a/src/maths/primitives.h +++ b/src/maths/primitives.h @@ -55,7 +55,7 @@ static mesh prim_cube_mesh_create() { /** @brief create a new model with the shape of a cube */ static model_handle prim_cube_new(core* core) { - model model = { 0 }; + model model = { 0 }; mesh cube = prim_cube_mesh_create(); mesh_darray_push(model.meshes, cube); diff --git a/src/renderer/backends/backend_vulkan.c b/src/renderer/backends/backend_vulkan.c index f83b271..1657594 100644 --- a/src/renderer/backends/backend_vulkan.c +++ b/src/renderer/backends/backend_vulkan.c @@ -103,6 +103,7 @@ typedef struct vulkan_swapchain { vulkan_framebuffer_darray* framebuffers; } vulkan_swapchain; +// overengineered typedef enum vulkan_command_buffer_state { COMMAND_BUFFER_STATE_READY, COMMAND_BUFFER_STATE_IN_RENDER_PASS, diff --git a/src/renderer/cleanroom/types.h b/src/renderer/cleanroom/types.h index 0a26120..3f62cab 100644 --- a/src/renderer/cleanroom/types.h +++ b/src/renderer/cleanroom/types.h @@ -1,6 +1,7 @@ #pragma once #include "darray.h" #include "defines.h" +#include "maths_types.h" #include "str.h" typedef int texture_handle; @@ -14,9 +15,9 @@ typedef struct texture_desc { // u32x2 extents; } texture_desc; -/* +/* - render_types.h - - ral_types.h + - ral_types.h - ral.h - render.h ? */ @@ -49,15 +50,11 @@ typedef enum gpu_texture_format { typedef struct mesh mesh; typedef struct model model; typedef struct model pbr_material; -typedef struct model bp_material; // blinn-phong +typedef struct model bp_material; // blinn-phong #include "maths_types.h" -typedef enum vertex_format { - VERTEX_STATIC_3D, - VERTEX_SPRITE, - VERTEX_COUNT -} vertex_format; +typedef enum vertex_format { VERTEX_STATIC_3D, VERTEX_SPRITE, VERTEX_COUNT } vertex_format; typedef union vertex { struct { @@ -73,7 +70,14 @@ typedef union vertex { vec2 tex_coords; } sprite; - // TODO: animated 3d + struct { + vec3 position; + vec4 colour; + vec2 tex_coords; + vec3 normal; + vec4i bone_ids; // Integer vector for bone IDs + vec4 bone_weights; // Weight of each bone's influence + } animated_3d; /** @brief vertex format for skeletal (animated) geometry in 3D */ } vertex; KITC_DECL_TYPED_ARRAY(vertex) @@ -90,42 +94,93 @@ typedef struct mesh { buffer_handle index_buffer; u32 index_count; bool has_indices; - geometry_data* vertices; // NULL means it has been freed + geometry_data* vertices; // NULL means it has been freed } mesh; +/* Hot reloading: +C side - reload_model(): + - load model from disk using existing loader + - remove from transform graph so it isnt tried to be drawn + - + +*/ + typedef struct model { str8 debug_name; mesh* meshes; u32 mesh_count; } model; +// ? How to tie together materials and shaders + // Three registers // 1. low level graphics api calls "ral" // 2. higher level render calls // 3. simplified immediate mode API +// 3 - you don't need to know how the renderer works at all +// 2 - you need to know how the overall renderer is designed +// 1 - you need to understand graphics API specifics + /* render.h */ // frontend -- these can be called from say a loop in an example, or via FFI texture_handle texture_create(const char* debug_name, texture_desc description, const u8* data); void texture_data_upload(texture_handle texture); buffer_handle buffer_create(const char* debug_name, u64 size); +bool buffer_destroy(buffer_handle buffer); // models and meshes are implemented **in terms of the above** mesh mesh_create(geometry_data* geometry); -model_handle model_load(const char* filepath); +model_handle model_load(const char* debug_name, const char* filepath); /* ral.h */ + +enum pipeline_type { + GRAPHICS, + COMPUTE, +} pipeline_type; + // backend -- these are not seen by the higher-level code typedef struct gpu_swapchain gpu_swapchain; typedef struct gpu_device gpu_device; typedef struct gpu_pipeline gpu_pipeline; +typedef struct gpu_cmd_encoder gpu_cmd_encoder; +typedef struct gpu_cmd_buffer gpu_cmd_buffer; // Ready for submission -void gpu_texture_init(); -void gpu_texture_upload(); -void gpu_buffer_init(); +void gpu_cmd_encoder_begin(); +void gpu_cmd_encoder_begin_render(); +void gpu_cmd_encoder_begin_compute(); + +/* Actual commands that we can encode */ +void encode_buffer_copy(gpu_cmd_encoder* encoder, buffer_handle src, u64 src_offset, + buffer_handle dst, u64 dst_offset, u64 copy_size); +void encode_clear_buffer(gpu_cmd_encoder* encoder, buffer_handle buf); +// render pass +void encode_set_vertex_buffer(gpu_cmd_encoder* encoder, buffer_handle buf); +void encode_set_index_buffer(gpu_cmd_encoder* encoder, buffer_handle buf); +void encode_draw_indexed(gpu_cmd_encoder* encoder, u64 index_count, u64* indices); + +// FUTURE: compute passes + +/** @brief Finish recording and return a command buffer that can be submitted to a queue */ +gpu_cmd_buffer gpu_cmd_encoder_finish(gpu_cmd_encoder* encoder); + +void gpu_queue_submit(gpu_cmd_buffer* buffer); + +// Buffers +void gpu_buffer_create(u64 size); +void gpu_buffer_destroy(buffer_handle buffer); void gpu_buffer_upload(); -void gpu_buffer_bind(); +void gpu_buffer_bind(buffer_handle buffer); + +// Textures +void gpu_texture_create(); +void gpu_texture_destroy(); +void gpu_texture_upload(); + +// Samplers +void gpu_sampler_create(); // command buffer gubbins @@ -135,7 +190,8 @@ void gpu_buffer_bind(); void imm_draw_cuboid(); void imm_draw_sphere(vec3 pos, f32 radius, vec4 colour); void imm_draw_camera_frustum(); -static void imm_draw_model(const char* model_filepath); // tracks internally whether the model is loaded +static void imm_draw_model( + const char* model_filepath); // tracks internally whether the model is loaded static void imm_draw_model(const char* model_filepath) { // check that model is loaded -- cgit v1.2.3-70-g09d2 From a56349f682862f065c5e5af6183643fcb1f19617 Mon Sep 17 00:00:00 2001 From: Omniscient <17525998+omnisci3nce@users.noreply.github.com> Date: Sun, 31 Mar 2024 15:35:04 +1100 Subject: redo cube primitive vertex and normals --- examples/input/ex_input.c | 18 ++-- src/maths/maths.h | 42 ++++++++- src/maths/primitives.h | 160 ++++++++++++++++++++++++--------- src/renderer/backends/backend_vulkan.c | 46 ++++++---- 4 files changed, 196 insertions(+), 70 deletions(-) (limited to 'src/maths/maths.h') diff --git a/examples/input/ex_input.c b/examples/input/ex_input.c index f102fad..3101968 100644 --- a/examples/input/ex_input.c +++ b/examples/input/ex_input.c @@ -23,20 +23,19 @@ void update_camera_rotation(input_state* input, game_state* game, camera* cam); int main() { core* core = core_bringup(); - vec3 cam_pos = vec3_create(-15, 20.0, 13); + vec3 cam_pos = vec3_create(5, 5, 5); game_state game = { .camera = camera_create(cam_pos, vec3_negate(cam_pos), VEC3_Y, deg_to_rad(45.0)), .camera_euler = vec3_create(90, 0, 0), .first_mouse_update = true, }; - // model_handle cube_handle = prim_cube_new(core); - printf("Starting look direction: "); print_vec3(game.camera.front); // Main loop - const f32 camera_speed = 0.4; + const f32 camera_lateral_speed = 0.2; + const f32 camera_zoom_speed = 0.15; while (!should_exit(core)) { input_update(&core->input); @@ -44,18 +43,18 @@ int main() { vec3 translation = VEC3_ZERO; if (key_is_pressed(KEYCODE_W) || key_is_pressed(KEYCODE_KEY_UP)) { printf("Move Forwards\n"); - translation = vec3_mult(game.camera.front, camera_speed); + translation = vec3_mult(game.camera.front, camera_zoom_speed); } else if (key_is_pressed(KEYCODE_S) || key_is_pressed(KEYCODE_KEY_DOWN)) { printf("Move Backwards\n"); - translation = vec3_mult(game.camera.front, -camera_speed); + translation = vec3_mult(game.camera.front, -camera_zoom_speed); } else if (key_is_pressed(KEYCODE_A) || key_is_pressed(KEYCODE_KEY_LEFT)) { printf("Move Left\n"); vec3 lateral = vec3_normalise(vec3_cross(game.camera.front, game.camera.up)); - translation = vec3_mult(lateral, -camera_speed); + translation = vec3_mult(lateral, -camera_lateral_speed); } else if (key_is_pressed(KEYCODE_D) || key_is_pressed(KEYCODE_KEY_RIGHT)) { printf("Move Right\n"); vec3 lateral = vec3_normalise(vec3_cross(game.camera.front, game.camera.up)); - translation = vec3_mult(lateral, camera_speed); + translation = vec3_mult(lateral, camera_lateral_speed); } game.camera.position = vec3_add(game.camera.position, translation); // update_camera_rotation(&core->input, &game, &game.camera); @@ -64,7 +63,6 @@ int main() { render_frame_begin(&core->renderer); - // model cube = core->models->data[cube_handle.raw]; mat4 model = mat4_translation(VEC3_ZERO); gfx_backend_draw_frame(&core->renderer, &game.camera, model); @@ -86,7 +84,7 @@ void update_camera_rotation(input_state* input, game_state* game, camera* cam) { game->first_mouse_update = false; } - float sensitivity = 0.1f; // change this value to your liking + float sensitivity = 0.2f; // change this value to your liking xoffset *= sensitivity; yoffset *= sensitivity; diff --git a/src/maths/maths.h b/src/maths/maths.h index 6fa2f9b..1432581 100644 --- a/src/maths/maths.h +++ b/src/maths/maths.h @@ -132,6 +132,27 @@ static inline mat4 mat4_mult(mat4 lhs, mat4 rhs) { return out_matrix; } +static mat4 mat4_transposed(mat4 matrix) { + mat4 out_matrix = mat4_ident(); + out_matrix.data[0] = matrix.data[0]; + out_matrix.data[1] = matrix.data[4]; + out_matrix.data[2] = matrix.data[8]; + out_matrix.data[3] = matrix.data[12]; + out_matrix.data[4] = matrix.data[1]; + out_matrix.data[5] = matrix.data[5]; + out_matrix.data[6] = matrix.data[9]; + out_matrix.data[7] = matrix.data[13]; + out_matrix.data[8] = matrix.data[2]; + out_matrix.data[9] = matrix.data[6]; + out_matrix.data[10] = matrix.data[10]; + out_matrix.data[11] = matrix.data[14]; + out_matrix.data[12] = matrix.data[3]; + out_matrix.data[13] = matrix.data[7]; + out_matrix.data[14] = matrix.data[11]; + out_matrix.data[15] = matrix.data[15]; + return out_matrix; +} + #if defined(CEL_REND_BACKEND_VULKAN) /** @brief Creates a perspective projection matrix compatible with Vulkan */ static inline mat4 mat4_perspective(f32 fov_radians, f32 aspect_ratio, f32 near_clip, @@ -143,12 +164,31 @@ static inline mat4 mat4_perspective(f32 fov_radians, f32 aspect_ratio, f32 near_ mat4 out_matrix = { .data = { 0 } }; out_matrix.data[0] = 1.0f / (aspect_ratio * half_tan_fov); - out_matrix.data[5] = -1.0f / half_tan_fov; // Flip Y-axis for Vulkan + out_matrix.data[5] = 1.0f / half_tan_fov; // Flip Y-axis for Vulkan out_matrix.data[10] = -((far_clip + near_clip) / (far_clip - near_clip)); out_matrix.data[11] = -1.0f; out_matrix.data[14] = -((2.0f * far_clip * near_clip) / (far_clip - near_clip)); + // float half_tan_fov = tanf(fov_radians * 0.5); + // float k = far_clip / (far_clip - near_clip); + + // out_matrix.data[0] = 1.0f / (aspect_ratio * half_tan_fov); + // out_matrix.data[5] = 1.0f / half_tan_fov; + // out_matrix.data[10] = k; + // out_matrix.data[11] = -1.0; + // out_matrix.data[14] = -1.0 * near_clip * k; + + // f32 half_tan_fov = tan(fov_radians * 0.5f); + // out_matrix.data[0] = 1.0f / (aspect_ratio * half_tan_fov); + // out_matrix.data[5] = 1.0f / half_tan_fov; + // out_matrix.data[10] = -((far_clip + near_clip) / (far_clip - near_clip)); + // out_matrix.data[11] = -1.0f; + // out_matrix.data[14] = + // -((2.0f * far_clip * near_clip) / (far_clip - near_clip)); + // return out_matrix; + return out_matrix; + // return mat4_transposed(out_matrix); } #else /** @brief Creates a perspective projection matrix */ diff --git a/src/maths/primitives.h b/src/maths/primitives.h index fd798c1..77dbbae 100644 --- a/src/maths/primitives.h +++ b/src/maths/primitives.h @@ -1,55 +1,135 @@ #pragma once #include +#include #include "core.h" +#include "maths.h" #include "render_types.h" -static float cube_vertices[] = { - // positions // normals // texture coords - -0.5f, -0.5f, -0.5f, 0.0f, 0.0f, -1.0f, 0.0f, 0.0f, 0.5f, -0.5f, -0.5f, 0.0f, - 0.0f, -1.0f, 1.0f, 0.0f, 0.5f, 0.5f, -0.5f, 0.0f, 0.0f, -1.0f, 1.0f, 1.0f, - 0.5f, 0.5f, -0.5f, 0.0f, 0.0f, -1.0f, 1.0f, 1.0f, -0.5f, 0.5f, -0.5f, 0.0f, - 0.0f, -1.0f, 0.0f, 1.0f, -0.5f, -0.5f, -0.5f, 0.0f, 0.0f, -1.0f, 0.0f, 0.0f, - - -0.5f, -0.5f, 0.5f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f, 0.5f, -0.5f, 0.5f, 0.0f, - 0.0f, 1.0f, 1.0f, 0.0f, 0.5f, 0.5f, 0.5f, 0.0f, 0.0f, 1.0f, 1.0f, 1.0f, - 0.5f, 0.5f, 0.5f, 0.0f, 0.0f, 1.0f, 1.0f, 1.0f, -0.5f, 0.5f, 0.5f, 0.0f, - 0.0f, 1.0f, 0.0f, 1.0f, -0.5f, -0.5f, 0.5f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f, - - -0.5f, 0.5f, 0.5f, -1.0f, 0.0f, 0.0f, 1.0f, 0.0f, -0.5f, 0.5f, -0.5f, -1.0f, - 0.0f, 0.0f, 1.0f, 1.0f, -0.5f, -0.5f, -0.5f, -1.0f, 0.0f, 0.0f, 0.0f, 1.0f, - -0.5f, -0.5f, -0.5f, -1.0f, 0.0f, 0.0f, 0.0f, 1.0f, -0.5f, -0.5f, 0.5f, -1.0f, - 0.0f, 0.0f, 0.0f, 0.0f, -0.5f, 0.5f, 0.5f, -1.0f, 0.0f, 0.0f, 1.0f, 0.0f, - - 0.5f, 0.5f, 0.5f, 1.0f, 0.0f, 0.0f, 1.0f, 0.0f, 0.5f, 0.5f, -0.5f, 1.0f, - 0.0f, 0.0f, 1.0f, 1.0f, 0.5f, -0.5f, -0.5f, 1.0f, 0.0f, 0.0f, 0.0f, 1.0f, - 0.5f, -0.5f, -0.5f, 1.0f, 0.0f, 0.0f, 0.0f, 1.0f, 0.5f, -0.5f, 0.5f, 1.0f, - 0.0f, 0.0f, 0.0f, 0.0f, 0.5f, 0.5f, 0.5f, 1.0f, 0.0f, 0.0f, 1.0f, 0.0f, - - -0.5f, -0.5f, -0.5f, 0.0f, -1.0f, 0.0f, 0.0f, 1.0f, 0.5f, -0.5f, -0.5f, 0.0f, - -1.0f, 0.0f, 1.0f, 1.0f, 0.5f, -0.5f, 0.5f, 0.0f, -1.0f, 0.0f, 1.0f, 0.0f, - 0.5f, -0.5f, 0.5f, 0.0f, -1.0f, 0.0f, 1.0f, 0.0f, -0.5f, -0.5f, 0.5f, 0.0f, - -1.0f, 0.0f, 0.0f, 0.0f, -0.5f, -0.5f, -0.5f, 0.0f, -1.0f, 0.0f, 0.0f, 1.0f, - - -0.5f, 0.5f, -0.5f, 0.0f, 1.0f, 0.0f, 0.0f, 1.0f, 0.5f, 0.5f, -0.5f, 0.0f, - 1.0f, 0.0f, 1.0f, 1.0f, 0.5f, 0.5f, 0.5f, 0.0f, 1.0f, 0.0f, 1.0f, 0.0f, - 0.5f, 0.5f, 0.5f, 0.0f, 1.0f, 0.0f, 1.0f, 0.0f, -0.5f, 0.5f, 0.5f, 0.0f, - 1.0f, 0.0f, 0.0f, 0.0f, -0.5f, 0.5f, -0.5f, 0.0f, 1.0f, 0.0f, 0.0f, 1.0f -}; +static const vec3 BACK_BOT_LEFT = (vec3){ 0, 0, 0 }; +static const vec3 BACK_BOT_RIGHT = (vec3){ 1, 0, 0 }; +static const vec3 BACK_TOP_LEFT = (vec3){ 0, 1, 0 }; +static const vec3 BACK_TOP_RIGHT = (vec3){ 1, 1, 0 }; +static const vec3 FRONT_BOT_LEFT = (vec3){ 0, 0, 1 }; +static const vec3 FRONT_BOT_RIGHT = (vec3){ 1, 0, 1 }; +static const vec3 FRONT_TOP_LEFT = (vec3){ 0, 1, 1 }; +static const vec3 FRONT_TOP_RIGHT = (vec3){ 1, 1, 1 }; static mesh prim_cube_mesh_create() { mesh cube = { 0 }; cube.vertices = vertex_darray_new(36); - for (int i = 0; i < 36; i++) { - vertex vert = { .position = vec3_create(cube_vertices[(i * 8) + 0], cube_vertices[(i * 8) + 1], - cube_vertices[(i * 8) + 2]), - .normal = vec3_create(cube_vertices[(i * 8) + 3], cube_vertices[(i * 8) + 4], - cube_vertices[(i * 8) + 5]), - .uv = (vec2){ .x = cube_vertices[(i * 8) + 6], - .y = cube_vertices[(i * 8) + 7] } }; - vertex_darray_push(cube.vertices, vert); + // back faces + vertex_darray_push( + cube.vertices, + (vertex){ .position = BACK_BOT_LEFT, .normal = VEC3_NEG_Z, .uv = (vec2){ 0 } }); + vertex_darray_push( + cube.vertices, + (vertex){ .position = BACK_TOP_LEFT, .normal = VEC3_NEG_Z, .uv = (vec2){ 0 } }); + vertex_darray_push( + cube.vertices, + (vertex){ .position = BACK_TOP_LEFT, .normal = VEC3_NEG_Z, .uv = (vec2){ 0 } }); + vertex_darray_push( + cube.vertices, + (vertex){ .position = BACK_TOP_RIGHT, .normal = VEC3_NEG_Z, .uv = (vec2){ 0 } }); + vertex_darray_push( + cube.vertices, + (vertex){ .position = BACK_BOT_RIGHT, .normal = VEC3_NEG_Z, .uv = (vec2){ 0 } }); + vertex_darray_push( + cube.vertices, + (vertex){ .position = BACK_BOT_LEFT, .normal = VEC3_NEG_Z, .uv = (vec2){ 0 } }); + + // front faces + vertex_darray_push(cube.vertices, + (vertex){ .position = FRONT_BOT_LEFT, .normal = VEC3_Z, .uv = (vec2){ 0 } }); + vertex_darray_push(cube.vertices, + (vertex){ .position = FRONT_TOP_RIGHT, .normal = VEC3_Z, .uv = (vec2){ 0 } }); + vertex_darray_push(cube.vertices, + (vertex){ .position = FRONT_TOP_LEFT, .normal = VEC3_Z, .uv = (vec2){ 0 } }); + vertex_darray_push(cube.vertices, + (vertex){ .position = FRONT_BOT_LEFT, .normal = VEC3_Z, .uv = (vec2){ 0 } }); + vertex_darray_push(cube.vertices, + (vertex){ .position = FRONT_BOT_RIGHT, .normal = VEC3_Z, .uv = (vec2){ 0 } }); + vertex_darray_push(cube.vertices, + (vertex){ .position = FRONT_TOP_RIGHT, .normal = VEC3_Z, .uv = (vec2){ 0 } }); + + // top faces + vertex_darray_push(cube.vertices, + (vertex){ .position = BACK_TOP_LEFT, .normal = VEC3_Y, .uv = (vec2){ 0 } }); + vertex_darray_push(cube.vertices, + (vertex){ .position = FRONT_TOP_LEFT, .normal = VEC3_Y, .uv = (vec2){ 0 } }); + vertex_darray_push(cube.vertices, + (vertex){ .position = FRONT_TOP_RIGHT, .normal = VEC3_Y, .uv = (vec2){ 0 } }); + vertex_darray_push(cube.vertices, + (vertex){ .position = BACK_TOP_LEFT, .normal = VEC3_Y, .uv = (vec2){ 0 } }); + vertex_darray_push(cube.vertices, + (vertex){ .position = FRONT_TOP_RIGHT, .normal = VEC3_Y, .uv = (vec2){ 0 } }); + vertex_darray_push(cube.vertices, + (vertex){ .position = BACK_TOP_RIGHT, .normal = VEC3_Y, .uv = (vec2){ 0 } }); + + // bottom faces + vertex_darray_push( + cube.vertices, + (vertex){ .position = BACK_BOT_LEFT, .normal = VEC3_NEG_Y, .uv = (vec2){ 0 } }); + vertex_darray_push( + cube.vertices, + (vertex){ .position = FRONT_BOT_RIGHT, .normal = VEC3_NEG_Y, .uv = (vec2){ 0 } }); + vertex_darray_push( + cube.vertices, + (vertex){ .position = FRONT_BOT_LEFT, .normal = VEC3_NEG_Y, .uv = (vec2){ 0 } }); + vertex_darray_push( + cube.vertices, + (vertex){ .position = BACK_BOT_LEFT, .normal = VEC3_NEG_Y, .uv = (vec2){ 0 } }); + vertex_darray_push( + cube.vertices, + (vertex){ .position = BACK_BOT_RIGHT, .normal = VEC3_NEG_Y, .uv = (vec2){ 0 } }); + vertex_darray_push( + cube.vertices, + (vertex){ .position = FRONT_BOT_RIGHT, .normal = VEC3_NEG_Y, .uv = (vec2){ 0 } }); + + // right faces + vertex_darray_push(cube.vertices, + (vertex){ .position = FRONT_TOP_RIGHT, .normal = VEC3_X, .uv = (vec2){ 0 } }); + vertex_darray_push(cube.vertices, + (vertex){ .position = BACK_BOT_RIGHT, .normal = VEC3_X, .uv = (vec2){ 0 } }); + vertex_darray_push(cube.vertices, + (vertex){ .position = BACK_TOP_RIGHT, .normal = VEC3_X, .uv = (vec2){ 0 } }); + vertex_darray_push(cube.vertices, + (vertex){ .position = BACK_BOT_RIGHT, .normal = VEC3_X, .uv = (vec2){ 0 } }); + vertex_darray_push(cube.vertices, + (vertex){ .position = FRONT_TOP_RIGHT, .normal = VEC3_X, .uv = (vec2){ 0 } }); + vertex_darray_push(cube.vertices, + (vertex){ .position = FRONT_BOT_RIGHT, .normal = VEC3_X, .uv = (vec2){ 0 } }); + + // left faces + vertex_darray_push( + cube.vertices, + (vertex){ .position = FRONT_TOP_LEFT, .normal = VEC3_NEG_X, .uv = (vec2){ 0 } }); + vertex_darray_push( + cube.vertices, + (vertex){ .position = BACK_TOP_LEFT, .normal = VEC3_NEG_X, .uv = (vec2){ 0 } }); + vertex_darray_push( + cube.vertices, + (vertex){ .position = BACK_BOT_LEFT, .normal = VEC3_NEG_X, .uv = (vec2){ 0 } }); + vertex_darray_push( + cube.vertices, + (vertex){ .position = BACK_BOT_LEFT, .normal = VEC3_NEG_X, .uv = (vec2){ 0 } }); + vertex_darray_push( + cube.vertices, + (vertex){ .position = FRONT_BOT_LEFT, .normal = VEC3_NEG_X, .uv = (vec2){ 0 } }); + vertex_darray_push( + cube.vertices, + (vertex){ .position = FRONT_TOP_LEFT, .normal = VEC3_NEG_X, .uv = (vec2){ 0 } }); + + cube.indices_len = cube.vertices->len; + cube.indices = malloc(sizeof(u32) * cube.indices_len); + + for (u32 i = 0; i < cube.indices_len; i++) { + cube.indices[i] = i; } + + cube.has_indices = true; + return cube; } diff --git a/src/renderer/backends/backend_vulkan.c b/src/renderer/backends/backend_vulkan.c index 1657594..97e0a44 100644 --- a/src/renderer/backends/backend_vulkan.c +++ b/src/renderer/backends/backend_vulkan.c @@ -654,10 +654,10 @@ void vulkan_object_shader_update_object(vulkan_context* context, vulkan_shader* vkCmdBindVertexBuffers(cmd_buffer, 0, 1, &context->object_vertex_buffer.handle, (VkDeviceSize*)offsets); - // vkCmdBindIndexBuffer(cmd_buffer, context->object_index_buffer.handle, 0, VK_INDEX_TYPE_UINT32); + vkCmdBindIndexBuffer(cmd_buffer, context->object_index_buffer.handle, 0, VK_INDEX_TYPE_UINT32); - // vkCmdDrawIndexed(cmd_buffer, 6, 1, 0, 0, 0); - vkCmdDraw(cmd_buffer, 36, 1, 0, 0); + vkCmdDrawIndexed(cmd_buffer, 36, 1, 0, 0, 0); + // vkCmdDraw(cmd_buffer, 36, 1, 0, 0); } bool select_physical_device(vulkan_context* ctx) { @@ -1351,11 +1351,9 @@ void upload_data_range(vulkan_context* context, VkCommandPool pool, VkFence fenc VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT | VK_MEMORY_PROPERTY_HOST_COHERENT_BIT; vulkan_buffer staging; vulkan_buffer_create(context, size, VK_BUFFER_USAGE_TRANSFER_SRC_BIT, flags, true, &staging); - TRACE("HERE"); // load data into staging buffer printf("Size: %ld\n", size); vulkan_buffer_load_data(context, &staging, 0, size, 0, data); - TRACE("here"); // copy vulkan_buffer_copy_to(context, pool, fence, queue, staging.handle, 0, buffer->handle, offset, @@ -1587,18 +1585,19 @@ bool gfx_backend_init(renderer* ren) { mesh cube = prim_cube_mesh_create(); - const u32 vert_count = 36; - // vertex_pos verts[4] = { 0 }; + // const u32 vert_count = 36; - vertex_pos verts[36] = { 0 }; + vertex_pos* verts = malloc(sizeof(vertex_pos) * cube.vertices->len); f32 scale = 3.0; - for (size_t i = 0; i < 36; i++) { + for (size_t i = 0; i < cube.vertices->len; i++) { verts[i].pos = vec3_mult(cube.vertices->data[i].position, scale); verts[i].normal = cube.vertices->data[i].normal; } - // const f32 s = 10.0; + // const f32 s = 1.0; + // const u32 vert_count = 4; + // vertex_pos verts[4] = { 0 }; // verts[0].pos.x = -0.5 * s; // verts[0].pos.y = -0.5 * s; @@ -1612,15 +1611,16 @@ bool gfx_backend_init(renderer* ren) { // verts[3].pos.x = 0.5 * s; // verts[3].pos.y = -0.5 * s; - const u32 index_count = 6; - u32 indices[6] = { 0, 1, 2, 0, 3, 1 }; + // const u32 index_count = 6; + // u32 indices[6] = { 0, 1, 2, 0, 3, 1 }; upload_data_range(&context, context.device.gfx_command_pool, 0, context.device.graphics_queue, - &context.object_vertex_buffer, 0, sizeof(vertex_pos) * vert_count, verts); + &context.object_vertex_buffer, 0, sizeof(vertex_pos) * cube.vertices->len, + verts); TRACE("Uploaded vertex data"); - // upload_data_range(&context, context.device.gfx_command_pool, 0, context.device.graphics_queue, - // &context.object_index_buffer, 0, sizeof(u32) * index_count, indices); - // TRACE("Uploaded index data"); + upload_data_range(&context, context.device.gfx_command_pool, 0, context.device.graphics_queue, + &context.object_index_buffer, 0, sizeof(u32) * cube.indices_len, cube.indices); + TRACE("Uploaded index data"); // --- End test code INFO("Vulkan renderer initialisation succeeded"); @@ -1661,9 +1661,9 @@ void backend_begin_frame(renderer* ren, f32 delta_time) { VkViewport viewport; viewport.x = 0.0; - viewport.y = 0.0; + viewport.y = (f32)context.framebuffer_height; viewport.width = (f32)context.framebuffer_width; - viewport.height = (f32)context.framebuffer_height; + viewport.height = -(f32)context.framebuffer_height; viewport.minDepth = 0.0; viewport.maxDepth = 1.0; @@ -1741,7 +1741,15 @@ void gfx_backend_draw_frame(renderer* ren, camera* cam, mat4 model) { camera_view_projection(cam, SCR_HEIGHT, SCR_WIDTH, &view, &proj); - gfx_backend_update_global_state(proj, view, VEC3_ZERO, vec4(1.0, 1.0, 1.0, 1.0), 0); + // proj = mat4_perspective(deg_to_rad(45.0), (f32)SCR_WIDTH / SCR_HEIGHT, 0.1, 100.0); + + // proj.data[5] *= -1.0; + + // vec3 pos = vec3_create(2, 2, 2); + // vec3 up = VEC3_Y; + // view = mat4_look_at(pos, VEC3_ZERO, up); + + gfx_backend_update_global_state(proj, view, cam->position, vec4(1.0, 1.0, 1.0, 1.0), 0); vulkan_object_shader_update_object(&context, &context.object_shader, model); backend_end_frame(ren, 16.0); -- cgit v1.2.3-70-g09d2 From 1b4c27d514423c9e27a93742b8c8e9eb9f588e27 Mon Sep 17 00:00:00 2001 From: Omniscient <17525998+omnisci3nce@users.noreply.github.com> Date: Sun, 31 Mar 2024 15:43:08 +1100 Subject: fix discrepancy between opengl and vulkan --- assets/shaders/blinn_phong.vert | 11 ++++------- src/maths/maths.h | 24 +----------------------- src/renderer/backends/backend_vulkan.c | 17 ++++------------- 3 files changed, 9 insertions(+), 43 deletions(-) (limited to 'src/maths/maths.h') diff --git a/assets/shaders/blinn_phong.vert b/assets/shaders/blinn_phong.vert index 041c3d1..6028178 100644 --- a/assets/shaders/blinn_phong.vert +++ b/assets/shaders/blinn_phong.vert @@ -4,13 +4,10 @@ layout (location = 0) in vec3 inPos; layout (location = 1) in vec3 inNormal; layout (location = 2) in vec2 inTexCoords; -// Uniform block -layout (std140, binding = 0) uniform MatrixBlock { - mat4 model; - mat4 view; - mat4 projection; - mat4 lightSpaceMatrix; -}; +uniform mat4 model; +uniform mat4 view; +uniform mat4 projection; +uniform mat4 lightSpaceMatrix; // Output out VS_OUT { diff --git a/src/maths/maths.h b/src/maths/maths.h index 1432581..c9bcaad 100644 --- a/src/maths/maths.h +++ b/src/maths/maths.h @@ -157,38 +157,16 @@ static mat4 mat4_transposed(mat4 matrix) { /** @brief Creates a perspective projection matrix compatible with Vulkan */ static inline mat4 mat4_perspective(f32 fov_radians, f32 aspect_ratio, f32 near_clip, f32 far_clip) { - // near_clip *= -1.0; - // far_clip *= -1.0; - f32 half_tan_fov = tanf(fov_radians * 0.5f); mat4 out_matrix = { .data = { 0 } }; out_matrix.data[0] = 1.0f / (aspect_ratio * half_tan_fov); - out_matrix.data[5] = 1.0f / half_tan_fov; // Flip Y-axis for Vulkan + out_matrix.data[5] = -1.0f / half_tan_fov; // Flip Y-axis for Vulkan out_matrix.data[10] = -((far_clip + near_clip) / (far_clip - near_clip)); out_matrix.data[11] = -1.0f; out_matrix.data[14] = -((2.0f * far_clip * near_clip) / (far_clip - near_clip)); - // float half_tan_fov = tanf(fov_radians * 0.5); - // float k = far_clip / (far_clip - near_clip); - - // out_matrix.data[0] = 1.0f / (aspect_ratio * half_tan_fov); - // out_matrix.data[5] = 1.0f / half_tan_fov; - // out_matrix.data[10] = k; - // out_matrix.data[11] = -1.0; - // out_matrix.data[14] = -1.0 * near_clip * k; - - // f32 half_tan_fov = tan(fov_radians * 0.5f); - // out_matrix.data[0] = 1.0f / (aspect_ratio * half_tan_fov); - // out_matrix.data[5] = 1.0f / half_tan_fov; - // out_matrix.data[10] = -((far_clip + near_clip) / (far_clip - near_clip)); - // out_matrix.data[11] = -1.0f; - // out_matrix.data[14] = - // -((2.0f * far_clip * near_clip) / (far_clip - near_clip)); - // return out_matrix; - return out_matrix; - // return mat4_transposed(out_matrix); } #else /** @brief Creates a perspective projection matrix */ diff --git a/src/renderer/backends/backend_vulkan.c b/src/renderer/backends/backend_vulkan.c index 97e0a44..d149e15 100644 --- a/src/renderer/backends/backend_vulkan.c +++ b/src/renderer/backends/backend_vulkan.c @@ -1,7 +1,8 @@ #include "camera.h" #include "primitives.h" #define CDEBUG -#define CEL_PLATFORM_LINUX +// #define CEL_PLATFORM_LINUX +#if CEL_REND_BACKEND_VULKAN // ^ Temporary #include @@ -30,8 +31,6 @@ #define SCR_WIDTH 1000 #define SCR_HEIGHT 1000 -#if CEL_REND_BACKEND_VULKAN - #include #include @@ -1661,9 +1660,9 @@ void backend_begin_frame(renderer* ren, f32 delta_time) { VkViewport viewport; viewport.x = 0.0; - viewport.y = (f32)context.framebuffer_height; + viewport.y = 0; viewport.width = (f32)context.framebuffer_width; - viewport.height = -(f32)context.framebuffer_height; + viewport.height = (f32)context.framebuffer_height; viewport.minDepth = 0.0; viewport.maxDepth = 1.0; @@ -1741,14 +1740,6 @@ void gfx_backend_draw_frame(renderer* ren, camera* cam, mat4 model) { camera_view_projection(cam, SCR_HEIGHT, SCR_WIDTH, &view, &proj); - // proj = mat4_perspective(deg_to_rad(45.0), (f32)SCR_WIDTH / SCR_HEIGHT, 0.1, 100.0); - - // proj.data[5] *= -1.0; - - // vec3 pos = vec3_create(2, 2, 2); - // vec3 up = VEC3_Y; - // view = mat4_look_at(pos, VEC3_ZERO, up); - gfx_backend_update_global_state(proj, view, cam->position, vec4(1.0, 1.0, 1.0, 1.0), 0); vulkan_object_shader_update_object(&context, &context.object_shader, model); -- cgit v1.2.3-70-g09d2