/* * Copyright (c) 2002-2008 LWJGL Project * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are * met: * * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * * Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * * * Neither the name of 'LWJGL' nor the names of * its contributors may be used to endorse or promote products derived * from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ /** * $Id$ * * @author elias_naur * @version $Revision$ */ #import #import "context.h" static CFBundleRef opengl_bundle = NULL; void *extgl_GetProcAddress(const char *name) { CFStringRef cf_name = CFStringCreateWithCString(NULL, name, kCFStringEncodingUTF8); void *address = CFBundleGetFunctionPointerForName(opengl_bundle, cf_name); CFRelease(cf_name); return address; } static CFBundleRef loadFramework(JNIEnv *env) { CFStringRef framework_path = CFSTR("/System/Library/Frameworks/OpenGL.framework"); if (framework_path == NULL) { printfDebugJava(env, "Failed to allocate string"); return NULL; } CFURLRef url = CFURLCreateWithFileSystemPath(NULL, framework_path, kCFURLPOSIXPathStyle, TRUE); if (url == NULL) { printfDebugJava(env, "Failed to allocate URL"); return NULL; } CFBundleRef opengl_bundle = CFBundleCreate(NULL, url); CFRelease(url); return opengl_bundle; } bool extgl_Open(JNIEnv *env) { if (opengl_bundle != NULL) return true; opengl_bundle = loadFramework(env); if (opengl_bundle != NULL) { return true; } else { throwException(env, "Could not load OpenGL library"); return false; } } void extgl_Close(void) { if (opengl_bundle != NULL) { CFRelease(opengl_bundle); opengl_bundle = NULL; } } #if __MAC_OS_X_VERSION_MAX_ALLOWED >= 1050 size_t CGDisplayBitsPerPixel(CGDirectDisplayID display) { CGDisplayModeRef mode = CGDisplayCopyDisplayMode(display); size_t depth = 0; CFStringRef pixEnc = CGDisplayModeCopyPixelEncoding(mode); if(CFStringCompare(pixEnc, CFSTR(IO32BitDirectPixels), kCFCompareCaseInsensitive) == kCFCompareEqualTo) depth = 32; else if(CFStringCompare(pixEnc, CFSTR(IO16BitDirectPixels), kCFCompareCaseInsensitive) == kCFCompareEqualTo) depth = 16; else if(CFStringCompare(pixEnc, CFSTR(IO8BitIndexedPixels), kCFCompareCaseInsensitive) == kCFCompareEqualTo) depth = 8; return depth; } #else // CGDisplayBitsPerPixel is defined #endif NSOpenGLPixelFormat *choosePixelFormat(JNIEnv *env, jobject pixel_format, bool gl32, bool use_display_bpp, bool support_window, bool support_pbuffer, bool double_buffered) { int bpp; jclass cls_pixel_format = (*env)->GetObjectClass(env, pixel_format); if (use_display_bpp) { if (floor(NSAppKitVersionNumber) > NSAppKitVersionNumber10_5) { // if OS X 10.6+ use newer api CGDisplayModeRef mode = CGDisplayCopyDisplayMode(kCGDirectMainDisplay); CFStringRef pixEnc = CGDisplayModeCopyPixelEncoding(mode); if (CFStringCompare(pixEnc, CFSTR(IO32BitDirectPixels), kCFCompareCaseInsensitive) == kCFCompareEqualTo) bpp = 32; else if(CFStringCompare(pixEnc, CFSTR(IO16BitDirectPixels), kCFCompareCaseInsensitive) == kCFCompareEqualTo) bpp = 16; else if(CFStringCompare(pixEnc, CFSTR(IO8BitIndexedPixels), kCFCompareCaseInsensitive) == kCFCompareEqualTo) bpp = 8; else bpp = CGDisplayBitsPerPixel(kCGDirectMainDisplay); } else { bpp = CGDisplayBitsPerPixel(kCGDirectMainDisplay); } } else bpp = (int)(*env)->GetIntField(env, pixel_format, (*env)->GetFieldID(env, cls_pixel_format, "bpp", "I")); int alpha = (int)(*env)->GetIntField(env, pixel_format, (*env)->GetFieldID(env, cls_pixel_format, "alpha", "I")); int depth = (int)(*env)->GetIntField(env, pixel_format, (*env)->GetFieldID(env, cls_pixel_format, "depth", "I")); int stencil = (int)(*env)->GetIntField(env, pixel_format, (*env)->GetFieldID(env, cls_pixel_format, "stencil", "I")); int samples = (int)(*env)->GetIntField(env, pixel_format, (*env)->GetFieldID(env, cls_pixel_format, "samples", "I")); int num_aux_buffers = (int)(*env)->GetIntField(env, pixel_format, (*env)->GetFieldID(env, cls_pixel_format, "num_aux_buffers", "I")); int accum_bpp = (int)(*env)->GetIntField(env, pixel_format, (*env)->GetFieldID(env, cls_pixel_format, "accum_bpp", "I")); int accum_alpha = (int)(*env)->GetIntField(env, pixel_format, (*env)->GetFieldID(env, cls_pixel_format, "accum_alpha", "I")); bool stereo = (bool)(*env)->GetBooleanField(env, pixel_format, (*env)->GetFieldID(env, cls_pixel_format, "stereo", "Z")); bool floating_point = (bool)(*env)->GetBooleanField(env, pixel_format, (*env)->GetFieldID(env, cls_pixel_format, "floating_point", "Z")); // TODO: Add floating_point_packed attribute below //bool floating_point_packed = (bool)(*env)->GetBooleanField(env, pixel_format, (*env)->GetFieldID(env, cls_pixel_format, "floating_point_packed", "Z")); // TODO: Add sRGB attribute below //bool sRGB = (bool)(*env)->GetBooleanField(env, pixel_format, (*env)->GetFieldID(env, cls_pixel_format, "sRGB", "Z")); attrib_list_t attribs; jboolean allow_software_acceleration = getBooleanProperty(env, "org.lwjgl.opengl.Display.allowSoftwareOpenGL"); initAttribList(&attribs); if (!allow_software_acceleration) putAttrib(&attribs, NSOpenGLPFAAccelerated); if (double_buffered) putAttrib(&attribs, NSOpenGLPFADoubleBuffer); putAttrib(&attribs, NSOpenGLPFAMinimumPolicy); putAttrib(&attribs, NSOpenGLPFAColorSize); putAttrib(&attribs, bpp); putAttrib(&attribs, NSOpenGLPFAAlphaSize); putAttrib(&attribs, alpha); putAttrib(&attribs, NSOpenGLPFADepthSize); putAttrib(&attribs, depth); putAttrib(&attribs, NSOpenGLPFAStencilSize); putAttrib(&attribs, stencil); putAttrib(&attribs, NSOpenGLPFAAccumSize); putAttrib(&attribs, accum_bpp + accum_alpha); putAttrib(&attribs, NSOpenGLPFASampleBuffers); putAttrib(&attribs, samples > 0 ? 1 : 0); putAttrib(&attribs, NSOpenGLPFASamples); putAttrib(&attribs, samples); putAttrib(&attribs, NSOpenGLPFAAuxBuffers); putAttrib(&attribs, num_aux_buffers); if (gl32) { putAttrib(&attribs, 99); // NSOpenGLPFAOpenGLProfile putAttrib(&attribs, 0x3200); // NSOpenGLProfileVersion3_2Core } else { if (support_window) putAttrib(&attribs, NSOpenGLPFAWindow); if (support_pbuffer) putAttrib(&attribs, NSOpenGLPFAPixelBuffer); } if (stereo) putAttrib(&attribs, NSOpenGLPFAStereo); if (floating_point) putAttrib(&attribs, NSOpenGLPFAColorFloat); putAttrib(&attribs, 0); NSOpenGLPixelFormat* fmt = [[NSOpenGLPixelFormat alloc] initWithAttributes:(NSOpenGLPixelFormatAttribute *)attribs.attribs]; if (fmt == nil) { throwException(env, "Could not create pixel format"); return NULL; } return fmt; }