Implemented the renderer abstraction for both OpenGL and Metal.

master
Yuval Dolev 2020-01-09 02:36:37 +02:00
parent 912bcae8a7
commit 88c933acd2
5 changed files with 94 additions and 62 deletions

View File

@ -259,8 +259,6 @@ metal__make_buffer(u32 size, id<MTLDevice> device){
} }
- (void)drawInMTKView:(nonnull MTKView*)view{ - (void)drawInMTKView:(nonnull MTKView*)view{
printf("Metal Renderer Draw!\n");
[capture_scope beginScope]; [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). // 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).

View File

@ -447,8 +447,6 @@ this only gets called for window creation and other extraordinary events.
[NSApp terminate:nil]; [NSApp terminate:nil];
} }
//mac_gl_render(&target);
//mac_metal_render(&target);
renderer->render(renderer, &target); renderer->render(renderer, &target);
mac_vars.first = false; 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 // NOTE(yuval): Create Window & Window Delegate
@ -707,9 +705,7 @@ main(int arg_count, char **args){
[mac_vars.window makeKeyAndOrderFront:nil]; [mac_vars.window makeKeyAndOrderFront:nil];
// NOTE(yuval): Initialize the renderer // NOTE(yuval): Initialize the renderer
//mac_gl_init(mac_vars.window); renderer = mac_init_renderer(MacRenderer_Metal, mac_vars.window, &target);
//mac_metal_init(mac_vars.window, &target);
renderer = mac_init_renderer(MacRenderer_OpenGL, mac_vars.window, &target);
mac_resize(w, h); mac_resize(w, h);

View File

@ -1,50 +1,85 @@
/* Mac Metal layer for 4coder */
#import "metal/4ed_metal_render.mm" #import "metal/4ed_metal_render.mm"
global Metal_Renderer *metal_renderer; ////////////////////////////////
global MTKView *metal_view;
function void struct Mac_Metal{
mac_metal_init(NSWindow *window, Render_Target *target){ Mac_Renderer base;
// NOTE(yuval): Create Metal view
NSView *content_view = [window contentView];
metal_view = [[MTKView alloc] initWithFrame:[content_view bounds]]; Metal_Renderer *renderer;
[metal_view setAutoresizingMask:NSViewWidthSizable | NSViewHeightSizable]; MTKView *view;
[metal_view setPaused:YES]; };
[metal_view setEnableSetNeedsDisplay:NO];
[metal_view setSampleCount:4]; ////////////////////////////////
function
mac_render_sig(mac_metal__render){
printf("Rendering using Metal!\n");
metal_view.device = MTLCreateSystemDefaultDevice(); Mac_Metal *metal = (Mac_Metal*)renderer;
metal->renderer.target = target;
// NOTE(yuval): Add the Metal view as a subview of the window [metal->view draw];
[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;
} }
function void function
mac_metal_render(Render_Target* target){ mac_get_texture_sig(mac_metal__get_texture){
metal_renderer.target = target; Mac_Metal *metal = (Mac_Metal*)renderer;
[metal_view draw]; u32 result = [metal->renderer get_texture_of_dim:dim
}
function u32
mac_metal_get_texture(Vec3_i32 dim, Texture_Kind texture_kind){
u32 result = [metal_renderer get_texture_of_dim:dim
kind:texture_kind]; kind:texture_kind];
return result; return(result);
} }
function b32 function
mac_metal_fill_texture(Texture_Kind texture_kind, u32 texture, Vec3_i32 p, Vec3_i32 dim, void *data){ mac_fill_texture_sig(mac_metal__fill_texture){
b32 result = [metal_renderer fill_texture:texture Mac_Metal *metal = (Mac_Metal*)renderer;
b32 result = [metal->renderer fill_texture:texture
kind:texture_kind kind:texture_kind
pos:p pos:p
dim:dim dim:dim
data:data]; 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);
} }

View File

@ -24,9 +24,10 @@
//////////////////////////////// ////////////////////////////////
struct Mac_OpenGL_Renderer{ struct Mac_OpenGL{
Mac_Renderer base; Mac_Renderer base;
OpenGL_View *opengl_view;
OpenGL_View *view;
}; };
//////////////////////////////// ////////////////////////////////
@ -125,44 +126,44 @@ struct Mac_OpenGL_Renderer{
//////////////////////////////// ////////////////////////////////
function function
mac_render_sig(mac_gl_render){ mac_render_sig(mac_gl__render){
printf("Rendering using OpenGL!\n"); printf("Rendering using OpenGL!\n");
Mac_OpenGL_Renderer *gl = (Mac_OpenGL_Renderer*)renderer; Mac_OpenGL *gl = (Mac_OpenGL*)renderer;
[gl->opengl_view render:target]; [gl->view render:target];
} }
function 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); u32 result = gl__get_texture(dim, texture_kind);
return(result); return(result);
} }
function 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); b32 result = gl__fill_texture(texture_kind, texture, p, dim, data);
return(result); return(result);
} }
function Mac_OpenGL_Renderer* function Mac_OpenGL*
mac_gl__init(NSWindow *window, Render_Target *target){ mac_gl__init(NSWindow *window, Render_Target *target){
// NOTE(yuval): Create the Mac Renderer // NOTE(yuval): Create the Mac OpenGL Renderer
Mac_OpenGL_Renderer *gl = (Mac_OpenGL_Renderer*)system_memory_allocate(sizeof(Mac_OpenGL_Renderer), Mac_OpenGL *gl = (Mac_OpenGL*)system_memory_allocate(sizeof(Mac_OpenGL),
file_name_line_number_lit_u8); file_name_line_number_lit_u8);
gl->base.render = mac_gl_render; gl->base.render = mac_gl__render;
gl->base.get_texture = mac_gl_get_texture; gl->base.get_texture = mac_gl__get_texture;
gl->base.fill_texture = mac_gl_fill_texture; gl->base.fill_texture = mac_gl__fill_texture;
// NOTE(yuval): Create the OpenGL view // NOTE(yuval): Create the OpenGL view
NSView *content_view = [window contentView]; NSView *content_view = [window contentView];
gl->opengl_view = [[OpenGL_View alloc] init]; gl->view = [[OpenGL_View alloc] init];
[gl->opengl_view setFrame:[content_view bounds]]; [gl->view setFrame:[content_view bounds]];
[gl->opengl_view setAutoresizingMask:NSViewWidthSizable | NSViewHeightSizable]; [gl->view setAutoresizingMask:NSViewWidthSizable | NSViewHeightSizable];
[gl->opengl_view setWantsBestResolutionOpenGLSurface:YES]; [gl->view setWantsBestResolutionOpenGLSurface:YES];
// NOTE(yuval): Add the OpenGL view as a subview of the window // 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 // NOTE(yuval): Load gl functions
void *gl_image = dlopen("/System/Library/Frameworks/OpenGL.framework/Versions/Current/OpenGL", RTLD_LAZY); 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); return(gl);
} }
////////////////////////////////
// TODO(yuval): This function should be exported to a DLL // TODO(yuval): This function should be exported to a DLL
function function
mac_load_renderer_sig(mac_load_opengl_renderer){ 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); Mac_Renderer *renderer = (Mac_Renderer*)mac_gl__init(window, target);
return(renderer); return(renderer);

View File

@ -18,7 +18,7 @@ mac_init_renderer(Mac_Renderer_Kind kind, NSWindow *window, Render_Target *targe
case MacRenderer_Metal: case MacRenderer_Metal:
{ {
//result = mac_load_metal_renderer(window, target); result = mac_load_metal_renderer(window, target);
} break; } break;
default: InvalidPath; default: InvalidPath;