From 88c933acd2d3ca548bbc40057952f9ea2fd5a866 Mon Sep 17 00:00:00 2001 From: Yuval Dolev Date: Thu, 9 Jan 2020 02:36:37 +0200 Subject: [PATCH] Implemented the renderer abstraction for both OpenGL and Metal. --- metal/4ed_metal_render.mm | 2 - platform_mac/mac_4ed.mm | 8 +-- platform_mac/mac_4ed_metal.mm | 101 +++++++++++++++++++++---------- platform_mac/mac_4ed_opengl.mm | 43 +++++++------ platform_mac/mac_4ed_renderer.mm | 2 +- 5 files changed, 94 insertions(+), 62 deletions(-) diff --git a/metal/4ed_metal_render.mm b/metal/4ed_metal_render.mm index d5126396..3209e53e 100644 --- a/metal/4ed_metal_render.mm +++ b/metal/4ed_metal_render.mm @@ -259,8 +259,6 @@ metal__make_buffer(u32 size, id device){ } - (void)drawInMTKView:(nonnull MTKView*)view{ - printf("Metal Renderer Draw!\n"); - [capture_scope beginScope]; // HACK(yuval): This is the best way I found to force valid width and height without drawing on the next drawing cycle (1 frame delay). diff --git a/platform_mac/mac_4ed.mm b/platform_mac/mac_4ed.mm index 33f645f7..29465700 100644 --- a/platform_mac/mac_4ed.mm +++ b/platform_mac/mac_4ed.mm @@ -447,8 +447,6 @@ this only gets called for window creation and other extraordinary events. [NSApp terminate:nil]; } - //mac_gl_render(&target); - //mac_metal_render(&target); renderer->render(renderer, &target); mac_vars.first = false; @@ -663,7 +661,7 @@ main(int arg_count, char **args){ } // - // Window and GL View Initialization + // Window and Renderer Initialization // // NOTE(yuval): Create Window & Window Delegate @@ -707,9 +705,7 @@ main(int arg_count, char **args){ [mac_vars.window makeKeyAndOrderFront:nil]; // NOTE(yuval): Initialize the renderer - //mac_gl_init(mac_vars.window); - //mac_metal_init(mac_vars.window, &target); - renderer = mac_init_renderer(MacRenderer_OpenGL, mac_vars.window, &target); + renderer = mac_init_renderer(MacRenderer_Metal, mac_vars.window, &target); mac_resize(w, h); diff --git a/platform_mac/mac_4ed_metal.mm b/platform_mac/mac_4ed_metal.mm index ba44930b..117eec2d 100644 --- a/platform_mac/mac_4ed_metal.mm +++ b/platform_mac/mac_4ed_metal.mm @@ -1,50 +1,85 @@ +/* Mac Metal layer for 4coder */ + #import "metal/4ed_metal_render.mm" -global Metal_Renderer *metal_renderer; -global MTKView *metal_view; +//////////////////////////////// -function void -mac_metal_init(NSWindow *window, Render_Target *target){ - // NOTE(yuval): Create Metal view - NSView *content_view = [window contentView]; +struct Mac_Metal{ + Mac_Renderer base; - metal_view = [[MTKView alloc] initWithFrame:[content_view bounds]]; - [metal_view setAutoresizingMask:NSViewWidthSizable | NSViewHeightSizable]; - [metal_view setPaused:YES]; - [metal_view setEnableSetNeedsDisplay:NO]; - [metal_view setSampleCount:4]; + Metal_Renderer *renderer; + MTKView *view; +}; + +//////////////////////////////// + +function +mac_render_sig(mac_metal__render){ + printf("Rendering using Metal!\n"); - metal_view.device = MTLCreateSystemDefaultDevice(); - - // NOTE(yuval): Add the Metal view as a subview of the window - [content_view addSubview:metal_view]; - - // NOTE(yuval): Create the Metal renderer and set it as the Metal view's delegate - metal_renderer = [[Metal_Renderer alloc] initWithMetalKitView:metal_view]; - metal_view.delegate = metal_renderer; + Mac_Metal *metal = (Mac_Metal*)renderer; + metal->renderer.target = target; + [metal->view draw]; } -function void -mac_metal_render(Render_Target* target){ - metal_renderer.target = target; - [metal_view draw]; -} - -function u32 -mac_metal_get_texture(Vec3_i32 dim, Texture_Kind texture_kind){ - u32 result = [metal_renderer get_texture_of_dim:dim +function +mac_get_texture_sig(mac_metal__get_texture){ + Mac_Metal *metal = (Mac_Metal*)renderer; + u32 result = [metal->renderer get_texture_of_dim:dim kind:texture_kind]; - return result; + return(result); } -function b32 -mac_metal_fill_texture(Texture_Kind texture_kind, u32 texture, Vec3_i32 p, Vec3_i32 dim, void *data){ - b32 result = [metal_renderer fill_texture:texture +function +mac_fill_texture_sig(mac_metal__fill_texture){ + Mac_Metal *metal = (Mac_Metal*)renderer; + b32 result = [metal->renderer fill_texture:texture kind:texture_kind pos:p dim:dim data:data]; - return result; + return(result); +} + +function Mac_Metal* +mac_metal__init(NSWindow *window, Render_Target *target){ + // NOTE(yuval): Create the Mac Metal rendere + Mac_Metal *metal = (Mac_Metal*)system_memory_allocate(sizeof(Mac_Metal), + file_name_line_number_lit_u8); + metal->base.render = mac_metal__render; + metal->base.get_texture = mac_metal__get_texture; + metal->base.fill_texture = mac_metal__fill_texture; + + // NOTE(yuval): Create the Metal view + NSView *content_view = [window contentView]; + + metal->view = [[MTKView alloc] initWithFrame:[content_view bounds]]; + [metal->view setAutoresizingMask:NSViewWidthSizable | NSViewHeightSizable]; + [metal->view setPaused:YES]; + [metal->view setEnableSetNeedsDisplay:NO]; + [metal->view setSampleCount:4]; + + metal->view.device = MTLCreateSystemDefaultDevice(); + + // NOTE(yuval): Add the Metal view as a subview of the window + [content_view addSubview:metal->view]; + + // NOTE(yuval): Create the Metal renderer and set it as the Metal view's delegate + metal->renderer = [[Metal_Renderer alloc] initWithMetalKitView:metal->view]; + metal->view.delegate = metal->renderer; + + return(metal); +} + +//////////////////////////////// + +// TODO(yuval): This function should be exported to a DLL +function +mac_load_renderer_sig(mac_load_metal_renderer){ + printf("Loding The Metal Renderer!\n"); + + Mac_Renderer *renderer = (Mac_Renderer*)mac_metal__init(window, target); + return(renderer); } diff --git a/platform_mac/mac_4ed_opengl.mm b/platform_mac/mac_4ed_opengl.mm index 0a73c9c9..57dd3348 100644 --- a/platform_mac/mac_4ed_opengl.mm +++ b/platform_mac/mac_4ed_opengl.mm @@ -24,9 +24,10 @@ //////////////////////////////// -struct Mac_OpenGL_Renderer{ +struct Mac_OpenGL{ Mac_Renderer base; - OpenGL_View *opengl_view; + + OpenGL_View *view; }; //////////////////////////////// @@ -125,44 +126,44 @@ struct Mac_OpenGL_Renderer{ //////////////////////////////// function -mac_render_sig(mac_gl_render){ +mac_render_sig(mac_gl__render){ printf("Rendering using OpenGL!\n"); - Mac_OpenGL_Renderer *gl = (Mac_OpenGL_Renderer*)renderer; - [gl->opengl_view render:target]; + Mac_OpenGL *gl = (Mac_OpenGL*)renderer; + [gl->view render:target]; } function -mac_get_texture_sig(mac_gl_get_texture){ +mac_get_texture_sig(mac_gl__get_texture){ u32 result = gl__get_texture(dim, texture_kind); return(result); } function -mac_fill_texture_sig(mac_gl_fill_texture){ +mac_fill_texture_sig(mac_gl__fill_texture){ b32 result = gl__fill_texture(texture_kind, texture, p, dim, data); return(result); } -function Mac_OpenGL_Renderer* +function Mac_OpenGL* mac_gl__init(NSWindow *window, Render_Target *target){ - // NOTE(yuval): Create the Mac Renderer - Mac_OpenGL_Renderer *gl = (Mac_OpenGL_Renderer*)system_memory_allocate(sizeof(Mac_OpenGL_Renderer), - file_name_line_number_lit_u8); - gl->base.render = mac_gl_render; - gl->base.get_texture = mac_gl_get_texture; - gl->base.fill_texture = mac_gl_fill_texture; + // NOTE(yuval): Create the Mac OpenGL Renderer + Mac_OpenGL *gl = (Mac_OpenGL*)system_memory_allocate(sizeof(Mac_OpenGL), + file_name_line_number_lit_u8); + gl->base.render = mac_gl__render; + gl->base.get_texture = mac_gl__get_texture; + gl->base.fill_texture = mac_gl__fill_texture; // NOTE(yuval): Create the OpenGL view NSView *content_view = [window contentView]; - gl->opengl_view = [[OpenGL_View alloc] init]; - [gl->opengl_view setFrame:[content_view bounds]]; - [gl->opengl_view setAutoresizingMask:NSViewWidthSizable | NSViewHeightSizable]; - [gl->opengl_view setWantsBestResolutionOpenGLSurface:YES]; + gl->view = [[OpenGL_View alloc] init]; + [gl->view setFrame:[content_view bounds]]; + [gl->view setAutoresizingMask:NSViewWidthSizable | NSViewHeightSizable]; + [gl->view setWantsBestResolutionOpenGLSurface:YES]; // NOTE(yuval): Add the OpenGL view as a subview of the window - [content_view addSubview:gl->opengl_view]; + [content_view addSubview:gl->view]; // NOTE(yuval): Load gl functions void *gl_image = dlopen("/System/Library/Frameworks/OpenGL.framework/Versions/Current/OpenGL", RTLD_LAZY); @@ -173,10 +174,12 @@ mac_gl__init(NSWindow *window, Render_Target *target){ return(gl); } +//////////////////////////////// + // TODO(yuval): This function should be exported to a DLL function mac_load_renderer_sig(mac_load_opengl_renderer){ - printf("Initializing The OpenGL Renderer!\n"); + printf("Loding The OpenGL Renderer!\n"); Mac_Renderer *renderer = (Mac_Renderer*)mac_gl__init(window, target); return(renderer); diff --git a/platform_mac/mac_4ed_renderer.mm b/platform_mac/mac_4ed_renderer.mm index f1b18967..5b4e4015 100644 --- a/platform_mac/mac_4ed_renderer.mm +++ b/platform_mac/mac_4ed_renderer.mm @@ -18,7 +18,7 @@ mac_init_renderer(Mac_Renderer_Kind kind, NSWindow *window, Render_Target *targe case MacRenderer_Metal: { - //result = mac_load_metal_renderer(window, target); + result = mac_load_metal_renderer(window, target); } break; default: InvalidPath;