- (NSOpenGLPixelFormat *) createPixelFormat
{
NSOpenGLPixelFormatAttribute attr[] =
{
//NSOpenGLPFAOpenGLProfile, NSOpenGLProfileVersion3_2Core,
NSOpenGLPFAAccelerated,
NSOpenGLPFADoubleBuffer,
NSOpenGLPFADepthSize, 16,
0
};
return [(NSOpenGLPixelFormat *)[NSOpenGLPixelFormat alloc]
initWithAttributes:attr];
}
- (id)initWithFrame:(NSRect)frame
{
NSOpenGLPixelFormat *pixelFormat;
pixelFormat = [self createPixelFormat];
self = [super initWithFrame:frame pixelFormat:pixelFormat];
if (self)
{
m_bRedraw = false;
}
return self;
}
- (BOOL) isOpaque
{
return YES;
}
- (BOOL) isFlipped
{
return YES;
}
CVReturn MyDisplayLinkCallback(CVDisplayLinkRef displayLink, const CVTimeStamp* now, const CVTimeStamp* outputTime, CVOptionFlags flagsIn, CVOptionFlags* flagsOut, void* displayLinkContext)
{
CVReturn result = [(__bridge OpenGLHelper*)displayLinkContext getFrameForTime:outputTime];
return result;
}
- (CVReturn)getFrameForTime:(const CVTimeStamp*)outputTime
{
@autoreleasepool
{
if ([self lockFocusIfCanDraw])
{
NSRect curFrame = [self frame];
[self drawFrame: curFrame];
[self unlockFocus];
}
}
return kCVReturnSuccess;
}
- (void) prepareOpenGL
{
[super prepareOpenGL];
// Synchronize buffer swaps with vertical refresh rate
GLint swapInt = 1;
[[self openGLContext] makeCurrentContext];
[[self openGLContext] setValues:&swapInt forParameter:NSOpenGLCPSwapInterval];
CGLLockContext([[self openGLContext] CGLContextObj]);
glEnable( GL_TEXTURE_2D );
glShadeModel( GL_SMOOTH );
glEnable(GL_DEPTH_TEST);
glEnable(GL_LINE_SMOOTH);
glHint(GL_LINE_SMOOTH_HINT, GL_NICEST);
glEnable(GL_BLEND);
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
CGLUnlockContext([[self openGLContext] CGLContextObj]);
// Create a display link capable of being used with all active displays
CVDisplayLinkCreateWithActiveCGDisplays(&displayLink);
// Set the renderer output callback function
CVDisplayLinkSetOutputCallback(displayLink, &MyDisplayLinkCallback, (__bridge void *)(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);
[[NSNotificationCenter defaultCenter] addObserver:self
selector:@selector(applicationWillTerminate:)
name:NSApplicationWillTerminateNotification
object:nil];
}
- (void) SetResizeRedraw: (bool) redraw
{
m_bRedraw = redraw;
}
- (void) reshape
{
NSRect rect;
//[super reshape];
CGLLockContext([[self openGLContext] CGLContextObj]);
[[self openGLContext] makeCurrentContext];
[[self openGLContext] update];
rect = [self bounds];
glViewport(0, 0, rect.size.width, rect.size.height);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
glOrtho(0, rect.size.width, rect.size.height, 0, 0, 100.0f);
CGLUnlockContext([[self openGLContext] CGLContextObj]);
//if (!CVDisplayLinkIsRunning(displayLink))
// Will work if this is uncommented, but kills performance
/*if(m_bRedraw)
{
[self drawFrame:[self frame]];
}*/
}
- (void)drawRect:(NSRect)dirtyRect
{
if (!CVDisplayLinkIsRunning(displayLink))
{
[self drawFrame:dirtyRect];
}
}
- (void) drawFrame:(NSRect)dirtyRect
{
CGLLockContext([[self openGLContext] CGLContextObj]);
[[self openGLContext] makeCurrentContext];
glClearColor(0, 0, 0, 255);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
CGLFlushDrawable([[self openGLContext] CGLContextObj]);
CGLUnlockContext([[self openGLContext] CGLContextObj]);
}