bloat-buster/bootstrap/std/metal_rendering.c
2025-01-05 21:54:19 -06:00

149 lines
5.1 KiB
C

#pragma once
global_variable Renderer renderer_memory;
fn NSString* apple_string(String string)
{
NSString* result = [[NSString alloc] initWithBytes:string.pointer length:string.length encoding:NSUTF8StringEncoding];
return result;
}
fn Renderer* rendering_initialize(Arena* arena)
{
Renderer* renderer = &renderer_memory;
@autoreleasepool {
renderer->device = MTLCreateSystemDefaultDevice();
String shader_source = file_read(arena, strlit("bootstrap/std/shaders/rect.metal"));
NSString* apple_shader_source = apple_string(shader_source);
NSError* error = nil;
id<MTLLibrary> library = [renderer->device newLibraryWithSource: apple_shader_source options:nil error:&error];
if (!library)
{
// Inspect the error
NSLog(@"Error Domain: %@", error.domain);
NSLog(@"Error Code: %ld", (long)error.code);
NSLog(@"Localized Description: %@", error.localizedDescription);
NSDictionary *userInfo = error.userInfo;
if (userInfo) {
NSLog(@"Additional Info: %@", userInfo);
}
// Take action based on the error
if ([error.domain isEqualToString:MTLLibraryErrorDomain]) {
NSLog(@"Metal Library Compilation Error. Check the shader source.");
} else {
NSLog(@"Unexpected error occurred.");
}
}
id<MTLFunction> vertex = [library newFunctionWithName:@"vertex_main"];
id<MTLFunction> fragment = [library newFunctionWithName:@"fragment_main"];
MTLRenderPipelineDescriptor* pipeline_descriptor = [[MTLRenderPipelineDescriptor alloc] init];
pipeline_descriptor.vertexFunction = vertex;
pipeline_descriptor.fragmentFunction = fragment;
pipeline_descriptor.colorAttachments[0].pixelFormat = MTLPixelFormatBGRA8Unorm_sRGB;
id<MTLRenderPipelineState> pipeline_state = [renderer->device newRenderPipelineStateWithDescriptor:pipeline_descriptor error:&error];
if (!pipeline_state)
{
// Inspect the error
NSLog(@"Error Domain: %@", error.domain);
NSLog(@"Error Code: %ld", (long)error.code);
NSLog(@"Localized Description: %@", error.localizedDescription);
NSDictionary *userInfo = error.userInfo;
if (userInfo) {
NSLog(@"Additional Info: %@", userInfo);
}
}
id<MTLCommandQueue> command_queue = [renderer->device newCommandQueue];
}
return renderer;
}
global_variable RenderWindow render_window_memory;
fn RenderWindow* rendering_initialize_window(Renderer* renderer, WindowingInstance* window)
{
RenderWindow* render_window = &render_window_memory;
CAMetalLayer* layer = [CAMetalLayer layer];
render_window->layer = layer;
layer.device = renderer->device;
layer.pixelFormat = MTLPixelFormatBGRA8Unorm_sRGB;
layer.framebufferOnly = true;
layer.frame = window.frame;
window.contentView.layer = layer;
window.opaque = true;
window.backgroundColor = nil;
return render_window;
}
fn void renderer_window_frame_begin(Renderer* renderer, RenderWindow* window)
{
@autoreleasepool {
id<CAMetalDrawable> drawable = [window->layer nextDrawable];
MTLRenderPassDescriptor* render_pass_descriptor = [MTLRenderPassDescriptor renderPassDescriptor];
MTLRenderPassColorAttachmentDescriptor* color_attachment = render_pass_descriptor.colorAttachments[0];
color_attachment.clearColor = MTLClearColorMake(1, 1, 1, 1);
color_attachment.storeAction = MTLStoreActionStore;
color_attachment.texture = drawable.texture;
id<MTLCommandBuffer> command_buffer = [renderer->command_queue commandBuffer];
id<MTLRenderCommandEncoder> render_command_encoder = [command_buffer renderCommandEncoderWithDescriptor:render_pass_descriptor];
[render_command_encoder setRenderPipelineState: renderer->pipeline_state];
[render_command_encoder drawPrimitives:MTLPrimitiveTypeTriangle vertexStart:0 vertexCount:3];
[render_command_encoder endEncoding];
[command_buffer presentDrawable:drawable];
[command_buffer commit];
}
}
fn void renderer_window_frame_end(Renderer* renderer, RenderWindow* window)
{
// todo();
}
fn TextureIndex renderer_texture_create(Renderer* renderer, TextureMemory texture_memory)
{
todo();
}
fn void window_rect_texture_update_begin(RenderWindow* window)
{
todo();
}
fn void renderer_queue_font_update(Renderer* renderer, RenderWindow* window, RenderFontType type, TextureAtlas atlas)
{
todo();
}
fn void window_queue_rect_texture_update(RenderWindow* window, RectTextureSlot slot, TextureIndex texture_index)
{
todo();
}
fn void window_rect_texture_update_end(Renderer* renderer, RenderWindow* window)
{
todo();
}
fn void window_render_rect(RenderWindow* window, RectDraw draw)
{
// todo();
}
fn void window_render_text(Renderer* renderer, RenderWindow* window, String string, float4 color, RenderFontType font_type, u32 x_offset, u32 y_offset)
{
// todo();
}