diff --git a/src/java/org/lwjgl/opengl/DisplayImplementation.java b/src/java/org/lwjgl/opengl/DisplayImplementation.java index 4d79d3fb..fd1f7695 100644 --- a/src/java/org/lwjgl/opengl/DisplayImplementation.java +++ b/src/java/org/lwjgl/opengl/DisplayImplementation.java @@ -234,4 +234,7 @@ public interface DisplayImplementation { public Object createCursor(int width, int height, int xHotspot, int yHotspot, int numImages, IntBuffer images, IntBuffer delays) throws LWJGLException; public void destroyCursor(Object cursor_handle); + + /* Pbuffer caps */ + public int getPbufferCaps(); } diff --git a/src/java/org/lwjgl/opengl/LinuxDisplay.java b/src/java/org/lwjgl/opengl/LinuxDisplay.java index fbd23ebb..6cad0a78 100644 --- a/src/java/org/lwjgl/opengl/LinuxDisplay.java +++ b/src/java/org/lwjgl/opengl/LinuxDisplay.java @@ -102,4 +102,5 @@ final class LinuxDisplay implements DisplayImplementation { } public native void destroyCursor(Object cursorHandle); + public native int getPbufferCaps(); } diff --git a/src/java/org/lwjgl/opengl/MacOSXDisplay.java b/src/java/org/lwjgl/opengl/MacOSXDisplay.java index 18f3b316..1bc05b41 100644 --- a/src/java/org/lwjgl/opengl/MacOSXDisplay.java +++ b/src/java/org/lwjgl/opengl/MacOSXDisplay.java @@ -376,6 +376,10 @@ final class MacOSXDisplay implements DisplayImplementation { public void destroyCursor(Object cursor_handle) { } + public int getPbufferCaps() { + return GL11.glGetString(GL11.GL_EXTENSIONS).indexOf("GL_APPLE_pixel_buffer") != -1 ? Pbuffer.PBUFFER_SUPPORTED : 0; + } + /** * This class captures com.apple.eawt.ApplicationEvents through reflection * to enable compilation on other platforms than Mac OS X diff --git a/src/java/org/lwjgl/opengl/Pbuffer.java b/src/java/org/lwjgl/opengl/Pbuffer.java index 6edf2eb3..c8efbbea 100644 --- a/src/java/org/lwjgl/opengl/Pbuffer.java +++ b/src/java/org/lwjgl/opengl/Pbuffer.java @@ -236,7 +236,9 @@ public final class Pbuffer { * * @return a bitmask of Pbuffer capabilities. */ - public static native int getPbufferCaps(); + public static int getPbufferCaps() { + return Display.getImplementation().getPbufferCaps(); + } /** * Native method to create a Pbuffer diff --git a/src/java/org/lwjgl/opengl/Win32Display.java b/src/java/org/lwjgl/opengl/Win32Display.java index 153a2dea..04843a27 100644 --- a/src/java/org/lwjgl/opengl/Win32Display.java +++ b/src/java/org/lwjgl/opengl/Win32Display.java @@ -102,4 +102,5 @@ final class Win32Display implements DisplayImplementation { } public native void destroyCursor(Object cursorHandle); + public native int getPbufferCaps(); } diff --git a/src/native/linux/org_lwjgl_opengl_Pbuffer.c b/src/native/linux/org_lwjgl_opengl_Pbuffer.c index ea01ac16..f5540cae 100644 --- a/src/native/linux/org_lwjgl_opengl_Pbuffer.c +++ b/src/native/linux/org_lwjgl_opengl_Pbuffer.c @@ -40,6 +40,7 @@ */ #include +#include "org_lwjgl_opengl_LinuxDisplay.h" #include "org_lwjgl_opengl_Pbuffer.h" #include "extgl.h" #include "Window.h" @@ -57,8 +58,8 @@ JNIEXPORT jboolean JNICALL Java_org_lwjgl_opengl_Pbuffer_nIsBufferLost return JNI_FALSE; } -JNIEXPORT jint JNICALL Java_org_lwjgl_opengl_Pbuffer_getPbufferCaps - (JNIEnv *env, jclass clazz) +JNIEXPORT jint JNICALL Java_org_lwjgl_opengl_LinuxDisplay_getPbufferCaps + (JNIEnv *env, jobject this) { // Only support the GLX 1.3 Pbuffers and ignore the GLX_SGIX_pbuffer extension return extgl_Extensions.GLX13 ? org_lwjgl_opengl_Pbuffer_PBUFFER_SUPPORTED : 0; diff --git a/src/native/macosx/org_lwjgl_opengl_Pbuffer.c b/src/native/macosx/display.h similarity index 82% rename from src/native/macosx/org_lwjgl_opengl_Pbuffer.c rename to src/native/macosx/display.h index f25086e5..98a41317 100644 --- a/src/native/macosx/org_lwjgl_opengl_Pbuffer.c +++ b/src/native/macosx/display.h @@ -33,14 +33,16 @@ /** * $Id$ * - * Mac OS X Pbuffer. + * Mac OS Xspecific display functions. * * @author elias_naur * @version $Revision$ */ -#include +#import +#import "common_tools.h" + +/* Will return NULL and throw exception if it fails */ +extern NSOpenGLContext *createContext(JNIEnv *env, jobject pixel_format, bool double_buffered, bool use_display_bpp, long drawable_type, NSOpenGLContext *share_context); +extern NSOpenGLContext *getDisplayContext(); -JNIEXPORT jint JNICALL Java_org_lwjgl_opengl_Pbuffer_getPbufferCaps(JNIEnv *env, jclass clazz) { - return 0; -} diff --git a/src/native/macosx/org_lwjgl_opengl_Display.m b/src/native/macosx/org_lwjgl_opengl_Display.m index 838d928f..e32998e0 100644 --- a/src/native/macosx/org_lwjgl_opengl_Display.m +++ b/src/native/macosx/org_lwjgl_opengl_Display.m @@ -40,23 +40,25 @@ */ #import -#import #import #import #import #import +#import "display.h" #import "common_tools.h" #define WAIT_DELAY 100 static NSOpenGLContext *gl_context; -JNIEXPORT void JNICALL Java_org_lwjgl_opengl_MacOSXDisplay_createContext(JNIEnv *env, jobject this, jobject pixel_format) { - NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init]; - - size_t bpp = CGDisplayBitsPerPixel(kCGDirectMainDisplay); - +NSOpenGLContext *createContext(JNIEnv *env, jobject pixel_format, bool double_buffered, bool use_display_bpp, long drawable_type, NSOpenGLContext *share_context) { + int bpp; jclass cls_pixel_format = (*env)->GetObjectClass(env, pixel_format); + if (use_display_bpp) + bpp = CGDisplayBitsPerPixel(kCGDirectMainDisplay); + else + bpp = (int)(*env)->GetIntField(env, pixel_format, (*env)->GetFieldID(env, cls_pixel_format, "bpp", "I")); + int alpha = (int)(*env)->GetIntField(env, pixel_format, (*env)->GetFieldID(env, cls_pixel_format, "alpha", "I")); int depth = (int)(*env)->GetIntField(env, pixel_format, (*env)->GetFieldID(env, cls_pixel_format, "depth", "I")); int stencil = (int)(*env)->GetIntField(env, pixel_format, (*env)->GetFieldID(env, cls_pixel_format, "stencil", "I")); @@ -66,37 +68,45 @@ JNIEXPORT void JNICALL Java_org_lwjgl_opengl_MacOSXDisplay_createContext(JNIEnv int accum_alpha = (int)(*env)->GetIntField(env, pixel_format, (*env)->GetFieldID(env, cls_pixel_format, "accum_alpha", "I")); bool stereo = (bool)(*env)->GetBooleanField(env, pixel_format, (*env)->GetFieldID(env, cls_pixel_format, "stereo", "Z")); - NSOpenGLPixelFormatAttribute attribs[] = { - NSOpenGLPFAAccelerated, - NSOpenGLPFADoubleBuffer, - NSOpenGLPFAColorSize, bpp, - NSOpenGLPFAAlphaSize, alpha, - NSOpenGLPFADepthSize, depth, - NSOpenGLPFAStencilSize, stencil, - NSOpenGLPFAAccumSize, accum_bpp + accum_alpha, - NSOpenGLPFASampleBuffers, samples > 0 ? 1 : 0, - NSOpenGLPFASamples, samples, - NSOpenGLPFAAuxBuffers, num_aux_buffers, - NSOpenGLPFAWindow, - 0, - 0 - }; - + attrib_list_t attribs; + initAttribList(&attribs); + putAttrib(&attribs, NSOpenGLPFAAccelerated); + if (double_buffered) + putAttrib(&attribs, NSOpenGLPFADoubleBuffer); + putAttrib(&attribs, NSOpenGLPFAColorSize); putAttrib(&attribs, bpp); + putAttrib(&attribs, NSOpenGLPFAAlphaSize); putAttrib(&attribs, alpha); + putAttrib(&attribs, NSOpenGLPFADepthSize); putAttrib(&attribs, depth); + putAttrib(&attribs, NSOpenGLPFAStencilSize); putAttrib(&attribs, stencil); + putAttrib(&attribs, NSOpenGLPFAAccumSize); putAttrib(&attribs, accum_bpp + accum_alpha); + putAttrib(&attribs, NSOpenGLPFASampleBuffers); putAttrib(&attribs, samples > 0 ? 1 : 0); + putAttrib(&attribs, NSOpenGLPFASamples); putAttrib(&attribs, samples); + putAttrib(&attribs, NSOpenGLPFAAuxBuffers); putAttrib(&attribs, num_aux_buffers); + putAttrib(&attribs, drawable_type); if (stereo) - attribs[19] = NSOpenGLPFAStereo; - NSOpenGLPixelFormat* fmt = [[NSOpenGLPixelFormat alloc] initWithAttributes:attribs]; + putAttrib(&attribs, NSOpenGLPFAStereo); + putAttrib(&attribs, 0); + NSOpenGLPixelFormat* fmt = [[NSOpenGLPixelFormat alloc] initWithAttributes:(NSOpenGLPixelFormatAttribute *)attribs.attribs]; if (fmt == nil) { throwException(env, "Could not create pixel format"); - [pool release]; - return; + return NULL; } - gl_context = [[NSOpenGLContext alloc] initWithFormat:fmt shareContext:nil]; + NSOpenGLContext *context = [[NSOpenGLContext alloc] initWithFormat:fmt shareContext:share_context]; [fmt release]; - if (gl_context == nil) + if (context == nil) throwException(env, "Could not create context"); + return context; +} + +NSOpenGLContext *getDisplayContext() { + return gl_context; +} + +JNIEXPORT void JNICALL Java_org_lwjgl_opengl_MacOSXDisplay_createContext(JNIEnv *env, jobject this, jobject pixel_format) { + NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init]; + gl_context = createContext(env, pixel_format, true, true, NSOpenGLPFAWindow, nil); [pool release]; } diff --git a/src/native/macosx/org_lwjgl_opengl_Pbuffer.m b/src/native/macosx/org_lwjgl_opengl_Pbuffer.m new file mode 100644 index 00000000..e8d14313 --- /dev/null +++ b/src/native/macosx/org_lwjgl_opengl_Pbuffer.m @@ -0,0 +1,119 @@ +/* + * Copyright (c) 2002-2004 LWJGL Project + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * * Neither the name of 'LWJGL' nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +/** + * $Id$ + * + * Mac OS X Pbuffer. + * + * @author elias_naur + * @version $Revision$ + */ + +#import +#import +#import "org_lwjgl_opengl_Pbuffer.h" +#import "display.h" + +typedef struct { + NSOpenGLPixelBuffer *pbuffer; + NSOpenGLContext *context; +} PbufferInfo; + +/* Check capacity and throw i not large enough to hold a PbufferInfo struct */ +static bool checkCapacity(JNIEnv *env, jobject pbuffer_handle) { + if ((*env)->GetDirectBufferCapacity(env, pbuffer_handle) < sizeof(PbufferInfo)) { + throwException(env, "Handle buffer not large enough"); + return false; + } else + return true; +} + +static PbufferInfo *getPbufferInfoFromBuffer(JNIEnv *env, jobject pbuffer_handle) { + if (checkCapacity(env, pbuffer_handle)) + return (PbufferInfo *)(*env)->GetDirectBufferAddress(env, pbuffer_handle); + else + return NULL; +} + +JNIEXPORT jboolean JNICALL Java_org_lwjgl_opengl_Pbuffer_nIsBufferLost(JNIEnv *env, jclass clazz, jobject pbuffer_handle) { + return JNI_FALSE; +} + +JNIEXPORT void JNICALL Java_org_lwjgl_opengl_Pbuffer_nMakeCurrent(JNIEnv *env, jclass clazz, jobject pbuffer_handle) { + NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init]; + PbufferInfo *pbuffer_handle_ptr = getPbufferInfoFromBuffer(env, pbuffer_handle); + if (pbuffer_handle_ptr == NULL) + return; + [pbuffer_handle_ptr->context makeCurrentContext]; + [pool release]; +} + +static void createPbuffer(JNIEnv *env, jobject pbuffer_handle, jint width, jint height, jobject pixel_format) { + if (!checkCapacity(env, pbuffer_handle)) + return; + NSOpenGLPixelBuffer *pbuffer = [[NSOpenGLPixelBuffer alloc] initWithTextureTarget:GL_TEXTURE_2D textureInternalFormat:GL_RGBA textureMaxMipMapLevel:0 pixelsWide:width pixelsHigh:height]; + if (pbuffer == nil) { + throwException(env, "Could not allocate Pbuffer"); + return; + } + NSOpenGLContext *display_context = getDisplayContext(); + NSOpenGLContext *context = createContext(env, pixel_format, false, false, NSOpenGLPFAPixelBuffer, display_context); + if (context == nil) + return; + int screen; + if (display_context != NULL) + screen = [display_context currentVirtualScreen]; + else + screen = 0; + [context setPixelBuffer:pbuffer cubeMapFace:0 mipMapLevel:0 currentVirtualScreen:screen]; + PbufferInfo *pbuffer_handle_ptr = (PbufferInfo *)(*env)->GetDirectBufferAddress(env, pbuffer_handle); + pbuffer_handle_ptr->pbuffer = pbuffer; + pbuffer_handle_ptr->context = context; +} + +JNIEXPORT void JNICALL Java_org_lwjgl_opengl_Pbuffer_nCreate(JNIEnv *env, jclass clazz, jobject pbuffer_handle, jint width, jint height, jobject pixel_format, jobject pixelFormatCaps, jobject pBufferAttribs) { + NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init]; + createPbuffer(env, pbuffer_handle, width, height, pixel_format); + [pool release]; +} + +JNIEXPORT void JNICALL Java_org_lwjgl_opengl_Pbuffer_nDestroy(JNIEnv *env, jclass clazz, jobject pbuffer_handle) { + NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init]; + PbufferInfo *pbuffer_handle_ptr = getPbufferInfoFromBuffer(env, pbuffer_handle); + if (pbuffer_handle_ptr == NULL) + return; + [pbuffer_handle_ptr->context clearDrawable]; + [pbuffer_handle_ptr->context release]; + [pbuffer_handle_ptr->pbuffer release]; + [pool release]; +} diff --git a/src/native/win32/org_lwjgl_opengl_Pbuffer.cpp b/src/native/win32/org_lwjgl_opengl_Pbuffer.cpp index f1b533b2..0341c3be 100755 --- a/src/native/win32/org_lwjgl_opengl_Pbuffer.cpp +++ b/src/native/win32/org_lwjgl_opengl_Pbuffer.cpp @@ -40,6 +40,7 @@ */ #include +#include "org_lwjgl_opengl_Win32Display.h" #include "org_lwjgl_opengl_Pbuffer.h" #include "Window.h" @@ -54,13 +55,8 @@ typedef struct _PbufferInfo { HDC Pbuffer_dc; } PbufferInfo; -/* - * Class: org_lwjgl_opengl_Pbuffer - * Method: isPbufferSupported - * Signature: ()Z - */ -JNIEXPORT jint JNICALL Java_org_lwjgl_opengl_Pbuffer_getPbufferCaps - (JNIEnv *env, jclass clazz) +JNIEXPORT jint JNICALL Java_org_lwjgl_opengl_Win32Display_getPbufferCaps + (JNIEnv *env, jobject self) { int caps = 0; if ( extgl_Extensions.WGL_ARB_pixel_format && extgl_Extensions.WGL_ARB_pbuffer )