diff --git a/src/java/org/lwjgl/Display.java b/src/java/org/lwjgl/Display.java index 05a400fa..ddf0dc8b 100644 --- a/src/java/org/lwjgl/Display.java +++ b/src/java/org/lwjgl/Display.java @@ -48,11 +48,6 @@ import java.util.Arrays; public final class Display { - static { - System.loadLibrary(Sys.getLibraryName()); - init(); - } - /** Has the display been created? */ private static boolean created; @@ -79,6 +74,11 @@ public final class Display { /** MacOSX platform */ public static final int PLATFORM_AGL = 2; + static { + System.loadLibrary(Sys.getLibraryName()); + init(); + } + /** * No construction allowed. */ diff --git a/src/java/org/lwjgl/Window.java b/src/java/org/lwjgl/Window.java index 6bcbf93a..b247e102 100644 --- a/src/java/org/lwjgl/Window.java +++ b/src/java/org/lwjgl/Window.java @@ -26,8 +26,11 @@ public abstract class Window { System.loadLibrary(Sys.getLibraryName()); } - /** Whether we have a window already */ + /** The currently created window */ private static Window currentWindow; + + /** Whether the window is currently created, ie. has a native peer */ + private boolean created; /** The window's native data structure. On Win32 this is an HWND. */ private int handle; @@ -66,7 +69,7 @@ public abstract class Window { * In this abstract base class, no actual window peer is constructed. This should be * done in specialised derived classes. * - * Only one Window can be constructed at a time; to create another Window you must + * Only one Window can be created() at a time; to create another Window you must * first destroy() the first window. * * @param title The window's title @@ -76,15 +79,12 @@ public abstract class Window { * @throws RuntimeException if you attempt to create more than one window at the same time */ protected Window(String title, int x, int y, int width, int height) { - if (currentWindow != null) - throw new RuntimeException("Only one LWJGL window may be instantiated at any one time."); this.title = title; this.x = x; this.y = y; this.width = width; this.height = height; - currentWindow = this; } /** @@ -164,14 +164,40 @@ public abstract class Window { */ private native void swapBuffers(); + /** + * Create the window. + */ + public final void create() throws Exception { + if (currentWindow != null) + throw new RuntimeException("Only one LWJGL window may be instantiated at any one time."); + doCreate(); + currentWindow = this; + created = true; + } + + /** + * Create the window (derived classes). + * @throws Exception + */ + protected abstract void doCreate() throws Exception; + /** * Destroy the window. */ - public void destroy() { - currentWindow = null; + public final void destroy() { + if (!created) + return; + doDestroy(); nDestroy(); + currentWindow = null; + created = false; } + /** + * Destroy the window (derived classes) + */ + protected abstract void doDestroy(); + /** * Natively destroy the window */ @@ -185,10 +211,10 @@ public abstract class Window { } /** - * @return true if a window has been created + * @return true if the window's native peer has been created */ - public static boolean isCreated() { - return currentWindow != null; + public final boolean isCreated() { + return created; } /** @@ -197,4 +223,20 @@ public abstract class Window { */ public final native void tick(); + /* (non-Javadoc) + * @see java.lang.Object#finalize() + */ + protected void finalize() throws Throwable { + super.finalize(); + + destroy(); + } + + /* (non-Javadoc) + * @see java.lang.Object#toString() + */ + public String toString() { + return "Window["+title+"]"; + } + } diff --git a/src/java/org/lwjgl/input/Keyboard.java b/src/java/org/lwjgl/input/Keyboard.java index 99a8fc20..9f63c08e 100644 --- a/src/java/org/lwjgl/input/Keyboard.java +++ b/src/java/org/lwjgl/input/Keyboard.java @@ -35,7 +35,6 @@ package org.lwjgl.input; import java.nio.ByteBuffer; import java.nio.ByteOrder; -import org.lwjgl.*; import org.lwjgl.Sys; /** @@ -249,8 +248,6 @@ public class Keyboard { public static void create() throws Exception { if (created) return; - if (!Window.isCreated()) - throw new Exception("The display has not yet been created."); if (!nCreate()) throw new Exception("The keyboard could not be created."); created = true; diff --git a/src/java/org/lwjgl/input/Mouse.java b/src/java/org/lwjgl/input/Mouse.java index b0ae2e50..25dadf0e 100644 --- a/src/java/org/lwjgl/input/Mouse.java +++ b/src/java/org/lwjgl/input/Mouse.java @@ -101,8 +101,6 @@ public class Mouse { public static void create() throws Exception { if (created) return; - if (!Window.isCreated()) - throw new Exception("The display has not yet been created."); if (!nCreate()) throw new Exception("The mouse could not be created."); created = true; diff --git a/src/java/org/lwjgl/opengl/BaseGL.java b/src/java/org/lwjgl/opengl/BaseGL.java index 815034d9..38056734 100644 --- a/src/java/org/lwjgl/opengl/BaseGL.java +++ b/src/java/org/lwjgl/opengl/BaseGL.java @@ -51,16 +51,37 @@ import org.lwjgl.Window; * @author cix_foo * @version $Revision$ */ -public abstract class BaseGL extends Window { +public class BaseGL extends Window { + static { + System.loadLibrary(Sys.getLibraryName()); + } + /** The current rendering context */ - private static BaseGL currentContext; + //private static BaseGL currentContext; /** Has the GL been created yet? */ private boolean created; /** Handle to the native GL rendering context */ protected int handle; + + /** Color bits */ + protected final int color; + + /** Alpha bits */ + protected final int alpha; + + /** Depth bits */ + protected final int depth; + + /** Stencil bits */ + protected final int stencil; + + private int x, y; + + /** Fullscreen */ + protected final boolean fullscreen; /** * Construct a windowed instance of GL. If the underlying OS does not @@ -78,7 +99,14 @@ public abstract class BaseGL extends Window { public BaseGL(String title, int x, int y, int width, int height, int bpp, int alpha, int depth, int stencil) throws Exception { super(title, x, y, width, height); - nCreate(title, x, y, width, height, false, bpp, alpha, depth, stencil); + this.x = x; + this.y = y; + this.color = bpp; + this.alpha = alpha; + this.depth = depth; + this.stencil = stencil; + this.fullscreen = false; + } /** @@ -92,33 +120,44 @@ public abstract class BaseGL extends Window { public BaseGL(String title, int bpp, int alpha, int depth, int stencil) throws Exception { super(title, 0, 0, Display.getWidth(), Display.getHeight()); - nCreate(title, 0, 0, Display.getWidth(), Display.getHeight(), true, bpp, alpha, depth, stencil); + this.x = 0; + this.y = 0; + this.color = bpp; + this.alpha = alpha; + this.depth = depth; + this.stencil = stencil; + this.fullscreen = true; + + } + + protected void doCreate() throws Exception { + nCreate(x, y, getWidth(), getHeight(), color, alpha, depth, stencil, fullscreen); } /** * Native method to create a windowed GL */ - private native void nCreate(String title, int x, int y, int width, int height, boolean fullscreen, int bpp, int alpha, int depth, int stencil) throws Exception; - - /** - * Finalizer, marked final. Ensures the window is destroyed. - */ - public final void finalize() throws Throwable { - super.finalize(); - - destroy(); - } - /* (non-Javadoc) - * @see org.lwjgl.Window#destroy() - */ - public void destroy() { - // Do native destroy first - super.destroy(); - } + private native void nCreate( + int x, + int y, + int width, + int height, + int bpp, + int alpha, + int depth, + int stencil, + boolean fullscreen) throws Exception; + /* (non-Javadoc) + * @see org.lwjgl.Window#doDestroy() + */ + protected void doDestroy() { + nDestroyGL(); + } + /** * Natively destroy any GL-related stuff */ - private native void nDestroy(); + private native void nDestroyGL(); } diff --git a/src/java/org/lwjgl/opengl/GL.java b/src/java/org/lwjgl/opengl/GL.java index f9753aeb..7c1ae04c 100644 --- a/src/java/org/lwjgl/opengl/GL.java +++ b/src/java/org/lwjgl/opengl/GL.java @@ -62,7 +62,6 @@ public class GL extends CoreGL implements GLConstants { */ public GL(String title, int x, int y, int width, int height, int bpp, int alpha, int depth, int stencil) throws Exception { super(title, x, y, width, height, bpp, alpha, depth, stencil); - determineAvailableExtensions(); } /** @@ -75,9 +74,18 @@ public class GL extends CoreGL implements GLConstants { */ public GL(String title, int bpp, int alpha, int depth, int stencil) throws Exception { super(title, bpp, alpha, depth, stencil); + } + + /* (non-Javadoc) + * @see org.lwjgl.opengl.BaseGL#doCreate() + */ + protected void doCreate() throws Exception { + super.doCreate(); + determineAvailableExtensions(); } + public native void activeStencilFaceEXT(int face); public native void activeTextureARB(int texture); @@ -1573,7 +1581,7 @@ public class GL extends CoreGL implements GLConstants { /** * Determine which extensions are available */ - private void determineAvailableExtensions() { + public void determineAvailableExtensions() { determineAvailableWGLExtensions(); diff --git a/src/native/common/org_lwjgl_opengl_BaseGL.h b/src/native/common/org_lwjgl_opengl_BaseGL.h index 7994808e..6653ec57 100644 --- a/src/native/common/org_lwjgl_opengl_BaseGL.h +++ b/src/native/common/org_lwjgl_opengl_BaseGL.h @@ -8,21 +8,20 @@ extern "C" { #endif /* Inaccessible static: currentWindow */ -/* Inaccessible static: currentContext */ /* * Class: org_lwjgl_opengl_BaseGL * Method: nCreate - * Signature: (Ljava/lang/String;IIIIZIIII)V + * Signature: (IIIIIIIIZ)V */ JNIEXPORT void JNICALL Java_org_lwjgl_opengl_BaseGL_nCreate - (JNIEnv *, jobject, jstring, jint, jint, jint, jint, jboolean, jint, jint, jint, jint); + (JNIEnv *, jobject, jint, jint, jint, jint, jint, jint, jint, jint, jboolean); /* * Class: org_lwjgl_opengl_BaseGL - * Method: nDestroy + * Method: nDestroyGL * Signature: ()V */ -JNIEXPORT void JNICALL Java_org_lwjgl_opengl_BaseGL_nDestroy +JNIEXPORT void JNICALL Java_org_lwjgl_opengl_BaseGL_nDestroyGL (JNIEnv *, jobject); #ifdef __cplusplus diff --git a/src/native/win32/Window.h b/src/native/win32/Window.h index c3124349..edb60e12 100644 --- a/src/native/win32/Window.h +++ b/src/native/win32/Window.h @@ -58,7 +58,7 @@ extern HDC hdc; // Device context extern LPDIRECTINPUT lpdi; // DirectInput extern bool isFullScreen; // Whether we're fullscreen or not - + extern bool isMinimized; // Whether we're minimized or not #endif /* _PRIVATE_WINDOW_H_ */ /* diff --git a/src/native/win32/org_lwjgl_Display.cpp b/src/native/win32/org_lwjgl_Display.cpp index a1c239a3..4118ab66 100644 --- a/src/native/win32/org_lwjgl_Display.cpp +++ b/src/native/win32/org_lwjgl_Display.cpp @@ -191,17 +191,17 @@ JNIEXPORT void JNICALL Java_org_lwjgl_Display_setDisplayMode (JNIEnv * env, jclass clazz, jobject mode) { - jfieldID fid_width = env->GetFieldID(clazz, "width", "I"); - jfieldID fid_height = env->GetFieldID(clazz, "height", "I"); - jfieldID fid_bpp = env->GetFieldID(clazz, "bpp", "I"); - jfieldID fid_freq = env->GetFieldID(clazz, "freq", "I"); + jclass cls_displayMode = env->FindClass("org/lwjgl/DisplayMode"); + jfieldID fid_width = env->GetFieldID(cls_displayMode, "width", "I"); + jfieldID fid_height = env->GetFieldID(cls_displayMode, "height", "I"); + jfieldID fid_bpp = env->GetFieldID(cls_displayMode, "bpp", "I"); + jfieldID fid_freq = env->GetFieldID(cls_displayMode, "freq", "I"); int width = env->GetIntField(mode, fid_width); int height = env->GetIntField(mode, fid_height); int bpp = env->GetIntField(mode, fid_bpp); int freq = env->GetIntField(mode, fid_freq); - DEVMODE devmode; devmode.dmSize = sizeof(DEVMODE); devmode.dmBitsPerPel = bpp; @@ -229,6 +229,7 @@ JNIEXPORT void JNICALL Java_org_lwjgl_Display_setDisplayMode printf("Failed to set display mode using dual monitors\n"); #endif throwException(env, "Failed to set display mode."); + return; } } @@ -245,13 +246,12 @@ JNIEXPORT void JNICALL Java_org_lwjgl_Display_setDisplayMode freq = GetDeviceCaps(screenDC, VREFRESH); if (freq <= 1) freq = 0; // Unknown - ReleaseDC(NULL, screenDC); + DeleteDC(screenDC); - jclass jclass_DisplayMode = env->FindClass("org/lwjgl/DisplayMode"); - jmethodID ctor = env->GetMethodID(jclass_DisplayMode, "", "(IIII)V"); - jobject newMode = env->NewObject(jclass_DisplayMode, ctor, width, height, bpp, freq); - jfieldID fid_mode= env->GetStaticFieldID(clazz, "mode", "[org/lwjgl/DisplayMode;"); - env->SetStaticObjectField(clazz, fid_mode, newMode); + jmethodID ctor = env->GetMethodID(cls_displayMode, "", "(IIII)V"); + jobject newMode = env->NewObject(cls_displayMode, ctor, width, height, bpp, freq); + jfieldID fid_initialMode = env->GetStaticFieldID(clazz, "mode", "Lorg/lwjgl/DisplayMode;"); + env->SetStaticObjectField(clazz, fid_initialMode, newMode); env->DeleteLocalRef(newMode); } @@ -302,9 +302,12 @@ JNIEXPORT void JNICALL Java_org_lwjgl_Display_init (JNIEnv * env, jclass clazz) { // Determine the current screen resolution - // Get the screen HDC screenDC = CreateCompatibleDC(NULL); + if (!screenDC) { + printf("Couldn't get screen DC!\n"); + return; + } // Get the device caps int width = GetDeviceCaps(screenDC, HORZRES); int height = GetDeviceCaps(screenDC, VERTRES); @@ -312,13 +315,12 @@ JNIEXPORT void JNICALL Java_org_lwjgl_Display_init int freq = GetDeviceCaps(screenDC, VREFRESH); if (freq <= 1) freq = 0; // Unknown - ReleaseDC(NULL, screenDC); + DeleteDC(screenDC); jclass jclass_DisplayMode = env->FindClass("org/lwjgl/DisplayMode"); jmethodID ctor = env->GetMethodID(jclass_DisplayMode, "", "(IIII)V"); jobject newMode = env->NewObject(jclass_DisplayMode, ctor, width, height, bpp, freq); - - jfieldID fid_initialMode = env->GetFieldID(clazz, "initialMode", "[org/lwjgl/DisplayMode;"); + jfieldID fid_initialMode = env->GetStaticFieldID(clazz, "mode", "Lorg/lwjgl/DisplayMode;"); env->SetStaticObjectField(clazz, fid_initialMode, newMode); env->DeleteLocalRef(newMode); } diff --git a/src/native/win32/org_lwjgl_Window.cpp b/src/native/win32/org_lwjgl_Window.cpp index 71c3db8e..a550d20e 100644 --- a/src/native/win32/org_lwjgl_Window.cpp +++ b/src/native/win32/org_lwjgl_Window.cpp @@ -48,6 +48,7 @@ HWND hwnd = NULL; // Handle to the window HDC hdc = NULL; // Device context LPDIRECTINPUT lpdi = NULL; // DirectInput bool isFullScreen = false; // Whether we're fullscreen or not +bool isMinimized = false; // Whether we're minimized or not JNIEnv * environment; // Cached environment jobject window; // Cached Java Window instance handle extern HINSTANCE dll_handle; // Handle to the LWJGL dll @@ -169,11 +170,11 @@ LRESULT CALLBACK lwjglWindowProc(HWND hWnd, break; case WM_ACTIVATE: { - bool isMinimized = false; switch(LOWORD(wParam)) { case WA_ACTIVE: case WA_CLICKACTIVE: environment->SetBooleanField(window, environment->GetFieldID(environment->GetObjectClass(window), "minimized", "Z"), false); + isMinimized = false; break; case WA_INACTIVE: environment->SetBooleanField(window, environment->GetFieldID(environment->GetObjectClass(window), "minimized", "Z"), true); @@ -222,6 +223,7 @@ bool registerWindow() printf("Failed to register window class\n"); return false; } + printf("Window registered\n"); oneShotInitialised = true; } @@ -373,8 +375,8 @@ void handleMessages(JNIEnv * env, jobject obj) 0, // first message 0, // last message PM_REMOVE // removal options - )) { - + )) + { TranslateMessage(&msg); DispatchMessage(&msg); }; diff --git a/src/native/win32/org_lwjgl_opengl_BaseGL.cpp b/src/native/win32/org_lwjgl_opengl_BaseGL.cpp index f7cde4dc..eb3d82f5 100644 --- a/src/native/win32/org_lwjgl_opengl_BaseGL.cpp +++ b/src/native/win32/org_lwjgl_opengl_BaseGL.cpp @@ -43,22 +43,24 @@ #include "org_lwjgl_opengl_BaseGL.h" #include "extgl.h" #include "Window.h" +#include "jni.h" HGLRC hglrc = NULL; // OpenGL rendering context - /* * Class: org_lwjgl_opengl_BaseGL * Method: nCreate - * Signature: (Ljava/lang/String;IIIIZ)V + * Signature: (Ljava/lang/String;IIIIIIIIZ)V */ JNIEXPORT void JNICALL Java_org_lwjgl_opengl_BaseGL_nCreate - (JNIEnv * env, jobject obj, jstring title, jint x, jint y, jint width, jint height, jboolean fullscreen, jint bpp, jint alpha, jint depth, jint stencil) + (JNIEnv * env, jobject obj, + jstring title, jint x, jint y, jint width, jint height, jint bpp, jint alpha, jint depth, jint stencil, jboolean fullscreen) { + // 1. Create a window const char * titleString = env->GetStringUTFChars(title, NULL); if (!createWindow(titleString, x, y, width, height, fullscreen == JNI_TRUE ? true : false)) { - env->ReleaseStringUTFChars(title, titleString); + env->ReleaseStringUTFChars((jstring) title, titleString); closeWindow(); throwException(env, "Failed to create the window."); return; @@ -156,16 +158,16 @@ JNIEXPORT void JNICALL Java_org_lwjgl_opengl_BaseGL_nCreate // 4. Initialise other things now if (extgl_Open() != 0) { - closeWindow(); throwException(env, "Failed to open extgl"); + closeWindow(); return; } // Create a rendering context hglrc = wglCreateContext(hdc); if (hglrc == NULL) { - closeWindow(); throwException(env, "Failed to create OpenGL rendering context"); + closeWindow(); return; } @@ -189,13 +191,16 @@ JNIEXPORT void JNICALL Java_org_lwjgl_opengl_BaseGL_nCreate * Method: nDestroy * Signature: ()V */ -JNIEXPORT void JNICALL Java_org_lwjgl_opengl_BaseGL_nDestroy +JNIEXPORT void JNICALL Java_org_lwjgl_opengl_BaseGL_nDestroyGL (JNIEnv * env, jobject obj) { wglMakeCurrent(NULL, NULL); // Delete the rendering context - if (hglrc != NULL) + if (hglrc != NULL) { wglDeleteContext(hglrc); + hglrc = NULL; + } + extgl_Close(); }