From a62e12f4f500a9e823e7cf1e2433393d43da2140 Mon Sep 17 00:00:00 2001 From: =?utf8?q?Jos=C3=A9=20Fonseca?= Date: Fri, 7 Oct 2011 15:33:48 +0100 Subject: [PATCH] Use Cocoa on Mac OS X. It will enable better control for OpenGL context creation. --- CMakeLists.txt | 45 +++------ glws_cocoa.mm | 241 +++++++++++++++++++++++++++++++++++++++++++++++++ glws_glx.cpp | 8 -- 3 files changed, 256 insertions(+), 38 deletions(-) create mode 100644 glws_cocoa.mm diff --git a/CMakeLists.txt b/CMakeLists.txt index c81e44d..d91d326 100755 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -36,34 +36,17 @@ if (ENABLE_GUI) find_package (QJSON ${REQUIRE_GUI}) endif () -if (NOT WIN32) +if (WIN32) + find_package (DirectX) +elif (APPLE) +else () find_package (X11 REQUIRED) - # On Mac OS X, GLX is provided as a separate OpenGL implementation, different - # from the standard OpenGL framework which provides support for native Mac OS X - # applications. - if (APPLE) - find_path (X11_GL_INCLUDE_PATH GL/glx.h ${X11_INC_SEARCH_PATH}) - if (NOT X11_GL_INCLUDE_PATH) - message (SEND_ERROR "Could not find GL/glx.h") - endif (NOT X11_GL_INCLUDE_PATH) - set (X11_INCLUDE_DIR ${X11_INCLUDE_DIR} ${X11_GL_INCLUDE_PATH}) - - find_library (X11_GL_LIB GL ${X11_LIB_SEARCH_PATH}) - if (NOT X11_GL_LIB) - message (SEND_ERROR "Could not find libGL.dylib") - endif (NOT X11_GL_LIB) - else () - set (X11_INCLUDE_DIR ${X11_INCLUDE_DIR} ${OPENGL_INCLUDE_DIR}) - set (X11_GL_LIB ${OPENGL_gl_LIBRARY}) - endif () + set (X11_INCLUDE_DIR ${X11_INCLUDE_DIR} ${OPENGL_INCLUDE_DIR}) + set (X11_GL_LIB ${OPENGL_gl_LIBRARY}) include_directories (${X11_INCLUDE_DIR}) -endif (NOT WIN32) - -if (WIN32) - find_package (DirectX) -endif (WIN32) +endif () ############################################################################## @@ -198,10 +181,14 @@ add_custom_command ( if (WIN32) set (os os_win32.cpp) set (glws_os glws_wgl.cpp) -else (WIN32) +else () set (os os_posix.cpp) - set (glws_os glws_glx.cpp) -endif (WIN32) + if (APPLE) + set (glws_os glws_cocoa.mm) + else () + set (glws_os glws_glx.cpp) + endif () +endif () add_library (common STATIC common/trace_file.cpp @@ -431,10 +418,8 @@ target_link_libraries (glretrace if (WIN32) target_link_libraries (glretrace ${OPENGL_gl_LIBRARY}) elseif (APPLE) - # XXX: We use GLX on MacOSX, which is in a separate library. target_link_libraries (glretrace - ${X11_GL_LIB} - ${X11_X11_LIB} + "-framework Cocoa" "-framework ApplicationServices" # CGS* ${OPENGL_gl_LIBRARY} # CGL* ) 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 +#include + +#include + +#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(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(visual)->pixelFormat; + NSOpenGLContext *share_context = nil; + NSOpenGLContext *context; + + if (shareContext) { + share_context = dynamic_cast(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(drawable); + CocoaContext *cocoaContext = dynamic_cast(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 */ diff --git a/glws_glx.cpp b/glws_glx.cpp index c082417..d26066a 100644 --- a/glws_glx.cpp +++ b/glws_glx.cpp @@ -30,13 +30,7 @@ #include "glws.hpp" -#ifdef __APPLE__ -#include -#include -#include -#else #include "glproc.hpp" -#endif namespace glws { @@ -304,7 +298,6 @@ createContext(const Visual *_visual, Context *shareContext) share_context = dynamic_cast(shareContext)->context; } -#ifndef __APPLE__ if (glxVersion >= 0x0104 && has_GLX_ARB_create_context) { Attributes attribs; attribs.add(GLX_RENDER_TYPE, GLX_RGBA_TYPE); @@ -315,7 +308,6 @@ createContext(const Visual *_visual, Context *shareContext) context = glXCreateContextAttribsARB(display, visual->fbconfig, share_context, True, attribs); } else -#endif if (glxVersion >= 0x103) { context = glXCreateNewContext(display, visual->fbconfig, GLX_RGBA_TYPE, share_context, True); } else { -- 2.43.0