From e59ed5d906af92fababb23c9449391c176e08eae Mon Sep 17 00:00:00 2001 From: Elias Naur Date: Sat, 3 Jul 2004 10:16:28 +0000 Subject: [PATCH] Win32 part of Display/Window merge --- src/java/org/lwjgl/opengl/Display.java | 12 +- src/java/org/lwjgl/opengl/Pbuffer.java | 10 +- src/native/common/org_lwjgl_opengl_Display.h | 8 - src/native/common/org_lwjgl_opengl_Pbuffer.h | 4 +- src/native/linux/org_lwjgl_opengl_Pbuffer.cpp | 2 +- src/native/win32/Window.h | 5 + .../{org_lwjgl_Display.cpp => display.cpp} | 151 ++----- src/native/win32/display.h | 51 +++ ...indow.cpp => org_lwjgl_opengl_Display.cpp} | 378 +++++++++++------- src/native/win32/org_lwjgl_opengl_Pbuffer.cpp | 50 +-- 10 files changed, 342 insertions(+), 329 deletions(-) rename src/native/win32/{org_lwjgl_Display.cpp => display.cpp} (81%) create mode 100644 src/native/win32/display.h rename src/native/win32/{org_lwjgl_opengl_Window.cpp => org_lwjgl_opengl_Display.cpp} (61%) mode change 100755 => 100644 diff --git a/src/java/org/lwjgl/opengl/Display.java b/src/java/org/lwjgl/opengl/Display.java index 70e47541..8cee12d0 100644 --- a/src/java/org/lwjgl/opengl/Display.java +++ b/src/java/org/lwjgl/opengl/Display.java @@ -168,6 +168,8 @@ public final class Display { */ private static void createWindow() throws LWJGLException { nCreateWindow(current_mode, fullscreen); + if (title != null) + nSetTitle(title); initControls(); } @@ -360,10 +362,9 @@ public final class Display { * @param newTitle The new window title */ public static void setTitle(String newTitle) { - if (!isCreated()) - throw new IllegalStateException("Cannot set title on uncreated window"); title = newTitle; - nSetTitle(title); + if (isCreated()) + nSetTitle(title); } /** @@ -607,11 +608,6 @@ public final class Display { return context; } - /** - * Destroy the native window peer. - */ - private static native void nDestroy(); - /** * @return true if the window's native peer has been created */ diff --git a/src/java/org/lwjgl/opengl/Pbuffer.java b/src/java/org/lwjgl/opengl/Pbuffer.java index 0841d712..e8d98ae0 100644 --- a/src/java/org/lwjgl/opengl/Pbuffer.java +++ b/src/java/org/lwjgl/opengl/Pbuffer.java @@ -182,11 +182,11 @@ public final class Pbuffer { this.height = height; if ( renderTexture == null ) - handle = nCreate(width, height, pixel_format, null, 0, null, 0); + handle = nCreate(width, height, pixel_format, null, null); else handle = nCreate(width, height, pixel_format, - renderTexture.pixelFormatCaps, renderTexture.pixelFormatCaps.limit(), - renderTexture.pBufferAttribs, renderTexture.pBufferAttribs.limit()); + renderTexture.pixelFormatCaps, + renderTexture.pBufferAttribs); } /** @@ -230,8 +230,8 @@ public final class Pbuffer { * Native method to create a Pbuffer */ private static native int nCreate(int width, int height, PixelFormat pixel_format, - IntBuffer pixelFormatCaps, int pixelFormatCapsSize, - IntBuffer pBufferAttribs, int pBufferAttribsSize) throws LWJGLException; + 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 diff --git a/src/native/common/org_lwjgl_opengl_Display.h b/src/native/common/org_lwjgl_opengl_Display.h index 8e7d2f54..25ccb536 100644 --- a/src/native/common/org_lwjgl_opengl_Display.h +++ b/src/native/common/org_lwjgl_opengl_Display.h @@ -169,14 +169,6 @@ JNIEXPORT void JNICALL Java_org_lwjgl_opengl_Display_createContext JNIEXPORT void JNICALL Java_org_lwjgl_opengl_Display_destroyContext (JNIEnv *, jclass); -/* - * Class: org_lwjgl_opengl_Display - * Method: nDestroy - * Signature: ()V - */ -JNIEXPORT void JNICALL Java_org_lwjgl_opengl_Display_nDestroy - (JNIEnv *, jclass); - /* * Class: org_lwjgl_opengl_Display * Method: nUpdate diff --git a/src/native/common/org_lwjgl_opengl_Pbuffer.h b/src/native/common/org_lwjgl_opengl_Pbuffer.h index 38ca86cf..619b066b 100644 --- a/src/native/common/org_lwjgl_opengl_Pbuffer.h +++ b/src/native/common/org_lwjgl_opengl_Pbuffer.h @@ -69,10 +69,10 @@ JNIEXPORT jint JNICALL Java_org_lwjgl_opengl_Pbuffer_getPbufferCaps /* * Class: org_lwjgl_opengl_Pbuffer * Method: nCreate - * Signature: (IILorg/lwjgl/opengl/PixelFormat;Ljava/nio/IntBuffer;ILjava/nio/IntBuffer;I)I + * Signature: (IILorg/lwjgl/opengl/PixelFormat;Ljava/nio/IntBuffer;Ljava/nio/IntBuffer;)I */ JNIEXPORT jint JNICALL Java_org_lwjgl_opengl_Pbuffer_nCreate - (JNIEnv *, jclass, jint, jint, jobject, jobject, jint, jobject, jint); + (JNIEnv *, jclass, jint, jint, jobject, jobject, jobject); /* * Class: org_lwjgl_opengl_Pbuffer diff --git a/src/native/linux/org_lwjgl_opengl_Pbuffer.cpp b/src/native/linux/org_lwjgl_opengl_Pbuffer.cpp index fa93a7c7..3a778f50 100644 --- a/src/native/linux/org_lwjgl_opengl_Pbuffer.cpp +++ b/src/native/linux/org_lwjgl_opengl_Pbuffer.cpp @@ -88,7 +88,7 @@ static void destroyPbuffer(PbufferInfo *buffer_info) { * Method: nCreate */ JNIEXPORT jint JNICALL Java_org_lwjgl_opengl_Pbuffer_nCreate(JNIEnv *env, jclass clazz, jint width, jint height, jobject pixel_format, - jobject pixelFormatCaps, jint pixelFormatCapsSize, jobject pBufferAttribs, jint pBufferAttribsSize) + jobject pixelFormatCaps, jobject pBufferAttribs) { Display *disp = incDisplay(env); if (disp == NULL) diff --git a/src/native/win32/Window.h b/src/native/win32/Window.h index f54222dd..552b32d7 100644 --- a/src/native/win32/Window.h +++ b/src/native/win32/Window.h @@ -62,6 +62,11 @@ extern HGLRC hglrc; #endif /* _PRIVATE_WINDOW_H_ */ + /* + * Find a suitable pixel format using the WGL_ARB_pixel_format extension + */ + WINDOW_H_API int findPixelFormatARB(JNIEnv *env, jobject pixel_format, jobject pixelFormatCaps, bool use_hdc_bpp, bool window, bool pbuffer); + /* * Create a window with the specified title, position, size, and * fullscreen attribute. The window will have DirectInput associated diff --git a/src/native/win32/org_lwjgl_Display.cpp b/src/native/win32/display.cpp similarity index 81% rename from src/native/win32/org_lwjgl_Display.cpp rename to src/native/win32/display.cpp index a0309ffc..c3f757fe 100644 --- a/src/native/win32/org_lwjgl_Display.cpp +++ b/src/native/win32/display.cpp @@ -33,14 +33,15 @@ /** * $Id$ * - * Win32 specific library for display handdling. + * Win32 specific library for display handling. * * @author cix_foo * @version $Revision$ */ -#include "Window.h" -#include "org_lwjgl_Display.h" +#include +#include +#include "display.h" #include "common_tools.h" #define WINDOWCLASSNAME "LWJGLWINDOW" @@ -54,13 +55,7 @@ WORD* currentGamma = new WORD[256 * 3]; // Current gamma settings DEVMODE devmode; // Now we'll remember this value for the future char * driver = getDriver(); -/* - * Class: org_lwjgl_Display - * Method: nGetAvailableDisplayModes - * Signature: ()[Lorg/lwjgl/DisplayMode; - */ -JNIEXPORT jobjectArray JNICALL Java_org_lwjgl_Display_nGetAvailableDisplayModes - (JNIEnv * env, jclass clazz) +jobjectArray getAvailableDisplayModes(JNIEnv *env) { jobjectArray result = GetAvailableDisplayModesEx(env); if (result == NULL) { @@ -124,7 +119,7 @@ static jobjectArray GetAvailableDisplayModesEx(JNIEnv * env) { // now that we have the count create the classes, and add 'em all - we'll remove dups in Java // Allocate an array of DisplayModes big enough - jclass displayModeClass = env->FindClass("org/lwjgl/DisplayMode"); + jclass displayModeClass = env->FindClass("org/lwjgl/opengl/DisplayMode"); jobjectArray ret = env->NewObjectArray(AvailableModes, displayModeClass, NULL); jmethodID displayModeConstructor = env->GetMethodID(displayModeClass, "", "(IIII)V"); @@ -177,7 +172,7 @@ static jobjectArray GetAvailableDisplayModes(JNIEnv * env) { // now that we have the count create the classes, and add 'em all - we'll remove dups in Java // Allocate an array of DisplayModes big enough - jclass displayModeClass = env->FindClass("org/lwjgl/DisplayMode"); + jclass displayModeClass = env->FindClass("org/lwjgl/opengl/DisplayMode"); jobjectArray ret = env->NewObjectArray(AvailableModes, displayModeClass, NULL); jmethodID displayModeConstructor = env->GetMethodID(displayModeClass, "", "(IIII)V"); @@ -196,16 +191,10 @@ static jobjectArray GetAvailableDisplayModes(JNIEnv * env) { return ret; } -/* - * Class: org_lwjgl_Display - * Method: setDisplayMode - * Signature: (Lorg/lwjgl/DisplayMode;)V - */ -JNIEXPORT void JNICALL Java_org_lwjgl_Display_setDisplayMode - (JNIEnv * env, jclass clazz, jobject mode) +void switchDisplayMode(JNIEnv * env, jobject mode) { - jclass cls_displayMode = env->FindClass("org/lwjgl/DisplayMode"); + jclass cls_displayMode = env->GetObjectClass(mode); 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"); @@ -242,60 +231,13 @@ JNIEXPORT void JNICALL Java_org_lwjgl_Display_setDisplayMode } } - // The change was successful but might not be the exact change we were expecting. - // Now we'll construct a new DisplayMode instance and stash it back in the Display - // class's mode instance variable. - - // Get the screen - HDC screenDC = GetDC(NULL); - // Get the device caps - width = GetDeviceCaps(screenDC, HORZRES); - height = GetDeviceCaps(screenDC, VERTRES); - bpp = GetDeviceCaps(screenDC, BITSPIXEL); - freq = GetDeviceCaps(screenDC, VREFRESH); - if (freq <= 1) - freq = 0; // Unknown - ReleaseDC(NULL, screenDC); - - 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); - modeSet = true; } -/* - * Class: org_lwjgl_Display - * Method: resetDisplayMode - * Signature: ()V - */ -JNIEXPORT void JNICALL Java_org_lwjgl_Display_resetDisplayMode - (JNIEnv * env, jclass clazz) -{ - - // Return device gamma to normal - HDC screenDC = GetDC(NULL); - if (!SetDeviceGammaRamp(screenDC, originalGamma)) { - printfDebug("Could not reset device gamma\n"); - } - ReleaseDC(NULL, screenDC); - - if (modeSet) { - modeSet = false; - // Under Win32, all we have to do is: - ChangeDisplaySettings(NULL, 0); - - // And we'll call init() again to put the correct mode back in Display - Java_org_lwjgl_Display_init(env, clazz); - } -} - /* * Temporarily reset display settings. This is called when the window is minimized. */ -static void tempResetDisplayMode() { +/*static void tempResetDisplayMode() { // Return device gamma to normal HDC screenDC = GetDC(NULL); if (!SetDeviceGammaRamp(screenDC, originalGamma)) { @@ -310,11 +252,11 @@ static void tempResetDisplayMode() { ChangeDisplaySettings(NULL, 0); } } - +*/ /* * Put display settings back to what they were when the window is maximized. */ -static void tempRestoreDisplayMode() { +/*static void tempRestoreDisplayMode() { // Restore gamma HDC screenDC = GetDC(NULL); if (!SetDeviceGammaRamp(screenDC, currentGamma)) { @@ -332,26 +274,14 @@ static void tempRestoreDisplayMode() { } } } +*/ - -/* - * Class: org_lwjgl_Display - * Method: getGammaRampLength - * Signature: ()I - */ -JNIEXPORT jint JNICALL Java_org_lwjgl_Display_getGammaRampLength - (JNIEnv *env, jclass clazz) +int getGammaRampLength(void) { return 256; } -/* - * Class: org_lwjgl_Display - * Method: setGammaRamp - * Signature: (I)Z - */ -JNIEXPORT void JNICALL Java_org_lwjgl_Display_setGammaRamp - (JNIEnv * env, jclass clazz, jobject gammaRampBuffer) +void setGammaRamp(JNIEnv * env, jobject gammaRampBuffer) { const float *gammaRamp = (const float *)env->GetDirectBufferAddress(gammaRampBuffer); // Turn array of floats into array of RGB WORDs @@ -371,20 +301,14 @@ JNIEXPORT void JNICALL Java_org_lwjgl_Display_setGammaRamp } -/* - * Class: org_lwjgl_Display - * Method: init - * Signature: ()V - */ -JNIEXPORT void JNICALL Java_org_lwjgl_Display_init - (JNIEnv * env, jclass clazz) +jobject initDisplay(JNIEnv * env) { // Determine the current screen resolution // Get the screen HDC screenDC = GetDC(NULL); if (!screenDC) { - printf("Couldn't get screen DC!\n"); - return; + throwException(env, "Couldn't get screen DC!"); + return NULL; } // Get the device caps int width = GetDeviceCaps(screenDC, HORZRES); @@ -394,19 +318,36 @@ JNIEXPORT void JNICALL Java_org_lwjgl_Display_init if (freq <= 1) freq = 0; // Unknown - jclass jclass_DisplayMode = env->FindClass("org/lwjgl/DisplayMode"); + jclass jclass_DisplayMode = env->FindClass("org/lwjgl/opengl/DisplayMode"); jmethodID ctor = env->GetMethodID(jclass_DisplayMode, "", "(IIII)V"); jobject newMode = env->NewObject(jclass_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); // Get the default gamma ramp if (GetDeviceGammaRamp(screenDC, originalGamma) == FALSE) { printfDebug("Failed to get initial device gamma\n"); } ReleaseDC(NULL, screenDC); + return newMode; +} +void resetDisplayMode(JNIEnv * env) +{ + + // Return device gamma to normal + HDC screenDC = GetDC(NULL); + if (!SetDeviceGammaRamp(screenDC, originalGamma)) { + printfDebug("Could not reset device gamma\n"); + } + ReleaseDC(NULL, screenDC); + + if (modeSet) { + modeSet = false; + // Under Win32, all we have to do is: + ChangeDisplaySettings(NULL, 0); + + // And we'll call init() again to put the correct mode back in Display + initDisplay(env); + } } static char * getDriver() { @@ -466,12 +407,7 @@ static char * getDriver() { return szDriverValue; } -/* - * Class: org_lwjgl_Display - * Method: getAdapter - */ -JNIEXPORT jstring JNICALL Java_org_lwjgl_Display_getAdapter - (JNIEnv * env, jclass clazz) +jstring getAdapter(JNIEnv * env) { jstring ret = NULL; @@ -486,12 +422,7 @@ JNIEXPORT jstring JNICALL Java_org_lwjgl_Display_getAdapter -/* - * Class: org_lwjgl_Display - * Method: getVersion - */ -JNIEXPORT jstring JNICALL Java_org_lwjgl_Display_getVersion - (JNIEnv * env, jclass clazz) +jstring getVersion(JNIEnv * env) { jstring ret = NULL; diff --git a/src/native/win32/display.h b/src/native/win32/display.h new file mode 100644 index 00000000..f861c27d --- /dev/null +++ b/src/native/win32/display.h @@ -0,0 +1,51 @@ +/* + * 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$ + * + * Win32 specific library for display handling. + * + * @author cix_foo + * @version $Revision$ + */ + +#include + +extern jobjectArray getAvailableDisplayModes(JNIEnv *env); +extern void switchDisplayMode(JNIEnv * env, jobject mode); +extern void resetDisplayMode(JNIEnv * env); +extern int getGammaRampLength(void); +extern void setGammaRamp(JNIEnv * env, jobject gammaRampBuffer); +extern jobject initDisplay(JNIEnv * env); +extern jstring getAdapter(JNIEnv * env); +extern jstring getVersion(JNIEnv * env); \ No newline at end of file diff --git a/src/native/win32/org_lwjgl_opengl_Window.cpp b/src/native/win32/org_lwjgl_opengl_Display.cpp old mode 100755 new mode 100644 similarity index 61% rename from src/native/win32/org_lwjgl_opengl_Window.cpp rename to src/native/win32/org_lwjgl_opengl_Display.cpp index 1536e4ac..ed6a3411 --- a/src/native/win32/org_lwjgl_opengl_Window.cpp +++ b/src/native/win32/org_lwjgl_opengl_Display.cpp @@ -33,7 +33,7 @@ /** * $Id$ * - * Base Win32 window + * Base Win32 display * * @author cix_foo * @version $Revision$ @@ -42,7 +42,8 @@ #define _PRIVATE_WINDOW_H_ #include "Window.h" #include "common_tools.h" -#include "org_lwjgl_opengl_Window.h" +#include "display.h" +#include "org_lwjgl_opengl_Display.h" static bool oneShotInitialised = false; // Registers the LWJGL window class @@ -58,7 +59,7 @@ extern HINSTANCE dll_handle; // Handle to the LWJGL dll RECT clientSize; static bool closerequested; -static jboolean allowSoftwareOpenGL; // Whether to allow software opengl +static int pixel_format_index; #define WINDOWCLASSNAME "LWJGL" @@ -77,29 +78,56 @@ static bool applyPixelFormat(JNIEnv *env, HDC hdc, int iPixelFormat) { return true; } -static int findPixelFormatARB(JNIEnv *env, int bpp, int alpha, int depth, int stencil, int samples) { +static int findPixelFormatARBFromBPP(JNIEnv *env, jobject pixel_format, jobject pixelFormatCaps, int bpp, bool window, bool pbuffer) { + jclass cls_pixel_format = env->GetObjectClass(pixel_format); + int alpha = (int)env->GetIntField(pixel_format, env->GetFieldID(cls_pixel_format, "alpha", "I")); + int depth = (int)env->GetIntField(pixel_format, env->GetFieldID(cls_pixel_format, "depth", "I")); + int stencil = (int)env->GetIntField(pixel_format, env->GetFieldID(cls_pixel_format, "stencil", "I")); + int samples = (int)env->GetIntField(pixel_format, env->GetFieldID(cls_pixel_format, "samples", "I")); + int num_aux_buffers = (int)env->GetIntField(pixel_format, env->GetFieldID(cls_pixel_format, "num_aux_buffers", "I")); + int accum_bpp = (int)env->GetIntField(pixel_format, env->GetFieldID(cls_pixel_format, "accum_bpp", "I")); + int accum_alpha = (int)env->GetIntField(pixel_format, env->GetFieldID(cls_pixel_format, "accum_alpha", "I")); + jboolean stereo = env->GetBooleanField(pixel_format, env->GetFieldID(cls_pixel_format, "stereo", "Z")); int iPixelFormat; unsigned int num_formats_returned; - int attrib_list[] = {WGL_DRAW_TO_WINDOW_ARB, TRUE, - WGL_ACCELERATION_ARB, WGL_FULL_ACCELERATION_ARB, - WGL_PIXEL_TYPE_ARB, WGL_TYPE_RGBA_ARB, - WGL_DOUBLE_BUFFER_ARB, TRUE, - WGL_SUPPORT_OPENGL_ARB, TRUE, - WGL_COLOR_BITS_ARB, bpp, - WGL_ALPHA_BITS_ARB, alpha, - WGL_DEPTH_BITS_ARB, depth, - WGL_STENCIL_BITS_ARB, stencil, - 0, 0, /* For ARB_multisample */ - 0, 0, /* */ - 0}; - - if (samples > 0 && extgl_Extensions.WGL_ARB_multisample) { - attrib_list[18] = WGL_SAMPLE_BUFFERS_ARB; - attrib_list[19] = 1; - attrib_list[20] = WGL_SAMPLES_ARB; - attrib_list[21] = samples; + attrib_list_t attrib_list; + initAttribList(&attrib_list); + if (window) { + putAttrib(&attrib_list, WGL_DRAW_TO_WINDOW_ARB); putAttrib(&attrib_list, TRUE); } - BOOL result = wglChoosePixelFormatARB(hdc, attrib_list, NULL, 1, &iPixelFormat, &num_formats_returned); + if (pbuffer) { + putAttrib(&attrib_list, WGL_DRAW_TO_PBUFFER_ARB); putAttrib(&attrib_list, TRUE); + } + putAttrib(&attrib_list, WGL_ACCELERATION_ARB); putAttrib(&attrib_list, WGL_FULL_ACCELERATION_ARB); + putAttrib(&attrib_list, WGL_PIXEL_TYPE_ARB); putAttrib(&attrib_list, WGL_TYPE_RGBA_ARB); + putAttrib(&attrib_list, WGL_DOUBLE_BUFFER_ARB); putAttrib(&attrib_list, TRUE); + putAttrib(&attrib_list, WGL_SUPPORT_OPENGL_ARB); putAttrib(&attrib_list, TRUE); + putAttrib(&attrib_list, WGL_COLOR_BITS_ARB); putAttrib(&attrib_list, bpp); + putAttrib(&attrib_list, WGL_ALPHA_BITS_ARB); putAttrib(&attrib_list, alpha); + putAttrib(&attrib_list, WGL_DEPTH_BITS_ARB); putAttrib(&attrib_list, depth); + putAttrib(&attrib_list, WGL_STENCIL_BITS_ARB); putAttrib(&attrib_list, stencil); + if (samples > 0 && extgl_Extensions.WGL_ARB_multisample) { + putAttrib(&attrib_list, WGL_SAMPLE_BUFFERS_ARB); putAttrib(&attrib_list, 1); + putAttrib(&attrib_list, WGL_SAMPLES_ARB); putAttrib(&attrib_list, samples); + } + putAttrib(&attrib_list, WGL_ACCUM_BITS_ARB); putAttrib(&attrib_list, accum_bpp); + putAttrib(&attrib_list, WGL_ACCUM_ALPHA_BITS_ARB); putAttrib(&attrib_list, accum_alpha); + putAttrib(&attrib_list, WGL_STEREO_ARB); putAttrib(&attrib_list, stereo ? TRUE : FALSE); + putAttrib(&attrib_list, WGL_AUX_BUFFERS_ARB); putAttrib(&attrib_list, num_aux_buffers); + if ( pixelFormatCaps != NULL ) { + if ( !extgl_Extensions.WGL_ARB_render_texture ) { + throwException(env, "The render-to-texture extension is not supported."); + return -1; + } + + GLuint *pixelFormatCaps_ptr = (GLuint *)env->GetDirectBufferAddress(pixelFormatCaps); + jlong pixelFormatCapsSize = env->GetDirectBufferCapacity(pixelFormatCaps); + + for (jlong i = 0; i < pixelFormatCapsSize;) + putAttrib(&attrib_list, pixelFormatCaps_ptr[i]); + } + putAttrib(&attrib_list, 0); putAttrib(&attrib_list, 0); + BOOL result = wglChoosePixelFormatARB(hdc, attrib_list.attribs, NULL, 1, &iPixelFormat, &num_formats_returned); if (result == FALSE || num_formats_returned < 1) { throwException(env, "Could not choose ARB pixel formats."); @@ -108,15 +136,41 @@ static int findPixelFormatARB(JNIEnv *env, int bpp, int alpha, int depth, int st return iPixelFormat; } +int findPixelFormatARB(JNIEnv *env, jobject pixel_format, jobject pixelFormatCaps, bool use_hdc_bpp, bool window, bool pbuffer) { + int bpp; + jclass cls_pixel_format = env->GetObjectClass(pixel_format); + if (use_hdc_bpp) { + bpp = GetDeviceCaps(hdc, BITSPIXEL); + int iPixelFormat = findPixelFormatARBFromBPP(env, pixel_format, pixelFormatCaps, bpp, window, pbuffer); + if (iPixelFormat == -1) + bpp = 16; + else + return iPixelFormat; + } else + bpp = (int)env->GetIntField(pixel_format, env->GetFieldID(cls_pixel_format, "bpp", "I")); + return findPixelFormatARBFromBPP(env, pixel_format, pixelFormatCaps, bpp, window, pbuffer); +} + /* * Find an appropriate pixel format */ -static int findPixelFormat(JNIEnv *env, int bpp, int alpha, int depth, int stencil) +static int findPixelFormat(JNIEnv *env, jobject pixel_format) { + int bpp = GetDeviceCaps(hdc, BITSPIXEL); + jclass cls_pixel_format = env->GetObjectClass(pixel_format); + int alpha = (int)env->GetIntField(pixel_format, env->GetFieldID(cls_pixel_format, "alpha", "I")); + int depth = (int)env->GetIntField(pixel_format, env->GetFieldID(cls_pixel_format, "depth", "I")); + int stencil = (int)env->GetIntField(pixel_format, env->GetFieldID(cls_pixel_format, "stencil", "I")); + int samples = (int)env->GetIntField(pixel_format, env->GetFieldID(cls_pixel_format, "samples", "I")); + int num_aux_buffers = (int)env->GetIntField(pixel_format, env->GetFieldID(cls_pixel_format, "num_aux_buffers", "I")); + int accum_bpp = (int)env->GetIntField(pixel_format, env->GetFieldID(cls_pixel_format, "accum_bpp", "I")); + int accum_alpha = (int)env->GetIntField(pixel_format, env->GetFieldID(cls_pixel_format, "accum_alpha", "I")); + jboolean stereo = env->GetBooleanField(pixel_format, env->GetFieldID(cls_pixel_format, "stereo", "Z")); unsigned int flags = PFD_DRAW_TO_WINDOW | // support window PFD_SUPPORT_OPENGL | // support OpenGL PFD_DOUBLEBUFFER; // double buffered - + if (stereo) + flags = flags | PFD_STEREO; PIXELFORMATDESCRIPTOR pfd = { sizeof(PIXELFORMATDESCRIPTOR), // size of this pfd 1, // version number @@ -126,11 +180,11 @@ static int findPixelFormat(JNIEnv *env, int bpp, int alpha, int depth, int stenc 0, 0, 0, 0, 0, 0, // color bits ignored (BYTE)alpha, 0, // shift bit ignored - 0, // no accumulation buffer + accum_bpp + accum_alpha, // no accumulation buffer 0, 0, 0, 0, // accum bits ignored (BYTE)depth, (BYTE)stencil, - 0, // No auxiliary buffer + num_aux_buffers, PFD_MAIN_PLANE, // main layer 0, // reserved 0, 0, 0 // layer masks ignored @@ -170,10 +224,11 @@ static int findPixelFormat(JNIEnv *env, int bpp, int alpha, int depth, int stenc } if ((desc.dwFlags & PFD_GENERIC_FORMAT) != 0 || (desc.dwFlags & PFD_GENERIC_ACCELERATED) != 0) { - // secondary check for software override - if(!allowSoftwareOpenGL) { - throwException(env, "Mode not supported by hardware"); - return -1; + jboolean allowSoftwareOpenGL = getBooleanProperty(env, "org.lwjgl.opengl.Window.allowSoftwareOpenGL"); + // secondary check for software override + if(!allowSoftwareOpenGL) { + throwException(env, "Mode not supported by hardware"); + return -1; } } @@ -342,7 +397,7 @@ static void handleMessages(JNIEnv * env, jclass clazz) * * Returns true for success, or false for failure */ -static bool createWindow(JNIEnv *env, jstring title_obj, int x, int y, int width, int height, bool fullscreen, bool undecorated) +static bool createWindow(JNIEnv *env, int width, int height, bool fullscreen, bool undecorated) { int exstyle, windowflags; @@ -372,45 +427,23 @@ static bool createWindow(JNIEnv *env, jstring title_obj, int x, int y, int width ); // Create the window now, using that class: - const char * title = env->GetStringUTFChars(title_obj, NULL); hwnd = CreateWindowEx ( exstyle, WINDOWCLASSNAME, - title, + "", windowflags, - x, y, clientSize.right - clientSize.left, clientSize.bottom - clientSize.top, + 0, 0, clientSize.right - clientSize.left, clientSize.bottom - clientSize.top, NULL, NULL, dll_handle, NULL); - env->ReleaseStringUTFChars(title_obj, title); if (hwnd == NULL) { throwException(env, "Failed to create the window."); return false; } hdc = GetDC(hwnd); - - return true; -} - -static bool createContext(JNIEnv *env, int iPixelFormat) { - if (iPixelFormat == -1) { - closeWindow(); - return false; - } - if (!applyPixelFormat(env, hdc, iPixelFormat)) { - closeWindow(); - return false; - } - hglrc = wglCreateContext(hdc); - if (hglrc == NULL) { - throwException(env, "Failed to create OpenGL rendering context"); - closeWindow(); - return false; - } - wglMakeCurrent(hdc, hglrc); return true; } @@ -419,7 +452,7 @@ static bool createContext(JNIEnv *env, int iPixelFormat) { * Method: nSetTitle * Signature: ()V */ -JNIEXPORT void JNICALL Java_org_lwjgl_opengl_Window_nSetTitle +JNIEXPORT void JNICALL Java_org_lwjgl_opengl_Display_nSetTitle (JNIEnv * env, jclass clazz, jstring title_obj) { const char * title = env->GetStringUTFChars(title_obj, NULL); @@ -432,7 +465,7 @@ JNIEXPORT void JNICALL Java_org_lwjgl_opengl_Window_nSetTitle * Method: update * Signature: ()V */ -JNIEXPORT void JNICALL Java_org_lwjgl_opengl_Window_nUpdate +JNIEXPORT void JNICALL Java_org_lwjgl_opengl_Display_nUpdate (JNIEnv * env, jclass clazz) { handleMessages(env, clazz); @@ -444,7 +477,7 @@ JNIEXPORT void JNICALL Java_org_lwjgl_opengl_Window_nUpdate * Method: swapBuffers * Signature: ()V */ -JNIEXPORT void JNICALL Java_org_lwjgl_opengl_Window_swapBuffers +JNIEXPORT void JNICALL Java_org_lwjgl_opengl_Display_swapBuffers (JNIEnv * env, jclass clazz) { isDirty = false; @@ -452,97 +485,12 @@ JNIEXPORT void JNICALL Java_org_lwjgl_opengl_Window_swapBuffers // wglSwapLayerBuffers(hdc, WGL_SWAP_MAIN_PLANE); } -/* - * Class: org_lwjgl_Window - * Method: nCreate - * Signature: (Ljava/lang/String;IIIIZIIII)V - */ -JNIEXPORT void JNICALL Java_org_lwjgl_opengl_Window_nCreate - (JNIEnv * env, jclass clazz, jstring title, jint x, jint y, jint width, jint height, jboolean fullscreen, jint bpp, jint alpha, jint depth, jint stencil, jint samples) -{ - closerequested = false; - isMinimized = false; - isFocused = true; - isDirty = true; - isFullScreen = fullscreen == JNI_TRUE; - isUndecorated = getBooleanProperty(env, "org.lwjgl.opengl.Window.undecorated"); - - // Speacial option for allowing software opengl - allowSoftwareOpenGL = getBooleanProperty(env, "org.lwjgl.opengl.Window.allowSoftwareOpenGL"); - - // 1. Register window class if necessary - if (!registerWindow()) { - throwException(env, "Could not register window class"); - return; - } - - if (!extgl_Open()) { - throwException(env, "Failed to open extgl"); - return; - } - - if (!createWindow(env, title, x, y, width, height, isFullScreen, isUndecorated)) { - extgl_Close(); - return; - } - int iPixelFormat = findPixelFormat(env, bpp, alpha, depth, stencil); - if (!createContext(env, iPixelFormat)) { - extgl_Close(); - return; - } - - // Some crazy strangeness here so we can use ARB_pixel_format to specify the number - // of multisamples we want. If the extension is present we'll delete the existing - // rendering context and start over, using the ARB extension instead to pick the context. - extgl_InitWGL(env); - if (extgl_Extensions.WGL_ARB_pixel_format && samples > 0) { - wglMakeCurrent(NULL, NULL); - wglDeleteContext(hglrc); - closeWindow(); - if (!createWindow(env, title, x, y, width, height, isFullScreen, isUndecorated)) { - extgl_Close(); - return; - } - iPixelFormat = findPixelFormatARB(env, bpp, alpha, depth, stencil, samples); - if (!createContext(env, iPixelFormat)) { - extgl_Close(); - return; - } - extgl_InitWGL(env); - } - - ShowWindow(hwnd, SW_SHOW); - UpdateWindow(hwnd); - SetForegroundWindow(hwnd); - SetFocus(hwnd); -} - -/* - * Class: org_lwjgl_Window - * Method: doDestroy - * Signature: ()V - */ -JNIEXPORT void JNICALL Java_org_lwjgl_opengl_Window_nDestroy - (JNIEnv * env, jclass clazz) -{ - wglMakeCurrent(NULL, NULL); - - // Delete the rendering context - if (hglrc != NULL) { - printfDebug("Deleting GL context\n"); - wglDeleteContext(hglrc); - hglrc = NULL; - } - closeWindow(); - extgl_Close(); -} - /* * Class: org_lwjgl_opengl_Window * Method: nIsDirty * Signature: ()Z */ -JNIEXPORT jboolean JNICALL Java_org_lwjgl_opengl_Window_nIsDirty +JNIEXPORT jboolean JNICALL Java_org_lwjgl_opengl_Display_nIsDirty (JNIEnv *env, jclass clazz) { bool result = isDirty; isDirty = false; @@ -554,7 +502,7 @@ JNIEXPORT jboolean JNICALL Java_org_lwjgl_opengl_Window_nIsDirty * Method: nIsVisible * Signature: ()Z */ -JNIEXPORT jboolean JNICALL Java_org_lwjgl_opengl_Window_nIsVisible +JNIEXPORT jboolean JNICALL Java_org_lwjgl_opengl_Display_nIsVisible (JNIEnv *env, jclass clazz) { return isMinimized ? JNI_FALSE : JNI_TRUE; } @@ -564,7 +512,7 @@ JNIEXPORT jboolean JNICALL Java_org_lwjgl_opengl_Window_nIsVisible * Method: nIsCloseRequested * Signature: ()Z */ -JNIEXPORT jboolean JNICALL Java_org_lwjgl_opengl_Window_nIsCloseRequested +JNIEXPORT jboolean JNICALL Java_org_lwjgl_opengl_Display_nIsCloseRequested (JNIEnv *, jclass) { bool saved = closerequested; closerequested = false; @@ -576,7 +524,7 @@ JNIEXPORT jboolean JNICALL Java_org_lwjgl_opengl_Window_nIsCloseRequested * Method: nIsActive * Signature: ()Z */ -JNIEXPORT jboolean JNICALL Java_org_lwjgl_opengl_Window_nIsActive +JNIEXPORT jboolean JNICALL Java_org_lwjgl_opengl_Display_nIsActive (JNIEnv *env, jclass clazz) { return isFocused; } @@ -586,7 +534,7 @@ JNIEXPORT jboolean JNICALL Java_org_lwjgl_opengl_Window_nIsActive * Method: nSetVSyncEnabled * Signature: (Z)Z */ -JNIEXPORT void JNICALL Java_org_lwjgl_opengl_Window_nSetVSyncEnabled +JNIEXPORT void JNICALL Java_org_lwjgl_opengl_Display_nSetVSyncEnabled (JNIEnv * env, jclass clazz, jboolean sync) { if (extgl_Extensions.WGL_EXT_swap_control) { @@ -598,14 +546,14 @@ JNIEXPORT void JNICALL Java_org_lwjgl_opengl_Window_nSetVSyncEnabled } } -JNIEXPORT void JNICALL Java_org_lwjgl_opengl_Window_nMakeCurrent +JNIEXPORT void JNICALL Java_org_lwjgl_opengl_Display_nMakeCurrent (JNIEnv *env, jclass clazz) { wglMakeCurrent(hdc, hglrc); } /* -JNIEXPORT void JNICALL Java_org_lwjgl_opengl_Window_nReshape +JNIEXPORT void JNICALL Java_org_lwjgl_opengl_Display_nReshape (JNIEnv *env, jclass clazz, jint x, jint y, jint width, jint height) { if (isFullScreen) { @@ -640,3 +588,131 @@ JNIEXPORT void JNICALL Java_org_lwjgl_opengl_Window_nReshape clientSize.bottom - clientSize.top, SWP_NOZORDER); } */ + +JNIEXPORT jobjectArray JNICALL Java_org_lwjgl_opengl_Display_nGetAvailableDisplayModes(JNIEnv *env, jclass clazz) { + return getAvailableDisplayModes(env); +} + +JNIEXPORT void JNICALL Java_org_lwjgl_opengl_Display_nCreateWindow(JNIEnv *env, jclass clazz, jobject mode, jboolean fullscreen) { + closerequested = false; + isMinimized = false; + isFocused = true; + isDirty = true; + isFullScreen = fullscreen == JNI_TRUE; + isUndecorated = getBooleanProperty(env, "org.lwjgl.opengl.Window.undecorated"); + jclass cls_displayMode = env->GetObjectClass(mode); + jfieldID fid_width = env->GetFieldID(cls_displayMode, "width", "I"); + jfieldID fid_height = env->GetFieldID(cls_displayMode, "height", "I"); + int width = env->GetIntField(mode, fid_width); + int height = env->GetIntField(mode, fid_height); + + if (!createWindow(env, width, height, isFullScreen, isUndecorated)) { + return; + } + if (!applyPixelFormat(env, hdc, pixel_format_index)) { + closeWindow(); + return; + } + + wglMakeCurrent(hdc, hglrc); + ShowWindow(hwnd, SW_SHOW); + UpdateWindow(hwnd); + SetForegroundWindow(hwnd); + SetFocus(hwnd); +} + +JNIEXPORT void JNICALL Java_org_lwjgl_opengl_Display_nDestroyWindow(JNIEnv *env, jclass clazz) { + closeWindow(); +} + +JNIEXPORT void JNICALL Java_org_lwjgl_opengl_Display_switchDisplayMode(JNIEnv *env, jclass clazz, jobject mode) { + switchDisplayMode(env, mode); +} + +JNIEXPORT void JNICALL Java_org_lwjgl_opengl_Display_resetDisplayMode(JNIEnv *env, jclass clazz) { + resetDisplayMode(env); +} + +JNIEXPORT jint JNICALL Java_org_lwjgl_opengl_Display_getGammaRampLength(JNIEnv *env, jclass clazz) { + return getGammaRampLength(); +} + +JNIEXPORT void JNICALL Java_org_lwjgl_opengl_Display_setGammaRamp(JNIEnv *env, jclass clazz, jobject gamma_buffer) { + setGammaRamp(env, gamma_buffer); +} + +JNIEXPORT jstring JNICALL Java_org_lwjgl_opengl_Display_getAdapter(JNIEnv *env, jclass clazz) { + return getAdapter(env); +} + +JNIEXPORT jstring JNICALL Java_org_lwjgl_opengl_Display_getVersion(JNIEnv *env, jclass clazz) { + return getVersion(env); +} + +JNIEXPORT jobject JNICALL Java_org_lwjgl_opengl_Display_init(JNIEnv *env, jclass clazz) { + return initDisplay(env); +} + +JNIEXPORT void JNICALL Java_org_lwjgl_opengl_Display_createContext(JNIEnv *env, jclass clazz, jobject pixel_format) { + if (!extgl_Open()) { + throwException(env, "Failed to open extgl"); + return; + } + + // 1. Register window class if necessary + if (!registerWindow()) { + throwException(env, "Could not register window class"); + return; + } + + if (!createWindow(env, 1, 1, false, false)) { + extgl_Close(); + return; + } + pixel_format_index = findPixelFormat(env, pixel_format); + // Special option for allowing software opengl + if (!applyPixelFormat(env, hdc, pixel_format_index)) { + closeWindow(); + extgl_Close(); + return; + } + + hglrc = wglCreateContext(hdc); + if (hglrc == NULL) { + throwException(env, "Failed to create OpenGL rendering context"); + extgl_Close(); + return; + } + wglMakeCurrent(hdc, hglrc); + // Some crazy strangeness here so we can use ARB_pixel_format to specify the number + // of multisamples we want. If the extension is present we'll delete the existing + // rendering context and start over, using the ARB extension instead to pick the context. + extgl_InitWGL(env); + if (extgl_Extensions.WGL_ARB_pixel_format) { + pixel_format_index = findPixelFormatARB(env, pixel_format, NULL, true, true, false); + wglMakeCurrent(NULL, NULL); + wglDeleteContext(hglrc); + hglrc = wglCreateContext(hdc); + if (hglrc == NULL) { + throwException(env, "Failed to create OpenGL rendering context (ARB)"); + closeWindow(); + extgl_Close(); + return; + } + wglMakeCurrent(hdc, hglrc); + extgl_InitWGL(env); + } + closeWindow(); +} + +JNIEXPORT void JNICALL Java_org_lwjgl_opengl_Display_destroyContext(JNIEnv *env, jclass clazz) { + wglMakeCurrent(NULL, NULL); + + // Delete the rendering context + if (hglrc != NULL) { + printfDebug("Deleting GL context\n"); + wglDeleteContext(hglrc); + hglrc = NULL; + } + extgl_Close(); +} diff --git a/src/native/win32/org_lwjgl_opengl_Pbuffer.cpp b/src/native/win32/org_lwjgl_opengl_Pbuffer.cpp index 34f1859b..74f29cae 100755 --- a/src/native/win32/org_lwjgl_opengl_Pbuffer.cpp +++ b/src/native/win32/org_lwjgl_opengl_Pbuffer.cpp @@ -66,7 +66,6 @@ JNIEXPORT jint JNICALL Java_org_lwjgl_opengl_Pbuffer_getPbufferCaps (JNIEnv *env, jclass clazz) { int caps = 0; - if ( extgl_Extensions.WGL_ARB_pixel_format && extgl_Extensions.WGL_ARB_pbuffer ) caps |= org_lwjgl_opengl_Pbuffer_PBUFFER_SUPPORTED; @@ -88,49 +87,11 @@ JNIEXPORT jint JNICALL Java_org_lwjgl_opengl_Pbuffer_getPbufferCaps */ JNIEXPORT jint JNICALL Java_org_lwjgl_opengl_Pbuffer_nCreate (JNIEnv *env, jclass clazz, - jint width, jint height, - jint bpp, jint alpha, jint depth, jint stencil, - jint samples, - jobject pixelFormatCaps, jint pixelFormatCapsSize, jobject pBufferAttribs, jint pBufferAttribsSize) + jint width, jint height, jobject pixel_format, + jobject pixelFormatCaps, jobject pBufferAttribs) { - int iPixelFormat; - unsigned int num_formats_returned; - int pixelAttribList[] = {WGL_DRAW_TO_PBUFFER_ARB, TRUE, - WGL_ACCELERATION_ARB, WGL_FULL_ACCELERATION_ARB, - WGL_PIXEL_TYPE_ARB, WGL_TYPE_RGBA_ARB, - WGL_DOUBLE_BUFFER_ARB, FALSE, - WGL_SUPPORT_OPENGL_ARB, TRUE, - WGL_COLOR_BITS_ARB, bpp, - WGL_ALPHA_BITS_ARB, alpha, - WGL_DEPTH_BITS_ARB, depth, - WGL_STENCIL_BITS_ARB, stencil, - 0, 0, /* For ARB_multisample */ - 0, 0, /* */ - 0, 0, /* For WGL_ARB_render_texture */ - 0, 0, /* */ - 0}; - - if (samples > 0 && extgl_Extensions.WGL_ARB_multisample) { - pixelAttribList[18] = WGL_SAMPLE_BUFFERS_ARB; - pixelAttribList[19] = 1; - pixelAttribList[20] = WGL_SAMPLES_ARB; - pixelAttribList[21] = samples; - } - - if ( pixelFormatCaps != NULL ) { - if ( !extgl_Extensions.WGL_ARB_render_texture ) { - throwException(env, "The render-to-texture extension is not supported."); - return (jint)NULL; - } - - GLuint *pixelFormatCaps_ptr = (GLuint *)env->GetDirectBufferAddress(pixelFormatCaps); - - for ( int i = 0; i < pixelFormatCapsSize; ) - pixelAttribList[22 + i++] = pixelFormatCaps_ptr[i]; - } - - BOOL result = wglChoosePixelFormatARB(hdc, pixelAttribList, NULL, 1, &iPixelFormat, &num_formats_returned); - if (result == FALSE || num_formats_returned < 1) { + int iPixelFormat = findPixelFormatARB(env, pixel_format, pixelFormatCaps, false, false, true); + if (iPixelFormat == -1) { throwException(env, "Could not choose pixel formats."); return (jint)NULL; @@ -140,10 +101,11 @@ JNIEXPORT jint JNICALL Java_org_lwjgl_opengl_Pbuffer_nCreate if ( pBufferAttribs != NULL ) { GLuint *pBufferAttribs_ptr = (GLuint *)env->GetDirectBufferAddress(pBufferAttribs); + jlong pBufferAttribsSize = env->GetDirectBufferCapacity(pBufferAttribs); int pBufferAttribList[9]; - int i; + jlong i; for ( i = 0; i < pBufferAttribsSize; ) pBufferAttribList[i++] = pBufferAttribs_ptr[i];