#import <Cocoa/Cocoa.h> #import <OpenGL/gl.h> #import <jni.h> #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, int redBits, int greenBits, int blueBits, int alphaBits, int depthBits, int stencilBits, int accumRedBits, int accumGreenBits, int accumBlueBits, int accumAlphaBits, int sampleBuffers, int numSamples) { int colorSize = redBits + greenBits + blueBits; int accumSize = accumRedBits + accumGreenBits + accumBlueBits; 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]; } NSOpenGLPixelFormatAttribute attribs[] = { NSOpenGLPFANoRecovery, YES, NSOpenGLPFAAccelerated, YES, NSOpenGLPFADoubleBuffer, YES, NSOpenGLPFAColorSize, colorSize, NSOpenGLPFAAlphaSize, alphaBits, NSOpenGLPFADepthSize, depthBits, NSOpenGLPFAStencilSize, stencilBits, NSOpenGLPFAAccumSize, accumSize, NSOpenGLPFASampleBuffers, sampleBuffers, NSOpenGLPFASamples, numSamples, 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]; return NULL; } void updateContextUnregister(void* context, void* view, void* updater) { //fprintf(stderr, "updateContextUnregister context=%p, view=%p\n", context, view); ContextUpdater *contextUpdater = (ContextUpdater *)updater; [contextUpdater release]; } void* createPBuffer(int renderTarget, int width, int height) { // fprintf(stderr, "createPBuffer renderTarget=%d width=%d height=%d\n", renderTarget, width, height); NSOpenGLPixelBuffer* pBuffer = [[NSOpenGLPixelBuffer alloc] initWithTextureTarget:renderTarget textureInternalFormat:GL_RGBA textureMaxMipMapLevel:0 pixelsWide:width pixelsHigh:height]; return pBuffer; } Bool destroyPBuffer(void* context, void* buffer) { //fprintf(stderr, "destroyPBuffer context=%p, buffer=%p\n", context, buffer); NSOpenGLContext *nsContext = (NSOpenGLContext*)context; NSOpenGLPixelBuffer *pBuffer = (NSOpenGLPixelBuffer*)buffer; if (nsContext != NULL) { [nsContext clearDrawable]; } [pBuffer release]; return true; } void setContextPBuffer(void* context, void* buffer) { NSOpenGLContext *nsContext = (NSOpenGLContext*)context; NSOpenGLPixelBuffer *pBuffer = (NSOpenGLPixelBuffer*)buffer; [nsContext setPixelBuffer: pBuffer cubeMapFace: 0 mipMapLevel: 0 currentVirtualScreen: [nsContext currentVirtualScreen]]; } void setContextTextureImageToPBuffer(void* context, void* buffer, int colorBuffer) { NSOpenGLContext *nsContext = (NSOpenGLContext*)context; NSOpenGLPixelBuffer *pBuffer = (NSOpenGLPixelBuffer*)buffer; [nsContext setTextureImageToPixelBuffer: pBuffer colorBuffer: (unsigned long) colorBuffer]; } #include <mach-o/dyld.h> 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; }