summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authoromniscient <17525998+omnisci3nce@users.noreply.github.com>2024-10-17 21:44:44 +1100
committeromniscient <17525998+omnisci3nce@users.noreply.github.com>2024-10-17 21:44:44 +1100
commit70175cfce551a6b534771bd2b1dea6cfb417be1f (patch)
treef29381cde897b024ecb781ff63cd75c3a16f6434 /src
parenta5f1733a09aa99379cf48ed326b4660fbc17cb25 (diff)
starting on cube
Diffstat (limited to 'src')
-rw-r--r--src/backend_mtl.m61
-rw-r--r--src/core.c9
-rw-r--r--src/geometry.c88
-rw-r--r--src/impl.c4
-rw-r--r--src/maths.c2
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
diff --git a/src/core.c b/src/core.c
index 210c282..9359a6b 100644
--- a/src/core.c
+++ b/src/core.c
@@ -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