Browse Source

Added OSX entry point and OpenGL context

Added OSX entry point and OpenGL context
Garett Bass 13 năm trước cách đây
mục cha
commit
2bbcb92109

+ 2 - 0
bgfx.sln.bat

@@ -0,0 +1,2 @@
+@echo off
+start .build/projects/vs2012/bgfx.sln

+ 1 - 1
examples/common/dbg.cpp

@@ -28,7 +28,7 @@ void dbgOutput(const char* _out)
 {
 {
 #if BX_PLATFORM_WINDOWS || BX_PLATFORM_XBOX360
 #if BX_PLATFORM_WINDOWS || BX_PLATFORM_XBOX360
 	OutputDebugStringA(_out);
 	OutputDebugStringA(_out);
-#elif BX_PLATFORM_NACL || BX_PLATFORM_LINUX
+#elif BX_PLATFORM_NACL || BX_PLATFORM_LINUX || BX_PLATFORM_OSX
 	fputs(_out, stderr);
 	fputs(_out, stderr);
 	fflush(stderr);
 	fflush(stderr);
 #endif // BX_PLATFORM_
 #endif // BX_PLATFORM_

+ 0 - 28
examples/common/entry_osx.cpp

@@ -1,28 +0,0 @@
-/*
- * Copyright 2011-2013 Branimir Karadzic. All rights reserved.
- * License: http://www.opensource.org/licenses/BSD-2-Clause
- */
-
-#include <bx/bx.h>
-
-#if BX_PLATFORM_OSX
-
-#include "entry.h"
-
-namespace entry
-{
-	Event::Enum poll()
-	{
-		return Event::Nop;
-	}
-
-} // namespace entry
-
-extern int _main_(int _argc, char** _argv);
-
-int main(int _argc, char** _argv)
-{
-	return _main_(_argc, _argv);
-}
-
-#endif // BX_PLATFORM_OSX

+ 235 - 0
examples/common/entry_osx.mm

@@ -0,0 +1,235 @@
+/*
+ * Copyright 2011-2013 Branimir Karadzic. All rights reserved.
+ * License: http://www.opensource.org/licenses/BSD-2-Clause
+ */
+
+#include <bx/bx.h>
+
+#if BX_PLATFORM_OSX
+
+#include <bgfxplatform.h>
+#include <bx/uint32_t.h>
+#include <bx/thread.h>
+
+#include "entry.h"
+#include "dbg.h"
+
+#define DEFAULT_WIDTH 1280
+#define DEFAULT_HEIGHT 720
+
+extern int _main_(int _argc, char** _argv);
+
+@interface bgfxApplicationDelegate : NSObject <NSApplicationDelegate> {
+	bool terminated;
+}
++ (bgfxApplicationDelegate *)sharedDelegate;
+- (id)init;
+- (NSApplicationTerminateReply)applicationShouldTerminate:(NSApplication *)sender;
+- (bool)applicationHasTerminated;
+@end
+
+@implementation bgfxApplicationDelegate
++ (bgfxApplicationDelegate *)sharedDelegate {
+	static id delegate = [bgfxApplicationDelegate new];
+	return delegate;
+}
+
+- (id)init {
+	self = [super init];
+	if (self) {
+		self->terminated = false;        
+	}
+	return self;
+}
+
+- (NSApplicationTerminateReply)applicationShouldTerminate:(NSApplication *)sender {
+	self->terminated = true;
+	return NSTerminateCancel;
+}
+
+- (bool)applicationHasTerminated {
+	return self->terminated;
+}
+@end
+
+@interface bgfxWindowDelegate : NSObject <NSWindowDelegate> {
+	unsigned int windowCount;
+}
++ (bgfxWindowDelegate *)sharedDelegate;
+- (id)init;
+- (void)windowCreated:(NSWindow *)window;
+- (BOOL)windowShouldClose:(NSWindow *)window;
+@end
+
+@implementation bgfxWindowDelegate
++ (bgfxWindowDelegate *)sharedDelegate {
+	static id windowDelegate = [bgfxWindowDelegate new];
+	return windowDelegate;
+}
+
+- (id)init {
+	self = [super init];
+	if (self) {
+		self->windowCount = 0;
+	}
+	return self;
+}
+
+- (void)windowCreated:(NSWindow *)window {
+	assert(window);
+	
+	[window setDelegate:self];
+
+	assert(self->windowCount < ~0u);
+	self->windowCount += 1;
+}
+
+- (BOOL)windowShouldClose:(NSWindow *)window {
+	assert(window);
+	
+	[window setDelegate:nil];
+
+	assert(self->windowCount);
+	self->windowCount -= 1;
+	
+	if (self->windowCount == 0) {
+		[NSApp terminate:self];
+		return false;
+	}
+	return true;
+}
+@end
+
+namespace entry
+{
+	struct MainThreadEntry
+	{
+		int m_argc;
+		char** m_argv;
+		
+		static int32_t threadFunc(void* _userData)
+		{
+			MainThreadEntry* self = (MainThreadEntry*)_userData;
+			return _main_(self->m_argc, self->m_argv);
+		}
+	};
+	
+	struct Context
+	{
+		Context()
+			: m_exit(false)
+		{
+		}
+		
+		NSEvent* WaitEvent () {
+			return
+			[NSApp
+			 nextEventMatchingMask:NSAnyEventMask
+			 untilDate:[NSDate distantFuture] // wait for event
+			 inMode:NSDefaultRunLoopMode
+			 dequeue:YES];
+		}
+		
+		NSEvent* PeekEvent () {
+			return
+			[NSApp
+			 nextEventMatchingMask:NSAnyEventMask
+			 untilDate:[NSDate distantPast] // do not wait for event
+			 inMode:NSDefaultRunLoopMode
+			 dequeue:YES];
+		}
+		
+		bool DispatchEvent (NSEvent* event) {
+			if (event) {
+				[NSApp sendEvent:event];
+				[NSApp updateWindows];
+				return true;
+			}
+			return false;
+		}
+		
+		int32_t main(int _argc, char** _argv)
+		{
+			[NSApplication sharedApplication];			
+			id dg = [bgfxApplicationDelegate sharedDelegate];
+			[NSApp setDelegate:dg];
+			[NSApp setActivationPolicy:NSApplicationActivationPolicyRegular];
+			[NSApp activateIgnoringOtherApps:YES];
+			[NSApp finishLaunching];
+			[[NSNotificationCenter defaultCenter]
+			 postNotificationName:NSApplicationWillFinishLaunchingNotification
+			 object:NSApp];
+			[[NSNotificationCenter defaultCenter]
+			 postNotificationName:NSApplicationDidFinishLaunchingNotification
+			 object:NSApp];
+			
+			id quitMenuItem = [NSMenuItem new];
+			[quitMenuItem
+				initWithTitle:@"Quit"
+				action:@selector(terminate:)
+				keyEquivalent:@"q"];
+			id appMenu = [NSMenu new];
+			[appMenu addItem:quitMenuItem];
+			id appMenuItem = [NSMenuItem new];
+			[appMenuItem setSubmenu:appMenu];
+			id menubar = [[NSMenu new] autorelease];
+			[menubar addItem:appMenuItem];
+			[NSApp setMainMenu:menubar];
+			
+			NSRect rect = NSMakeRect(0, 0, DEFAULT_WIDTH, DEFAULT_HEIGHT);
+			NSWindow* window = [NSWindow alloc];
+			[window
+			 initWithContentRect:rect
+			 styleMask:0
+			 |NSTitledWindowMask
+			 |NSClosableWindowMask
+			 |NSMiniaturizableWindowMask
+			 |NSResizableWindowMask
+			 backing:NSBackingStoreBuffered defer:NO
+			 ];
+			NSString* appName = [[NSProcessInfo processInfo] processName];    
+			[window setTitle:appName];
+			[window cascadeTopLeftFromPoint:NSMakePoint(20,20)];
+			[window makeKeyAndOrderFront:nil];
+			[[bgfxWindowDelegate sharedDelegate] windowCreated:window];
+			
+			bgfx::osxSetNSWindow(window);
+			
+			MainThreadEntry mte;
+			mte.m_argc = _argc;
+			mte.m_argv = _argv;
+			
+			bx::Thread thread;
+			thread.init(mte.threadFunc, &mte);
+
+			while (!(m_exit = [dg applicationHasTerminated]))
+			{
+				DispatchEvent(WaitEvent());				
+				while (DispatchEvent(PeekEvent()));
+			}
+			
+			thread.shutdown();
+			
+			return 0;
+		}
+		
+		bool m_exit;
+		
+	};
+	
+	static Context s_ctx;
+	
+	Event::Enum poll()
+	{
+		return s_ctx.m_exit ? Event::Exit : Event::Nop;
+	}
+
+} // namespace entry
+
+int main(int _argc, char** _argv)
+{
+	using namespace entry;
+	return s_ctx.main(_argc, _argv);
+}
+
+#endif // BX_PLATFORM_OSX

+ 9 - 0
include/bgfxplatform.h

@@ -38,6 +38,15 @@ namespace bgfx
 	void winSetHwnd(::HWND _hwnd);
 	void winSetHwnd(::HWND _hwnd);
 } // namespace bgfx
 } // namespace bgfx
 
 
