Implement CALayer rendering, no input yet

This commit is contained in:
kappaOne 2013-01-13 15:34:24 +00:00
parent 790f895220
commit 0dda33cd2d
5 changed files with 126 additions and 63 deletions

View file

@ -84,6 +84,8 @@ final class MacOSXDisplay implements DisplayImplementation {
private static final IntBuffer current_viewport = BufferUtils.createIntBuffer(16);
private boolean close_requested;
private boolean native_mode = true;
MacOSXDisplay() {
@ -123,6 +125,8 @@ final class MacOSXDisplay implements DisplayImplementation {
close_requested = false;
native_mode = isNativeMode();
DrawableGL gl_drawable = (DrawableGL)Display.getDrawable();
PeerInfo peer_info = gl_drawable.peer_info;
ByteBuffer peer_handle = peer_info.lockAndGetHandle();
@ -148,6 +152,10 @@ final class MacOSXDisplay implements DisplayImplementation {
peer_info.unlock();
}
}
private boolean isNativeMode() {
return true;
}
public void doHandleQuit() {
synchronized (this) {

View file

@ -102,10 +102,16 @@ typedef struct {
@private
CGLContextObj contextObject;
int fboID;
int imageRenderBufferID;
int depthRenderBufferID;
int fboWidth;
int fboHeight;
}
- (void) attachLayer;
- (void) removeLayer;
- (void) blitFrameBuffer;
@end

View file

@ -435,35 +435,29 @@ JNIEXPORT jobject JNICALL Java_org_lwjgl_opengl_MacOSXDisplay_nCreateWindow(JNIE
if (!fullscreen) {
int default_window_mask = NSBorderlessWindowMask; // undecorated
if (!undecorated) {
default_window_mask = NSTitledWindowMask | NSClosableWindowMask | NSMiniaturizableWindowMask;
}
if (resizable) {
default_window_mask |= NSResizableWindowMask;
}
if (parented) {
if (peer_info->parent != nil) {
window_info->window = [peer_info->parent window];
if (peer_info->isCALayer) {
window_info->window = [[MacOSXKeyableWindow alloc] initWithContentRect:window_info->display_rect styleMask:NSBorderlessWindowMask backing:NSBackingStoreBuffered defer:NO];
[window_info->window setContentView:window_info->view];
}
else {
window_info->window = nil;
}
if (window_info->window != nil) {
window_info->window = [peer_info->parent window];
[peer_info->parent addSubview:window_info->view];
[window_info->view setAutoresizingMask:NSViewWidthSizable | NSViewHeightSizable];
}
else {
// failed to get parent window, create a new window
window_info->window = [[MacOSXKeyableWindow alloc] initWithContentRect:window_info->display_rect styleMask:default_window_mask backing:NSBackingStoreBuffered defer:NO];
[window_info->window setContentView:window_info->view];
}
}
else {
int default_window_mask = NSBorderlessWindowMask; // undecorated
if (!undecorated) {
default_window_mask = NSTitledWindowMask | NSClosableWindowMask | NSMiniaturizableWindowMask;
}
if (resizable) {
default_window_mask |= NSResizableWindowMask;
}
window_info->window = [[MacOSXKeyableWindow alloc] initWithContentRect:window_info->display_rect styleMask:default_window_mask backing:NSBackingStoreBuffered defer:NO];
[window_info->window setContentView:window_info->view];
@ -501,9 +495,15 @@ JNIEXPORT jobject JNICALL Java_org_lwjgl_opengl_MacOSXDisplay_nCreateWindow(JNIE
// Inform the view of its parent window info;
[window_info->view setParent:window_info];
[window_info->window performSelectorOnMainThread:@selector(makeFirstResponder:) withObject:window_info->view waitUntilDone:NO];
[window_info->window performSelectorOnMainThread:@selector(setInitialFirstResponder:) withObject:window_info->view waitUntilDone:NO];
[window_info->window performSelectorOnMainThread:@selector(makeKeyAndOrderFront:) withObject:[NSApplication sharedApplication] waitUntilDone:NO];
if (peer_info->isCALayer) {
// hidden window when using CALayer
[window_info->window orderOut:nil];
}
else {
[window_info->window performSelectorOnMainThread:@selector(makeFirstResponder:) withObject:window_info->view waitUntilDone:NO];
[window_info->window performSelectorOnMainThread:@selector(setInitialFirstResponder:) withObject:window_info->view waitUntilDone:NO];
[window_info->window performSelectorOnMainThread:@selector(makeKeyAndOrderFront:) withObject:[NSApplication sharedApplication] waitUntilDone:NO];
}
window_info->fullscreen = fullscreen;
@ -525,7 +525,7 @@ JNIEXPORT void JNICALL Java_org_lwjgl_opengl_MacOSXDisplay_nDestroyWindow(JNIEnv
[window_info->window close];
}
else {
// the nsview has a parent, so remove it from there
// the nsview has a parent, remove it from there
[window_info->view removeFromSuperviewWithoutNeedingDisplay];
}
}

View file

@ -98,6 +98,68 @@ JNIEXPORT void JNICALL Java_org_lwjgl_opengl_MacOSXCanvasPeerInfo_nInitHandle
surfaceLayers.layer = nil;
}
- (void) blitFrameBuffer {
// get the size of the CALayer/AWT Canvas
int width = self.bounds.size.width;
int height = self.bounds.size.height;
if (width != fboWidth || height != fboHeight) {
// store current fbo/renderbuffers for later deletion
int oldFboID = fboID;
int oldImageRenderBufferID = imageRenderBufferID;
int oldDepthRenderBufferID = depthRenderBufferID;
// set the size of the offscreen frame buffer window
window_info->display_rect = NSMakeRect(0, 0, width, height);
[window_info->window setFrame:window_info->display_rect display:false];
// create new fbo
int tempFBO;
glGenFramebuffersEXT(1, &tempFBO);
// create new render buffers
glGenRenderbuffersEXT(1, &imageRenderBufferID);
glGenRenderbuffersEXT(1, &depthRenderBufferID);
// switch to new fbo to attach render buffers
glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, tempFBO);
// initialize and attach image render buffer
glBindRenderbufferEXT(GL_RENDERBUFFER_EXT, imageRenderBufferID);
glRenderbufferStorageEXT(GL_RENDERBUFFER_EXT, GL_RGB, width, height);
glFramebufferRenderbufferEXT(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT, GL_RENDERBUFFER_EXT, imageRenderBufferID);
// initialize and attach depth render buffer
glBindRenderbufferEXT(GL_RENDERBUFFER_EXT, depthRenderBufferID);
glRenderbufferStorageEXT(GL_RENDERBUFFER_EXT, GL_DEPTH_COMPONENT24, width, height);
glFramebufferRenderbufferEXT(GL_FRAMEBUFFER_EXT, GL_DEPTH_ATTACHMENT_EXT, GL_RENDERBUFFER_EXT, depthRenderBufferID);
// set new fbo and its sizes
fboID = tempFBO;
fboWidth = width;
fboHeight = height;
// clean up the old fbo and renderBuffers
glDeleteFramebuffersEXT(1, &oldFboID);
glDeleteRenderbuffersEXT(1, &oldImageRenderBufferID);
glDeleteRenderbuffersEXT(1, &oldDepthRenderBufferID);
}
else {
glBindFramebufferEXT(GL_READ_FRAMEBUFFER_EXT, 0);
glBindFramebufferEXT(GL_DRAW_FRAMEBUFFER_EXT, fboID);
glBlitFramebufferEXT(0, 0, width, height,
0, 0, width, height,
GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT,
GL_NEAREST);
}
// restore default framebuffer
glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0);
}
-(void)drawInCGLContext:(CGLContextObj)glContext
pixelFormat:(CGLPixelFormatObj)pixelFormat
forLayerTime:(CFTimeInterval)timeInterval
@ -106,48 +168,30 @@ JNIEXPORT void JNICALL Java_org_lwjgl_opengl_MacOSXCanvasPeerInfo_nInitHandle
// set the current context
CGLSetCurrentContext(glContext);
GLint originalFBO;
if (fboID == 0) {
// clear garbage background before lwjgl fbo is set
glClearColor(0.0, 0.0, 0.0, 1.0);
glClear(GL_COLOR_BUFFER_BIT);
}
// get the size of the CALayer
int width = fboWidth;
int height = fboHeight;
GLint originalReadFBO;
GLint originalDrawFBO;
// get and save the current fbo values
glGetIntegerv(GL_FRAMEBUFFER_BINDING_EXT, &originalFBO);
glGetIntegerv(GL_READ_FRAMEBUFFER_BINDING_EXT, &originalReadFBO);
glGetIntegerv(GL_DRAW_FRAMEBUFFER_BINDING_EXT, &originalDrawFBO);
/*glClearColor(0.0, 0.0, 0.0, 1.0);
glClear(GL_COLOR_BUFFER_BIT);
// read the LWJGL FBO and blit it into this CALayers FBO
glBindFramebufferEXT(GL_READ_FRAMEBUFFER_EXT, fboID);
glBlitFramebufferEXT(0, 0, width, height,
0, 0, width, height,
GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT,
GL_NEAREST);
// copy/blit the LWJGL FBO to this CALayers FBO
// TODO
glBindFramebufferEXT(GL_READ_FRAMEBUFFER_EXT, 1);//lwjglFBO);
glBindFramebufferEXT(GL_DRAW_FRAMEBUFFER_EXT, originalFBO);
glBlitFramebufferEXT(0, 0, 640, 480,//width, height,
0, 0, 640, 480,//width, height,
GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT,
GL_NEAREST);*/
// for testing, draw a single yellow quad spinning around based on the current time
GLfloat rotate = timeInterval * 60.0; // 60 degrees per second
glClearColor(0.0, 0.0, 0.0, 1.0);
glClear(GL_COLOR_BUFFER_BIT);
glMatrixMode(GL_MODELVIEW);
glPushMatrix();
glRotatef(rotate, 0.0, 0.0, 1.0);
glBegin(GL_QUADS);
glColor3f(1.0, 1.0, 0.0);
glVertex2f(-0.5, -0.5);
glVertex2f(-0.5, 0.5);
glVertex2f( 0.5, 0.5);
glVertex2f( 0.5, -0.5);
glEnd();
glPopMatrix();
// restore original fbo read and draw values
// restore original fbo read value
glBindFramebufferEXT(GL_READ_FRAMEBUFFER_EXT, originalReadFBO);
glBindFramebufferEXT(GL_DRAW_FRAMEBUFFER_EXT, originalDrawFBO);
// call super to finalize the drawing - by default all it does is call glFlush()
[super drawInCGLContext:glContext pixelFormat:pixelFormat forLayerTime:timeInterval displayTime:timeStamp];
@ -177,4 +221,4 @@ JNIEXPORT void JNICALL Java_org_lwjgl_opengl_MacOSXCanvasPeerInfo_nInitHandle
}
@end
@end

View file

@ -115,10 +115,15 @@ JNIEXPORT void JNICALL Java_org_lwjgl_opengl_MacOSXContextImplementation_nSwapBu
NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
MacOSXPeerInfo *peer_info = ((MacOSXContext *)(*env)->GetDirectBufferAddress(env, context_handle))->peer_info;
[[peer_info->window_info->view openGLContext] flushBuffer];
if (peer_info->isCALayer) {
// blit the contents of buffer to CALayer
[peer_info->glLayer blitFrameBuffer];
}
[pool release];
}
JNIEXPORT void JNICALL Java_org_lwjgl_opengl_MacOSXContextImplementation_nUpdate
(JNIEnv *env, jclass clazz, jobject context_handle) {
NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
@ -128,7 +133,7 @@ JNIEXPORT void JNICALL Java_org_lwjgl_opengl_MacOSXContextImplementation_nUpdate
}
JNIEXPORT void JNICALL Java_org_lwjgl_opengl_MacOSXContextImplementation_clearDrawable
(JNIEnv *env, jclass clazz, jobject context_handle) {
(JNIEnv *env, jclass clazz, jobject context_handle) {
NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
MacOSXPeerInfo *peer_info = ((MacOSXContext *)(*env)->GetDirectBufferAddress(env, context_handle))->peer_info;
[[peer_info->window_info->view openGLContext] clearDrawable];