1
0
mirror of https://github.com/TomHarte/CLK.git synced 2024-07-17 13:29:02 +00:00
CLK/OSBindings/Mac/Clock Signal/OpenGLView.m

95 lines
2.7 KiB
Objective-C

//
// OpenGLView.m
// ElectrEm
//
// Created by Thomas Harte on 16/07/2015.
// Copyright © 2015 Thomas Harte. All rights reserved.
//
#import "OpenGLView.h"
@import CoreVideo;
#import <OpenGL/gl.h>
@implementation CSOpenGLView {
CVDisplayLinkRef displayLink;
}
- (void)prepareOpenGL
{
// Synchronize buffer swaps with vertical refresh rate
GLint swapInt = 1;
[[self openGLContext] setValues:&swapInt forParameter:NSOpenGLCPSwapInterval];
// Create a display link capable of being used with all active displays
CVDisplayLinkCreateWithActiveCGDisplays(&displayLink);
// Set the renderer output callback function
CVDisplayLinkSetOutputCallback(displayLink, DisplayLinkCallback, (__bridge void * __nullable)(self));
// Set the display link for the current renderer
CGLContextObj cglContext = [[self openGLContext] CGLContextObj];
CGLPixelFormatObj cglPixelFormat = [[self pixelFormat] CGLPixelFormatObj];
CVDisplayLinkSetCurrentCGDisplayFromOpenGLContext(displayLink, cglContext, cglPixelFormat);
// Activate the display link
CVDisplayLinkStart(displayLink);
}
static CVReturn DisplayLinkCallback(CVDisplayLinkRef displayLink, const CVTimeStamp* now, const CVTimeStamp* outputTime, CVOptionFlags flagsIn, CVOptionFlags* flagsOut, void* displayLinkContext)
{
CSOpenGLView *view = (__bridge CSOpenGLView *)displayLinkContext;
[view.delegate openGLView:view didUpdateToTime:*now];
return kCVReturnSuccess;
}
- (void)dealloc
{
// Release the display link
CVDisplayLinkRelease(displayLink);
}
- (void)reshape
{
[super reshape];
CGSize viewSize = [self convertSize:self.bounds.size toView:self];
glViewport(0, 0, viewSize.width, viewSize.height);
}
- (void)drawRect:(NSRect)dirtyRect
{
[self.openGLContext makeCurrentContext];
[self.delegate openGLViewDrawView:self];
glSwapAPPLE();
}
- (void) awakeFromNib
{
NSOpenGLPixelFormatAttribute attributes[] =
{
NSOpenGLPFADoubleBuffer,
NSOpenGLPFAOpenGLProfile, NSOpenGLProfileVersion3_2Core,
0
};
NSOpenGLPixelFormat *pixelFormat = [[NSOpenGLPixelFormat alloc] initWithAttributes:attributes];
NSOpenGLContext *context = [[NSOpenGLContext alloc] initWithFormat:pixelFormat shareContext:nil];
#ifdef DEBUG
// When we're using a CoreProfile context, crash if we call a legacy OpenGL function
// This will make it much more obvious where and when such a function call is made so
// that we can remove such calls.
// Without this we'd simply get GL_INVALID_OPERATION error for calling legacy functions
// but it would be more difficult to see where that function was called.
CGLEnable([context CGLContextObj], kCGLCECrashOnRemovedFunctions);
#endif
self.pixelFormat = pixelFormat;
self.openGLContext = context;
self.wantsBestResolutionOpenGLSurface = YES;
}
@end