+#elif BX_PLATFORM_OSX
+#	include <Cocoa/Cocoa.h>
+#	include <stdlib.h>
+
+namespace bgfx
+{
+	void osxSetNSWindow(void* _nsWindow);
+} // namespace bgfx
+
 #endif // BX_PLATFORM_
 #endif // BX_PLATFORM_
 
 
 #endif // __BGFXPLATFORM_H__
 #endif // __BGFXPLATFORM_H__

+ 11 - 0
makefile

@@ -11,6 +11,7 @@ all:
 	premake --file=premake/premake4.lua --gcc=mingw gmake
 	premake --file=premake/premake4.lua --gcc=mingw gmake
 	premake --file=premake/premake4.lua --gcc=linux gmake
 	premake --file=premake/premake4.lua --gcc=linux gmake
 	premake --file=premake/premake4.lua --gcc=emscripten gmake
 	premake --file=premake/premake4.lua --gcc=emscripten gmake
+	premake --file=premake/premake4.lua --gcc=osx gmake
 	premake --file=premake/premake4.lua xcode4
 	premake --file=premake/premake4.lua xcode4
 	make -s --no-print-directory -C src
 	make -s --no-print-directory -C src
 
 
@@ -49,6 +50,16 @@ pnacl-debug:
 pnacl-release:
 pnacl-release:
 	make -R -C .build/projects/gmake-pnacl config=release64
 	make -R -C .build/projects/gmake-pnacl config=release64
 
 
