OpenGL renderer abstraction. The OpenGL renderer is now in its own view that's separate from the main 4coder view which handles all input and updates. Also added a Window Delegate which handled window events.

master
Yuval Dolev 2020-01-03 00:09:22 +02:00
parent d1b9977a63
commit 4e0549f270
3 changed files with 184 additions and 125 deletions

View File

@ -120,11 +120,13 @@ struct Mac_Input_Chunk{
//////////////////////////////// ////////////////////////////////
@interface AppDelegate : NSObject<NSApplicationDelegate, NSWindowDelegate> @interface FCoderAppDelegate : NSObject<NSApplicationDelegate>
@end @end
@interface OpenGLView : NSOpenGLView @interface FCoderWindowDelegate : NSObject<NSWindowDelegate>
- (void)init_opengl; @end
@interface FCoderView : NSView
- (void)requestDisplay; - (void)requestDisplay;
@end @end
@ -160,8 +162,6 @@ struct Mac_Object{
}; };
struct Mac_Vars { struct Mac_Vars {
b32 gl_is_initialized;
i32 width, height; i32 width, height;
Thread_Context *tctx; Thread_Context *tctx;
@ -181,7 +181,7 @@ struct Mac_Vars {
String_Const_u8 clipboard_contents; String_Const_u8 clipboard_contents;
NSWindow *window; NSWindow *window;
OpenGLView *view; FCoderView *view;
f32 screen_scale_factor; f32 screen_scale_factor;
mach_timebase_info_data_t timebase_info; mach_timebase_info_data_t timebase_info;
@ -318,69 +318,61 @@ mac_resize(float width, float height){
system_signal_step(0); system_signal_step(0);
} }
function inline void
mac_resize(NSWindow *window){
NSRect bounds = [[window contentView] bounds];
mac_resize(bounds.size.width, bounds.size.height);
}
//////////////////////////////// ////////////////////////////////
@implementation AppDelegate // TODO(yuval): mac_resize(bounds.size.width, bounds.size.height);
@implementation FCoderAppDelegate
- (void)applicationDidFinishLaunching:(id)sender{ - (void)applicationDidFinishLaunching:(id)sender{
} }
- (BOOL)applicationShouldTerminateAfterLastWindowClosed:(NSApplication*)sender{ - (BOOL)applicationShouldTerminateAfterLastWindowClosed:(NSApplication*)sender{
return YES; return(YES);
} }
- (void)applicationWillTerminate:(NSNotification*)notification{ - (void)applicationWillTerminate:(NSNotification*)notification{
} }
@end @end
@implementation OpenGLView @implementation FCoderWindowDelegate
- (BOOL)windowShouldClose:(id)sender {
mac_vars.input_chunk.trans.trying_to_kill = true;
system_signal_step(0);
return(NO);
}
- (void)windowDidResize:(NSNotification*)notification {
mac_resize(mac_vars.window);
}
- (void)windowDidMiniaturize:(NSNotification*)notification {
}
- (void)windowDidDeminiaturize:(NSNotification*)notification {
}
@end
@implementation FCoderView
- (id)init{ - (id)init{
self = [super init]; self = [super init];
if (self == nil){ return(self);
return nil;
}
[self init_opengl];
return self;
} }
- (void)dealloc{ - (void)dealloc{
[super dealloc]; [super dealloc];
} }
- (void)prepareOpenGL{
[super prepareOpenGL];
[[self openGLContext] makeCurrentContext];
// NOTE(yuval): Setup vsync
GLint swapInt = 1;
[[self openGLContext] setValues:&swapInt forParameter:NSOpenGLCPSwapInterval];
}
- (void)awakeFromNib{
[self init_opengl];
}
- (void)reshape{
[super reshape];
NSRect bounds = [self bounds];
mac_resize(bounds.size.width, bounds.size.height);
}
- (void)viewDidChangeBackingProperties{ - (void)viewDidChangeBackingProperties{
// NOTE(yuval): Screen scale factor calculation // NOTE(yuval): Screen scale factor calculation
NSScreen* screen = [NSScreen mainScreen]; printf("Backing changed!\n");
NSDictionary* desc = [screen deviceDescription]; mac_resize(mac_vars.window);
NSSize size = [[desc valueForKey:NSDeviceResolution] sizeValue];
f32 max_dpi = Max(size.width, size.height);
mac_vars.screen_scale_factor = (max_dpi / 72.0f);
NSRect frame = [screen frame];
printf("Screen: w:%f h:%f\n", frame.size.width, frame.size.height);
printf("Scale Factor: %f\n\n", mac_vars.screen_scale_factor);
} }
- (void)drawRect:(NSRect)bounds{ - (void)drawRect:(NSRect)bounds{
@ -424,33 +416,29 @@ mac_resize(float width, float height){
result = app.step(mac_vars.tctx, &target, mac_vars.base_ptr, &input); result = app.step(mac_vars.tctx, &target, mac_vars.base_ptr, &input);
} }
CGLLockContext([[self openGLContext] CGLContextObj]); // NOTE(yuval): Quit the app
[[self openGLContext] makeCurrentContext]; if (result.perform_kill){
gl_render(&target); printf("Terminating 4coder!\n");
[[self openGLContext] flushBuffer]; [NSApp terminate:nil];
CGLUnlockContext([[self openGLContext] CGLContextObj]); }
mac_gl_render(&target);
mac_vars.first = false; mac_vars.first = false;
linalloc_clear(mac_vars.frame_arena); linalloc_clear(mac_vars.frame_arena);
} }
- (BOOL)windowShouldClose:(NSWindow*)sender{
// osx_try_to_close();
printf("Window Closing!\n");
return(NO);
}
- (BOOL)acceptsFirstResponder{ - (BOOL)acceptsFirstResponder{
return YES; return(YES);
} }
- (BOOL)becomeFirstResponder{ - (BOOL)becomeFirstResponder{
return YES; return(YES);
} }
- (BOOL)resignFirstResponder{ - (BOOL)resignFirstResponder{
return YES; return(YES);
} }
- (void)keyDown:(NSEvent *)event{ - (void)keyDown:(NSEvent *)event{
@ -480,44 +468,6 @@ mac_resize(float width, float height){
- (void)mouseDown:(NSEvent*)event{ - (void)mouseDown:(NSEvent*)event{
} }
- (void)init_opengl{
if (mac_vars.gl_is_initialized){
return;
}
[self setAutoresizingMask:NSViewWidthSizable | NSViewHeightSizable];
// NOTE(yuval): Setup OpenGL
NSOpenGLPixelFormatAttribute opengl_attrs[] = {
NSOpenGLPFAOpenGLProfile, NSOpenGLProfileVersion3_2Core,
NSOpenGLPFAAccelerated,
NSOpenGLPFADoubleBuffer,
NSOpenGLPFAColorSize, 32,
NSOpenGLPFAAlphaSize, 8,
NSOpenGLPFADepthSize, 24,
NSOpenGLPFASampleBuffers, 1,
NSOpenGLPFASamples, 16,
0
};
NSOpenGLPixelFormat *pixel_format = [[NSOpenGLPixelFormat alloc] initWithAttributes:opengl_attrs];
if (pixel_format == nil){
fprintf(stderr, "Error creating OpenGLPixelFormat\n");
exit(1);
}
NSOpenGLContext *context = [[NSOpenGLContext alloc] initWithFormat:pixel_format shareContext:nil];
[self setPixelFormat:pixel_format];
[self setOpenGLContext:context];
[context makeCurrentContext];
[pixel_format release];
mac_vars.gl_is_initialized = true;
}
- (void)requestDisplay{ - (void)requestDisplay{
CGRect cg_rect = CGRectMake(0, 0, mac_vars.width, mac_vars.height); CGRect cg_rect = CGRectMake(0, 0, mac_vars.width, mac_vars.height);
NSRect rect = NSRectFromCGRect(cg_rect); NSRect rect = NSRectFromCGRect(cg_rect);
@ -531,11 +481,13 @@ int
main(int arg_count, char **args){ main(int arg_count, char **args){
@autoreleasepool{ @autoreleasepool{
// NOTE(yuval): Create NSApplication & Delegate // NOTE(yuval): Create NSApplication & Delegate
NSApplication *ns_app = [NSApplication sharedApplication]; [NSApplication sharedApplication];
Assert(NSApp != nil);
[NSApp setActivationPolicy:NSApplicationActivationPolicyRegular]; [NSApp setActivationPolicy:NSApplicationActivationPolicyRegular];
AppDelegate *app_delegate = [[AppDelegate alloc] init]; FCoderAppDelegate *app_delegate = [[FCoderAppDelegate alloc] init];
[ns_app setDelegate:app_delegate]; [NSApp setDelegate:app_delegate];
pthread_mutex_init(&memory_tracker_mutex, 0); pthread_mutex_init(&memory_tracker_mutex, 0);
@ -687,10 +639,7 @@ main(int arg_count, char **args){
// Window and GL View Initialization // Window and GL View Initialization
// //
// NOTE(yuval): Load OpenGL functions // NOTE(yuval): Create Window & Window Delegate
mac_gl_load_functions();
// NOTE(yuval): Create NSWindow
i32 w; i32 w;
i32 h; i32 h;
if (plat_settings.set_window_size){ if (plat_settings.set_window_size){
@ -711,23 +660,24 @@ main(int arg_count, char **args){
backing:NSBackingStoreBuffered backing:NSBackingStoreBuffered
defer:NO]; defer:NO];
FCoderWindowDelegate *window_delegate = [[FCoderWindowDelegate alloc] init];
[mac_vars.window setDelegate:window_delegate];
[mac_vars.window setMinSize:NSMakeSize(100, 100)]; [mac_vars.window setMinSize:NSMakeSize(100, 100)];
[mac_vars.window setBackgroundColor:NSColor.blackColor]; [mac_vars.window setBackgroundColor:NSColor.blackColor];
[mac_vars.window setDelegate:app_delegate];
[mac_vars.window setTitle:@WINDOW_NAME]; [mac_vars.window setTitle:@WINDOW_NAME];
[mac_vars.window setAcceptsMouseMovedEvents:YES]; [mac_vars.window setAcceptsMouseMovedEvents:YES];
// NOTE(yuval): Create OpenGLView
NSView* content_view = [mac_vars.window contentView]; NSView* content_view = [mac_vars.window contentView];
mac_vars.gl_is_initialized = false; // NOTE(yuval): Initialize the renderer
mac_gl_init(mac_vars.window);
mac_vars.view = [[OpenGLView alloc] init]; // NOTE(yuval): Create the 4coder view
mac_vars.view = [[FCoderView alloc] init];
[mac_vars.view setFrame:[content_view bounds]]; [mac_vars.view setFrame:[content_view bounds]];
[mac_vars.view setAutoresizingMask:NSViewWidthSizable | NSViewHeightSizable]; [mac_vars.view setAutoresizingMask:NSViewWidthSizable | NSViewHeightSizable];
[mac_vars.view setWantsBestResolutionOpenGLSurface:YES];
// NOTE(yuval): Display opengl view and window
[content_view addSubview:mac_vars.view]; [content_view addSubview:mac_vars.view];
[mac_vars.window makeKeyAndOrderFront:nil]; [mac_vars.window makeKeyAndOrderFront:nil];

View File

@ -362,8 +362,8 @@ system_now_time_sig(){
// NOTE(yuval): Now time nanoseconds conversion // NOTE(yuval): Now time nanoseconds conversion
f64 now_nano = (f64)((f64)now * f64 now_nano = (f64)((f64)now *
(f64)mac_vars.timebase_info.numer / ((f64)mac_vars.timebase_info.numer /
(f64)mac_vars.timebase_info.denom); (f64)mac_vars.timebase_info.denom));
// NOTE(yuval): Conversion to useconds // NOTE(yuval): Conversion to useconds
u64 result = (u64)(now_nano * 1.0E-3); u64 result = (u64)(now_nano * 1.0E-3);
@ -416,8 +416,8 @@ function
system_sleep_sig(){ system_sleep_sig(){
u64 nanoseconds = (microseconds * Thousand(1)); u64 nanoseconds = (microseconds * Thousand(1));
u64 abs_sleep_time = (u64)((f64)nanoseconds * u64 abs_sleep_time = (u64)((f64)nanoseconds *
(f64)mac_vars.timebase_info.denom / ((f64)mac_vars.timebase_info.denom /
(f64)mac_vars.timebase_info.numer); (f64)mac_vars.timebase_info.numer));
u64 now = mach_absolute_time(); u64 now = mach_absolute_time();
mach_wait_until(now + abs_sleep_time); mach_wait_until(now + abs_sleep_time);

View File

@ -7,17 +7,126 @@
#include "opengl/4ed_opengl_render.cpp" #include "opengl/4ed_opengl_render.cpp"
function b32 @interface OpenGLView : NSOpenGLView
mac_gl_load_functions(){ - (void)initGL;
b32 result = true; - (void)render:(Render_Target*)target;
@end
// NOTE(yuval): Open the gl dynamic library global OpenGLView *opengl_view;
void* gl_image = dlopen("/System/Library/Frameworks/OpenGL.framework/Versions/Current/OpenGL", RTLD_LAZY);
@implementation OpenGLView{
b32 glIsInitialized;
}
- (id)init{
self = [super init];
if (self == nil){
return nil;
}
glIsInitialized = false;
[self initGL];
return self;
}
- (void)dealloc{
[super dealloc];
}
- (void)prepareOpenGL{
[super prepareOpenGL];
[[self openGLContext] makeCurrentContext];
// NOTE(yuval): Setup vsync
GLint swapInt = 1;
printf("Using vsync: %d\n", swapInt);
[[self openGLContext] setValues:&swapInt forParameter:NSOpenGLCPSwapInterval];
}
- (void)awakeFromNib{
[self initGL];
}
- (void)reshape{
[super reshape];
[[self openGLContext] makeCurrentContext];
[[self openGLContext] update];
}
- (void)initGL{
if (glIsInitialized){
return;
}
// NOTE(yuval): Setup OpenGL
NSOpenGLPixelFormatAttribute opengl_attrs[] = {
NSOpenGLPFAOpenGLProfile, NSOpenGLProfileVersion3_2Core,
NSOpenGLPFAAccelerated,
NSOpenGLPFADoubleBuffer,
NSOpenGLPFAColorSize, 32,
NSOpenGLPFAAlphaSize, 8,
NSOpenGLPFADepthSize, 24,
NSOpenGLPFASampleBuffers, 1,
NSOpenGLPFASamples, 16,
0
};
NSOpenGLPixelFormat *pixel_format = [[NSOpenGLPixelFormat alloc] initWithAttributes:opengl_attrs];
if (pixel_format == nil){
fprintf(stderr, "Error creating OpenGLPixelFormat\n");
exit(1);
}
NSOpenGLContext *context = [[NSOpenGLContext alloc] initWithFormat:pixel_format shareContext:nil];
[self setPixelFormat:pixel_format];
[self setOpenGLContext:context];
[context makeCurrentContext];
[pixel_format release];
glIsInitialized = true;
}
- (void)render:(Render_Target*)target{
Assert(glIsInitialized);
CGLLockContext([[self openGLContext] CGLContextObj]);
[[self openGLContext] makeCurrentContext];
gl_render(target);
[[self openGLContext] flushBuffer];
CGLUnlockContext([[self openGLContext] CGLContextObj]);
}
@end
function void
mac_gl_init(NSWindow *window){
// NOTE(yuval): Create OpenGLView
NSView *content_view = [window contentView];
opengl_view = [[OpenGLView alloc] init];
[opengl_view setFrame:[content_view bounds]];
[opengl_view setAutoresizingMask:NSViewWidthSizable | NSViewHeightSizable];
[opengl_view setWantsBestResolutionOpenGLSurface:YES];
// NOTE(yuval): Add the OpenGL view as a subview of the window
[content_view addSubview:opengl_view];
// NOTE(yuval): Load gl functions // NOTE(yuval): Load gl functions
#define GL_FUNC(f,R,P) Stmnt((f) = (f##_Function*)dlsym(gl_image, #f); \ void *gl_image = dlopen("/System/Library/Frameworks/OpenGL.framework/Versions/Current/OpenGL", RTLD_LAZY);
(result) &= (f != 0););
#include "mac_4ed_opengl_funcs.h"
return result; #define GL_FUNC(f,R,P) ((f) = (f##_Function*)dlsym(gl_image, #f));
#include "mac_4ed_opengl_funcs.h"
}
function void
mac_gl_render(Render_Target* target){
f64 begin_time = system_now_time() / 1000000.0;
[opengl_view render:target];
f64 end_time = system_now_time() / 1000000.0;
printf("Render Time: %fs\n", (end_time - begin_time));
} }