diff options
author | José Fonseca <jfonseca@vmware.com> | 2011-10-07 15:33:48 +0100 |
---|---|---|
committer | José Fonseca <jfonseca@vmware.com> | 2011-10-10 19:23:58 +0100 |
commit | a62e12f4f500a9e823e7cf1e2433393d43da2140 (patch) | |
tree | 4dc097460b7ccc59a1e5ee93e8216cff5ff881f5 /glws_cocoa.mm | |
parent | f5cda41c985730fc27361f3bb36cc2c5ede77e1c (diff) |
Use Cocoa on Mac OS X.
It will enable better control for OpenGL context creation.
Diffstat (limited to 'glws_cocoa.mm')
-rw-r--r-- | glws_cocoa.mm | 241 |
1 files changed, 241 insertions, 0 deletions
diff --git a/glws_cocoa.mm b/glws_cocoa.mm new file mode 100644 index 0000000..c22a823 --- /dev/null +++ b/glws_cocoa.mm @@ -0,0 +1,241 @@ +/************************************************************************** + * + * Copyright 2011 Jose Fonseca + * All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + * + **************************************************************************/ + +#include <stdlib.h> +#include <iostream> + +#include <Cocoa/Cocoa.h> + +#include "glws.hpp" + + +namespace glws { + + +NSAutoreleasePool *autoreleasePool = nil; + + +class CocoaVisual : public Visual +{ +public: + NSOpenGLPixelFormat *pixelFormat; + + CocoaVisual(NSOpenGLPixelFormat *pf) : + pixelFormat(pf) + {} + + ~CocoaVisual() { + [pixelFormat release]; + } +}; + + +class CocoaDrawable : public Drawable +{ +public: + NSWindow *window; + NSOpenGLContext *currentContext; + + CocoaDrawable(const Visual *vis, int w, int h) : + Drawable(vis, w, h), + currentContext(nil) + { + NSOpenGLPixelFormat *pixelFormat = dynamic_cast<const CocoaVisual *>(visual)->pixelFormat; + + NSRect winRect = NSMakeRect(0, 0, w, h); + + window = [[NSWindow alloc] + initWithContentRect:winRect + styleMask:NSTitledWindowMask | + NSClosableWindowMask | + NSMiniaturizableWindowMask + backing:NSBackingStoreRetained + defer:NO]; + assert(window != nil); + + NSOpenGLView *view = [[NSOpenGLView alloc] + initWithFrame:winRect + pixelFormat:pixelFormat]; + assert(view != nil); + + [window setContentView:view]; + [window setTitle:@"glretrace"]; + + } + + ~CocoaDrawable() { + [window release]; + } + + void + resize(int w, int h) { + Drawable::resize(w, h); + + [window setContentSize:NSMakeSize(w, h)]; + + if (currentContext != nil) { + [currentContext update]; + [window makeKeyAndOrderFront:nil]; + [currentContext setView:[window contentView]]; + [currentContext makeCurrentContext]; + } + } + + void show(void) { + if (!visible) { + // TODO + Drawable::show(); + } + } + + void swapBuffers(void) { + if (currentContext != nil) { + [currentContext flushBuffer]; + } + } +}; + + +class CocoaContext : public Context +{ +public: + NSOpenGLContext *context; + + CocoaContext(const Visual *vis, NSOpenGLContext *ctx) : + Context(vis), + context(ctx) + {} + + ~CocoaContext() { + [context release]; + } +}; + + +void +init(void) { + [NSApplication sharedApplication]; + + autoreleasePool = [[NSAutoreleasePool alloc] init]; + + [NSApp finishLaunching]; +} + + +void +cleanup(void) { + [autoreleasePool release]; +} + + +Visual * +createVisual(bool doubleBuffer) { + NSOpenGLPixelFormatAttribute single_attribs[] = { + NSOpenGLPFAAlphaSize, (NSOpenGLPixelFormatAttribute)1, + NSOpenGLPFAColorSize, (NSOpenGLPixelFormatAttribute)24, + NSOpenGLPFADepthSize, (NSOpenGLPixelFormatAttribute)1, + NSOpenGLPFAStencilSize, (NSOpenGLPixelFormatAttribute)1, + (NSOpenGLPixelFormatAttribute)0 + }; + + NSOpenGLPixelFormatAttribute double_attribs[] = { + NSOpenGLPFAAlphaSize, (NSOpenGLPixelFormatAttribute)1, + NSOpenGLPFAColorSize, (NSOpenGLPixelFormatAttribute)24, + NSOpenGLPFADoubleBuffer, + NSOpenGLPFADepthSize, (NSOpenGLPixelFormatAttribute)1, + NSOpenGLPFAStencilSize, (NSOpenGLPixelFormatAttribute)1, + (NSOpenGLPixelFormatAttribute)0 + }; + + NSOpenGLPixelFormatAttribute *attribs = doubleBuffer ? double_attribs : single_attribs; + + NSOpenGLPixelFormat *pixelFormat = [[NSOpenGLPixelFormat alloc] + initWithAttributes:attribs]; + + return new CocoaVisual(pixelFormat); +} + +Drawable * +createDrawable(const Visual *visual, int width, int height) +{ + return new CocoaDrawable(visual, width, height); +} + +Context * +createContext(const Visual *visual, Context *shareContext) +{ + NSOpenGLPixelFormat *pixelFormat = dynamic_cast<const CocoaVisual *>(visual)->pixelFormat; + NSOpenGLContext *share_context = nil; + NSOpenGLContext *context; + + if (shareContext) { + share_context = dynamic_cast<CocoaContext*>(shareContext)->context; + } + + context = [[NSOpenGLContext alloc] + initWithFormat:pixelFormat + shareContext:share_context]; + assert(context != nil); + + return new CocoaContext(visual, context); +} + +bool +makeCurrent(Drawable *drawable, Context *context) +{ + if (!drawable || !context) { + [NSOpenGLContext clearCurrentContext]; + } else { + CocoaDrawable *cocoaDrawable = dynamic_cast<CocoaDrawable *>(drawable); + CocoaContext *cocoaContext = dynamic_cast<CocoaContext *>(context); + + [cocoaDrawable->window makeKeyAndOrderFront:nil]; + [cocoaContext->context setView:[cocoaDrawable->window contentView]]; + [cocoaContext->context makeCurrentContext]; + + cocoaDrawable->currentContext = cocoaContext->context; + } + + return TRUE; +} + +bool +processEvents(void) { + NSEvent* event; + + do { + event = [NSApp nextEventMatchingMask:NSAnyEventMask + untilDate:[NSDate distantPast] + inMode:NSDefaultRunLoopMode + dequeue:YES]; + if (event) + [NSApp sendEvent:event]; + } while (event); + + return true; +} + + +} /* namespace glws */ |