+osx-debug32:
+	make -C .build/projects/gmake-osx config=debug32
+osx-release32:
+	make -C .build/projects/gmake-osx config=release32
+osx-debug64:
+	make -C .build/projects/gmake-osx config=debug64
+osx-release64:
+	make -C .build/projects/gmake-osx config=release64
+osx: osx-debug32 osx-release32 osx-debug64 osx-release64
+
 docs:
 docs:
 	markdown README.md > .build/docs/readme.html
 	markdown README.md > .build/docs/readme.html
 
 

+ 1 - 0
premake/bgfx.lua

@@ -41,6 +41,7 @@ project "bgfx"
 		BGFX_DIR .. "include/**.h",
 		BGFX_DIR .. "include/**.h",
 		BGFX_DIR .. "src/**.cpp",
 		BGFX_DIR .. "src/**.cpp",
 		BGFX_DIR .. "src/**.h",
 		BGFX_DIR .. "src/**.h",
+		BGFX_DIR .. "src/**.mm",
 	}
 	}
 
 
 	excludes {
 	excludes {

+ 7 - 0
premake/example-00-helloworld.lua

@@ -10,6 +10,7 @@ project "example-00-helloworld"
 	files {
 	files {
 		BGFX_DIR .. "examples/common/**.cpp",
 		BGFX_DIR .. "examples/common/**.cpp",
 		BGFX_DIR .. "examples/common/**.h",
 		BGFX_DIR .. "examples/common/**.h",
+		BGFX_DIR .. "examples/common/**.mm",
 		BGFX_DIR .. "examples/00-helloworld/**.cpp",
 		BGFX_DIR .. "examples/00-helloworld/**.cpp",
 		BGFX_DIR .. "examples/00-helloworld/**.h",
 		BGFX_DIR .. "examples/00-helloworld/**.h",
 	}
 	}
@@ -35,3 +36,9 @@ project "example-00-helloworld"
 			"GL",
 			"GL",
 			"pthread",
 			"pthread",
 		}
 		}
+
+	configuration { "macosx" }
+		links {
+			"Cocoa.framework",
+			"OpenGL.framework",
+		}

+ 7 - 0
premake/example-01-cubes.lua

@@ -12,6 +12,7 @@ project "example-01-cubes"
 	files {
 	files {
 		BGFX_DIR .. "examples/common/**.cpp",
 		BGFX_DIR .. "examples/common/**.cpp",
 		BGFX_DIR .. "examples/common/**.h",
 		BGFX_DIR .. "examples/common/**.h",
+		BGFX_DIR .. "examples/common/**.mm",
 		BGFX_DIR .. "examples/01-cubes/**.cpp",
 		BGFX_DIR .. "examples/01-cubes/**.cpp",
 		BGFX_DIR .. "examples/01-cubes/**.h",
 		BGFX_DIR .. "examples/01-cubes/**.h",
 	}
 	}
