diff options
-rw-r--r-- | assets/shaders/object.frag | 5 | ||||
-rw-r--r-- | assets/shaders/object.vert | 10 | ||||
-rw-r--r-- | examples/gltf_loading/ex_gltf_loading.c | 0 | ||||
-rw-r--r-- | examples/input/ex_input.c | 10 | ||||
-rw-r--r-- | src/maths/maths.h | 19 | ||||
-rw-r--r-- | src/maths/primitives.h | 67 | ||||
-rw-r--r-- | src/renderer/backends/backend_vulkan.c | 62 | ||||
-rw-r--r-- | src/renderer/cleanroom/types.h | 7 |
8 files changed, 149 insertions, 31 deletions
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 --- /dev/null +++ b/examples/gltf_loading/ex_gltf_loading.c 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 <assert.h> +#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(); |