aboutsummaryrefslogtreecommitdiffstats
path: root/src/jogl/native/macosx/MacOSXWindowSystemInterface-calayer.m
diff options
context:
space:
mode:
authorSven Gothel <[email protected]>2012-10-31 15:16:56 +0100
committerSven Gothel <[email protected]>2012-10-31 15:16:56 +0100
commit7dff066bb823dddb5d6e0e7672f5599afa5a43b9 (patch)
tree1981fa4c69ae8c2037ed17af5d2987b8cf6b55b1 /src/jogl/native/macosx/MacOSXWindowSystemInterface-calayer.m
parentc2b328ea96b6cb16ca39f13d4bb4d1236c4b8a1d (diff)
Add OSX CALayer OpenGL 3 (core) support: Derive pixelformat from parent (GL3), use GL3.2 compatible shader; Use VBO in general.
Covered by: Auto unit tests: TestOffscreenLayer01GLCanvasAWT, TestOffscreenLayer02NewtCanvasAWT Manual: TestGearsES2AWT '-gl3 -layered'
Diffstat (limited to 'src/jogl/native/macosx/MacOSXWindowSystemInterface-calayer.m')
-rw-r--r--src/jogl/native/macosx/MacOSXWindowSystemInterface-calayer.m150
1 files changed, 118 insertions, 32 deletions
diff --git a/src/jogl/native/macosx/MacOSXWindowSystemInterface-calayer.m b/src/jogl/native/macosx/MacOSXWindowSystemInterface-calayer.m
index e83d0adcb..6ebf400e2 100644
--- a/src/jogl/native/macosx/MacOSXWindowSystemInterface-calayer.m
+++ b/src/jogl/native/macosx/MacOSXWindowSystemInterface-calayer.m
@@ -3,6 +3,22 @@
#import <pthread.h>
#include "timespec.h"
+#import <OpenGL/glext.h>
+
+/**
+ * Partial include of gl3.h - which we can only expect and use
+ * in case of a GL3 core context at runtime.
+ * Otherwise we would need to have 2 modules, one including GL2
+ * and one inclusing GL3 headers.
+ */
+#ifndef GL_ARB_vertex_array_object
+#define GL_VERTEX_ARRAY_BINDING 0x85B5
+extern void glBindVertexArray (GLuint array);
+extern void glDeleteVertexArrays (GLsizei n, const GLuint *arrays);
+extern void glGenVertexArrays (GLsizei n, GLuint *arrays);
+extern GLboolean glIsVertexArray (GLuint array);
+#endif
+
//
// CADisplayLink only available on iOS >= 3.1, sad, since it's convenient.
// Use CVDisplayLink otherwise.
@@ -82,11 +98,18 @@
@protected
NSOpenGLContext* parentCtx;
+ GLuint gl3ShaderProgramName;
+ GLuint vboBufVert;
+ GLuint vboBufTexCoord;
+ GLint vertAttrLoc;
+ GLint texCoordAttrLoc;
NSOpenGLPixelFormat* parentPixelFmt;
+ int texWidth;
+ int texHeight;
+ int newTexWidth;
+ int newTexHeight;
volatile NSOpenGLPixelBuffer* pbuffer;
volatile GLuint textureID;
- volatile int texWidth;
- volatile int texHeight;
volatile NSOpenGLPixelBuffer* newPBuffer;
#ifdef HAS_CADisplayLink
CADisplayLink* displayLink;
@@ -102,11 +125,10 @@
pthread_mutex_t renderLock;
pthread_cond_t renderSignal;
volatile Bool shallDraw;
- volatile int newTexWidth;
- volatile int newTexHeight;
}
- (id) setupWithContext: (NSOpenGLContext*) parentCtx
+ gl3ShaderProgramName: (GLuint) gl3ShaderProgramName
pixelFormat: (NSOpenGLPixelFormat*) pfmt
pbuffer: (NSOpenGLPixelBuffer*) p
texIDArg: (GLuint) texID
@@ -122,6 +144,7 @@
- (void) setNewPBuffer: (NSOpenGLPixelBuffer*)p;
- (void) applyNewPBuffer;
+- (NSOpenGLPixelFormat *)openGLPixelFormatForDisplayMask:(uint32_t)mask;
- (NSOpenGLContext *)openGLContextForPixelFormat:(NSOpenGLPixelFormat *)pixelFormat;
- (void)disableAnimation;
- (void)pauseAnimation:(Bool)pause;
@@ -172,6 +195,7 @@ static const GLfloat gl_verts[] = {
@implementation MyNSOpenGLLayer
- (id) setupWithContext: (NSOpenGLContext*) _parentCtx
+ gl3ShaderProgramName: (GLuint) _gl3ShaderProgramName
pixelFormat: (NSOpenGLPixelFormat*) _parentPixelFmt
pbuffer: (NSOpenGLPixelBuffer*) p
texIDArg: (GLuint) texID
@@ -192,6 +216,11 @@ static const GLfloat gl_verts[] = {
}
}
parentCtx = _parentCtx;
+ gl3ShaderProgramName = _gl3ShaderProgramName;
+ vboBufVert = 0;
+ vboBufTexCoord = 0;
+ vertAttrLoc = 0;
+ texCoordAttrLoc = 0;
parentPixelFmt = _parentPixelFmt;
swapInterval = 1; // defaults to on (as w/ new GL profiles)
swapIntervalCounter = 0;
@@ -339,7 +368,7 @@ static const GLfloat gl_verts[] = {
SYNC_PRINT("<NP-A %p -> %p>", pbuffer, newPBuffer);
if( 0 != textureID ) {
- glDeleteTextures(1, &textureID);
+ glDeleteTextures(1, (GLuint *)&textureID);
[self setTextureID: 0];
}
[pbuffer release];
@@ -359,7 +388,7 @@ static const GLfloat gl_verts[] = {
DBG_PRINT("MyNSOpenGLLayer::deallocPBuffer (with ctx) %p (refcnt %d) - context %p, pbuffer %p, texID %d\n", self, (int)[self retainCount], context, pbuffer, (int)textureID);
if( 0 != textureID ) {
- glDeleteTextures(1, &textureID);
+ glDeleteTextures(1, (GLuint *)&textureID);
[self setTextureID: 0];
}
if(NULL != pbuffer) {
@@ -378,13 +407,12 @@ static const GLfloat gl_verts[] = {
}
}
-/**
- (NSOpenGLPixelFormat *)openGLPixelFormatForDisplayMask:(uint32_t)mask
{
DBG_PRINT("MyNSOpenGLLayer::openGLPixelFormatForDisplayMask: %p (refcnt %d) - parent-pfmt %p -> new-pfmt %p\n",
self, (int)[self retainCount], parentPixelFmt, parentPixelFmt);
return parentPixelFmt;
-} */
+}
- (NSOpenGLContext *)openGLContextForPixelFormat:(NSOpenGLPixelFormat *)pixelFormat
{
@@ -487,12 +515,16 @@ static const GLfloat gl_verts[] = {
if( NULL != pbuffer ) {
if( texSizeChanged && 0 != textureID ) {
- glDeleteTextures(1, &textureID);
+ glDeleteTextures(1, (GLuint *)&textureID);
[self setTextureID: 0];
}
textureTarget = [pbuffer textureTarget];
+ if( 0 != gl3ShaderProgramName ) {
+ glUseProgram(gl3ShaderProgramName);
+ glActiveTexture(GL_TEXTURE0);
+ }
if( 0 == textureID ) {
- glGenTextures(1, &textureID);
+ glGenTextures(1, (GLuint *)&textureID);
glBindTexture(textureTarget, textureID);
glTexParameteri(textureTarget, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
glTexParameteri(textureTarget, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
@@ -501,26 +533,80 @@ static const GLfloat gl_verts[] = {
} else {
glBindTexture(textureTarget, textureID);
}
- [context setTextureImageToPixelBuffer: pbuffer colorBuffer: GL_FRONT];
+ [context setTextureImageToPixelBuffer: (NSOpenGLPixelBuffer*) pbuffer colorBuffer: GL_FRONT];
} else {
+ if( 0 != gl3ShaderProgramName ) {
+ glUseProgram(gl3ShaderProgramName);
+ glActiveTexture(GL_TEXTURE0);
+ }
textureTarget = GL_TEXTURE_2D;
glBindTexture(textureTarget, textureID);
}
- SYNC_PRINT(" %d*>", (int)textureID);
-
- glEnable(textureTarget);
-
- glEnableClientState(GL_VERTEX_ARRAY);
- glEnableClientState(GL_TEXTURE_COORD_ARRAY);
- glVertexPointer(2, GL_FLOAT, 0, gl_verts);
- glTexCoordPointer(2, GL_FLOAT, 0, gl_texCoords);
-
- glDrawArrays(GL_QUADS, 0, 4);
-
- glDisableClientState(GL_VERTEX_ARRAY);
- glDisableClientState(GL_TEXTURE_COORD_ARRAY);
-
- glDisable(textureTarget);
+ SYNC_PRINT(" %d gl3Prog %d/%d*>", (int)textureID, (int)gl3ShaderProgramName, (int)glIsProgram (gl3ShaderProgramName));
+
+ if( 0 == vboBufVert ) { // Once: Init Data and Bind to Pointer
+ if( 0 != gl3ShaderProgramName ) {
+ // Install default VAO as required by GL 3.2 core!
+ GLuint vaoBuf = 0;
+ glGenVertexArrays(1, &vaoBuf);
+ glBindVertexArray(vaoBuf);
+
+ // Set texture-unit 0
+ GLint texUnitLoc = glGetUniformLocation (gl3ShaderProgramName, "mgl_Texture0");
+ glUniform1i (texUnitLoc, 0);
+ }
+ glGenBuffers( 1, &vboBufVert );
+ glBindBuffer( GL_ARRAY_BUFFER, vboBufVert );
+ glBufferData( GL_ARRAY_BUFFER, 4 * 2 * sizeof(GLfloat), gl_verts, GL_STATIC_DRAW);
+ if( 0 != gl3ShaderProgramName ) {
+ vertAttrLoc = glGetAttribLocation( gl3ShaderProgramName, "mgl_Vertex" );
+ glVertexAttribPointer( vertAttrLoc, 2, GL_FLOAT, GL_FALSE, 0, NULL );
+ } else {
+ glVertexPointer(2, GL_FLOAT, 0, NULL);
+ }
+
+ glGenBuffers( 1, &vboBufTexCoord );
+ glBindBuffer( GL_ARRAY_BUFFER, vboBufTexCoord );
+ glBufferData( GL_ARRAY_BUFFER, 4 * 2 * sizeof(GLfloat), gl_texCoords, GL_STATIC_DRAW);
+ if( 0 != gl3ShaderProgramName ) {
+ texCoordAttrLoc = glGetAttribLocation( gl3ShaderProgramName, "mgl_MultiTexCoord" );
+ glVertexAttribPointer( texCoordAttrLoc, 2, GL_FLOAT, GL_FALSE, 0, NULL );
+ } else {
+ glTexCoordPointer(2, GL_FLOAT, 0, NULL);
+ }
+ }
+ if( texSizeChanged ) {
+ glBindBuffer( GL_ARRAY_BUFFER, vboBufTexCoord );
+ glBufferSubData( GL_ARRAY_BUFFER, 0, 4 * 2 * sizeof(GLfloat), gl_texCoords);
+ if( 0 != gl3ShaderProgramName ) {
+ glVertexAttribPointer( texCoordAttrLoc, 2, GL_FLOAT, GL_FALSE, 0, NULL );
+ } else {
+ glTexCoordPointer(2, GL_FLOAT, 0, NULL);
+ }
+ }
+ if( 0 != gl3ShaderProgramName ) {
+ glEnableVertexAttribArray( vertAttrLoc );
+ glEnableVertexAttribArray( texCoordAttrLoc );
+ } else {
+ glEnable(textureTarget);
+
+ glEnableClientState(GL_VERTEX_ARRAY);
+ glEnableClientState(GL_TEXTURE_COORD_ARRAY);
+ }
+
+ glDrawArrays(GL_TRIANGLE_FAN, 0, 4);
+
+ if( 0 != gl3ShaderProgramName ) {
+ glDisableVertexAttribArray( vertAttrLoc );
+ glDisableVertexAttribArray( texCoordAttrLoc );
+ glUseProgram(0);
+ } else {
+ glDisableClientState(GL_VERTEX_ARRAY);
+ glDisableClientState(GL_TEXTURE_COORD_ARRAY);
+
+ glDisable(textureTarget);
+ }
+
glBindTexture(textureTarget, 0);
[context clearDrawable];
@@ -664,13 +750,13 @@ static const GLfloat gl_verts[] = {
@end
-NSOpenGLLayer* createNSOpenGLLayer(NSOpenGLContext* ctx, NSOpenGLPixelFormat* fmt, NSOpenGLPixelBuffer* p, uint32_t texID, Bool opaque, int texWidth, int texHeight) {
+NSOpenGLLayer* createNSOpenGLLayer(NSOpenGLContext* ctx, int gl3ShaderProgramName, NSOpenGLPixelFormat* fmt, NSOpenGLPixelBuffer* p, uint32_t texID, Bool opaque, int texWidth, int texHeight) {
// This simply crashes after dealloc() has been called .. ie. ref-count -> 0 too early ?
// However using alloc/init, actual dealloc happens at JAWT destruction, hence too later IMHO.
// return [[MyNSOpenGLLayer layer] setupWithContext:ctx pixelFormat: fmt pbuffer: p texIDArg: (GLuint)texID
// opaque: opaque texWidth: texWidth texHeight: texHeight];
- return [[[MyNSOpenGLLayer alloc] init] setupWithContext:ctx pixelFormat: fmt pbuffer: p texIDArg: (GLuint)texID
+ return [[[MyNSOpenGLLayer alloc] init] setupWithContext:ctx gl3ShaderProgramName: (GLuint)gl3ShaderProgramName pixelFormat: fmt pbuffer: p texIDArg: (GLuint)texID
opaque: opaque texWidth: texWidth texHeight: texHeight];
}
@@ -688,7 +774,7 @@ void waitUntilNSOpenGLLayerIsReady(NSOpenGLLayer* layer, long to_micros) {
[pool release];
}
-void setNSOpenGLLayerNeedsDisplayFBO(NSOpenGLLayer* layer, uint32_t texID, int texWidth, int texHeight) {
+void setNSOpenGLLayerNeedsDisplayFBO(NSOpenGLLayer* layer, uint32_t texID) {
MyNSOpenGLLayer* l = (MyNSOpenGLLayer*) layer;
NSAutoreleasePool* pool = [[NSAutoreleasePool alloc] init];
Bool shallDraw;
@@ -698,7 +784,7 @@ void setNSOpenGLLayerNeedsDisplayFBO(NSOpenGLLayer* layer, uint32_t texID, int t
shallDraw = [l isGLSourceValid];
l->shallDraw = shallDraw;
- SYNC_PRINT("<! T%dx%d O%dx%d %d>", texWidth, texHeight, l->newTexWidth, l->newTexHeight, (int)shallDraw);
+ SYNC_PRINT("<! T %d>", (int)shallDraw);
if(shallDraw) {
if ( [NSThread isMainThread] == YES ) {
[l setNeedsDisplay];
@@ -711,7 +797,7 @@ void setNSOpenGLLayerNeedsDisplayFBO(NSOpenGLLayer* layer, uint32_t texID, int t
[pool release];
}
-void setNSOpenGLLayerNeedsDisplayPBuffer(NSOpenGLLayer* layer, NSOpenGLPixelBuffer* p, int texWidth, int texHeight) {
+void setNSOpenGLLayerNeedsDisplayPBuffer(NSOpenGLLayer* layer, NSOpenGLPixelBuffer* p) {
MyNSOpenGLLayer* l = (MyNSOpenGLLayer*) layer;
NSAutoreleasePool* pool = [[NSAutoreleasePool alloc] init];
Bool shallDraw;
@@ -724,7 +810,7 @@ void setNSOpenGLLayerNeedsDisplayPBuffer(NSOpenGLLayer* layer, NSOpenGLPixelBuff
shallDraw = [l isGLSourceValid];
l->shallDraw = shallDraw;
- SYNC_PRINT("<! T%dx%d O%dx%d %d>", texWidth, texHeight, l->newTexWidth, l->newTexHeight, (int)shallDraw);
+ SYNC_PRINT("<! T %d>", (int)shallDraw);
if(shallDraw) {
if ( [NSThread isMainThread] == YES ) {
[l setNeedsDisplay];