diff options
Diffstat (limited to 'src/jogl/native/macosx/MacOSXWindowSystemInterface-pbuffer.m')
-rw-r--r-- | src/jogl/native/macosx/MacOSXWindowSystemInterface-pbuffer.m | 151 |
1 files changed, 151 insertions, 0 deletions
diff --git a/src/jogl/native/macosx/MacOSXWindowSystemInterface-pbuffer.m b/src/jogl/native/macosx/MacOSXWindowSystemInterface-pbuffer.m new file mode 100644 index 000000000..16e5829ba --- /dev/null +++ b/src/jogl/native/macosx/MacOSXWindowSystemInterface-pbuffer.m @@ -0,0 +1,151 @@ +#import "MacOSXWindowSystemInterface.h" + +@interface MyNSOpenGLLayer: NSOpenGLLayer +{ +@protected + NSOpenGLPixelBuffer* pbuffer; + int width; + int height; + GLuint textureID; +@public + volatile BOOL shallDraw; +} + +- (id) initWithContext: (NSOpenGLContext*) ctx + pixelFormat: (NSOpenGLPixelFormat*) pfmt + pbuffer: (NSOpenGLPixelBuffer*) p + opaque: (Bool) opaque + width: (int) width + height: (int) height; + +@end + +@implementation MyNSOpenGLLayer + +- (id) initWithContext: (NSOpenGLContext*) _ctx + pixelFormat: (NSOpenGLPixelFormat*) _fmt + pbuffer: (NSOpenGLPixelBuffer*) p + opaque: (Bool) opaque + width: (int) _width + height: (int) _height; +{ + self = [super init]; + pbuffer = p; + [pbuffer retain]; + + [self setAsynchronous: NO]; + // [self setAsynchronous: YES]; // FIXME: JAU + [self setNeedsDisplayOnBoundsChange: NO]; + [self setOpaque: opaque ? YES : NO]; + width = _width; + height = _height; + textureID = 0; + shallDraw = NO; + DBG_PRINT("MyNSOpenGLLayer::init %p, ctx %p, pfmt %p, pbuffer %p, opaque %d, %dx%d -> %dx%d\n", + self, _ctx, _fmt, pbuffer, opaque, width, height, [pbuffer pixelsWide], [pbuffer pixelsHigh]); + return self; +} + +- (void)dealloc +{ + [pbuffer release]; + DBG_PRINT("MyNSOpenGLLayer::dealloc %p\n", self); + [super dealloc]; +} + +- (BOOL)canDrawInOpenGLContext:(NSOpenGLContext *)context pixelFormat:(NSOpenGLPixelFormat *)pixelFormat + forLayerTime:(CFTimeInterval)timeInterval displayTime:(const CVTimeStamp *)timeStamp +{ + DBG_PRINT("MyNSOpenGLLayer::canDrawInOpenGLContext %p: %d\n", self, self->shallDraw); + return self->shallDraw; +} + +- (void)drawInOpenGLContext:(NSOpenGLContext *)context pixelFormat:(NSOpenGLPixelFormat *)pixelFormat + forLayerTime:(CFTimeInterval)timeInterval displayTime:(const CVTimeStamp *)timeStamp +{ + self->shallDraw = NO; + + [context makeCurrentContext]; + + GLenum textureTarget = [pbuffer textureTarget]; + GLsizei pwidth = [pbuffer pixelsWide]; + GLsizei pheight = [pbuffer pixelsHigh]; + GLfloat tWidth = textureTarget == GL_TEXTURE_2D ? (GLfloat)width/(GLfloat)pwidth : pwidth; + GLfloat tHeight = textureTarget == GL_TEXTURE_2D ? (GLfloat)height/(GLfloat)pheight : pheight; + + DBG_PRINT("MyNSOpenGLLayer::drawInOpenGLContext %p, ctx %p, pfmt %p %dx%d -> %fx%f 0x%X\n", + self, context, pixelFormat, width, height, tWidth, tHeight, textureTarget); + + if(0 == textureID) { + glGenTextures(1, &textureID); + } + glBindTexture(textureTarget, textureID); + + [context setTextureImageToPixelBuffer: pbuffer colorBuffer: GL_FRONT]; + + glTexParameteri(textureTarget, GL_TEXTURE_MIN_FILTER, GL_NEAREST); + glTexParameteri(textureTarget, GL_TEXTURE_MAG_FILTER, GL_NEAREST); + glTexParameteri(textureTarget, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); + glTexParameteri(textureTarget, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); + + glEnable(textureTarget); + + static GLfloat verts[] = { + -1.0, -1.0, + -1.0, 1.0, + 1.0, 1.0, + 1.0, -1.0 + }; + + GLfloat tex[] = { + 0.0, 0.0, + 0.0, tHeight, + tWidth, tHeight, + tWidth, 0.0 + }; + + glEnableClientState(GL_VERTEX_ARRAY); + glEnableClientState(GL_TEXTURE_COORD_ARRAY); + glVertexPointer(2, GL_FLOAT, 0, verts); + glTexCoordPointer(2, GL_FLOAT, 0, tex); + + glDrawArrays(GL_QUADS, 0, 4); + + glDisableClientState(GL_VERTEX_ARRAY); + glDisableClientState(GL_TEXTURE_COORD_ARRAY); + + glDisable(textureTarget); + + [super drawInOpenGLContext: context pixelFormat: pixelFormat forLayerTime: timeInterval displayTime: timeStamp]; +} + +@end + +NSOpenGLLayer* createNSOpenGLLayer(NSOpenGLContext* ctx, NSOpenGLPixelFormat* fmt, NSOpenGLPixelBuffer* p, Bool opaque, int width, int height) { + return [[MyNSOpenGLLayer alloc] initWithContext:ctx pixelFormat: fmt pbuffer: p opaque: opaque width: width height: height]; +} + +void setNSOpenGLLayerNeedsDisplay(NSOpenGLLayer* layer) { + MyNSOpenGLLayer* l = (MyNSOpenGLLayer*) layer; + NSAutoreleasePool* pool = [[NSAutoreleasePool alloc] init]; + l->shallDraw = YES; + if ( [NSThread isMainThread] == YES ) { + [l setNeedsDisplay]; + } else { + // [l performSelectorOnMainThread:@selector(setNeedsDisplay) withObject:nil waitUntilDone:YES]; + [l performSelectorOnMainThread:@selector(setNeedsDisplay) withObject:nil waitUntilDone:NO]; + } + // NSView* view = [l view]; + // [view setNeedsDisplay: YES]; // FIXME: JAU + // [view performSelectorOnMainThread:@selector(setNeedsDisplay:) withObject:YES waitUntilDone:YES]; + // [view performSelectorOnMainThread:@selector(display) withObject:nil waitUntilDone:YES]; + DBG_PRINT("MyNSOpenGLLayer::setNSOpenGLLayerNeedsDisplay %p\n", l); + [pool release]; +} + +void releaseNSOpenGLLayer(NSOpenGLLayer* l) { + NSAutoreleasePool* pool = [[NSAutoreleasePool alloc] init]; + [l release]; + [pool release]; +} + |