#import #import #import #import "ContextUpdater.h" // see MacOSXPbufferGLContext.java createPbuffer #define USE_GL_TEXTURE_RECTANGLE_EXT #ifdef USE_GL_TEXTURE_RECTANGLE_EXT #ifndef GL_TEXTURE_RECTANGLE_EXT #define GL_TEXTURE_RECTANGLE_EXT 0x84F5 #endif #endif typedef int Bool; NSAutoreleasePool* gAutoreleasePool = NULL; void* createContext( JNIEnv* env, jobject glCapabilities, void* shareContext, void* view) { // fprintf( stderr, "Creating context \n"); jclass clazz = (*env)->GetObjectClass( env, glCapabilities ); jfieldID redSizeField = (*env)->GetFieldID( env, clazz, "redBits" , "I" ); jfieldID greenSizeField = (*env)->GetFieldID( env, clazz, "greenBits" , "I" ); jfieldID blueSizeField = (*env)->GetFieldID( env, clazz, "blueBits" , "I" ); jfieldID alphaSizeField = (*env)->GetFieldID( env, clazz, "alphaBits", "I" ); jfieldID depthSizeField = (*env)->GetFieldID( env, clazz, "depthBits", "I" ); jfieldID stencilSizeField = (*env)->GetFieldID( env, clazz, "stencilBits", "I" ); jfieldID accumRedSizeField = (*env)->GetFieldID( env, clazz, "accumRedBits", "I" ); jfieldID accumGreenSizeField = (*env)->GetFieldID( env, clazz, "accumGreenBits", "I" ); jfieldID accumBlueSizeField = (*env)->GetFieldID( env, clazz, "accumBlueBits", "I" ); jfieldID accumAlphaSizeField = (*env)->GetFieldID( env, clazz, "accumAlphaBits", "I" ); jint redSize = (*env)->GetIntField( env, glCapabilities, redSizeField ); jint greenSize = (*env)->GetIntField( env, glCapabilities, greenSizeField ); jint blueSize = (*env)->GetIntField( env, glCapabilities, blueSizeField ); jint colorSize = redSize + greenSize + blueSize; jint accumRedSize = (*env)->GetIntField( env, glCapabilities, accumRedSizeField ); jint accumGreenSize = (*env)->GetIntField( env, glCapabilities, accumGreenSizeField ); jint accumBlueSize = (*env)->GetIntField( env, glCapabilities, accumBlueSizeField ); jint accumAlphaSize = (*env)->GetIntField( env, glCapabilities, accumAlphaSizeField ); jint accumSize = accumRedSize + accumGreenSize + accumBlueSize + accumAlphaSize; jint alphaSize = (*env)->GetIntField( env, glCapabilities, alphaSizeField ); jint depthSize = (*env)->GetIntField( env, glCapabilities, depthSizeField ); jint stencilSize = (*env)->GetIntField( env, glCapabilities, stencilSizeField ); // fprintf(stderr, "Color %d, alpha %d, depth %d, stencil %d, accum %d", colorSize, alphaSize, depthSize, stencilSize, accumSize ); //fprintf(stderr, "createContext shareContext=%p view=%p\n", shareContext, view); NSOpenGLContext *nsChareCtx = (NSOpenGLContext*)shareContext; NSView *nsView = (NSView*)view; if (nsView != NULL) { NSRect frame = [nsView frame]; if ((frame.size.width == 0) || (frame.size.height == 0)) { fprintf(stderr, "Error: view width or height == 0at \"%s:%s:%d\"\n", __FILE__, __FUNCTION__, __LINE__); // the view is not ready yet return NULL; } else if ([nsView lockFocusIfCanDraw] == NO) { fprintf(stderr, "Error: view not ready, cannot lock focus at \"%s:%s:%d\"\n", __FILE__, __FUNCTION__, __LINE__); // the view is not ready yet return NULL; } } if (gAutoreleasePool == NULL) { gAutoreleasePool = [[NSAutoreleasePool alloc] init]; } // FIXME: hardcoded pixel format. Instead pass these attributes down // as arguments. There is really no way to enumerate the possible // pixel formats for a given window on Mac OS X, so we will assume // that we can match the requested capabilities and leave the // selection up to the built-in pixel format selection algorithm. NSOpenGLPixelFormatAttribute attribs[] = { NSOpenGLPFANoRecovery, YES, NSOpenGLPFAAccelerated, YES, NSOpenGLPFADoubleBuffer, YES, NSOpenGLPFAColorSize, colorSize, NSOpenGLPFAAlphaSize, alphaSize, NSOpenGLPFADepthSize, depthSize, NSOpenGLPFAStencilSize, stencilSize, NSOpenGLPFAAccumSize, accumSize, 0 }; NSOpenGLPixelFormat* fmt = [[NSOpenGLPixelFormat alloc] initWithAttributes:attribs]; NSOpenGLContext* nsContext = [[NSOpenGLContext alloc] initWithFormat:fmt shareContext:nsChareCtx]; [fmt release]; if (nsView != nil) { [nsContext setView:nsView]; [nsView unlockFocus]; } [nsContext retain]; //fprintf(stderr, " nsContext=%p\n", nsContext); return nsContext; } Bool makeCurrentContext(void* context, void* view) { //fprintf(stderr, "makeCurrentContext context=%p, view=%p\n", context, view); NSOpenGLContext *nsContext = (NSOpenGLContext*)context; [nsContext makeCurrentContext]; return true; } Bool clearCurrentContext(void* context, void* view) { //fprintf(stderr, "clearCurrentContext context=%p, view=%p\n", context, view); [NSOpenGLContext clearCurrentContext]; return true; } Bool deleteContext(void* context, void* view) { //fprintf(stderr, "deleteContext context=%p, view=%p\n", context, view); NSOpenGLContext *nsContext = (NSOpenGLContext*)context; [nsContext clearDrawable]; [nsContext release]; return true; } Bool flushBuffer(void* context, void* view) { //fprintf(stderr, "flushBuffer context=%p, view=%p\n", context, view); NSOpenGLContext *nsContext = (NSOpenGLContext*)context; [nsContext flushBuffer]; return true; } void updateContext(void* context, void* view) { //fprintf(stderr, "updateContext context=%p, view=%p\n", context, view); NSOpenGLContext *nsContext = (NSOpenGLContext*)context; [nsContext update]; } void* updateContextRegister(void* context, void* view) { //fprintf(stderr, "updateContextRegister context=%p, view=%p\n", context, view); NSOpenGLContext *nsContext = (NSOpenGLContext*)context; NSView *nsView = (NSView*)view; ContextUpdater *contextUpdater = [[ContextUpdater alloc] init]; [contextUpdater registerFor:nsContext with:nsView]; } void updateContextUnregister(void* context, void* view, void* updater) { //fprintf(stderr, "updateContextUnregister context=%p, view=%p\n", context, view); ContextUpdater *contextUpdater = (ContextUpdater *)updater; [contextUpdater release]; } #ifndef USE_GL_TEXTURE_RECTANGLE_EXT static int getNextPowerOf2(int number) { if (((number-1) & number) == 0) { //ex: 8 -> 0b1000; 8-1=7 -> 0b0111; 0b1000&0b0111 == 0 return number; } int power = 0; while (number > 0) { number = number>>1; power++; } return (1< Bool imagesInitialized = false; static char libGLStr[] = "/System/Library/Frameworks/OpenGL.framework/Libraries/libGL.dylib"; static char libGLUStr[] = "/System/Library/Frameworks/OpenGL.framework/Libraries/libGLU.dylib"; static const struct mach_header *libGLImage; static const struct mach_header *libGLUImage; void* getProcAddress(const char *procname) { if (imagesInitialized == false) { imagesInitialized = true; unsigned long options = NSADDIMAGE_OPTION_RETURN_ON_ERROR; libGLImage = NSAddImage(libGLStr, options); libGLUImage = NSAddImage(libGLUStr, options); } unsigned long options = NSLOOKUPSYMBOLINIMAGE_OPTION_BIND | NSLOOKUPSYMBOLINIMAGE_OPTION_RETURN_ON_ERROR; char underscoreName[512] = "_"; strcat(underscoreName, procname); if (NSIsSymbolNameDefinedInImage(libGLImage, underscoreName) == YES) { NSSymbol sym = NSLookupSymbolInImage(libGLImage, underscoreName, options); return NSAddressOfSymbol(sym); } if (NSIsSymbolNameDefinedInImage(libGLUImage, underscoreName) == YES) { NSSymbol sym = NSLookupSymbolInImage(libGLUImage, underscoreName, options); return NSAddressOfSymbol(sym); } if (NSIsSymbolNameDefinedWithHint(underscoreName, "GL")) { NSSymbol sym = NSLookupAndBindSymbol(underscoreName); return NSAddressOfSymbol(sym); } return NULL; }