summaryrefslogtreecommitdiffstats
path: root/src/jogl/native/macosx/MacOSXWindowSystemInterface-pbuffer.m
diff options
context:
space:
mode:
Diffstat (limited to 'src/jogl/native/macosx/MacOSXWindowSystemInterface-pbuffer.m')
-rw-r--r--src/jogl/native/macosx/MacOSXWindowSystemInterface-pbuffer.m151
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];
+}
+