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{
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).

View File

@ -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);

View File

@ -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);
}

View File

@ -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);

View File

@ -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;