diff --git a/src/java/org/lwjgl/opengl/DisplayImplementation.java b/src/java/org/lwjgl/opengl/DisplayImplementation.java index e112ee03..7d7098d0 100644 --- a/src/java/org/lwjgl/opengl/DisplayImplementation.java +++ b/src/java/org/lwjgl/opengl/DisplayImplementation.java @@ -233,8 +233,36 @@ public interface DisplayImplementation { void destroyCursor(Object cursor_handle); - /* Pbuffer caps */ + /* Pbuffer */ int getPbufferCaps(); + /** + * Method to test for buffer integrity + */ + public boolean isBufferLost(ByteBuffer handle); + + /** + * Method to make a pbuffer current. + */ + public void makePbufferCurrent(ByteBuffer handle) throws LWJGLException; + + /** + * Method to create a Pbuffer + */ + public ByteBuffer createPbuffer(int width, int height, PixelFormat pixel_format, + IntBuffer pixelFormatCaps, + IntBuffer pBufferAttribs, ByteBuffer shared_pbuffer_handle) throws LWJGLException; + + /** + * Destroy pbuffer + */ + public void destroyPbuffer(ByteBuffer handle); + + public void setPbufferAttrib(ByteBuffer handle, int attrib, int value); + + public void bindTexImageToPbuffer(ByteBuffer handle, int buffer); + + public void releaseTexImageFromPbuffer(ByteBuffer handle, int buffer); + boolean openURL(String url); } diff --git a/src/java/org/lwjgl/opengl/LinuxDisplay.java b/src/java/org/lwjgl/opengl/LinuxDisplay.java index 4bca9b9e..6e9c699f 100644 --- a/src/java/org/lwjgl/opengl/LinuxDisplay.java +++ b/src/java/org/lwjgl/opengl/LinuxDisplay.java @@ -48,6 +48,7 @@ import org.lwjgl.LWJGLException; final class LinuxDisplay implements DisplayImplementation { private static final int CURSOR_HANDLE_SIZE = 8; + private static final int PBUFFER_HANDLE_SIZE = 24; public native void createWindow(DisplayMode mode, boolean fullscreen, int x, int y) throws LWJGLException; public native void destroyWindow(); @@ -113,6 +114,37 @@ final class LinuxDisplay implements DisplayImplementation { public native void destroyCursor(Object cursorHandle); public native int getPbufferCaps(); + public boolean isBufferLost(ByteBuffer handle) { + return false; + } + + public native void makePbufferCurrent(ByteBuffer handle) throws LWJGLException; + + public ByteBuffer createPbuffer(int width, int height, PixelFormat pixel_format, + IntBuffer pixelFormatCaps, + IntBuffer pBufferAttribs, ByteBuffer shared_pbuffer_handle) throws LWJGLException { + ByteBuffer handle = BufferUtils.createByteBuffer(PBUFFER_HANDLE_SIZE); + nCreatePbuffer(handle, width, height, pixel_format, pixelFormatCaps, pBufferAttribs, shared_pbuffer_handle); + return handle; + } + + private native void nCreatePbuffer(ByteBuffer handle, int width, int height, PixelFormat pixel_format, + IntBuffer pixelFormatCaps, + IntBuffer pBufferAttribs, ByteBuffer shared_pbuffer_handle) throws LWJGLException; + + public native void destroyPbuffer(ByteBuffer handle); + + public void setPbufferAttrib(ByteBuffer handle, int attrib, int value) { + throw new UnsupportedOperationException(); + } + + public void bindTexImageToPbuffer(ByteBuffer handle, int buffer) { + throw new UnsupportedOperationException(); + } + + public void releaseTexImageFromPbuffer(ByteBuffer handle, int buffer) { + throw new UnsupportedOperationException(); + } public boolean openURL(String url) { // Linux may as well resort to pure Java hackery, as there's no Linux native way of doing it diff --git a/src/java/org/lwjgl/opengl/MacOSXDisplay.java b/src/java/org/lwjgl/opengl/MacOSXDisplay.java index 42653b57..2e740cae 100644 --- a/src/java/org/lwjgl/opengl/MacOSXDisplay.java +++ b/src/java/org/lwjgl/opengl/MacOSXDisplay.java @@ -55,9 +55,11 @@ import java.util.ArrayList; import java.util.List; import org.lwjgl.LWJGLException; +import org.lwjgl.BufferUtils; import org.lwjgl.input.Keyboard; final class MacOSXDisplay implements DisplayImplementation { + private static final int PBUFFER_HANDLE_SIZE = 24; private static final int GAMMA_LENGTH = 256; private MacOSXFrame frame; @@ -426,4 +428,36 @@ final class MacOSXDisplay implements DisplayImplementation { return null; } } + + public boolean isBufferLost(ByteBuffer handle) { + return false; + } + + public native void makePbufferCurrent(ByteBuffer handle) throws LWJGLException; + + public ByteBuffer createPbuffer(int width, int height, PixelFormat pixel_format, + IntBuffer pixelFormatCaps, + IntBuffer pBufferAttribs, ByteBuffer shared_pbuffer_handle) throws LWJGLException { + ByteBuffer handle = BufferUtils.createByteBuffer(PBUFFER_HANDLE_SIZE); + nCreatePbuffer(handle, width, height, pixel_format, pixelFormatCaps, pBufferAttribs, shared_pbuffer_handle); + return handle; + } + + private native void nCreatePbuffer(ByteBuffer handle, int width, int height, PixelFormat pixel_format, + IntBuffer pixelFormatCaps, + IntBuffer pBufferAttribs, ByteBuffer shared_pbuffer_handle) throws LWJGLException; + + public native void destroyPbuffer(ByteBuffer handle); + + public void setPbufferAttrib(ByteBuffer handle, int attrib, int value) { + throw new UnsupportedOperationException(); + } + + public void bindTexImageToPbuffer(ByteBuffer handle, int buffer) { + throw new UnsupportedOperationException(); + } + + public void releaseTexImageFromPbuffer(ByteBuffer handle, int buffer) { + throw new UnsupportedOperationException(); + } } diff --git a/src/java/org/lwjgl/opengl/Pbuffer.java b/src/java/org/lwjgl/opengl/Pbuffer.java index c8efbbea..06e936aa 100644 --- a/src/java/org/lwjgl/opengl/Pbuffer.java +++ b/src/java/org/lwjgl/opengl/Pbuffer.java @@ -136,11 +136,6 @@ public final class Pbuffer { */ public static final int DEPTH_BUFFER = RenderTexture.WGL_DEPTH_COMPONENT_NV; - /** - * The maximum number of bytes in the native handle - */ - private static final int HANDLE_SIZE = 24; - /** * Handle to the native GL rendering context */ @@ -163,38 +158,38 @@ public final class Pbuffer { /** * Create an instance of a Pbuffer with a unique OpenGL context. The buffer is single-buffered. *
- * NOTE: The Pbuffer will have its own context that shares display lists and textures with the Display context (if it is created), - * but it will have its own OpenGL state. Therefore, state changes to a pbuffer will not be seen in the window context and vice versa. - * - * This kind of Pbuffer is primarily intended for non interactive use, since the makeCurrent context switch will be more expensive - * than a Pbuffer using the Display context. + * NOTE: The Pbuffer will have its own context that shares display lists and textures withshared_context,
+ * or, if shared_context is null, the Display context if it is created. The Pbuffer
+ * will have its own OpenGL state. Therefore, state changes to a pbuffer will not be seen in the window context and vice versa.
*
* The renderTexture parameter defines the necessary state for enabling render-to-texture. When this parameter is null,
* render-to-texture is not available. Before using render-to-texture, the Pbuffer capabilities must be queried to ensure that
* it is supported.
+ *
*
* @param width Pbuffer width
* @param height Pbuffer height
* @param pixel_format Minimum Pbuffer context properties
* @param renderTexture
+ * @param shared_context If non-null the Pbuffer will share display lists and textures with it. Otherwise, the Pbuffer will share
+ * with the Display context (if created).
*/
- public Pbuffer(int width, int height, PixelFormat pixel_format, RenderTexture renderTexture) throws LWJGLException {
+ public Pbuffer(int width, int height, PixelFormat pixel_format, RenderTexture renderTexture, Pbuffer shared_context) throws LWJGLException {
this.width = width;
this.height = height;
- this.handle = createPbuffer(width, height, pixel_format, renderTexture);
+ this.handle = createPbuffer(width, height, pixel_format, renderTexture, shared_context != null ? shared_context.handle : null);
}
- private static ByteBuffer createPbuffer(int width, int height, PixelFormat pixel_format, RenderTexture renderTexture) throws LWJGLException {
+ private static ByteBuffer createPbuffer(int width, int height, PixelFormat pixel_format, RenderTexture renderTexture, ByteBuffer shared_context_handle) throws LWJGLException {
GLContext.loadOpenGLLibrary();
try {
- ByteBuffer handle = BufferUtils.createByteBuffer(HANDLE_SIZE);
if ( renderTexture == null )
- nCreate(handle, width, height, pixel_format, null, null);
+ return Display.getImplementation().createPbuffer(width, height, pixel_format, null, null, shared_context_handle);
else
- nCreate(handle, width, height, pixel_format,
+ return Display.getImplementation().createPbuffer(width, height, pixel_format,
renderTexture.pixelFormatCaps,
- renderTexture.pBufferAttribs);
- return handle;
+ renderTexture.pBufferAttribs,
+ shared_context_handle);
} catch (LWJGLException e) {
GLContext.unloadOpenGLLibrary();
throw e;
@@ -209,28 +204,18 @@ public final class Pbuffer {
* @return true if the buffer is lost and destroyed, false if the buffer is valid.
*/
public boolean isBufferLost() {
- return nIsBufferLost(handle);
+ return Display.getImplementation().isBufferLost(handle);
}
- /**
- * Native method to test for buffer integrity
- */
- private static native boolean nIsBufferLost(ByteBuffer handle);
-
/**
* Method to make the Pbuffer context current. All subsequent OpenGL calls will go to this buffer.
* @throws LWJGLException if the context could not be made current
*/
public void makeCurrent() throws LWJGLException {
- nMakeCurrent(handle);
+ Display.getImplementation().makePbufferCurrent(handle);
GLContext.useContext(this);
}
- /**
- * Native method to make a pbuffer current.
- */
- private static native void nMakeCurrent(ByteBuffer handle) throws LWJGLException;
-
/**
* Gets the Pbuffer capabilities.
*
@@ -240,13 +225,6 @@ public final class Pbuffer {
return Display.getImplementation().getPbufferCaps();
}
- /**
- * Native method to create a Pbuffer
- */
- private static native void nCreate(ByteBuffer handle, int width, int height, PixelFormat pixel_format,
- IntBuffer pixelFormatCaps,
- IntBuffer pBufferAttribs) throws LWJGLException;
-
/**
* Destroys the Pbuffer. After this call, there will be no valid GL rendering context - regardless of whether this Pbuffer was
* the current rendering context or not.
@@ -255,7 +233,7 @@ public final class Pbuffer {
try {
makeCurrent();
int error = GL11.glGetError();
- nDestroy(handle);
+ Display.getImplementation().destroyPbuffer(handle);
GLContext.useContext(null);
GLContext.unloadOpenGLLibrary();
if (error != GL11.GL_NO_ERROR)
@@ -265,11 +243,6 @@ public final class Pbuffer {
}
}
- /**
- * Natively destroy any GL-related stuff
- */
- private static native void nDestroy(ByteBuffer handle);
-
// -----------------------------------------------------------------------------------------
// ------------------------------- Render-to-Texture Methods -------------------------------
// -----------------------------------------------------------------------------------------
@@ -287,11 +260,9 @@ public final class Pbuffer {
* @param value
*/
public void setAttrib(int attrib, int value) {
- nSetAttrib(handle, attrib, value);
+ Display.getImplementation().setPbufferAttrib(handle, attrib, value);
}
- private static native void nSetAttrib(ByteBuffer handle, int attrib, int value);
-
/**
* Binds the currently bound texture to the buffer specified. The buffer can be one of the following:
*
@@ -300,22 +271,18 @@ public final class Pbuffer {
* @param buffer
*/
public void bindTexImage(int buffer) {
- nBindTexImage(handle, buffer);
+ Display.getImplementation().bindTexImageToPbuffer(handle, buffer);
}
- private static native void nBindTexImage(ByteBuffer handle, int buffer);
-
/**
* Releases the currently bound texture from the buffer specified.
*
* @param buffer
*/
public void releaseTexImage(int buffer) {
- nReleaseTexImage(handle, buffer);
+ Display.getImplementation().releaseTexImageFromPbuffer(handle, buffer);
}
- private static native void nReleaseTexImage(ByteBuffer handle, int buffer);
-
/**
* @return Returns the height.
*/
diff --git a/src/java/org/lwjgl/opengl/Win32Display.java b/src/java/org/lwjgl/opengl/Win32Display.java
index ac8a0a81..dcfcd1db 100644
--- a/src/java/org/lwjgl/opengl/Win32Display.java
+++ b/src/java/org/lwjgl/opengl/Win32Display.java
@@ -47,6 +47,7 @@ import org.lwjgl.LWJGLException;
final class Win32Display implements DisplayImplementation {
private static final int CURSOR_HANDLE_SIZE = 8;
+ private static final int PBUFFER_HANDLE_SIZE = 24;
public native void createWindow(DisplayMode mode, boolean fullscreen, int x, int y) throws LWJGLException;
public native void destroyWindow();
@@ -104,6 +105,27 @@ final class Win32Display implements DisplayImplementation {
public native void destroyCursor(Object cursorHandle);
public native int getPbufferCaps();
+ public native boolean isBufferLost(ByteBuffer handle);
+ public native void makePbufferCurrent(ByteBuffer handle) throws LWJGLException;
+
+ public ByteBuffer createPbuffer(int width, int height, PixelFormat pixel_format,
+ IntBuffer pixelFormatCaps,
+ IntBuffer pBufferAttribs, ByteBuffer shared_pbuffer_handle) throws LWJGLException {
+ ByteBuffer handle = BufferUtils.createByteBuffer(PBUFFER_HANDLE_SIZE);
+ nCreatePbuffer(handle, width, height, pixel_format, pixelFormatCaps, pBufferAttribs, shared_pbuffer_handle);
+ return handle;
+ }
+
+ private native void nCreatePbuffer(ByteBuffer handle, int width, int height, PixelFormat pixel_format,
+ IntBuffer pixelFormatCaps,
+ IntBuffer pBufferAttribs, ByteBuffer shared_pbuffer_handle) throws LWJGLException;
+
+ public native void destroyPbuffer(ByteBuffer handle);
+
+ public native void setPbufferAttrib(ByteBuffer handle, int attrib, int value);
+ public native void bindTexImageToPbuffer(ByteBuffer handle, int buffer);
+ public native void releaseTexImageFromPbuffer(ByteBuffer handle, int buffer);
+
public boolean openURL(String url) {
nOpenURL(url);
return true;
diff --git a/src/java/org/lwjgl/test/opengl/PbufferTest.java b/src/java/org/lwjgl/test/opengl/PbufferTest.java
index 613dc377..e1756b47 100644
--- a/src/java/org/lwjgl/test/opengl/PbufferTest.java
+++ b/src/java/org/lwjgl/test/opengl/PbufferTest.java
@@ -96,7 +96,7 @@ public class PbufferTest {
private void initialize() {
try {
//find displaymode
- pbuffer = new Pbuffer(512, 512, new PixelFormat(), null);
+ pbuffer = new Pbuffer(512, 512, new PixelFormat(), null, null);
mode = findDisplayMode(800, 600, 16);
Display.setDisplayMode(mode);
// start of in windowed mode
@@ -176,7 +176,7 @@ public class PbufferTest {
System.out.println("Buffer contents lost - will recreate the buffer");
pbuffer.destroy();
try {
- pbuffer = new Pbuffer(512, 512, new PixelFormat(), null);
+ pbuffer = new Pbuffer(512, 512, new PixelFormat(), null, null);
initPbuffer();
} catch (LWJGLException e) {
e.printStackTrace();
diff --git a/src/java/org/lwjgl/test/opengl/pbuffers/UniqueRenderer.java b/src/java/org/lwjgl/test/opengl/pbuffers/UniqueRenderer.java
index 53838d29..8e4e647f 100644
--- a/src/java/org/lwjgl/test/opengl/pbuffers/UniqueRenderer.java
+++ b/src/java/org/lwjgl/test/opengl/pbuffers/UniqueRenderer.java
@@ -47,7 +47,7 @@ final class UniqueRenderer extends TextureRenderer {
Pbuffer pbuffer = null;
try {
- pbuffer = new Pbuffer(width, height, new PixelFormat(16, 0, 0, 0, 0), null);
+ pbuffer = new Pbuffer(width, height, new PixelFormat(16, 0, 0, 0, 0), null, null);
// Initialise state of the pbuffer context.
pbuffer.makeCurrent();
diff --git a/src/java/org/lwjgl/test/opengl/pbuffers/UniqueRendererRTT.java b/src/java/org/lwjgl/test/opengl/pbuffers/UniqueRendererRTT.java
index f3e67c45..3c9ab3cc 100644
--- a/src/java/org/lwjgl/test/opengl/pbuffers/UniqueRendererRTT.java
+++ b/src/java/org/lwjgl/test/opengl/pbuffers/UniqueRendererRTT.java
@@ -46,7 +46,7 @@ final class UniqueRendererRTT extends TextureRenderer {
try {
final RenderTexture rt = new RenderTexture(true, false, false, false, RenderTexture.RENDER_TEXTURE_2D, 0);
- pbuffer = new Pbuffer(width, height, new PixelFormat(16, 0, 0, 0, 0), rt);
+ pbuffer = new Pbuffer(width, height, new PixelFormat(16, 0, 0, 0, 0), rt, null);
// Initialise state of the pbuffer context.
pbuffer.makeCurrent();
diff --git a/src/native/linux/org_lwjgl_opengl_Pbuffer.c b/src/native/linux/org_lwjgl_opengl_Pbuffer.c
index f5540cae..ce8170d4 100644
--- a/src/native/linux/org_lwjgl_opengl_Pbuffer.c
+++ b/src/native/linux/org_lwjgl_opengl_Pbuffer.c
@@ -51,13 +51,6 @@ typedef struct _PbufferInfo {
GLXContext context;
} PbufferInfo;
-JNIEXPORT jboolean JNICALL Java_org_lwjgl_opengl_Pbuffer_nIsBufferLost
- (JNIEnv *env, jclass clazz, jobject handle_buffer)
-{
- // The buffer is never lost, because of the GLX_PRESERVED_CONTENTS flag
- return JNI_FALSE;
-}
-
JNIEXPORT jint JNICALL Java_org_lwjgl_opengl_LinuxDisplay_getPbufferCaps
(JNIEnv *env, jobject this)
{
@@ -96,7 +89,7 @@ static bool checkPbufferCaps(JNIEnv *env, GLXFBConfig config, int width, int hei
return true;
}
-static bool createPbufferUsingUniqueContext(JNIEnv *env, PbufferInfo *pbuffer_info, jobject pixel_format, int width, int height, const int *buffer_attribs) {
+static bool createPbufferUsingUniqueContext(JNIEnv *env, PbufferInfo *pbuffer_info, jobject pixel_format, int width, int height, const int *buffer_attribs, GLXContext shared_context) {
GLXFBConfig *configs = chooseVisualGLX13(env, pixel_format, false, GLX_PBUFFER_BIT, false);
if (configs == NULL) {
throwException(env, "No matching pixel format");
@@ -106,7 +99,7 @@ static bool createPbufferUsingUniqueContext(JNIEnv *env, PbufferInfo *pbuffer_in
XFree(configs);
return false;
}
- GLXContext context = glXCreateNewContext(getDisplay(), configs[0], GLX_RGBA_TYPE, getCurrentGLXContext(), True);
+ GLXContext context = glXCreateNewContext(getDisplay(), configs[0], GLX_RGBA_TYPE, shared_context, True);
if (context == NULL) {
XFree(configs);
throwException(env, "Could not create a GLX context");
@@ -126,7 +119,7 @@ static bool createPbufferUsingUniqueContext(JNIEnv *env, PbufferInfo *pbuffer_in
return true;
}
-JNIEXPORT void JNICALL Java_org_lwjgl_opengl_Pbuffer_nCreate(JNIEnv *env, jclass clazz, jobject handle_buffer, jint width, jint height, jobject pixel_format, jobject pixelFormatCaps, jobject pBufferAttribs)
+JNIEXPORT void JNICALL Java_org_lwjgl_opengl_LinuxDisplay_nCreatePbuffer(JNIEnv *env, jobject this, jobject handle_buffer, jint width, jint height, jobject pixel_format, jobject pixelFormatCaps, jobject pBufferAttribs, jobject shared_context_handle_buffer)
{
Display *disp = incDisplay(env);
if (disp == NULL) {
@@ -150,9 +143,14 @@ JNIEXPORT void JNICALL Java_org_lwjgl_opengl_Pbuffer_nCreate(JNIEnv *env, jclass
throwException(env, "Handle buffer not large enough");
return;
}
+ GLXContext shared_context = getCurrentGLXContext();
+ if (shared_context_handle_buffer != NULL) {
+ PbufferInfo *shared_buffer_info = (PbufferInfo *)(*env)->GetDirectBufferAddress(env, shared_context_handle_buffer);
+ shared_context = shared_buffer_info->context;
+ }
PbufferInfo *buffer_info = (PbufferInfo *)(*env)->GetDirectBufferAddress(env, handle_buffer);
bool result;
- result = createPbufferUsingUniqueContext(env, buffer_info, pixel_format, width, height, buffer_attribs);
+ result = createPbufferUsingUniqueContext(env, buffer_info, pixel_format, width, height, buffer_attribs, shared_context);
if (!result || !checkXError(env)) {
decDisplay();
destroyPbuffer(buffer_info);
@@ -160,8 +158,8 @@ JNIEXPORT void JNICALL Java_org_lwjgl_opengl_Pbuffer_nCreate(JNIEnv *env, jclass
}
}
-JNIEXPORT void JNICALL Java_org_lwjgl_opengl_Pbuffer_nMakeCurrent
- (JNIEnv *env, jclass clazz, jobject handle_buffer)
+JNIEXPORT void JNICALL Java_org_lwjgl_opengl_LinuxDisplay_makePbufferCurrent
+ (JNIEnv *env, jobject this, jobject handle_buffer)
{
PbufferInfo *buffer_info = (PbufferInfo *)(*env)->GetDirectBufferAddress(env, handle_buffer);
GLXPbuffer buffer = buffer_info->buffer;
@@ -171,27 +169,9 @@ JNIEXPORT void JNICALL Java_org_lwjgl_opengl_Pbuffer_nMakeCurrent
}
}
-JNIEXPORT void JNICALL Java_org_lwjgl_opengl_Pbuffer_nDestroy
- (JNIEnv *env, jclass clazz, jobject handle_buffer)
+JNIEXPORT void JNICALL Java_org_lwjgl_opengl_LinuxDisplay_destroyPbuffer
+ (JNIEnv *env, jobject this, jobject handle_buffer)
{
PbufferInfo *buffer_info = (PbufferInfo *)(*env)->GetDirectBufferAddress(env, handle_buffer);
destroyPbuffer(buffer_info);
}
-
-JNIEXPORT void JNICALL Java_org_lwjgl_opengl_Pbuffer_nSetAttrib
- (JNIEnv *env, jclass clazz, jobject handle_buffer, jint attrib, jint value)
-{
- throwException(env, "The render-to-texture extension is not supported.");
-}
-
-JNIEXPORT void JNICALL Java_org_lwjgl_opengl_Pbuffer_nBindTexImage
- (JNIEnv *env, jclass clazz, jobject handle_buffer, jint buffer)
-{
- throwException(env, "The render-to-texture extension is not supported.");
-}
-
-JNIEXPORT void JNICALL Java_org_lwjgl_opengl_Pbuffer_nReleaseTexImage
- (JNIEnv *env, jclass clazz, jobject handle_buffer, jint buffer)
-{
- throwException(env, "The render-to-texture extension is not supported.");
-}
diff --git a/src/native/macosx/org_lwjgl_opengl_Pbuffer.m b/src/native/macosx/org_lwjgl_opengl_Pbuffer.m
index e8d14313..a362d9a2 100644
--- a/src/native/macosx/org_lwjgl_opengl_Pbuffer.m
+++ b/src/native/macosx/org_lwjgl_opengl_Pbuffer.m
@@ -41,6 +41,7 @@
#import