#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(void* shareContext, void* view) { //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: empty view at \"%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 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, 32, NSOpenGLPFAAlphaSize, 8, NSOpenGLPFADepthSize, 8, NSOpenGLPFAStencilSize, 8, NSOpenGLPFAAccumSize, 0, 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; }