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 --- examples/input/ex_input.c | 113 ++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 113 insertions(+) create mode 100644 examples/input/ex_input.c (limited to 'examples/input/ex_input.c') 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); +} -- 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 'examples/input/ex_input.c') 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 c20740ecbb008afbe93c7fa1eb35851cedc6eb42 Mon Sep 17 00:00:00 2001 From: Omniscient <17525998+omnisci3nce@users.noreply.github.com> Date: Sat, 30 Mar 2024 23:14:39 +1100 Subject: vulkan glossary --- examples/input/ex_input.c | 2 +- src/renderer/backends/vulkan/vulkan_glossary.md | 18 ++++++++++++++++++ 2 files changed, 19 insertions(+), 1 deletion(-) create mode 100644 src/renderer/backends/vulkan/vulkan_glossary.md (limited to 'examples/input/ex_input.c') diff --git a/examples/input/ex_input.c b/examples/input/ex_input.c index 4bbf76a..7ead3ec 100644 --- a/examples/input/ex_input.c +++ b/examples/input/ex_input.c @@ -12,7 +12,7 @@ typedef struct game_state { camera camera; vec3 camera_euler; - bool first_mouse_update; + bool first_mouse_update; // so the camera doesnt lurch when you run the first process_camera_rotation } game_state; void update_camera_rotation(input_state* input, game_state* game, camera* cam); diff --git a/src/renderer/backends/vulkan/vulkan_glossary.md b/src/renderer/backends/vulkan/vulkan_glossary.md new file mode 100644 index 0000000..4214f9d --- /dev/null +++ b/src/renderer/backends/vulkan/vulkan_glossary.md @@ -0,0 +1,18 @@ +# Vulkan Glossary + +*from https://vkguide.dev/docs/introduction/vulkan_execution/* + +- **VkInstance**: The Vulkan context, used to access drivers. +- **VkPhysicalDevice**: A GPU. Used to query physical GPU details, like features, capabilities, memory size, etc. +- **VkDevice**: The “logical” GPU context that you actually execute things on. +- **VkBuffer**: A chunk of GPU visible memory. +- **VkImage**: A texture you can write to and read from. +- **VkPipeline**: Holds the state of the gpu needed to draw. For example: shaders, rasterization options, depth settings. +- **VkRenderPass**: Holds information about the images you are rendering into. All drawing commands have to be done inside a renderpass. Only used in legacy vkguide. +- **VkFrameBuffer**: Holds the target images for a renderpass. Only used in legacy vkguide. +- **VkCommandBuffer**: Encodes GPU commands. All execution that is performed on the GPU itself (not in the driver) has to be encoded in a VkCommandBuffer. +- **VkQueue**: Execution “port” for commands. GPUs will have a set of queues with different properties. Some allow only graphics commands, others only allow memory commands, etc. Command buffers are executed by submitting them into a queue, which will copy the rendering commands onto the GPU for execution. +- **VkDescriptorSet**: Holds the binding information that connects shader inputs to data such as VkBuffer resources and VkImage textures. Think of it as a set of gpu-side pointers that you bind once. +- **VkSwapchainKHR**: Holds the images for the screen. It allows you to render things into a visible window. The KHR suffix shows that it comes from an extension, which in this case is VK_KHR_swapchain. +- **VkSemaphore**: Synchronizes GPU to GPU execution of commands. Used for syncing multiple command buffer submissions one after another. +- **VkFence**: Synchronizes GPU to CPU execution of commands. Used to know if a command buffer has finished being executed on the GPU. -- cgit v1.2.3-70-g09d2 From b638fd776253fa0cb841175e3e134df4587101b6 Mon Sep 17 00:00:00 2001 From: Omniscient <17525998+omnisci3nce@users.noreply.github.com> Date: Sat, 30 Mar 2024 23:16:53 +1100 Subject: fix main loop example --- examples/input/ex_input.c | 3 ++- examples/main_loop/ex_main_loop.c | 5 ++++- 2 files changed, 6 insertions(+), 2 deletions(-) (limited to 'examples/input/ex_input.c') diff --git a/examples/input/ex_input.c b/examples/input/ex_input.c index 7ead3ec..0e72c16 100644 --- a/examples/input/ex_input.c +++ b/examples/input/ex_input.c @@ -12,7 +12,8 @@ typedef struct game_state { camera camera; vec3 camera_euler; - bool first_mouse_update; // so the camera doesnt lurch when you run the first process_camera_rotation + bool first_mouse_update; // so the camera doesnt lurch when you run the first + // process_camera_rotation } game_state; void update_camera_rotation(input_state* input, game_state* game, camera* cam); diff --git a/examples/main_loop/ex_main_loop.c b/examples/main_loop/ex_main_loop.c index 25dbf4a..31514bf 100644 --- a/examples/main_loop/ex_main_loop.c +++ b/examples/main_loop/ex_main_loop.c @@ -1,5 +1,6 @@ #include +#include "camera.h" #include "core.h" #include "maths.h" #include "render.h" @@ -8,6 +9,8 @@ int main() { core* core = core_bringup(); + camera camera = camera_create(vec3_create(0, 0, 20), VEC3_NEG_Z, VEC3_Y, deg_to_rad(45.0)); + // Main loop while (!glfwWindowShouldClose(core->renderer.window)) { input_update(&core->input); @@ -19,7 +22,7 @@ int main() { x += 0.01; mat4 model = mat4_translation(vec3(x, 0, 0)); - gfx_backend_draw_frame(&core->renderer, model); + gfx_backend_draw_frame(&core->renderer, &camera, model); // insert work here -- 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 'examples/input/ex_input.c') 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 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 'examples/input/ex_input.c') 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 fb3e055ff500e530e9ec46317441688bf4d07e13 Mon Sep 17 00:00:00 2001 From: Omniscient <17525998+omnisci3nce@users.noreply.github.com> Date: Mon, 1 Apr 2024 01:57:11 +1100 Subject: image / textures ! --- assets/shaders/object.frag | 14 ++- assets/shaders/object.vert | 11 +- examples/input/ex_input.c | 6 +- src/colours.h | 48 +++++++++ src/maths/primitives.h | 24 ++--- src/renderer/backends/backend_opengl.c | 2 +- src/renderer/backends/backend_vulkan.c | 191 +++++++++++++++++++++++---------- src/renderer/render.c | 2 +- src/renderer/render_backend.h | 2 +- 9 files changed, 219 insertions(+), 81 deletions(-) (limited to 'examples/input/ex_input.c') diff --git a/assets/shaders/object.frag b/assets/shaders/object.frag index 11b33e1..8466c1d 100644 --- a/assets/shaders/object.frag +++ b/assets/shaders/object.frag @@ -1,9 +1,15 @@ #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) in vec3 in_position; +layout(location = 1) in vec3 in_normal; +layout(location = 2) in vec2 in_tex_coord; -layout(location = 0) out vec4 out_colour; +layout(binding = 1) uniform sampler2D texSampler; -void main() { out_colour = vec4(in_normal, 1.0); } \ No newline at end of file +layout(location = 0) out vec4 out_color; + +void main() { + // out_color = vec4(1.0); + out_color = texture(texSampler, in_tex_coord); +} \ No newline at end of file diff --git a/assets/shaders/object.vert b/assets/shaders/object.vert index a7237bb..23c0ffb 100644 --- a/assets/shaders/object.vert +++ b/assets/shaders/object.vert @@ -3,9 +3,11 @@ layout(location = 0) in vec3 in_position; layout(location = 1) in vec3 in_normal; +layout(location = 2) in vec2 in_tex_coord; -layout(location = 0) out vec3 out_normal; -layout(location = 1) out vec3 out_position; +layout(location = 0) out vec3 out_position; +layout(location = 1) out vec3 out_normal; +layout(location = 2) out vec2 out_tex_coord; layout(set = 0, binding = 0) uniform global_object_uniform { mat4 projection; @@ -19,8 +21,9 @@ layout(push_constant) uniform push_constants { u_push_constants; void main() { - 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 + out_position = in_position; + out_normal = in_normal; + out_tex_coord = in_tex_coord; } \ No newline at end of file diff --git a/examples/input/ex_input.c b/examples/input/ex_input.c index 3101968..576b364 100644 --- a/examples/input/ex_input.c +++ b/examples/input/ex_input.c @@ -30,6 +30,10 @@ int main() { .first_mouse_update = true, }; + // load a texture + texture tex = texture_data_load("assets/models/obj/cube/container.jpg", false); + texture_data_upload(&tex); + printf("Starting look direction: "); print_vec3(game.camera.front); @@ -65,7 +69,7 @@ int main() { mat4 model = mat4_translation(VEC3_ZERO); - gfx_backend_draw_frame(&core->renderer, &game.camera, model); + gfx_backend_draw_frame(&core->renderer, &game.camera, model, &tex); render_frame_end(&core->renderer); } diff --git a/src/colours.h b/src/colours.h index fa5f54b..a981c6c 100644 --- a/src/colours.h +++ b/src/colours.h @@ -38,3 +38,51 @@ typedef struct rgba { #define CYAN_800 ((rgba){ 0.082, 0.369, 0.459, 1.0 }) #define CYAN_900 ((rgba){ 0.086, 0.306, 0.388, 1.0 }) #define CYAN_950 ((rgba){ 0.033, 0.200, 0.263, 1.0 }) + +#define GRAY_50 ((rgba){ 0.976, 0.980, 0.984, 1.0 }) +#define GRAY_100 ((rgba){ 0.953, 0.957, 0.965, 1.0 }) +#define GRAY_200 ((rgba){ 0.898, 0.906, 0.922, 1.0 }) +#define GRAY_300 ((rgba){ 0.820, 0.835, 0.859, 1.0 }) +#define GRAY_400 ((rgba){ 0.612, 0.639, 0.686, 1.0 }) +#define GRAY_500 ((rgba){ 0.420, 0.447, 0.502, 1.0 }) +#define GRAY_600 ((rgba){ 0.294, 0.333, 0.388, 1.0 }) +#define GRAY_700 ((rgba){ 0.216, 0.255, 0.318, 1.0 }) +#define GRAY_800 ((rgba){ 0.122, 0.161, 0.216, 1.0 }) +#define GRAY_900 ((rgba){ 0.067, 0.094, 0.153, 1.0 }) +#define GRAY_950 ((rgba){ 0.012, 0.027, 0.071, 1.0 }) + +#define RED_50 ((rgba){ 0.996, 0.949, 0.949, 1.0 }) +#define RED_100 ((rgba){ 0.996, 0.886, 0.886, 1.0 }) +#define RED_200 ((rgba){ 0.996, 0.792, 0.792, 1.0 }) +#define RED_300 ((rgba){ 0.988, 0.647, 0.647, 1.0 }) +#define RED_400 ((rgba){ 0.973, 0.443, 0.443, 1.0 }) +#define RED_500 ((rgba){ 0.937, 0.267, 0.267, 1.0 }) +#define RED_600 ((rgba){ 0.863, 0.149, 0.149, 1.0 }) +#define RED_700 ((rgba){ 0.725, 0.110, 0.110, 1.0 }) +#define RED_800 ((rgba){ 0.600, 0.106, 0.106, 1.0 }) +#define RED_900 ((rgba){ 0.498, 0.114, 0.114, 1.0 }) +#define RED_950 ((rgba){ 0.271, 0.039, 0.039, 1.0 }) + +#define ORANGE_50 ((rgba){ 1.000, 0.969, 0.929, 1.0 }) +#define ORANGE_100 ((rgba){ 1.000, 0.929, 0.835, 1.0 }) +#define ORANGE_200 ((rgba){ 0.996, 0.843, 0.667, 1.0 }) +#define ORANGE_300 ((rgba){ 0.992, 0.729, 0.455, 1.0 }) +#define ORANGE_400 ((rgba){ 0.984, 0.573, 0.235, 1.0 }) +#define ORANGE_500 ((rgba){ 0.976, 0.451, 0.086, 1.0 }) +#define ORANGE_600 ((rgba){ 0.918, 0.345, 0.047, 1.0 }) +#define ORANGE_700 ((rgba){ 0.761, 0.255, 0.047, 1.0 }) +#define ORANGE_800 ((rgba){ 0.604, 0.204, 0.071, 1.0 }) +#define ORANGE_900 ((rgba){ 0.486, 0.176, 0.071, 1.0 }) +#define ORANGE_950 ((rgba){ 0.263, 0.078, 0.027, 1.0 }) + +#define AMBER_50 ((rgba){ 1.000, 0.984, 0.922, 1.0 }) +#define AMBER_100 ((rgba){ 0.996, 0.953, 0.780, 1.0 }) +#define AMBER_200 ((rgba){ 0.992, 0.902, 0.541, 1.0 }) +#define AMBER_300 ((rgba){ 0.988, 0.827, 0.302, 1.0 }) +#define AMBER_400 ((rgba){ 0.984, 0.749, 0.141, 1.0 }) +#define AMBER_500 ((rgba){ 0.961, 0.620, 0.043, 1.0 }) +#define AMBER_600 ((rgba){ 0.851, 0.467, 0.024, 1.0 }) +#define AMBER_700 ((rgba){ 0.706, 0.325, 0.035, 1.0 }) +#define AMBER_800 ((rgba){ 0.573, 0.251, 0.055, 1.0 }) +#define AMBER_900 ((rgba){ 0.471, 0.208, 0.059, 1.0 }) +#define AMBER_950 ((rgba){ 0.271, 0.102, 0.012, 1.0 }) diff --git a/src/maths/primitives.h b/src/maths/primitives.h index 4fb6b4d..b7fefa0 100644 --- a/src/maths/primitives.h +++ b/src/maths/primitives.h @@ -55,17 +55,17 @@ static mesh prim_cube_mesh_create() { // top faces vertex_darray_push(cube.vertices, - (vertex){ .position = BACK_TOP_LEFT, .normal = VEC3_Y, .uv = (vec2){ 0 } }); + (vertex){ .position = BACK_TOP_LEFT, .normal = VEC3_Y, .uv = (vec2){ 0, 0 } }); vertex_darray_push(cube.vertices, - (vertex){ .position = FRONT_TOP_LEFT, .normal = VEC3_Y, .uv = (vec2){ 0 } }); + (vertex){ .position = FRONT_TOP_LEFT, .normal = VEC3_Y, .uv = (vec2){ 0, 1 } }); vertex_darray_push(cube.vertices, - (vertex){ .position = FRONT_TOP_RIGHT, .normal = VEC3_Y, .uv = (vec2){ 0 } }); + (vertex){ .position = FRONT_TOP_RIGHT, .normal = VEC3_Y, .uv = (vec2){ 1, 1 } }); vertex_darray_push(cube.vertices, - (vertex){ .position = BACK_TOP_LEFT, .normal = VEC3_Y, .uv = (vec2){ 0 } }); + (vertex){ .position = BACK_TOP_LEFT, .normal = VEC3_Y, .uv = (vec2){ 0, 0 } }); vertex_darray_push(cube.vertices, - (vertex){ .position = FRONT_TOP_RIGHT, .normal = VEC3_Y, .uv = (vec2){ 0 } }); + (vertex){ .position = FRONT_TOP_RIGHT, .normal = VEC3_Y, .uv = (vec2){ 1, 1 } }); vertex_darray_push(cube.vertices, - (vertex){ .position = BACK_TOP_RIGHT, .normal = VEC3_Y, .uv = (vec2){ 0 } }); + (vertex){ .position = BACK_TOP_RIGHT, .normal = VEC3_Y, .uv = (vec2){ 1, 0 } }); // bottom faces vertex_darray_push( @@ -89,17 +89,17 @@ static mesh prim_cube_mesh_create() { // right faces vertex_darray_push(cube.vertices, - (vertex){ .position = FRONT_TOP_RIGHT, .normal = VEC3_X, .uv = (vec2){ 0 } }); + (vertex){ .position = FRONT_TOP_RIGHT, .normal = VEC3_X, .uv = (vec2){ 0, 0 } }); vertex_darray_push(cube.vertices, - (vertex){ .position = BACK_BOT_RIGHT, .normal = VEC3_X, .uv = (vec2){ 0 } }); + (vertex){ .position = BACK_BOT_RIGHT, .normal = VEC3_X, .uv = (vec2){ 1, 1 } }); vertex_darray_push(cube.vertices, - (vertex){ .position = BACK_TOP_RIGHT, .normal = VEC3_X, .uv = (vec2){ 0 } }); + (vertex){ .position = BACK_TOP_RIGHT, .normal = VEC3_X, .uv = (vec2){ 1, 0 } }); vertex_darray_push(cube.vertices, - (vertex){ .position = BACK_BOT_RIGHT, .normal = VEC3_X, .uv = (vec2){ 0 } }); + (vertex){ .position = BACK_BOT_RIGHT, .normal = VEC3_X, .uv = (vec2){ 1,1 } }); vertex_darray_push(cube.vertices, - (vertex){ .position = FRONT_TOP_RIGHT, .normal = VEC3_X, .uv = (vec2){ 0 } }); + (vertex){ .position = FRONT_TOP_RIGHT, .normal = VEC3_X, .uv = (vec2){ 0, 0 } }); vertex_darray_push(cube.vertices, - (vertex){ .position = FRONT_BOT_RIGHT, .normal = VEC3_X, .uv = (vec2){ 0 } }); + (vertex){ .position = FRONT_BOT_RIGHT, .normal = VEC3_X, .uv = (vec2){ 0, 1 } }); // left faces vertex_darray_push( diff --git a/src/renderer/backends/backend_opengl.c b/src/renderer/backends/backend_opengl.c index a9f7482..e3a4fb6 100644 --- a/src/renderer/backends/backend_opengl.c +++ b/src/renderer/backends/backend_opengl.c @@ -60,7 +60,7 @@ void clear_screen(vec3 colour) { glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); } -void texture_data_upload(texture* tex) { +void texture_data_upload(texture *tex) { printf("Texture name %s\n", tex->name); TRACE("Upload texture data"); u32 texture_id; diff --git a/src/renderer/backends/backend_vulkan.c b/src/renderer/backends/backend_vulkan.c index 9d0ef51..e0b0e4e 100644 --- a/src/renderer/backends/backend_vulkan.c +++ b/src/renderer/backends/backend_vulkan.c @@ -145,6 +145,22 @@ typedef struct global_object_uniform { f32 padding[32]; } global_object_uniform; +typedef struct object_uniform { + vec4 diffuse_colour; + vec4 v_reserved0; + vec4 v_reserved1; + vec4 v_reserved2; +} object_uniform; + +#define MAX_OBJECT_COUNT 1024 +#define VULKAN_OBJECT_SHADER_DESCRIPTOR_COUNT 1 + +typedef struct geometry_render_data { + u32 id; + mat4 model; + texture* textures[16]; +} geometry_render_data; + typedef struct vulkan_buffer { u64 total_size; VkBuffer handle; @@ -171,6 +187,8 @@ typedef struct vulkan_shader { // Data that's global for all objects drawn global_object_uniform global_ubo; + object_uniform object_ubo; + vulkan_texture_data* texture_data; } vulkan_shader; typedef struct vulkan_context { @@ -324,7 +342,7 @@ bool vulkan_graphics_pipeline_create(vulkan_context* context, vulkan_renderpass* // Vertex input VkVertexInputBindingDescription binding_desc; binding_desc.binding = 0; - binding_desc.stride = sizeof(vertex_pos); + binding_desc.stride = sizeof(vertex); binding_desc.inputRate = VK_VERTEX_INPUT_RATE_VERTEX; VkPipelineVertexInputStateCreateInfo vertex_input_info = { @@ -436,6 +454,8 @@ bool vulkan_buffer_create(vulkan_context* context, u64 size, VkBufferUsageFlagBi vulkan_buffer_bind(context, out_buffer, 0); } + DEBUG("Created buffer."); + return true; } @@ -512,11 +532,21 @@ bool vulkan_object_shader_create(vulkan_context* context, vulkan_shader* out_sha global_ubo_layout_binding.pImmutableSamplers = 0; global_ubo_layout_binding.stageFlags = VK_SHADER_STAGE_VERTEX_BIT; + VkDescriptorSetLayoutBinding sampler_layout_binding; + sampler_layout_binding.binding = 1; + sampler_layout_binding.descriptorCount = 1; + sampler_layout_binding.descriptorType = VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER; + sampler_layout_binding.pImmutableSamplers = 0; + sampler_layout_binding.stageFlags = VK_SHADER_STAGE_FRAGMENT_BIT; + VkDescriptorSetLayoutCreateInfo global_layout_info = { VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO }; - global_layout_info.bindingCount = 1; - global_layout_info.pBindings = &global_ubo_layout_binding; + + VkDescriptorSetLayoutBinding bindings[2] = { global_ubo_layout_binding, sampler_layout_binding }; + + global_layout_info.bindingCount = 2; + global_layout_info.pBindings = bindings; VK_CHECK(vkCreateDescriptorSetLayout(context->device.logical_device, &global_layout_info, context->allocator, &out_shader->descriptor_set_layout)); @@ -525,9 +555,15 @@ bool vulkan_object_shader_create(vulkan_context* context, vulkan_shader* out_sha global_pool_size.type = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER; global_pool_size.descriptorCount = 3; + VkDescriptorPoolSize sampler_pool_size; + sampler_pool_size.type = VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER; + sampler_pool_size.descriptorCount = 3; + + VkDescriptorPoolSize pool_sizes[2] = { global_pool_size, sampler_pool_size }; + VkDescriptorPoolCreateInfo pool_info = { VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_CREATE_INFO }; - pool_info.poolSizeCount = 1; - pool_info.pPoolSizes = &global_pool_size; + pool_info.poolSizeCount = 2; + pool_info.pPoolSizes = pool_sizes; pool_info.maxSets = 3; VK_CHECK(vkCreateDescriptorPool(context->device.logical_device, &pool_info, context->allocator, @@ -549,12 +585,13 @@ bool vulkan_object_shader_create(vulkan_context* context, vulkan_shader* out_sha // Attributes u32 offset = 0; - const i32 attribute_count = 2; - VkVertexInputAttributeDescription attribute_descs[2]; + const i32 attribute_count = 3; + VkVertexInputAttributeDescription attribute_descs[3]; // Position - VkFormat formats[2] = { VK_FORMAT_R32G32B32_SFLOAT, VK_FORMAT_R32G32B32_SFLOAT }; + VkFormat formats[3] = { VK_FORMAT_R32G32B32_SFLOAT, VK_FORMAT_R32G32B32_SFLOAT, + VK_FORMAT_R32G32_SFLOAT }; - u64 sizes[2] = { sizeof(vec3), sizeof(vec3) }; + u64 sizes[3] = { sizeof(vec3), sizeof(vec3), sizeof(vec2) }; for (u32 i = 0; i < attribute_count; i++) { attribute_descs[i].binding = 0; @@ -629,15 +666,30 @@ void vulkan_object_shader_update_global_state(vulkan_context* context, vulkan_sh buffer_info.offset = offset; buffer_info.range = range; - VkWriteDescriptorSet descriptor_write = { VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET }; - descriptor_write.dstSet = shader->descriptor_sets[image_index]; - descriptor_write.dstBinding = 0; - descriptor_write.dstArrayElement = 0; - descriptor_write.descriptorType = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER; - descriptor_write.descriptorCount = 1; - descriptor_write.pBufferInfo = &buffer_info; + VkDescriptorImageInfo image_info; + image_info.imageLayout = VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL; + image_info.imageView = shader->texture_data->image.view; + image_info.sampler = shader->texture_data->sampler; + + VkWriteDescriptorSet uniform_write = { VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET }; + uniform_write.dstSet = shader->descriptor_sets[image_index]; + uniform_write.dstBinding = 0; + uniform_write.dstArrayElement = 0; + uniform_write.descriptorType = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER; + uniform_write.descriptorCount = 1; + uniform_write.pBufferInfo = &buffer_info; + + VkWriteDescriptorSet texture_write = { VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET }; + texture_write.dstSet = shader->descriptor_sets[image_index]; + texture_write.dstBinding = 1; + texture_write.dstArrayElement = 0; + texture_write.descriptorType = VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER; + texture_write.descriptorCount = 1; + texture_write.pImageInfo = &image_info; - vkUpdateDescriptorSets(context->device.logical_device, 1, &descriptor_write, 0, 0); + VkWriteDescriptorSet writes[2] = { uniform_write, texture_write }; + + vkUpdateDescriptorSets(context->device.logical_device, 2, writes, 0, 0); vkCmdBindDescriptorSets(cmd_buffer, VK_PIPELINE_BIND_POINT_GRAPHICS, shader->pipeline.layout, 0, 1, &global_descriptors, 0, 0); @@ -867,15 +919,10 @@ void vulkan_image_view_create(vulkan_context* context, VkFormat format, vulkan_i &image->view); } -void vulkan_image_transition_layout( - vulkan_context* context, - vulkan_command_buffer* command_buffer, - vulkan_image* image, - VkFormat format, - VkImageLayout old_layout, - VkImageLayout new_layout -) { - VkImageMemoryBarrier barrier = {VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER}; +void vulkan_image_transition_layout(vulkan_context* context, vulkan_command_buffer* command_buffer, + vulkan_image* image, VkFormat format, VkImageLayout old_layout, + VkImageLayout new_layout) { + VkImageMemoryBarrier barrier = { VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER }; barrier.oldLayout = old_layout; barrier.newLayout = new_layout; barrier.srcQueueFamilyIndex = context->device.graphics_queue_index; @@ -892,12 +939,16 @@ void vulkan_image_transition_layout( VkPipelineStageFlags source_stage; VkPipelineStageFlags dest_stage; - if (old_layout == VK_IMAGE_LAYOUT_UNDEFINED && new_layout == VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL) { + if (old_layout == VK_IMAGE_LAYOUT_UNDEFINED && + new_layout == VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL) { barrier.srcAccessMask = 0; barrier.dstAccessMask = VK_ACCESS_TRANSFER_WRITE_BIT; + source_stage = VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT; - dest_stage = VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT; - } else if (old_layout == VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL && new_layout == VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL) { + dest_stage = VK_PIPELINE_STAGE_TRANSFER_BIT; + + } else if (old_layout == VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL && + new_layout == VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL) { barrier.srcAccessMask = VK_ACCESS_TRANSFER_WRITE_BIT; barrier.dstAccessMask = VK_ACCESS_SHADER_READ_BIT; source_stage = VK_PIPELINE_STAGE_TRANSFER_BIT; @@ -907,25 +958,30 @@ void vulkan_image_transition_layout( return; } - vkCmdPipelineBarrier(command_buffer->handle, source_stage, dest_stage, 0, 0, 0, 0, 0, 1, &barrier); + vkCmdPipelineBarrier(command_buffer->handle, source_stage, dest_stage, 0, 0, 0, 0, 0, 1, + &barrier); } -void vulkan_image_copy_from_buffer( - vulkan_image* image, - VkBuffer buffer, - vulkan_command_buffer* command_buffer -) { +void vulkan_image_copy_from_buffer(vulkan_image* image, VkBuffer buffer, + vulkan_command_buffer* command_buffer) { VkBufferImageCopy region; region.bufferOffset = 0; + region.bufferRowLength = 0; + region.bufferImageHeight = 0; region.imageSubresource.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT; region.imageSubresource.mipLevel = 0; region.imageSubresource.baseArrayLayer = 0; region.imageSubresource.layerCount = 1; + printf("Image details width: %d height %d\n", image->width, image->height); + region.imageOffset.x = 0; + region.imageOffset.y = 0; + region.imageOffset.z = 0; region.imageExtent.width = image->width; region.imageExtent.height = image->height; region.imageExtent.depth = 1; - vkCmdCopyBufferToImage(command_buffer->handle, buffer, image->handle, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, 1, ®ion); + vkCmdCopyBufferToImage(command_buffer->handle, buffer, image->handle, + VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, 1, ®ion); } void vulkan_image_create(vulkan_context* context, VkImageType image_type, u32 width, u32 height, @@ -942,7 +998,7 @@ void vulkan_image_create(vulkan_context* context, VkImageType image_type, u32 wi image_create_info.extent.width = width; image_create_info.extent.height = height; image_create_info.extent.depth = 1; - image_create_info.mipLevels = 4; + image_create_info.mipLevels = 1; image_create_info.arrayLayers = 1; image_create_info.format = format; image_create_info.tiling = tiling; @@ -951,8 +1007,8 @@ void vulkan_image_create(vulkan_context* context, VkImageType image_type, u32 wi image_create_info.samples = VK_SAMPLE_COUNT_1_BIT; image_create_info.sharingMode = VK_SHARING_MODE_EXCLUSIVE; - vkCreateImage(context->device.logical_device, &image_create_info, context->allocator, - &out_image->handle); + VK_CHECK(vkCreateImage(context->device.logical_device, &image_create_info, context->allocator, + &out_image->handle)); VkMemoryRequirements memory_reqs; vkGetImageMemoryRequirements(context->device.logical_device, out_image->handle, &memory_reqs); @@ -1649,12 +1705,13 @@ bool gfx_backend_init(renderer* ren) { mesh cube = prim_cube_mesh_create(); - vertex_pos* verts = malloc(sizeof(vertex_pos) * cube.vertices->len); + vertex* verts = malloc(sizeof(vertex) * cube.vertices->len); f32 scale = 3.0; for (size_t i = 0; i < cube.vertices->len; i++) { - verts[i].pos = vec3_mult(cube.vertices->data[i].position, scale); + verts[i].position = vec3_mult(cube.vertices->data[i].position, scale); verts[i].normal = cube.vertices->data[i].normal; + verts[i].uv = cube.vertices->data[i].uv; } // const f32 s = 1.0; @@ -1677,14 +1734,16 @@ bool gfx_backend_init(renderer* ren) { // 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) * cube.vertices->len, - verts); + &context.object_vertex_buffer, 0, sizeof(vertex) * 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) * cube.indices_len, cube.indices); TRACE("Uploaded index data"); vertex_darray_free(cube.vertices); free(cube.indices); + + // upload texture + // --- End test code INFO("Vulkan renderer initialisation succeeded"); @@ -1750,32 +1809,46 @@ void texture_data_upload(texture* tex) { printf("Texture name %s\n", tex->name); tex->backend_data = malloc(sizeof(vulkan_texture_data)); vulkan_texture_data* data = (vulkan_texture_data*)tex->backend_data; - VkDeviceSize image_size = tex->width * tex->height * tex->channel_count; + printf("Texture (%s) details: \n width %d\n height %d\n channel count %d\n", tex->name, + tex->width, tex->height, tex->channel_count); + VkDeviceSize image_size = tex->width * tex->height * max(tex->channel_count, 4); - VkFormat image_format = VK_FORMAT_R8G8B8A8_SNORM; + TRACE("Creating buffer of size %ld", image_size); + + VkFormat image_format = VK_FORMAT_R8G8B8A8_SRGB; VkBufferUsageFlags usage = VK_BUFFER_USAGE_TRANSFER_SRC_BIT; - VkMemoryPropertyFlags memory_prop_flags = VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT | VK_MEMORY_PROPERTY_HOST_COHERENT_BIT; + VkMemoryPropertyFlags memory_prop_flags = + VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT | VK_MEMORY_PROPERTY_HOST_COHERENT_BIT; vulkan_buffer staging; vulkan_buffer_create(&context, image_size, usage, memory_prop_flags, true, &staging); + DEBUG("Uploading image data"); vulkan_buffer_load_data(&context, &staging, 0, image_size, 0, tex->image_data); + INFO("Loaded iamge data!"); - vulkan_image_create(&context, VK_IMAGE_TYPE_2D, tex->width, tex->height, image_format, VK_IMAGE_TILING_OPTIMAL, - VK_IMAGE_USAGE_TRANSFER_SRC_BIT | VK_IMAGE_USAGE_TRANSFER_DST_BIT | VK_IMAGE_USAGE_SAMPLED_BIT | VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT - , VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT, true, VK_IMAGE_ASPECT_COLOR_BIT, &data->image); + vulkan_image_create( + &context, VK_IMAGE_TYPE_2D, tex->width, tex->height, image_format, VK_IMAGE_TILING_OPTIMAL, + VK_IMAGE_USAGE_TRANSFER_SRC_BIT | VK_IMAGE_USAGE_TRANSFER_DST_BIT | + VK_IMAGE_USAGE_SAMPLED_BIT | VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT, + VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT, true, VK_IMAGE_ASPECT_COLOR_BIT, &data->image); vulkan_command_buffer temp_buffer; - vulkan_command_buffer_allocate_and_begin_oneshot(&context, context.device.gfx_command_pool, &temp_buffer); + vulkan_command_buffer_allocate_and_begin_oneshot(&context, context.device.gfx_command_pool, + &temp_buffer); - vulkan_image_transition_layout(&context, &temp_buffer, &data->image, image_format, VK_IMAGE_LAYOUT_UNDEFINED, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL); + vulkan_image_transition_layout(&context, &temp_buffer, &data->image, image_format, + VK_IMAGE_LAYOUT_UNDEFINED, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL); vulkan_image_copy_from_buffer(&data->image, staging.handle, &temp_buffer); - vulkan_image_transition_layout(&context, &temp_buffer, &data->image, image_format, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL); + vulkan_image_transition_layout(&context, &temp_buffer, &data->image, image_format, + VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, + VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL); - vulkan_command_buffer_end_oneshot(&context, context.device.gfx_command_pool, &temp_buffer, context.device.graphics_queue); + vulkan_command_buffer_end_oneshot(&context, context.device.gfx_command_pool, &temp_buffer, + context.device.graphics_queue); - VkSamplerCreateInfo sampler_info = {VK_STRUCTURE_TYPE_SAMPLER_CREATE_INFO}; + VkSamplerCreateInfo sampler_info = { VK_STRUCTURE_TYPE_SAMPLER_CREATE_INFO }; sampler_info.magFilter = VK_FILTER_LINEAR; sampler_info.minFilter = VK_FILTER_LINEAR; sampler_info.addressModeU = VK_SAMPLER_ADDRESS_MODE_REPEAT; @@ -1792,12 +1865,14 @@ void texture_data_upload(texture* tex) { sampler_info.minLod = 0.0; sampler_info.maxLod = 0.0; - VkResult res = vkCreateSampler(context.device.logical_device, &sampler_info, context.allocator, &data->sampler); + VkResult res = vkCreateSampler(context.device.logical_device, &sampler_info, context.allocator, + &data->sampler); if (res != VK_SUCCESS) { ERROR("Error creating texture sampler for image %s", tex->name); return; } - + + tex->image_data = (void*)data; } // TODO: destroy texture @@ -1840,7 +1915,7 @@ 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, camera* cam, mat4 model) { +void gfx_backend_draw_frame(renderer* ren, camera* cam, mat4 model, texture* tex) { backend_begin_frame(ren, 16.0); mat4 proj; @@ -1848,7 +1923,9 @@ void gfx_backend_draw_frame(renderer* ren, camera* cam, mat4 model) { camera_view_projection(cam, SCR_HEIGHT, SCR_WIDTH, &view, &proj); + context.object_shader.texture_data = (vulkan_texture_data*)tex->image_data; 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); diff --git a/src/renderer/render.c b/src/renderer/render.c index 9dc47c2..ebade4f 100644 --- a/src/renderer/render.c +++ b/src/renderer/render.c @@ -224,7 +224,7 @@ texture texture_data_load(const char* path, bool invert_y) { stbi_set_flip_vertically_on_load(invert_y); #pragma GCC diagnostic ignored "-Wpointer-sign" - char* data = stbi_load(path, &width, &height, &num_channels, 0); + char* data = stbi_load(path, &width, &height, &num_channels, STBI_rgb_alpha); if (data) { DEBUG("loaded texture: %s", path); } else { diff --git a/src/renderer/render_backend.h b/src/renderer/render_backend.h index af62f9f..da30bcc 100644 --- a/src/renderer/render_backend.h +++ b/src/renderer/render_backend.h @@ -13,7 +13,7 @@ bool gfx_backend_init(renderer* ren); void gfx_backend_shutdown(renderer* ren); -void gfx_backend_draw_frame(renderer* ren, camera* camera, mat4 model); +void gfx_backend_draw_frame(renderer* ren, camera* camera, mat4 model, texture* tex); void gfx_backend_update_global_state(mat4 projection, mat4 view, vec3 view_pos, vec4 ambient_colour, i32 mode); -- cgit v1.2.3-70-g09d2