mirror of
https://github.com/TomHarte/CLK.git
synced 2024-09-08 18:55:14 +00:00
95 lines
2.7 KiB
Objective-C
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
|