if_arch "darwin"
{
overlay "cocoa";
+ if_feature "opengl"
+ {
+ overlay "cgl";
+ };
};
if_arch "!windows"
{
--- /dev/null
+#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
--- /dev/null
+#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];
+}
--- /dev/null
+#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
--- /dev/null
+#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;
+}
--- /dev/null
+#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