You cannot select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and dots ('.'), can be up to 35 characters long. Letters must be lowercase.
298 lines
9.1 KiB
298 lines
9.1 KiB
//======================================================================== |
|
// GLFW 3.1 OS X - www.glfw.org |
|
//------------------------------------------------------------------------ |
|
// Copyright (c) 2009-2010 Camilla Berglund <elmindreda@elmindreda.org> |
|
// |
|
// This software is provided 'as-is', without any express or implied |
|
// warranty. In no event will the authors be held liable for any damages |
|
// arising from the use of this software. |
|
// |
|
// Permission is granted to anyone to use this software for any purpose, |
|
// including commercial applications, and to alter it and redistribute it |
|
// freely, subject to the following restrictions: |
|
// |
|
// 1. The origin of this software must not be misrepresented; you must not |
|
// claim that you wrote the original software. If you use this software |
|
// in a product, an acknowledgment in the product documentation would |
|
// be appreciated but is not required. |
|
// |
|
// 2. Altered source versions must be plainly marked as such, and must not |
|
// be misrepresented as being the original software. |
|
// |
|
// 3. This notice may not be removed or altered from any source |
|
// distribution. |
|
// |
|
//======================================================================== |
|
|
|
#include "internal.h" |
|
|
|
|
|
////////////////////////////////////////////////////////////////////////// |
|
////// GLFW internal API ////// |
|
////////////////////////////////////////////////////////////////////////// |
|
|
|
// Initialize OpenGL support |
|
// |
|
int _glfwInitContextAPI(void) |
|
{ |
|
if (!_glfwInitTLS()) |
|
return GL_FALSE; |
|
|
|
_glfw.nsgl.framework = |
|
CFBundleGetBundleWithIdentifier(CFSTR("com.apple.opengl")); |
|
if (_glfw.nsgl.framework == NULL) |
|
{ |
|
_glfwInputError(GLFW_PLATFORM_ERROR, |
|
"NSGL: Failed to locate OpenGL framework"); |
|
return GL_FALSE; |
|
} |
|
|
|
return GL_TRUE; |
|
} |
|
|
|
// Terminate OpenGL support |
|
// |
|
void _glfwTerminateContextAPI(void) |
|
{ |
|
_glfwTerminateTLS(); |
|
} |
|
|
|
// Create the OpenGL context |
|
// |
|
int _glfwCreateContext(_GLFWwindow* window, |
|
const _GLFWctxconfig* ctxconfig, |
|
const _GLFWfbconfig* fbconfig) |
|
{ |
|
unsigned int attributeCount = 0; |
|
|
|
if (ctxconfig->api == GLFW_OPENGL_ES_API) |
|
{ |
|
_glfwInputError(GLFW_VERSION_UNAVAILABLE, |
|
"NSGL: This API does not support OpenGL ES"); |
|
return GL_FALSE; |
|
} |
|
|
|
#if MAC_OS_X_VERSION_MAX_ALLOWED >= 1070 |
|
if (ctxconfig->major == 3 && ctxconfig->minor < 2) |
|
{ |
|
_glfwInputError(GLFW_VERSION_UNAVAILABLE, |
|
"NSGL: The targeted version of OS X does not " |
|
"support OpenGL 3.0 or 3.1"); |
|
return GL_FALSE; |
|
} |
|
|
|
if (ctxconfig->major > 2) |
|
{ |
|
if (!ctxconfig->forward) |
|
{ |
|
_glfwInputError(GLFW_VERSION_UNAVAILABLE, |
|
"NSGL: The targeted version of OS X only " |
|
"supports OpenGL 3.2 and later versions if they " |
|
"are forward-compatible"); |
|
return GL_FALSE; |
|
} |
|
|
|
if (ctxconfig->profile != GLFW_OPENGL_CORE_PROFILE) |
|
{ |
|
_glfwInputError(GLFW_VERSION_UNAVAILABLE, |
|
"NSGL: The targeted version of OS X only " |
|
"supports OpenGL 3.2 and later versions if they " |
|
"use the core profile"); |
|
return GL_FALSE; |
|
} |
|
} |
|
#else |
|
// Fail if OpenGL 3.0 or above was requested |
|
if (ctxconfig->major > 2) |
|
{ |
|
_glfwInputError(GLFW_VERSION_UNAVAILABLE, |
|
"NSGL: The targeted version of OS X does not " |
|
"support OpenGL version 3.0 or above"); |
|
return GL_FALSE; |
|
} |
|
#endif /*MAC_OS_X_VERSION_MAX_ALLOWED*/ |
|
|
|
// Context robustness modes (GL_KHR_robustness) are not yet supported on |
|
// OS X but are not a hard constraint, so ignore and continue |
|
|
|
#define ADD_ATTR(x) { attributes[attributeCount++] = x; } |
|
#define ADD_ATTR2(x, y) { ADD_ATTR(x); ADD_ATTR(y); } |
|
|
|
// Arbitrary array size here |
|
NSOpenGLPixelFormatAttribute attributes[40]; |
|
|
|
ADD_ATTR(NSOpenGLPFAClosestPolicy); |
|
|
|
#if MAC_OS_X_VERSION_MAX_ALLOWED >= 1070 |
|
if (ctxconfig->major > 2) |
|
ADD_ATTR2(NSOpenGLPFAOpenGLProfile, NSOpenGLProfileVersion3_2Core); |
|
#endif /*MAC_OS_X_VERSION_MAX_ALLOWED*/ |
|
|
|
if (fbconfig->redBits != GLFW_DONT_CARE && |
|
fbconfig->greenBits != GLFW_DONT_CARE && |
|
fbconfig->blueBits != GLFW_DONT_CARE) |
|
{ |
|
int colorBits = fbconfig->redBits + |
|
fbconfig->greenBits + |
|
fbconfig->blueBits; |
|
|
|
// OS X needs non-zero color size, so set resonable values |
|
if (colorBits == 0) |
|
colorBits = 24; |
|
else if (colorBits < 15) |
|
colorBits = 15; |
|
|
|
ADD_ATTR2(NSOpenGLPFAColorSize, colorBits); |
|
} |
|
|
|
if (fbconfig->alphaBits != GLFW_DONT_CARE) |
|
ADD_ATTR2(NSOpenGLPFAAlphaSize, fbconfig->alphaBits); |
|
|
|
if (fbconfig->depthBits != GLFW_DONT_CARE) |
|
ADD_ATTR2(NSOpenGLPFADepthSize, fbconfig->depthBits); |
|
|
|
if (fbconfig->stencilBits != GLFW_DONT_CARE) |
|
ADD_ATTR2(NSOpenGLPFAStencilSize, fbconfig->stencilBits); |
|
|
|
if (fbconfig->accumRedBits != GLFW_DONT_CARE && |
|
fbconfig->accumGreenBits != GLFW_DONT_CARE && |
|
fbconfig->accumBlueBits != GLFW_DONT_CARE && |
|
fbconfig->accumAlphaBits != GLFW_DONT_CARE) |
|
{ |
|
const int accumBits = fbconfig->accumRedBits + |
|
fbconfig->accumGreenBits + |
|
fbconfig->accumBlueBits + |
|
fbconfig->accumAlphaBits; |
|
|
|
ADD_ATTR2(NSOpenGLPFAAccumSize, accumBits); |
|
} |
|
|
|
if (fbconfig->auxBuffers != GLFW_DONT_CARE) |
|
ADD_ATTR2(NSOpenGLPFAAuxBuffers, fbconfig->auxBuffers); |
|
|
|
if (fbconfig->stereo) |
|
ADD_ATTR(NSOpenGLPFAStereo); |
|
|
|
if (fbconfig->doublebuffer) |
|
ADD_ATTR(NSOpenGLPFADoubleBuffer); |
|
|
|
if (fbconfig->samples != GLFW_DONT_CARE) |
|
{ |
|
if (fbconfig->samples == 0) |
|
{ |
|
ADD_ATTR2(NSOpenGLPFASampleBuffers, 0); |
|
} |
|
else |
|
{ |
|
ADD_ATTR2(NSOpenGLPFASampleBuffers, 1); |
|
ADD_ATTR2(NSOpenGLPFASamples, fbconfig->samples); |
|
} |
|
} |
|
|
|
// NOTE: All NSOpenGLPixelFormats on the relevant cards support sRGB |
|
// frambuffer, so there's no need (and no way) to request it |
|
|
|
ADD_ATTR(0); |
|
|
|
#undef ADD_ATTR |
|
#undef ADD_ATTR2 |
|
|
|
window->nsgl.pixelFormat = |
|
[[NSOpenGLPixelFormat alloc] initWithAttributes:attributes]; |
|
if (window->nsgl.pixelFormat == nil) |
|
{ |
|
_glfwInputError(GLFW_PLATFORM_ERROR, |
|
"NSGL: Failed to create OpenGL pixel format"); |
|
return GL_FALSE; |
|
} |
|
|
|
NSOpenGLContext* share = NULL; |
|
|
|
if (ctxconfig->share) |
|
share = ctxconfig->share->nsgl.context; |
|
|
|
window->nsgl.context = |
|
[[NSOpenGLContext alloc] initWithFormat:window->nsgl.pixelFormat |
|
shareContext:share]; |
|
if (window->nsgl.context == nil) |
|
{ |
|
_glfwInputError(GLFW_PLATFORM_ERROR, |
|
"NSGL: Failed to create OpenGL context"); |
|
return GL_FALSE; |
|
} |
|
|
|
return GL_TRUE; |
|
} |
|
|
|
// Destroy the OpenGL context |
|
// |
|
void _glfwDestroyContext(_GLFWwindow* window) |
|
{ |
|
[window->nsgl.pixelFormat release]; |
|
window->nsgl.pixelFormat = nil; |
|
|
|
[window->nsgl.context release]; |
|
window->nsgl.context = nil; |
|
} |
|
|
|
|
|
////////////////////////////////////////////////////////////////////////// |
|
////// GLFW platform API ////// |
|
////////////////////////////////////////////////////////////////////////// |
|
|
|
void _glfwPlatformMakeContextCurrent(_GLFWwindow* window) |
|
{ |
|
if (window) |
|
[window->nsgl.context makeCurrentContext]; |
|
else |
|
[NSOpenGLContext clearCurrentContext]; |
|
|
|
_glfwSetCurrentContext(window); |
|
} |
|
|
|
void _glfwPlatformSwapBuffers(_GLFWwindow* window) |
|
{ |
|
// ARP appears to be unnecessary, but this is future-proof |
|
[window->nsgl.context flushBuffer]; |
|
} |
|
|
|
void _glfwPlatformSwapInterval(int interval) |
|
{ |
|
_GLFWwindow* window = _glfwPlatformGetCurrentContext(); |
|
|
|
GLint sync = interval; |
|
[window->nsgl.context setValues:&sync forParameter:NSOpenGLCPSwapInterval]; |
|
} |
|
|
|
int _glfwPlatformExtensionSupported(const char* extension) |
|
{ |
|
// There are no NSGL extensions |
|
return GL_FALSE; |
|
} |
|
|
|
GLFWglproc _glfwPlatformGetProcAddress(const char* procname) |
|
{ |
|
CFStringRef symbolName = CFStringCreateWithCString(kCFAllocatorDefault, |
|
procname, |
|
kCFStringEncodingASCII); |
|
|
|
GLFWglproc symbol = CFBundleGetFunctionPointerForName(_glfw.nsgl.framework, |
|
symbolName); |
|
|
|
CFRelease(symbolName); |
|
|
|
return symbol; |
|
} |
|
|
|
|
|
////////////////////////////////////////////////////////////////////////// |
|
////// GLFW native API ////// |
|
////////////////////////////////////////////////////////////////////////// |
|
|
|
GLFWAPI id glfwGetNSGLContext(GLFWwindow* handle) |
|
{ |
|
_GLFWwindow* window = (_GLFWwindow*) handle; |
|
_GLFW_REQUIRE_INIT_OR_RETURN(nil); |
|
return window->nsgl.context; |
|
} |
|
|
|
|