@@ -37,3 +38,9 @@ project "example-01-cubes"
 			"GL",
 			"GL",
 			"pthread",
 			"pthread",
 		}
 		}
+
+	configuration { "macosx" }
+		links {
+			"Cocoa.framework",
+			"OpenGL.framework",
+		}

+ 7 - 0
premake/example-02-metaballs.lua

@@ -12,6 +12,7 @@ project "example-02-metaballs"
 	files {
 	files {
 		BGFX_DIR .. "examples/common/**.cpp",
 		BGFX_DIR .. "examples/common/**.cpp",
 		BGFX_DIR .. "examples/common/**.h",
 		BGFX_DIR .. "examples/common/**.h",
+		BGFX_DIR .. "examples/common/**.mm",
 		BGFX_DIR .. "examples/02-metaballs/**.cpp",
 		BGFX_DIR .. "examples/02-metaballs/**.cpp",
 		BGFX_DIR .. "examples/02-metaballs/**.h",
 		BGFX_DIR .. "examples/02-metaballs/**.h",
 	}
 	}
@@ -37,3 +38,9 @@ project "example-02-metaballs"
 			"GL",
 			"GL",
 			"pthread",
 			"pthread",
 		}
 		}
+
+	configuration { "macosx" }
+		links {
+			"Cocoa.framework",
+			"OpenGL.framework",
+		}

+ 7 - 0
premake/example-03-raymarch.lua

@@ -12,6 +12,7 @@ project "example-03-raymarch"
 	files {
 	files {
 		BGFX_DIR .. "examples/common/**.cpp",
 		BGFX_DIR .. "examples/common/**.cpp",
 		BGFX_DIR .. "examples/common/**.h",
 		BGFX_DIR .. "examples/common/**.h",
+		BGFX_DIR .. "examples/common/**.mm",
 		BGFX_DIR .. "examples/03-raymarch/**.cpp",
 		BGFX_DIR .. "examples/03-raymarch/**.cpp",
 		BGFX_DIR .. "examples/03-raymarch/**.h",
 		BGFX_DIR .. "examples/03-raymarch/**.h",
 	}
 	}
@@ -37,3 +38,9 @@ project "example-03-raymarch"
 			"GL",
 			"GL",
 			"pthread",
 			"pthread",
 		}
 		}
+
+	configuration { "macosx" }
+		links {
+			"Cocoa.framework",
+			"OpenGL.framework",
+		}

+ 7 - 0
premake/example-04-mesh.lua

@@ -12,6 +12,7 @@ project "example-04-mesh"
 	files {
 	files {
 		BGFX_DIR .. "examples/common/**.cpp",
 		BGFX_DIR .. "examples/common/**.cpp",
 		BGFX_DIR .. "examples/common/**.h",
 		BGFX_DIR .. "examples/common/**.h",
+		BGFX_DIR .. "examples/common/**.mm",
 		BGFX_DIR .. "examples/04-mesh/**.cpp",
 		BGFX_DIR .. "examples/04-mesh/**.cpp",
 		BGFX_DIR .. "examples/04-mesh/**.h",
 		BGFX_DIR .. "examples/04-mesh/**.h",
 	}
 	}
@@ -37,3 +38,9 @@ project "example-04-mesh"
 			"GL",
 			"GL",
 			"pthread",
 			"pthread",
 		}
 		}
+
+	configuration { "macosx" }
+		links {
+			"Cocoa.framework",
+			"OpenGL.framework",
+		}

+ 7 - 0
premake/example-05-instancing.lua

@@ -12,6 +12,7 @@ project "example-05-instancing"
 	files {
 	files {
 		BGFX_DIR .. "examples/common/**.cpp",
 		BGFX_DIR .. "examples/common/**.cpp",
 		BGFX_DIR .. "examples/common/**.h",
 		BGFX_DIR .. "examples/common/**.h",
+		BGFX_DIR .. "examples/common/**.mm",
 		BGFX_DIR .. "examples/05-instancing/**.cpp",
 		BGFX_DIR .. "examples/05-instancing/**.cpp",
 		BGFX_DIR .. "examples/05-instancing/**.h",
 		BGFX_DIR .. "examples/05-instancing/**.h",
 	}
 	}
@@ -37,3 +38,9 @@ project "example-05-instancing"
 			"GL",
 			"GL",
 			"pthread",
 			"pthread",
 		}
 		}
+
+	configuration { "macosx" }
+		links {
+			"Cocoa.framework",
+			"OpenGL.framework",
+		}

+ 7 - 0
premake/example-06-bump.lua

