]> git.tdb.fi Git - libs/gui.git/commitdiff
Add OpenGL context support on OS X
authorMikko Rasa <tdb@tdb.fi>
Tue, 1 Oct 2013 14:11:53 +0000 (17:11 +0300)
committerMikko Rasa <tdb@tdb.fi>
Wed, 2 Oct 2013 07:43:02 +0000 (10:43 +0300)
Build
source/graphics/cgl/cocoaglcontext.h [new file with mode: 0644]
source/graphics/cgl/cocoaglcontext.m [new file with mode: 0644]
source/graphics/cgl/cocoapixelformat.h [new file with mode: 0644]
source/graphics/cgl/cocoapixelformat.m [new file with mode: 0644]
source/graphics/cgl/glcontext.cpp [new file with mode: 0644]

diff --git a/Build b/Build
index 9e564ff56a8508934334e5e2cf64f9779189994b..0eac10a2e357cceabe9710141208212b55bf047f 100644 (file)
--- a/Build
+++ b/Build
@@ -82,6 +82,10 @@ package "mspgui"
                if_arch "darwin"
                {
                        overlay "cocoa";
+                       if_feature "opengl"
+                       {
+                               overlay "cgl";
+                       };
                };
                if_arch "!windows"
                {
diff --git a/source/graphics/cgl/cocoaglcontext.h b/source/graphics/cgl/cocoaglcontext.h
new file mode 100644 (file)
index 0000000..4a1fcca
--- /dev/null
@@ -0,0 +1,24 @@
+#ifndef MSP_GRAPHICS_COCOAGLCONTEXT_H_
+#define MSP_GRAPHICS_COCOAGLCONTEXT_H_
+
+#include "cocoapixelformat.h"
+#include "cocoawindow.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+struct _CocoaGLContext;
+typedef struct _CocoaGLContext CocoaGLContext;
+
+CocoaGLContext *create_gl_context(CocoaPixelFormat *);
+void destroy_gl_context(CocoaGLContext *);
+void attach_gl_context_to_window(CocoaGLContext *, CocoaWindow *);
+void make_gl_context_current(CocoaGLContext *);
+void flush_gl_buffer(CocoaGLContext *);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/source/graphics/cgl/cocoaglcontext.m b/source/graphics/cgl/cocoaglcontext.m
new file mode 100644 (file)
index 0000000..7bd8056
--- /dev/null
@@ -0,0 +1,46 @@
+#import <AppKit/NSOpenGL.h>
+#import <AppKit/NSWindow.h>
+#include <stdlib.h>
+#include "cocoaglcontext.h"
+
+NSOpenGLPixelFormat *get_native_pixel_format(CocoaPixelFormat *);
+NSWindow *get_native_window(CocoaWindow *);
+
+struct _CocoaGLContext
+{
+       NSOpenGLContext *context;
+};
+
+CocoaGLContext *create_gl_context(CocoaPixelFormat *format)
+{
+       NSOpenGLContext *ctx = [NSOpenGLContext alloc];
+       ctx = [ctx initWithFormat:get_native_pixel_format(format) shareContext:nil];
+       if(!ctx)
+               return NULL;
+
+       CocoaGLContext *wrapper = (CocoaGLContext *)malloc(sizeof(CocoaGLContext));
+       wrapper->context = ctx;
+       return wrapper;
+}
+
+void destroy_gl_context(CocoaGLContext *context)
+{
+       [context->context release];
+       free(context);
+}
+
+void attach_gl_context_to_window(CocoaGLContext *context, CocoaWindow *window)
+{
+       NSWindow *nswindow = get_native_window(window);
+       [context->context setView:[nswindow contentView]];
+}
+
+void make_gl_context_current(CocoaGLContext *context)
+{
+       [context->context makeCurrentContext];
+}
+
+void flush_gl_buffer(CocoaGLContext *context)
+{
+       [context->context flushBuffer];
+}
diff --git a/source/graphics/cgl/cocoapixelformat.h b/source/graphics/cgl/cocoapixelformat.h
new file mode 100644 (file)
index 0000000..9748bcd
--- /dev/null
@@ -0,0 +1,28 @@
+#ifndef MSP_GRAPHICS_COCOAPIXELFORMAT_H_
+#define MSP_GRAPHICS_COCOAPIXELFORMAT_H_
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+enum
+{
+       CPF_DOUBLEBUFFER = 5,
+       CPF_ALPHA_SIZE = 11,
+       CPF_DEPTH_SIZE = 12,
+       CPF_STENCIL_SIZE = 13,
+       CPF_SAMPLE_BUFFERS = 55,
+       CPF_SAMPLES = 56
+};
+
+struct _CocoaPixelFormat;
+typedef struct _CocoaPixelFormat CocoaPixelFormat;
+
+CocoaPixelFormat *choose_pixel_format(unsigned *);
+void destroy_pixel_format(CocoaPixelFormat *);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/source/graphics/cgl/cocoapixelformat.m b/source/graphics/cgl/cocoapixelformat.m
new file mode 100644 (file)
index 0000000..1f06f04
--- /dev/null
@@ -0,0 +1,31 @@
+#import <AppKit/NSOpenGL.h>
+#include <stdlib.h>
+#include "cocoapixelformat.h"
+
+struct _CocoaPixelFormat
+{
+       NSOpenGLPixelFormat *format;
+};
+
+CocoaPixelFormat *choose_pixel_format(unsigned *attribs)
+{
+       NSOpenGLPixelFormat *format = [NSOpenGLPixelFormat alloc];
+       format = [format initWithAttributes:attribs];
+       if(!format)
+               return NULL;
+
+       CocoaPixelFormat *wrapper = (CocoaPixelFormat *)malloc(sizeof(CocoaPixelFormat));
+       wrapper->format = format;
+       return wrapper;
+}
+
+void destroy_pixel_format(CocoaPixelFormat *format)
+{
+       [format->format release];
+       free(format);
+}
+
+NSOpenGLPixelFormat *get_native_pixel_format(CocoaPixelFormat *format)
+{
+       return format->format;
+}
diff --git a/source/graphics/cgl/glcontext.cpp b/source/graphics/cgl/glcontext.cpp
new file mode 100644 (file)
index 0000000..94b9b2f
--- /dev/null
@@ -0,0 +1,83 @@
+#include <vector>
+#include <OpenGL/gl.h>
+#include "cocoaglcontext.h"
+#include "cocoapixelformat.h"
+#include "glcontext.h"
+#include "window_private.h"
+
+using namespace std;
+
+namespace Msp {
+namespace Graphics {
+
+typedef CocoaGLContext *ContextHandle;
+
+struct GLContext::Private
+{
+       ContextHandle context;
+};
+
+void GLContext::platform_init(const GLOptions &opts)
+{
+       priv = new Private;
+
+       vector<unsigned> attribs;
+       
+       attribs.push_back(CPF_DEPTH_SIZE);
+       attribs.push_back(1);
+       
+       if(opts.alpha)
+       {
+               attribs.push_back(CPF_ALPHA_SIZE);
+               attribs.push_back(1);
+       }
+       
+       if(opts.stencil)
+       {
+               attribs.push_back(CPF_STENCIL_SIZE);
+               attribs.push_back(1);
+       }
+       
+       if(opts.doublebuffer)
+               attribs.push_back(CPF_DOUBLEBUFFER);
+       
+       if(opts.multisample>0)
+       {
+               attribs.push_back(CPF_SAMPLE_BUFFERS);
+               attribs.push_back(1);
+               attribs.push_back(CPF_SAMPLES);
+               attribs.push_back(opts.multisample);
+       }
+
+       attribs.push_back(0);
+
+       CocoaPixelFormat *pixfmt = choose_pixel_format(&attribs.front());
+       if(!pixfmt)
+               throw unsupported_gl_mode(opts);
+
+       priv->context = create_gl_context(pixfmt);
+       destroy_pixel_format(pixfmt);
+
+       attach_gl_context_to_window(priv->context, window.get_private().window);
+       make_gl_context_current(priv->context);
+}
+
+GLContext::~GLContext()
+{
+       destroy_gl_context(priv->context);
+       delete priv;
+}
+
+void GLContext::swap_buffers()
+{
+       flush_gl_buffer(priv->context);
+}
+
+void GLContext::window_resized(unsigned w, unsigned h)
+{
+       // XXX Call [context update] here?
+       glViewport(0, 0, w, h);
+}
+
+} // namespace Graphics
+} // namespace Msp