summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorOmniscient <17525998+omnisci3nce@users.noreply.github.com>2024-03-30 21:39:31 +1100
committerOmniscient <17525998+omnisci3nce@users.noreply.github.com>2024-03-30 21:39:31 +1100
commitf7b91c2eae24ecb7a20b638246fb849d6c63615a (patch)
tree4bdf8fd3425db9f0203f7cf1c58464f4be88e720
parent16237e6499f47d963df35c0f0c4649900ec98d84 (diff)
start adding mouse input processing
-rw-r--r--assets/shaders/object.vert10
-rw-r--r--examples/input/ex_input.c113
-rw-r--r--examples/main_loop/ex_main_loop.c6
-rw-r--r--src/core.c13
-rw-r--r--src/core.h1
-rw-r--r--src/maths/maths.h5
-rw-r--r--src/renderer/backends/backend_vulkan.c63
-rw-r--r--src/renderer/render.c2
-rw-r--r--src/renderer/render_backend.h6
-rw-r--r--src/systems/input.c19
-rw-r--r--src/systems/keys.h15
-rw-r--r--xmake.lua11
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
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 <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
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 <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
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")