@@ -12,6 +12,7 @@ project "example-06-bump"
 	files {
 	files {
 		BGFX_DIR .. "examples/common/**.cpp",
 		BGFX_DIR .. "examples/common/**.cpp",
 		BGFX_DIR .. "examples/common/**.h",
 		BGFX_DIR .. "examples/common/**.h",
+		BGFX_DIR .. "examples/common/**.mm",
 		BGFX_DIR .. "examples/06-bump/**.cpp",
 		BGFX_DIR .. "examples/06-bump/**.cpp",
 		BGFX_DIR .. "examples/06-bump/**.h",
 		BGFX_DIR .. "examples/06-bump/**.h",
 	}
 	}
@@ -34,3 +35,9 @@ project "example-06-bump"
 			"GL",
 			"GL",
 			"pthread",
 			"pthread",
 		}
 		}
+
+	configuration { "macosx" }
+		links {
+			"Cocoa.framework",
+			"OpenGL.framework",
+		}

+ 7 - 0
premake/example-07-callback.lua

@@ -12,6 +12,7 @@ project "example-07-callback"
 	files {
 	files {
 		BGFX_DIR .. "examples/common/**.cpp",
 		BGFX_DIR .. "examples/common/**.cpp",
 		BGFX_DIR .. "examples/common/**.h",
 		BGFX_DIR .. "examples/common/**.h",
+		BGFX_DIR .. "examples/common/**.mm",
 		BGFX_DIR .. "examples/07-callback/**.cpp",
 		BGFX_DIR .. "examples/07-callback/**.cpp",
 		BGFX_DIR .. "examples/07-callback/**.h",
 		BGFX_DIR .. "examples/07-callback/**.h",
 	}
 	}
@@ -34,3 +35,9 @@ project "example-07-callback"
 			"GL",
 			"GL",
 			"pthread",
 			"pthread",
 		}
 		}
+
+	configuration { "macosx" }
+		links {
+			"Cocoa.framework",
+			"OpenGL.framework",
+		}

+ 7 - 0
premake/example-08-update.lua

@@ -12,6 +12,7 @@ project "example-08-update"
 	files {
 	files {
 		BGFX_DIR .. "examples/common/**.cpp",
 		BGFX_DIR .. "examples/common/**.cpp",
 		BGFX_DIR .. "examples/common/**.h",
 		BGFX_DIR .. "examples/common/**.h",
+		BGFX_DIR .. "examples/common/**.mm",
 		BGFX_DIR .. "examples/08-update/**.cpp",
 		BGFX_DIR .. "examples/08-update/**.cpp",
 		BGFX_DIR .. "examples/08-update/**.h",
 		BGFX_DIR .. "examples/08-update/**.h",
 	}
 	}
@@ -37,3 +38,9 @@ project "example-08-update"
 			"GL",
 			"GL",
 			"pthread",
 			"pthread",
 		}
 		}
+
+	configuration { "macosx" }
+		links {
+			"Cocoa.framework",
+			"OpenGL.framework",
+		}

+ 8 - 1
src/bgfx.cpp

@@ -40,7 +40,14 @@ namespace bgfx
 	{
 	{
 		g_bgfxHwnd = _hwnd;
 		g_bgfxHwnd = _hwnd;
 	}
 	}
