diff options
-rw-r--r-- | assets/shaders/object.vert | 10 | ||||
-rw-r--r-- | examples/input/ex_input.c | 113 | ||||
-rw-r--r-- | examples/main_loop/ex_main_loop.c | 6 | ||||
-rw-r--r-- | src/core.c | 13 | ||||
-rw-r--r-- | src/core.h | 1 | ||||
-rw-r--r-- | src/maths/maths.h | 5 | ||||
-rw-r--r-- | src/renderer/backends/backend_vulkan.c | 63 | ||||
-rw-r--r-- | src/renderer/render.c | 2 | ||||
-rw-r--r-- | src/renderer/render_backend.h | 6 | ||||
-rw-r--r-- | src/systems/input.c | 19 | ||||
-rw-r--r-- | src/systems/keys.h | 15 | ||||
-rw-r--r-- | xmake.lua | 11 |
12 files changed, 235 insertions, 29 deletions
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 <glfw3.h> + +#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 @@ -2,6 +2,9 @@ #include <stdlib.h> +#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 @@ -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 <math.h> +#include <stdio.h> #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 <assert.h> #include <glfw3.h> +#include <string.h> #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 @@ -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") |