From 5356e13febc4307b77bd09c248416154b137f3cd Mon Sep 17 00:00:00 2001 From: Caspian Rychlik-Prince Date: Wed, 18 Feb 2004 17:48:26 +0000 Subject: [PATCH] New Context stuff --- src/java/org/lwjgl/opengl/GLContext.java | 56 ++++++++++++++++++ src/java/org/lwjgl/opengl/Pbuffer.java | 58 +++++++++++-------- src/java/org/lwjgl/opengl/VBOTracker.java | 51 +++++++++++----- src/java/org/lwjgl/opengl/Window.java | 56 +++++++++++++----- .../org/lwjgl/test/opengl/PbufferTest.java | 12 ++-- src/native/common/org_lwjgl_opengl_Pbuffer.h | 8 --- src/native/common/org_lwjgl_opengl_Window.h | 8 +++ src/native/linux/org_lwjgl_opengl_Pbuffer.cpp | 39 +++++-------- src/native/linux/org_lwjgl_opengl_Window.cpp | 13 ++++- src/native/win32/org_lwjgl_opengl_Window.cpp | 6 ++ 10 files changed, 213 insertions(+), 94 deletions(-) create mode 100644 src/java/org/lwjgl/opengl/GLContext.java diff --git a/src/java/org/lwjgl/opengl/GLContext.java b/src/java/org/lwjgl/opengl/GLContext.java new file mode 100644 index 00000000..44531eec --- /dev/null +++ b/src/java/org/lwjgl/opengl/GLContext.java @@ -0,0 +1,56 @@ +/* + * Copyright (c) 2003 Shaven Puppy Ltd + * 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 'Shaven Puppy' 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. + */ +package org.lwjgl.opengl; + +/** + * The interface for cross-API cross-platform GL contexts. + */ +public interface GLContext { + + /** + * Make this context the current rendering context for the current Thread. + */ + public void makeCurrent(); + + /** + * Get the width of the context in pixels + * @return int + */ + public int getWidth(); + + /** + * Get the height of the context in pixels + * @return int + */ + public int getHeight(); + +} diff --git a/src/java/org/lwjgl/opengl/Pbuffer.java b/src/java/org/lwjgl/opengl/Pbuffer.java index 2e57ddd8..19d2fb8e 100644 --- a/src/java/org/lwjgl/opengl/Pbuffer.java +++ b/src/java/org/lwjgl/opengl/Pbuffer.java @@ -47,7 +47,8 @@ import org.lwjgl.Sys; * @author elias_naur * @version $Revision$ */ -public class Pbuffer { +public final class Pbuffer implements GLContext { + public static final int PBUFFER_SUPPORTED = 1; /** Current Pbuffer */ @@ -56,8 +57,11 @@ public class Pbuffer { /** Handle to the native GL rendering context */ private final int handle; - /** Tracks VBO state */ - private final VBOTracker vbo_tracker; + /** Width */ + private final int width; + + /** Height */ + private final int height; static { System.loadLibrary(Sys.getLibraryName()); @@ -85,17 +89,9 @@ public class Pbuffer { Pass 0 to disable multisampling. This parameter is ignored if GL_ARB_multisample is not supported. */ public Pbuffer(int width, int height, int bpp, int alpha, int depth, int stencil, int samples) throws Exception { + this.width = width; + this.height = height; handle = nCreate(width, height, bpp, alpha, depth, stencil, samples); - vbo_tracker = new VBOTracker(); - } - - /** - * Method to release the current Pbuffer context and make the OpenGL window current. - */ - public static void releaseContext() { - currentBuffer = null; - VBOTracker.releaseCurrent(); - nReleaseContext(); } /** @@ -106,7 +102,7 @@ public class Pbuffer { * * @return true if the buffer is lost and destroyed, false if the buffer is valid. */ - public boolean isBufferLost() { + public synchronized boolean isBufferLost() { return nIsBufferLost(handle); } @@ -115,19 +111,14 @@ public class Pbuffer { */ private native static boolean nIsBufferLost(int handle); - /** - * Native method to release the context. - */ - private native static void nReleaseContext(); - /** * Method to make the Pbuffer context current. All subsequent OpenGL * calls will go to this buffer. */ - public void makeCurrent() { + public synchronized void makeCurrent() { currentBuffer = this; - VBOTracker.setCurrent(vbo_tracker); nMakeCurrent(handle); + VBOTracker.setCurrent(this); } /** @@ -156,11 +147,12 @@ public class Pbuffer { int samples) throws Exception; /** - * Destroys the Pbuffer. The buffer must not be current. + * 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. */ - public void destroy() { - if (currentBuffer == this) - releaseContext(); + public synchronized void destroy() { + makeCurrent(); + VBOTracker.remove(this); nDestroy(handle); } @@ -168,4 +160,20 @@ public class Pbuffer { * Natively destroy any GL-related stuff */ private native static void nDestroy(int handle); + + /** + * @return Returns the height. + */ + public int getHeight() { + return height; + } + + /** + * @return Returns the width. + */ + public int getWidth() { + return width; + } + + } diff --git a/src/java/org/lwjgl/opengl/VBOTracker.java b/src/java/org/lwjgl/opengl/VBOTracker.java index 3d4d7974..4e6ab10d 100644 --- a/src/java/org/lwjgl/opengl/VBOTracker.java +++ b/src/java/org/lwjgl/opengl/VBOTracker.java @@ -32,38 +32,61 @@ package org.lwjgl.opengl; +import java.util.HashMap; +import java.util.Map; + +/** + * Track Vertex Buffer Objects by context. + */ class VBOTracker { - private static VBOTracker default_tracker = new VBOTracker(); - private static VBOTracker current_tracker = default_tracker; + private static VBOTracker current_tracker = null; + + private static final Map contextToTracker = new HashMap(3, 1.0f); private final StateStack vbo_array_stack; private final StateStack vbo_element_stack; private final StateStack attrib_stack; - public static void setCurrent(VBOTracker tracker) { - current_tracker = tracker; - } - - public static void releaseCurrent() { - current_tracker = default_tracker; - } - - VBOTracker() { + private VBOTracker() { int stack_size = Util.getGLInteger(GL11.GL_MAX_CLIENT_ATTRIB_STACK_DEPTH); vbo_array_stack = new StateStack(stack_size, 0); vbo_element_stack = new StateStack(stack_size, 0); attrib_stack = new StateStack(stack_size, 0); } - public static StateStack getVBOArrayStack() { + static StateStack getVBOArrayStack() { return current_tracker.vbo_array_stack; } - public static StateStack getVBOElementStack() { + static StateStack getVBOElementStack() { return current_tracker.vbo_element_stack; } - public static StateStack getClientAttribStack() { + static StateStack getClientAttribStack() { return current_tracker.attrib_stack; } + + /** + * Called after a GLContext has been made current. This will set up the current + * VBO tracker. + * @param context + */ + static synchronized void setCurrent(GLContext context) { + current_tracker = (VBOTracker) contextToTracker.get(context); + if (current_tracker == null) { + current_tracker = new VBOTracker(); + contextToTracker.put(context, current_tracker); + } + } + + /** + * Remove a context when it is about to be destroyed. + * @param context + */ + static synchronized void remove(GLContext context) { + contextToTracker.remove(context); + if (current_tracker == context) { + current_tracker = null; + } + } } diff --git a/src/java/org/lwjgl/opengl/Window.java b/src/java/org/lwjgl/opengl/Window.java index b96aad07..38282001 100644 --- a/src/java/org/lwjgl/opengl/Window.java +++ b/src/java/org/lwjgl/opengl/Window.java @@ -58,9 +58,6 @@ public final class Window { System.loadLibrary(Sys.getLibraryName()); } - /** Whether the window is currently created, ie. has a native peer */ - private static boolean created; - /** X coordinate of the window */ private static int x; @@ -88,8 +85,24 @@ public final class Window { /** Tracks VBO state for the window context */ private static VBOTracker vbo_tracker; + /** Context: delegates calls to Window */ + private static class Context implements GLContext { + + public void makeCurrent() { + Window.makeCurrent(); + } + + public int getWidth() { + return width; + } + + public int getHeight() { + return height; + } + } + /** A unique context object, so we can track different contexts between creates() and destroys() */ - private static Window context; + private static Context context; /** * Only constructed by ourselves @@ -221,6 +234,20 @@ public final class Window { * Swap double buffers. */ private static native void swapBuffers(); + + /** + * Make the Window the current rendering context for GL calls. + */ + public static synchronized void makeCurrent() { + assert isCreated() : "No window has been created."; + nMakeCurrent(); + VBOTracker.setCurrent(context); + } + + /** + * Make the window the current rendering context for GL calls. + */ + private static native void nMakeCurrent(); /** * Create a fullscreen window. If the underlying OS does not @@ -304,26 +331,29 @@ public final class Window { private static void createWindow(int bpp, int alpha, int depth, int stencil, int samples) throws Exception { HashSet extensions = new HashSet(); nCreate(title, x, y, width, height, fullscreen, bpp, alpha, depth, stencil, samples, extensions); + context = new Context(); + context.makeCurrent(); GLCaps.determineAvailableExtensions(extensions); - context = new Window(); - created = true; } /** - * Destroy the window. + * Destroy the Window. After this call, there will be no current GL rendering context, + * regardless of whether the Window was the current rendering context. */ - public static void destroy() { - if (!created) + public static synchronized void destroy() { + if (context == null) { return; + } + makeCurrent(); nDestroy(); - created = false; + VBOTracker.remove(context); context = null; } /** - * @return the unique Window context + * @return the unique Window context (or null, if the Window has not been created) */ - public static final Window getContext() { + public static GLContext getContext() { return context; } @@ -336,7 +366,7 @@ public final class Window { * @return true if the window's native peer has been created */ public static boolean isCreated() { - return created; + return context != null; } /** diff --git a/src/java/org/lwjgl/test/opengl/PbufferTest.java b/src/java/org/lwjgl/test/opengl/PbufferTest.java index 641b801c..f51da13d 100644 --- a/src/java/org/lwjgl/test/opengl/PbufferTest.java +++ b/src/java/org/lwjgl/test/opengl/PbufferTest.java @@ -180,7 +180,6 @@ public class PbufferTest { private void render() { if (pbuffer.isBufferLost()) { System.out.println("Buffer contents lost - will recreate the buffer"); - Pbuffer.releaseContext(); pbuffer.destroy(); initPbuffer(); } @@ -206,7 +205,7 @@ public class PbufferTest { } GL11.glPopMatrix(); GL11.glCopyTexImage2D(GL11.GL_TEXTURE_2D, 0, GL11.GL_RGB, 0, 0, 512, 512, 0); - Pbuffer.releaseContext(); + Window.makeCurrent(); // OpenGL window rendering GL11.glClear(GL11.GL_COLOR_BUFFER_BIT); @@ -238,7 +237,7 @@ public class PbufferTest { pbuffer.makeCurrent(); initGLState(256, 256, 0.5f); GL11.glBindTexture(GL11.GL_TEXTURE_2D, tex_handle); - Pbuffer.releaseContext(); + Window.makeCurrent(); } catch (Exception e) { e.printStackTrace(); } @@ -256,8 +255,7 @@ public class PbufferTest { try { destroyTexture(); Keyboard.destroy(); - Pbuffer.releaseContext(); - pbuffer.destroy(); + pbuffer.destroy(); Window.destroy(); Display.setDisplayMode(mode); @@ -276,8 +274,7 @@ public class PbufferTest { try { destroyTexture(); Keyboard.destroy(); - Pbuffer.releaseContext(); - pbuffer.destroy(); + pbuffer.destroy(); Window.destroy(); Display.resetDisplayMode(); @@ -347,7 +344,6 @@ public class PbufferTest { private void cleanup() { destroyTexture(); Keyboard.destroy(); - Pbuffer.releaseContext(); pbuffer.destroy(); Window.destroy(); } diff --git a/src/native/common/org_lwjgl_opengl_Pbuffer.h b/src/native/common/org_lwjgl_opengl_Pbuffer.h index 59238a52..159a391e 100644 --- a/src/native/common/org_lwjgl_opengl_Pbuffer.h +++ b/src/native/common/org_lwjgl_opengl_Pbuffer.h @@ -18,14 +18,6 @@ extern "C" { JNIEXPORT jboolean JNICALL Java_org_lwjgl_opengl_Pbuffer_nIsBufferLost (JNIEnv *, jclass, jint); -/* - * Class: org_lwjgl_opengl_Pbuffer - * Method: nReleaseContext - * Signature: ()V - */ -JNIEXPORT void JNICALL Java_org_lwjgl_opengl_Pbuffer_nReleaseContext - (JNIEnv *, jclass); - /* * Class: org_lwjgl_opengl_Pbuffer * Method: nMakeCurrent diff --git a/src/native/common/org_lwjgl_opengl_Window.h b/src/native/common/org_lwjgl_opengl_Window.h index b4b08ca2..260470f4 100644 --- a/src/native/common/org_lwjgl_opengl_Window.h +++ b/src/native/common/org_lwjgl_opengl_Window.h @@ -123,6 +123,14 @@ JNIEXPORT jboolean JNICALL Java_org_lwjgl_opengl_Window_nIsVSyncEnabled JNIEXPORT void JNICALL Java_org_lwjgl_opengl_Window_nSetVSyncEnabled (JNIEnv *, jclass, jboolean); +/* + * Class: org_lwjgl_opengl_Window + * Method: nMakeCurrent + * Signature: ()V + */ +JNIEXPORT void JNICALL Java_org_lwjgl_opengl_Window_nMakeCurrent + (JNIEnv *, jclass); + #ifdef __cplusplus } #endif diff --git a/src/native/linux/org_lwjgl_opengl_Pbuffer.cpp b/src/native/linux/org_lwjgl_opengl_Pbuffer.cpp index 92844bec..d7fae932 100644 --- a/src/native/linux/org_lwjgl_opengl_Pbuffer.cpp +++ b/src/native/linux/org_lwjgl_opengl_Pbuffer.cpp @@ -1,35 +1,35 @@ -/* +/* * Copyright (c) 2002 Light Weight Java Game Library Project * All rights reserved. - * + * * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are + * modification, are permitted provided that the following conditions are * met: - * - * * Redistributions of source code must retain the above copyright + * + * * 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 'Light Weight Java Game Library' nor the names of - * its contributors may be used to endorse or promote products derived + * * Neither the name of 'Light Weight Java Game Library' 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 + * 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 + * 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$ * @@ -146,17 +146,6 @@ JNIEXPORT jint JNICALL Java_org_lwjgl_opengl_Pbuffer_nCreate return (jint)buffer_info; } -/* - * Class: org_lwjgl_opengl_Pbuffer - * Method: nReleaseContext - * Signature: ()V - */ -JNIEXPORT void JNICALL Java_org_lwjgl_opengl_Pbuffer_nReleaseContext - (JNIEnv *env, jclass clazz) -{ - makeCurrent(); -} - /* * Class: org_lwjgl_opengl_Pbuffer * Method: nMakeCurrent diff --git a/src/native/linux/org_lwjgl_opengl_Window.cpp b/src/native/linux/org_lwjgl_opengl_Window.cpp index cd521b2d..4bb7cf46 100644 --- a/src/native/linux/org_lwjgl_opengl_Window.cpp +++ b/src/native/linux/org_lwjgl_opengl_Window.cpp @@ -265,6 +265,17 @@ JNIEXPORT void JNICALL Java_org_lwjgl_opengl_Window_update handleMessages(); } +/* + * Class: org_lwjgl_Window + * Method: nMakeCurrent + * Signature: ()V + */ +JNIEXPORT void JNICALL Java_org_lwjgl_opengl_Window_nMakeCurrent + (JNIEnv *env, jclass clazz) +{ + makeCurrent(); +} + void makeCurrent(void) { if (USEGLX13) glXMakeContextCurrent(getCurrentDisplay(), glx_window, glx_window, context); @@ -371,7 +382,7 @@ static void destroy(void) { releaseContext(); if (USEGLX13) glXDestroyWindow(getCurrentDisplay(), glx_window); - glXDestroyContext(getCurrentDisplay(), context); + glXDestroyContext(getCurrentDisplay(), context); context = NULL; Display *disp = getCurrentDisplay(); destroyWindow(); diff --git a/src/native/win32/org_lwjgl_opengl_Window.cpp b/src/native/win32/org_lwjgl_opengl_Window.cpp index acf1e2ad..39e83074 100755 --- a/src/native/win32/org_lwjgl_opengl_Window.cpp +++ b/src/native/win32/org_lwjgl_opengl_Window.cpp @@ -675,3 +675,9 @@ JNIEXPORT void JNICALL Java_org_lwjgl_opengl_Window_nSetVSyncEnabled vsync = sync; } } + +JNIEXPORT void JNICALL Java_org_lwjgl_opengl_Window_nMakeCurrent + (JNIEnv *env, jclass clazz) +{ + wglMakeCurrent(hdc, hglrc); +}