-#endif // BX_PLATFORM_WINDOWS
+#elif BX_PLATFORM_OSX
+	void* g_bgfxNSWindow = NULL;
+	
+	void osxSetNSWindow(void* _nsWindow)
+	{
+		g_bgfxNSWindow = _nsWindow;
+	}
+#endif // BX_PLATFORM_*
 
 
 	struct CallbackStub : public CallbackI
 	struct CallbackStub : public CallbackI
 	{
 	{

+ 12 - 10
src/bgfx_p.h

@@ -31,7 +31,7 @@ extern void dbgPrintfData(const void* _data, uint32_t _size, const char* _format
 				do { \
 				do { \
 					if (!(_condition) ) \
 					if (!(_condition) ) \
 					{ \
 					{ \
-						BX_TRACE(BX_FILE_LINE_LITERAL "WARN " _format, ##__VA_ARGS__); \
+						BX_TRACE("WARN " _format, ##__VA_ARGS__); \
 					} \
 					} \
 				} while(0)
 				} while(0)
 
 
@@ -39,7 +39,7 @@ extern void dbgPrintfData(const void* _data, uint32_t _size, const char* _format
 				do { \
 				do { \
 					if (!(_condition) ) \
 					if (!(_condition) ) \
 					{ \
 					{ \
-						BX_TRACE(BX_FILE_LINE_LITERAL "CHECK " _format, ##__VA_ARGS__); \
+						BX_TRACE("CHECK " _format, ##__VA_ARGS__); \
 						bx::debugBreak(); \
 						bx::debugBreak(); \
 					} \
 					} \
 				} while(0)
 				} while(0)
@@ -75,9 +75,9 @@ extern void dbgPrintfData(const void* _data, uint32_t _size, const char* _format
 
 
 #include "dds.h"
 #include "dds.h"
 
 
-#define BGFX_CHUNK_MAGIC_FSH BX_MAKEFOURCC('F', 'S', 'H', 0x1)
+#define BGFX_CHUNK_MAGIC_FSH BX_MAKEFOURCC('F', 'S', 'H', 0x1)
 #define BGFX_CHUNK_MAGIC_TEX BX_MAKEFOURCC('T', 'E', 'X', 0x0)
 #define BGFX_CHUNK_MAGIC_TEX BX_MAKEFOURCC('T', 'E', 'X', 0x0)
-#define BGFX_CHUNK_MAGIC_VSH BX_MAKEFOURCC('V', 'S', 'H', 0x1)
+#define BGFX_CHUNK_MAGIC_VSH BX_MAKEFOURCC('V', 'S', 'H', 0x1)
 
 
 #if BGFX_CONFIG_USE_TINYSTL
 #if BGFX_CONFIG_USE_TINYSTL
 
 
@@ -145,7 +145,9 @@ namespace bgfx
 {
 {
 #if BX_PLATFORM_WINDOWS
 #if BX_PLATFORM_WINDOWS
 	extern HWND g_bgfxHwnd;
 	extern HWND g_bgfxHwnd;
-#endif // BX_PLATFORM_WINDOWS
+#elif BX_PLATFORM_OSX
+	extern void* g_bgfxNSWindow;
+#endif // BX_PLATFORM_*
 
 
 	struct Clear
 	struct Clear
 	{
 	{
@@ -1433,13 +1435,13 @@ namespace bgfx
 		{
 		{
 		}
 		}
 
 
-		static int32_t renderThread(void* _userData)
-		{
-			Context* ctx = (Context*)_userData;
+		static int32_t renderThread(void* _userData)
+		{
+			Context* ctx = (Context*)_userData;
 			while (!ctx->renderFrame() );
 			while (!ctx->renderFrame() );
 			return EXIT_SUCCESS;
 			return EXIT_SUCCESS;
-		}
-
+		}
+
 		// game thread
 		// game thread
 		void init(bool _createRenderThread);
 		void init(bool _createRenderThread);
 		void shutdown();
 		void shutdown();

+ 38 - 0
src/glcontext_nsgl.h

@@ -0,0 +1,38 @@
+/*
+ * Copyright 2011-2013 Branimir Karadzic. All rights reserved.
+ * License: http://www.opensource.org/licenses/BSD-2-Clause
+ */
+
+#ifndef __GLCONTEXT_NSGL_H__
+#define __GLCONTEXT_NSGL_H__
+
+#if BX_PLATFORM_OSX
+
+namespace bgfx
+{
+	struct GlContext
+	{
+		GlContext()
+        : m_context(0)
+		{
+		}
+        
+		void create(uint32_t _width, uint32_t _height);
+		void destroy();
+		void resize(uint32_t _width, uint32_t _height);
+		void swap();
+		void import();
+        
+		bool isValid() const
+		{
+			return 0 != m_context;
+		}
+        
+		void* m_view;
+		void* m_context;
+	};
+} // namespace bgfx
+
+#endif // BX_PLATFORM_OSX
+
+#endif // __GLCONTEXT_NSGL_H__

+ 108 - 0
src/glcontext_nsgl.mm

@@ -0,0 +1,108 @@
+/*
+ * Copyright 2011-2013 Branimir Karadzic. All rights reserved.
+ * License: http://www.opensource.org/licenses/BSD-2-Clause
+ */
+
+#include "bgfx_p.h"
+
+#if (BGFX_CONFIG_RENDERER_OPENGLES2|BGFX_CONFIG_RENDERER_OPENGLES3|BGFX_CONFIG_RENDERER_OPENGL)
+#	include "renderer_gl.h"
+
+#	if BX_PLATFORM_OSX
+
+#		include <mach-o/dyld.h>
+#		include <dlfcn.h>
+#		include <stdlib.h>
+#		include <string.h>
+#		include <Cocoa/Cocoa.h>
+#		include <OpenGL/OpenGL.h>
+
+static void* NSGLGetProcAddress (const char* name) {
+	static void* const dylib =
+	dlopen("/System/Library/Frameworks/"
+		   "OpenGL.framework/Versions/Current/OpenGL",
+		   RTLD_LAZY);
+    return dylib ? dlsym(dylib, name) : NULL;
+}
+
+namespace bgfx
+{
+
+#	define GL_IMPORT(_optional, _proto, _func) _proto _func
+#		include "glimports.h"
+#	undef GL_IMPORT
+	
+	void GlContext::create(uint32_t _width, uint32_t _height)
+	{
+		NSWindow* nsWindow = (NSWindow*)g_bgfxNSWindow;
+		
+		NSOpenGLPixelFormatAttribute pixelFormatAttributes[] = {
+			NSOpenGLPFAOpenGLProfile, NSOpenGLProfileVersionLegacy, //NSOpenGLProfileVersion3_2Core,
+			NSOpenGLPFAColorSize    , 24,
+			NSOpenGLPFAAlphaSize    ,  8,
+			NSOpenGLPFADepthSize    , 24,
+			NSOpenGLPFAStencilSize  ,  8,
+			NSOpenGLPFADoubleBuffer ,
+			NSOpenGLPFAAccelerated  ,
+			NSOpenGLPFANoRecovery   ,
+			0
+		};
+		
+		NSOpenGLPixelFormat* pixelFormat =
+		[[NSOpenGLPixelFormat alloc]
+		 initWithAttributes:pixelFormatAttributes];
+		
+		NSRect glViewRect = [[nsWindow contentView] bounds];
+		
+		NSOpenGLView* glView =
+		[[NSOpenGLView alloc]
+		 initWithFrame:glViewRect
+		 pixelFormat:pixelFormat];
+		
+		[pixelFormat release];
+		
+		[nsWindow setContentView:glView];
+		
+		NSOpenGLContext* glContext = [glView openGLContext];
+		[glContext makeCurrentContext];
+		
+		m_view    = glView;
+		m_context = glContext;
+		
+		import();
+	}
+
+	void GlContext::destroy()
+	{
+		NSOpenGLView* glView = (NSOpenGLView*)m_view;
+		m_view = 0;
+		m_context = 0;
+		[glView release];
+	}
+
+	void GlContext::resize(uint32_t _width, uint32_t _height)
+	{
+	}
+
+	void GlContext::swap()
+	{
+		NSOpenGLContext* glContext = (NSOpenGLContext*)m_context;
+		[glContext makeCurrentContext];
+		[glContext flushBuffer];
+	}
+
+	void GlContext::import()
+	{
+#	define GL_IMPORT(_optional, _proto, _func) \
+		{ \
+			_func = (_proto)NSGLGetProcAddress(#_func); \
+			BGFX_FATAL(_optional || NULL != _func, Fatal::UnableToInitialize, "Failed to create OpenGL context. NSGLGetProcAddress(\"%s\")", #_func); \
+		}
+#	include "glimports.h"
+#	undef GL_IMPORT
+	}
+
+} // namespace bgfx
+
+#	endif // BX_PLATFORM_OSX
+#endif //(BGFX_CONFIG_RENDERER_OPENGLES2|BGFX_CONFIG_RENDERER_OPENGLES3|BGFX_CONFIG_RENDERER_OPENGL)

+ 6 - 0
src/renderer_gl.cpp

@@ -1715,9 +1715,15 @@ namespace bgfx
 
 
 #	define GL_GET(_pname, _min) BX_TRACE(#_pname " %d (min: %d)", glGet(_pname), _min)
 #	define GL_GET(_pname, _min) BX_TRACE(#_pname " %d (min: %d)", glGet(_pname), _min)
 
 
+#	if BX_PLATFORM_OSX
+		GL_GET(GL_MAX_FRAGMENT_UNIFORM_COMPONENTS, 16 * 4);
+		GL_GET(GL_MAX_VERTEX_UNIFORM_COMPONENTS, 128 * 4);
+		GL_GET(GL_MAX_VARYING_FLOATS, 8 * 4);
+#	else
 		GL_GET(GL_MAX_FRAGMENT_UNIFORM_VECTORS, 16);
 		GL_GET(GL_MAX_FRAGMENT_UNIFORM_VECTORS, 16);
 		GL_GET(GL_MAX_VERTEX_UNIFORM_VECTORS, 128);
 		GL_GET(GL_MAX_VERTEX_UNIFORM_VECTORS, 128);
 		GL_GET(GL_MAX_VARYING_VECTORS, 8);
 		GL_GET(GL_MAX_VARYING_VECTORS, 8);
+#	endif
 		GL_GET(GL_MAX_VERTEX_ATTRIBS, 8);
 		GL_GET(GL_MAX_VERTEX_ATTRIBS, 8);
 		GL_GET(GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS, 8);
 		GL_GET(GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS, 8);
 		GL_GET(GL_MAX_CUBE_MAP_TEXTURE_SIZE, 16);
 		GL_GET(GL_MAX_CUBE_MAP_TEXTURE_SIZE, 16);

+ 11 - 10
src/renderer_gl.h

@@ -8,6 +8,7 @@
 
 
 #define BGFX_USE_EGL 0
 #define BGFX_USE_EGL 0
 #define BGFX_USE_WGL 0
 #define BGFX_USE_WGL 0
+#define BGFX_USE_NSGL 0
 
 
 #if BGFX_CONFIG_RENDERER_OPENGL
 #if BGFX_CONFIG_RENDERER_OPENGL
 #	if BX_PLATFORM_LINUX
 #	if BX_PLATFORM_LINUX
@@ -17,18 +18,15 @@
 #		include <GL/glx.h>
 #		include <GL/glx.h>
 #		undef GL_PROTOTYPES
 #		undef GL_PROTOTYPES
 #	elif BX_PLATFORM_OSX
 #	elif BX_PLATFORM_OSX
-#		define GL_PROTOTYPES
 #		define GL_GLEXT_LEGACY
 #		define GL_GLEXT_LEGACY
-#		define GL_VERSION_1_2
-#		define GL_VERSION_1_3
-#		define GL_VERSION_1_5
-#		define GL_VERSION_2_0
+#		define long ptrdiff_t
 #		include <OpenGL/gl.h>
 #		include <OpenGL/gl.h>
-#		undef GL_VERSION_2_0
-#		undef GL_VERSION_1_5
-#		undef GL_VERSION_1_3
+#		undef long
 #		undef GL_VERSION_1_2
 #		undef GL_VERSION_1_2
-#		undef GL_PROTOTYPES
+#		undef GL_VERSION_1_3
+#		undef GL_VERSION_1_4
+#		undef GL_VERSION_1_5
+#		undef GL_VERSION_2_0
 #	else
 #	else
 #		include <GL/gl.h>
 #		include <GL/gl.h>
 #	endif // BX_PLATFORM_
 #	endif // BX_PLATFORM_
@@ -147,6 +145,8 @@ typedef void (*PFNGLGETTRANSLATEDSHADERSOURCEANGLEPROC)(GLuint shader, GLsizei b
 #	include <windows.h>
 #	include <windows.h>
 #elif BX_PLATFORM_LINUX
 #elif BX_PLATFORM_LINUX
 #	include "glcontext_glx.h"
 #	include "glcontext_glx.h"
+#elif BX_PLATFORM_OSX
+#	include "glcontext_nsgl.h"
 #endif // BX_PLATFORM_
 #endif // BX_PLATFORM_
 
 
 #if BGFX_CONFIG_DEBUG_GREMEDY && (BX_PLATFORM_WINDOWS || BX_PLATFORM_LINUX)
 #if BGFX_CONFIG_DEBUG_GREMEDY && (BX_PLATFORM_WINDOWS || BX_PLATFORM_LINUX)
@@ -157,6 +157,7 @@ typedef void (*PFNGLGETTRANSLATEDSHADERSOURCEANGLEPROC)(GLuint shader, GLsizei b
 #	include "glcontext_wgl.h"
 #	include "glcontext_wgl.h"
 #endif // BGFX_USE_WGL
 #endif // BGFX_USE_WGL
 
 
+
 #ifndef GL_APIENTRY
 #ifndef GL_APIENTRY
 #   define GL_APIENTRY APIENTRY
 #   define GL_APIENTRY APIENTRY
 #endif // GL_APIENTRY
 #endif // GL_APIENTRY
@@ -363,7 +364,7 @@ namespace bgfx
 		void createColor(uint32_t _width, uint32_t _height, GLenum _min, GLenum _mag);
 		void createColor(uint32_t _width, uint32_t _height, GLenum _min, GLenum _mag);
 		void createDepth(uint32_t _width, uint32_t _height);
 		void createDepth(uint32_t _width, uint32_t _height);
 		void destroy();
 		void destroy();
-		void update(uint8_t _side, uint8_t _mip, const Rect& _rect, uint16_t _z, uint16_t _depth, const Memory* _mem);
+		void update(uint8_t _side, uint8_t _mip, const Rect& _rect, uint16_t _z, uint16_t _depth, const Memory* _mem);
 
 
 		GLuint m_id;
 		GLuint m_id;
 		GLenum m_target;
 		GLenum m_target;