diff options
author | omniscient <17525998+omnisci3nce@users.noreply.github.com> | 2024-10-17 21:44:44 +1100 |
---|---|---|
committer | omniscient <17525998+omnisci3nce@users.noreply.github.com> | 2024-10-17 21:44:44 +1100 |
commit | 70175cfce551a6b534771bd2b1dea6cfb417be1f (patch) | |
tree | f29381cde897b024ecb781ff63cd75c3a16f6434 /src | |
parent | a5f1733a09aa99379cf48ed326b4660fbc17cb25 (diff) |
starting on cube
Diffstat (limited to 'src')
-rw-r--r-- | src/backend_mtl.m | 61 | ||||
-rw-r--r-- | src/core.c | 9 | ||||
-rw-r--r-- | src/geometry.c | 88 | ||||
-rw-r--r-- | src/impl.c | 4 | ||||
-rw-r--r-- | src/maths.c | 2 |
5 files changed, 162 insertions, 2 deletions
diff --git a/src/backend_mtl.m b/src/backend_mtl.m index 6ff5058..48e0ab0 100644 --- a/src/backend_mtl.m +++ b/src/backend_mtl.m @@ -2,18 +2,20 @@ #ifdef GPU_METAL -#define MTL_DEBUG_LAYER 1 +#define MTL_DEBUG_LAYER 1 // enable all metal validation layers // Obj-C imports #import <Foundation/Foundation.h> #import <Metal/Metal.h> #import <MetalKit/MetalKit.h> #import <QuartzCore/CAMetalLayer.h> +#include <CoreGraphics/CGGeometry.h> #define GLFW_INCLUDE_NONE #import <GLFW/glfw3.h> #define GLFW_EXPOSE_NATIVE_COCOA #import <GLFW/glfw3native.h> +#include "stb_image.h" NAMESPACED_LOGGER(metal); @@ -37,7 +39,12 @@ typedef struct metal_buffer { id<MTLBuffer> id; } metal_buffer; +typedef struct metal_texture { + id<MTLTexture> id; +} metal_texture; + TYPED_POOL(metal_buffer, buf); +TYPED_POOL(metal_texture, tex); TYPED_POOL(metal_pipeline, pipeline); typedef struct metal_context { @@ -53,6 +60,7 @@ typedef struct metal_context { /* pools */ buf_pool bufpool; + tex_pool texpool; pipeline_pool psopool; // pso = pipeline state object } metal_context; @@ -66,15 +74,18 @@ void ral_backend_init(const char* window_name, struct GLFWwindow* window) { ctx.device = gpu; TRACE("window init"); - glfwWindowHint(GLFW_CLIENT_API, GLFW_NO_API); glfwMakeContextCurrent(window); NSWindow* nswindow = glfwGetCocoaWindow(window); ctx.metal_window = nswindow; + int width, height; + glfwGetFramebufferSize(window, &width, &height); + // effectively the "framebuffer" CAMetalLayer* metal_layer = [CAMetalLayer layer]; metal_layer.device = gpu; metal_layer.pixelFormat = MTLPixelFormatBGRA8Unorm; + metal_layer.drawableSize = CGSizeMake(width, height); ctx.metal_window.contentView.layer = metal_layer; ctx.metal_window.contentView.wantsLayer = true; ctx.default_swapchain.swapchain = metal_layer; @@ -87,6 +98,9 @@ void ral_backend_init(const char* window_name, struct GLFWwindow* window) { metal_buffer* buffer_storage = malloc(sizeof(metal_buffer) * 100); ctx.bufpool = buf_pool_create(buffer_storage, 100, sizeof(metal_buffer)); + metal_texture* texture_storage = malloc(sizeof(metal_texture) * 100); + ctx.texpool = tex_pool_create(texture_storage, 100, sizeof(metal_texture)); + metal_pipeline* pipeline_storage = malloc(sizeof(metal_pipeline) * 100); ctx.psopool = pipeline_pool_create(pipeline_storage, 100, sizeof(metal_pipeline)); @@ -114,6 +128,39 @@ buf_handle ral_buffer_create(u64 size, const void *data) { return handle; } +tex_handle ral_texture_create(texture_desc desc, bool create_view, const void *data) { + tex_handle handle; + metal_texture* texture = tex_pool_alloc(&ctx.texpool, &handle); + + MTLTextureDescriptor* texture_descriptor = [[MTLTextureDescriptor alloc] init]; + [texture_descriptor setPixelFormat:MTLPixelFormatRGBA8Unorm]; + [texture_descriptor setWidth:desc.width]; + [texture_descriptor setHeight:desc.height]; + + texture->id = [ctx.device newTextureWithDescriptor:texture_descriptor]; + + MTLRegion region = MTLRegionMake2D(0, 0, desc.width, desc.height); + u32 bytes_per_row = 4 * desc.width; + + [texture->id replaceRegion:region mipmapLevel:0 withBytes:data bytesPerRow:bytes_per_row]; + + [texture_descriptor release]; + + return handle; +} + +tex_handle ral_texture_load_from_file(const char* filepath) { + texture_desc desc; + + stbi_set_flip_vertically_on_load(true); + unsigned char* image = stbi_load(filepath, &desc.width, &desc.height, &desc.num_channels, STBI_rgb_alpha); + assert(image != NULL); + + tex_handle handle = ral_texture_create(desc, false, image); + stbi_image_free(image); + return handle; +} + pipeline_handle ral_gfx_pipeline_create(gfx_pipeline_desc desc) { TRACE("creating graphics pipeline"); @@ -187,6 +234,11 @@ void ral_encode_set_vertex_buf(gpu_encoder *enc, buf_handle vbuf) { [enc->cmd_encoder setVertexBuffer:b->id offset:0 atIndex:0 ]; } +void ral_encode_set_texture(gpu_encoder* enc, tex_handle texture, u32 slot) { + metal_texture* t = tex_pool_get(&ctx.texpool, texture); + [enc->cmd_encoder setFragmentTexture:t->id atIndex:slot]; +} + void ral_encode_draw_tris(gpu_encoder* enc, size_t start, size_t count) { MTLPrimitiveType tri_primitive = MTLPrimitiveTypeTriangle; [enc->cmd_encoder drawPrimitives:tri_primitive vertexStart:start vertexCount:count]; @@ -203,4 +255,9 @@ void ral_frame_draw(scoped_draw_commands draw_fn) { void ral_frame_end() {} +void ral_backend_resize_framebuffer(int width, int height) { + TRACE("resizing framebuffer"); + ctx.default_swapchain.swapchain.drawableSize = CGSizeMake((float)width, (float)height); +} + #endif
\ No newline at end of file @@ -2,6 +2,7 @@ #include <celeritas.h> #include <stdlib.h> +#include "glfw3.h" NAMESPACED_LOGGER(core); @@ -15,6 +16,7 @@ static const char* gapi = "Vulkan"; // forward declares void key_callback(GLFWwindow* win, int key, int scancode, int action, int mods); +void resize_callback(GLFWwindow* win, int width, int height); void core_bringup(const char* window_name, struct GLFWwindow* optional_window) { INFO("Initiate Core bringup"); @@ -22,6 +24,8 @@ void core_bringup(const char* window_name, struct GLFWwindow* optional_window) { INFO("Create GLFW window"); glfwInit(); + glfwWindowHint(GLFW_CLIENT_API, GLFW_NO_API); + char* full_window_name = malloc(sizeof(char) * 100); int _offset = sprintf(full_window_name, "%s (%s)", window_name, gapi); @@ -32,6 +36,7 @@ void core_bringup(const char* window_name, struct GLFWwindow* optional_window) { ral_backend_init(window_name, glfw_window); glfwSetKeyCallback(glfw_window, key_callback); + glfwSetFramebufferSizeCallback(glfw_window, resize_callback); } void core_shutdown() { ral_backend_shutdown(); @@ -46,4 +51,8 @@ void key_callback(GLFWwindow* window, int key, int scancode, int action, int mod if (key == GLFW_KEY_ESCAPE && action == GLFW_RELEASE) { g_core.should_exit = true; } +} + +void resize_callback(GLFWwindow* window, int width, int height) { + ral_backend_resize_framebuffer(width, height); }
\ No newline at end of file diff --git a/src/geometry.c b/src/geometry.c new file mode 100644 index 0000000..d9b0aee --- /dev/null +++ b/src/geometry.c @@ -0,0 +1,88 @@ +#include <celeritas.h> + +typedef struct static_3d_vert { + vec4 pos; + vec4 norm; + vec2 uv; + vec2 pad; +} static_3d_vert; + +vertex_desc static_3d_vertex_format() { + vertex_desc desc; + desc.label = "Static 3D Vertex"; + desc.attributes[0] = ATTR_F32x4; // position + desc.attributes[1] = ATTR_F32x4; // normal + desc.attributes[2] = ATTR_F32x2; // tex coord + desc.attribute_count = 3; + desc.padding = 16; // 16 bytes padding + + return desc; +} + +geometry geo_cuboid(f32 x_scale, f32 y_scale, f32 z_scale) { + vec4 BACK_BOT_LEFT = (vec4){ 0, 0, 0, 0 }; + vec4 BACK_BOT_RIGHT = (vec4){ 1, 0, 0, 0 }; + vec4 BACK_TOP_LEFT = (vec4){ 0, 1, 0, 0 }; + vec4 BACK_TOP_RIGHT = (vec4){ 1, 1, 0, 0 }; + vec4 FRONT_BOT_LEFT = (vec4){ 0, 0, 1, 0 }; + vec4 FRONT_BOT_RIGHT = (vec4){ 1, 0, 1, 0 }; + vec4 FRONT_TOP_LEFT = (vec4){ 0, 1, 1, 0 }; + vec4 FRONT_TOP_RIGHT = (vec4){ 1, 1, 1, 0 }; + + // allocate the data + static_3d_vert* vertices = malloc(36 * 64); + + vertices[0] = (static_3d_vert){ .pos = BACK_TOP_RIGHT, .norm = (v3tov4(VEC3_NEG_Z)), .uv = {0, 0}}; + vertices[1] = (static_3d_vert){ .pos = BACK_BOT_LEFT, .norm = v3tov4(VEC3_NEG_Z), .uv = {0, 1} }; + vertices[2] = (static_3d_vert){ .pos = BACK_TOP_LEFT, .norm = v3tov4(VEC3_NEG_Z), .uv = {0, 0} }; + vertices[3] = (static_3d_vert){ .pos = BACK_TOP_RIGHT, .norm = v3tov4(VEC3_NEG_Z), .uv = {1, 0} }; + vertices[4] = (static_3d_vert){ .pos = BACK_BOT_RIGHT, .norm = v3tov4(VEC3_NEG_Z), .uv = {1, 1} }; + vertices[5] = (static_3d_vert){ .pos = BACK_BOT_LEFT, .norm = v3tov4(VEC3_NEG_Z), .uv = {0, 1} }; + + // front faces + vertices[6] = (static_3d_vert){ .pos = FRONT_BOT_LEFT, .norm = v3tov4(VEC3_Z), .uv = {0, 1} }; + vertices[7] = (static_3d_vert){ .pos = FRONT_TOP_RIGHT, .norm = v3tov4(VEC3_Z), .uv = {1, 0} }; + vertices[8] = (static_3d_vert){ .pos = FRONT_TOP_LEFT, .norm = v3tov4(VEC3_Z), .uv = {0, 0} }; + vertices[9] = (static_3d_vert){ .pos = FRONT_BOT_LEFT, .norm = v3tov4(VEC3_Z), .uv = {0, 1} }; + vertices[10] = (static_3d_vert){ .pos = FRONT_BOT_RIGHT, .norm = v3tov4(VEC3_Z), .uv = {1, 1} }; + vertices[11] = (static_3d_vert){ .pos = FRONT_TOP_RIGHT, .norm = v3tov4(VEC3_Z), .uv = {1, 0} }; + + // top faces + vertices[12] = (static_3d_vert){ .pos = BACK_TOP_LEFT, .norm = v3tov4(VEC3_Y), .uv = {0, 0} }; + vertices[13] = (static_3d_vert){ .pos = FRONT_TOP_LEFT, .norm = v3tov4(VEC3_Y), .uv = {0, 1} }; + vertices[14] = (static_3d_vert){ .pos = FRONT_TOP_RIGHT, .norm = v3tov4(VEC3_Y), .uv = {1, 1} }; + vertices[15] = (static_3d_vert){ .pos = BACK_TOP_LEFT, .norm = v3tov4(VEC3_Y), .uv = {0, 0} }; + vertices[16] = (static_3d_vert){ .pos = FRONT_TOP_RIGHT, .norm = v3tov4(VEC3_Y), .uv = {1, 1} }; + vertices[17] = (static_3d_vert){ .pos = BACK_TOP_RIGHT, .norm = v3tov4(VEC3_Y), .uv = {1, 0} }; + + // bottom faces + vertices[18] = (static_3d_vert){ .pos = BACK_BOT_LEFT, .norm = v3tov4(VEC3_NEG_Y), .uv = {0, 1} }; + vertices[19] = (static_3d_vert){ .pos = FRONT_BOT_RIGHT, .norm = v3tov4(VEC3_NEG_Y), .uv = {1, 1} }; + vertices[20] = (static_3d_vert){ .pos = FRONT_BOT_LEFT, .norm = v3tov4(VEC3_NEG_Y), .uv = {0, 1} }; + vertices[21] = (static_3d_vert){ .pos = BACK_BOT_LEFT, .norm = v3tov4(VEC3_NEG_Y), .uv = {0, 1} }; + vertices[22] = (static_3d_vert){ .pos = BACK_BOT_RIGHT, .norm = v3tov4(VEC3_NEG_Y), .uv = {1, 1} }; + vertices[23] = (static_3d_vert){ .pos = FRONT_BOT_RIGHT, .norm = v3tov4(VEC3_NEG_Y), .uv = {0, 1} }; + + // right faces + vertices[24] = (static_3d_vert){ .pos = FRONT_TOP_RIGHT, .norm = v3tov4(VEC3_X), .uv = {0, 0} }; + vertices[25] = (static_3d_vert){ .pos = BACK_BOT_RIGHT, .norm = v3tov4(VEC3_X), .uv = {1, 1} }; + vertices[26] = (static_3d_vert){ .pos = BACK_TOP_RIGHT, .norm = v3tov4(VEC3_X), .uv = {1, 0} }; + vertices[27] = (static_3d_vert){ .pos = BACK_BOT_RIGHT, .norm = v3tov4(VEC3_X), .uv = {1, 1} }; + vertices[28] = (static_3d_vert){ .pos = FRONT_TOP_RIGHT, .norm = v3tov4(VEC3_X), .uv = {0, 0} }; + vertices[29] = (static_3d_vert){ .pos = FRONT_BOT_RIGHT, .norm = v3tov4(VEC3_X), .uv = {0, 1} }; + + // left faces + vertices[30] = (static_3d_vert){ .pos = FRONT_TOP_LEFT, .norm = v3tov4(VEC3_NEG_X), .uv = {0, 0} }; + vertices[31] = (static_3d_vert){ .pos = BACK_TOP_LEFT, .norm = v3tov4(VEC3_NEG_X), .uv = {0, 0} }; + vertices[32] = (static_3d_vert){ .pos = BACK_BOT_LEFT, .norm = v3tov4(VEC3_NEG_X), .uv = {0, 0} }; + vertices[33] = (static_3d_vert){ .pos = BACK_BOT_LEFT, .norm = v3tov4(VEC3_NEG_X), .uv = {0, 0} }; + vertices[34] = (static_3d_vert){ .pos = FRONT_BOT_LEFT, .norm = v3tov4(VEC3_NEG_X), .uv = {0, 0} }; + vertices[35] = (static_3d_vert){ .pos = FRONT_TOP_LEFT, .norm = v3tov4(VEC3_NEG_X), .uv = {0, 0} }; + + return (geometry) { + .vertex_format = static_3d_vertex_format(), + .vertex_data = vertices, + .has_indices = false, + .indices = NULL + }; +}
\ No newline at end of file diff --git a/src/impl.c b/src/impl.c new file mode 100644 index 0000000..18f2549 --- /dev/null +++ b/src/impl.c @@ -0,0 +1,4 @@ +// For pulling in implementation files of single-header libraries + +#define STB_IMAGE_IMPLEMENTATION +#include "stb_image.h"
\ No newline at end of file diff --git a/src/maths.c b/src/maths.c index f12c852..95283e6 100644 --- a/src/maths.c +++ b/src/maths.c @@ -1,3 +1,5 @@ #include <celeritas.h> vec3 vec3_create(f32 x, f32 y, f32 z) { return (vec3){ x, y, z }; } + +vec4 vec4_create(f32 x, f32 y, f32 z, f32 w) { return (vec4){ x, y, z , w }; }
\ No newline at end of file |