diff --git a/src/native/linux/Window.h b/src/native/linux/Window.h index c6cd710f..48110b36 100644 --- a/src/native/linux/Window.h +++ b/src/native/linux/Window.h @@ -130,10 +130,4 @@ * convert bit-per-pixel to bits-per-element */ extern int convertToBPE(int bpp); - - /* - * Return the current OpenGL window context - */ - GLXContext getCurrentContext(void); - #endif /* _LWJGL_WINDOW_H_INCLUDED_ */ diff --git a/src/native/linux/org_lwjgl_opengl_Pbuffer.cpp b/src/native/linux/org_lwjgl_opengl_Pbuffer.cpp index e6aab2e3..5a56c735 100644 --- a/src/native/linux/org_lwjgl_opengl_Pbuffer.cpp +++ b/src/native/linux/org_lwjgl_opengl_Pbuffer.cpp @@ -108,7 +108,7 @@ static bool createPbufferUsingUniqueContext(JNIEnv *env, PbufferInfo *pbuffer_in XFree(configs); return false; } - GLXContext context = glXCreateNewContext(getDisplay(), configs[0], GLX_RGBA_TYPE, getCurrentContext(), True); + GLXContext context = glXCreateNewContext(getDisplay(), configs[0], GLX_RGBA_TYPE, getCurrentGLXContext(), True); if (context == NULL) { XFree(configs); throwException(env, "Could not create a GLX context"); diff --git a/src/native/win32/Window.h b/src/native/win32/Window.h index 7d17cc39..4bfe7815 100644 --- a/src/native/win32/Window.h +++ b/src/native/win32/Window.h @@ -53,15 +53,21 @@ #define WINDOW_H_API extern extern HWND display_hwnd; // Handle to the window - extern HDC display_hdc; // Device context +// extern HDC display_hdc; // Device context extern bool isFullScreen; // Whether we're fullscreen or not extern bool isMinimized; // Whether we're minimized or not extern bool isFocused; // Whether we're focused or not extern bool isDirty; // Whether we're dirty or not extern RECT clientSize; - extern HGLRC display_hglrc; +// extern HGLRC display_hglrc; #endif /* _PRIVATE_WINDOW_H_ */ + WINDOW_H_API HDC getCurrentWindowDC(); + + WINDOW_H_API HGLRC getCurrentContext(); + + WINDOW_H_API int getCurrentPixelFormat(); + WINDOW_H_API bool applyPixelFormat(JNIEnv *env, HDC hdc, int iPixelFormat); WINDOW_H_API void closeWindow(HWND hwnd, HDC hdc); @@ -74,7 +80,7 @@ /* * Find a suitable pixel format using the WGL_ARB_pixel_format extension */ - WINDOW_H_API int findPixelFormatARB(JNIEnv *env, HDC hdc, jobject pixel_format, jobject pixelFormatCaps, bool use_hdc_bpp, bool window, bool double_buffer); + WINDOW_H_API int findPixelFormatARB(JNIEnv *env, HDC hdc, jobject pixel_format, jobject pixelFormatCaps, bool use_hdc_bpp, bool window, bool pbuffer, bool double_buffer); /* * Create a window with the specified title, position, size, and diff --git a/src/native/win32/org_lwjgl_opengl_Display.cpp b/src/native/win32/org_lwjgl_opengl_Display.cpp index e706cbe6..39207766 100644 --- a/src/native/win32/org_lwjgl_opengl_Display.cpp +++ b/src/native/win32/org_lwjgl_opengl_Display.cpp @@ -50,8 +50,8 @@ static bool oneShotInitialised = false; // Registers the LWJGL window class HWND display_hwnd = NULL; // Handle to the window -HDC display_hdc = NULL; // Device context -HGLRC display_hglrc = NULL; // OpenGL context +static HDC display_hdc = NULL; // Device context +static HGLRC display_hglrc = NULL; // OpenGL context static bool isFullScreen = false; // Whether we're fullscreen or not static bool isMinimized = false; // Whether we're minimized or not static bool isFocused = false; // whether we're focused or not @@ -80,7 +80,19 @@ bool applyPixelFormat(JNIEnv *env, HDC hdc, int iPixelFormat) { return true; } -static int findPixelFormatARBFromBPP(JNIEnv *env, HDC hdc, jobject pixel_format, jobject pixelFormatCaps, int bpp, bool window, bool double_buffer) { +HGLRC getCurrentContext() { + return display_hglrc; +} + +HDC getCurrentWindowDC() { + return display_hdc; +} + +int getCurrentPixelFormat() { + return pixel_format_index; +} + +static int findPixelFormatARBFromBPP(JNIEnv *env, HDC hdc, jobject pixel_format, jobject pixelFormatCaps, int bpp, bool window, bool pbuffer, bool double_buffer) { 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")); @@ -96,7 +108,8 @@ static int findPixelFormatARBFromBPP(JNIEnv *env, HDC hdc, jobject pixel_format, initAttribList(&attrib_list); if (window) { putAttrib(&attrib_list, WGL_DRAW_TO_WINDOW_ARB); putAttrib(&attrib_list, TRUE); - } else { + } + 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); @@ -117,7 +130,6 @@ static int findPixelFormatARBFromBPP(JNIEnv *env, HDC hdc, jobject pixel_format, 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; } @@ -131,25 +143,24 @@ static int findPixelFormatARBFromBPP(JNIEnv *env, HDC hdc, jobject pixel_format, 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."); return -1; } return iPixelFormat; } -int findPixelFormatARB(JNIEnv *env, HDC hdc, jobject pixel_format, jobject pixelFormatCaps, bool use_hdc_bpp, bool window, bool double_buffer) { +int findPixelFormatARB(JNIEnv *env, HDC hdc, jobject pixel_format, jobject pixelFormatCaps, bool use_hdc_bpp, bool window, bool pbuffer, bool double_buffer) { int bpp; jclass cls_pixel_format = env->GetObjectClass(pixel_format); if (use_hdc_bpp) { bpp = GetDeviceCaps(hdc, BITSPIXEL); - int iPixelFormat = findPixelFormatARBFromBPP(env, hdc, pixel_format, pixelFormatCaps, bpp, window, double_buffer); + int iPixelFormat = findPixelFormatARBFromBPP(env, hdc, pixel_format, pixelFormatCaps, bpp, window, pbuffer, double_buffer); 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, hdc, pixel_format, pixelFormatCaps, bpp, window, double_buffer); + return findPixelFormatARBFromBPP(env, hdc, pixel_format, pixelFormatCaps, bpp, window, pbuffer, double_buffer); } /* @@ -708,19 +719,23 @@ JNIEXPORT void JNICALL Java_org_lwjgl_opengl_Display_createContext(JNIEnv *env, return; } extgl_InitWGL(env); - jclass cls_pixel_format = env->GetObjectClass(pixel_format); - int samples = (int)env->GetIntField(pixel_format, env->GetFieldID(cls_pixel_format, "samples", "I")); // 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. - if (samples > 0 && extgl_Extensions.WGL_ARB_pixel_format) { - pixel_format_index = findPixelFormatARB(env, dummy_hdc, pixel_format, NULL, true, true, true); - wglMakeCurrent(NULL, NULL); - wglDeleteContext(display_hglrc); + if (extgl_Extensions.WGL_ARB_pixel_format) { + pixel_format_index = findPixelFormatARB(env, dummy_hdc, pixel_format, NULL, true, true, true, true); + if (pixel_format_index == -1) { + pixel_format_index = findPixelFormatARB(env, dummy_hdc, pixel_format, NULL, true, true, false, true); + } closeWindow(dummy_hwnd, dummy_hdc); if (pixel_format_index == -1) { + jclass cls_pixel_format = env->GetObjectClass(pixel_format); + int samples = (int)env->GetIntField(pixel_format, env->GetFieldID(cls_pixel_format, "samples", "I")); + if (samples > 0) + throwException(env, "Could not find suitable pixel format"); return; } + wglDeleteContext(display_hglrc); dummy_hwnd = createWindow(env, 1, 1, false, false); if (dummy_hwnd == NULL) { return; @@ -736,8 +751,9 @@ JNIEXPORT void JNICALL Java_org_lwjgl_opengl_Display_createContext(JNIEnv *env, throwException(env, "Failed to create OpenGL rendering context (ARB)"); return; } - } else + } else { closeWindow(dummy_hwnd, dummy_hdc); + } } JNIEXPORT void JNICALL Java_org_lwjgl_opengl_Display_destroyContext(JNIEnv *env, jclass clazz) { diff --git a/src/native/win32/org_lwjgl_opengl_Pbuffer.cpp b/src/native/win32/org_lwjgl_opengl_Pbuffer.cpp index a7ed1bce..f71d9089 100755 --- a/src/native/win32/org_lwjgl_opengl_Pbuffer.cpp +++ b/src/native/win32/org_lwjgl_opengl_Pbuffer.cpp @@ -49,13 +49,10 @@ #include "common_tools.h" typedef struct _PbufferInfo { - HGLRC Pbuffer_context; - HPBUFFERARB Pbuffer; - HDC Pbuffer_dc; - + bool use_display_context; } PbufferInfo; /* @@ -82,72 +79,80 @@ JNIEXPORT jint JNICALL Java_org_lwjgl_opengl_Pbuffer_getPbufferCaps return caps; } -/* - * Class: org_lwjgl_opengl_Pbuffer - * Method: nCreate - */ -JNIEXPORT jint JNICALL Java_org_lwjgl_opengl_Pbuffer_nCreate - (JNIEnv *env, jclass clazz, - jint width, jint height, jobject pixel_format, - jobject pixelFormatCaps, jobject pBufferAttribs) -{ +static HPBUFFERARB createPbuffer(JNIEnv *env, int width, int height, jobject pixel_format, jobject pixelFormatCaps, const int *pBufferAttribs_ptr) { HWND dummy_hwnd = createWindow(env, 1, 1, false, false); if (dummy_hwnd == NULL) { - return (jint)NULL; + return NULL; } HDC dummy_hdc = GetDC(dummy_hwnd); int iPixelFormat = findPixelFormat(env, dummy_hdc, pixel_format); if (iPixelFormat == -1) { - return (jint)NULL; + return NULL; } if (!applyPixelFormat(env, dummy_hdc, iPixelFormat)) { closeWindow(dummy_hwnd, dummy_hdc); - return (jint)NULL; + return NULL; } HGLRC dummy_hglrc = wglCreateContext(dummy_hdc); if (dummy_hglrc == NULL) { closeWindow(dummy_hwnd, dummy_hdc); throwException(env, "Failed to create OpenGL rendering context"); - return (jint)NULL; + return NULL; } BOOL result = wglMakeCurrent(dummy_hdc, dummy_hglrc); if (!result) { wglDeleteContext(dummy_hglrc); closeWindow(dummy_hwnd, dummy_hdc); throwException(env, "Could not bind context to dummy window"); - return (jint)NULL; + return NULL; } extgl_InitWGL(env); - iPixelFormat = findPixelFormatARB(env, dummy_hdc, pixel_format, pixelFormatCaps, false, false, false); - if (iPixelFormat == -1) { - wglDeleteContext(dummy_hglrc); - closeWindow(dummy_hwnd, dummy_hdc); - throwException(env, "Could not choose pixel formats."); - return (jint)NULL; - } - - HPBUFFERARB Pbuffer; - - if ( pBufferAttribs != NULL ) { - GLuint *pBufferAttribs_ptr = (GLuint *)env->GetDirectBufferAddress(pBufferAttribs); - jlong pBufferAttribsSize = env->GetDirectBufferCapacity(pBufferAttribs); - - int pBufferAttribList[9]; - - jlong i; - for ( i = 0; i < pBufferAttribsSize; ) - pBufferAttribList[i++] = pBufferAttribs_ptr[i]; - - pBufferAttribList[i] = 0; - - Pbuffer = wglCreatePbufferARB(dummy_hdc, iPixelFormat, width, height, pBufferAttribList); - } else { - Pbuffer = wglCreatePbufferARB(dummy_hdc, iPixelFormat, width, height, NULL); - } + iPixelFormat = findPixelFormatARB(env, dummy_hdc, pixel_format, pixelFormatCaps, false, false, true, false); wglDeleteContext(dummy_hglrc); + if (iPixelFormat == -1) { + closeWindow(dummy_hwnd, dummy_hdc); + throwException(env, "Could not find suitable pixel format."); + return NULL; + } + HPBUFFERARB Pbuffer = wglCreatePbufferARB(dummy_hdc, iPixelFormat, width, height, pBufferAttribs_ptr); closeWindow(dummy_hwnd, dummy_hdc); + return Pbuffer; +} + +static HGLRC createPbufferContext(JNIEnv *env, HDC Pbuffer_dc) { + HGLRC Pbuffer_context = wglCreateContext(Pbuffer_dc); + if (Pbuffer_context == NULL) { + throwException(env, "Failed to create Pbuffer rendering context"); + return NULL; + } + if (getCurrentContext() != NULL && !wglShareLists(getCurrentContext(), Pbuffer_context)) { + wglDeleteContext(Pbuffer_context); + throwException(env, "Could not share buffer context."); + return NULL; + } + return Pbuffer_context; +} + +JNIEXPORT jint JNICALL Java_org_lwjgl_opengl_Pbuffer_nCreate + (JNIEnv *env, jclass clazz, jboolean use_display_context, + jint width, jint height, jobject pixel_format, + jobject pixelFormatCaps, jobject pBufferAttribs) +{ + HPBUFFERARB Pbuffer; + const int *pBufferAttribs_ptr; + if ( pBufferAttribs != NULL ) { + pBufferAttribs_ptr = (const int *)env->GetDirectBufferAddress(pBufferAttribs); + } else { + pBufferAttribs_ptr = NULL; + } + if (use_display_context) { + int iPixelFormat = getCurrentPixelFormat(); + Pbuffer = wglCreatePbufferARB(getCurrentWindowDC(), iPixelFormat, width, height, pBufferAttribs_ptr); + } else { + Pbuffer = createPbuffer(env, width, height, pixel_format, pixelFormatCaps, pBufferAttribs_ptr); + } if (Pbuffer == NULL) { throwException(env, "Could not create Pbuffer."); @@ -160,38 +165,26 @@ JNIEXPORT jint JNICALL Java_org_lwjgl_opengl_Pbuffer_nCreate throwException(env, "Could not get Pbuffer dc."); return (jint)NULL; } - - // Create a rendering context - HGLRC Pbuffer_context = wglCreateContext(Pbuffer_dc); - if (Pbuffer_context == NULL) { - wglReleasePbufferDCARB(Pbuffer, Pbuffer_dc); - wglDestroyPbufferARB(Pbuffer); - throwException(env, "Failed to create Pbuffer rendering context"); - return (jint)NULL; - } - - if (display_hglrc != NULL && !wglShareLists(display_hglrc, Pbuffer_context)) { - wglDeleteContext(Pbuffer_context); - wglReleasePbufferDCARB(Pbuffer, Pbuffer_dc); - wglDestroyPbufferARB(Pbuffer); - throwException(env, "Could not share buffer context."); - return (jint)NULL; + HGLRC Pbuffer_context; + if (use_display_context) { + Pbuffer_context = getCurrentContext(); + } else { + Pbuffer_context = createPbufferContext(env, Pbuffer_dc); + if (Pbuffer_context == NULL) { + wglReleasePbufferDCARB(Pbuffer, Pbuffer_dc); + wglDestroyPbufferARB(Pbuffer); + return (jint)NULL; + } } PbufferInfo *Pbuffer_info = (PbufferInfo *)malloc(sizeof(PbufferInfo)); Pbuffer_info->Pbuffer = Pbuffer; Pbuffer_info->Pbuffer_context = Pbuffer_context; Pbuffer_info->Pbuffer_dc = Pbuffer_dc; - + Pbuffer_info->use_display_context = use_display_context == JNI_TRUE; return (jint)Pbuffer_info; } -JNIEXPORT void JNICALL Java_org_lwjgl_opengl_Pbuffer_nReleaseContext - (JNIEnv *env, jclass clazz) -{ - wglMakeCurrent(display_hdc, display_hglrc); -} - JNIEXPORT jboolean JNICALL Java_org_lwjgl_opengl_Pbuffer_nIsBufferLost (JNIEnv *env, jclass clazz, jint handle) { @@ -213,7 +206,8 @@ JNIEXPORT void JNICALL Java_org_lwjgl_opengl_Pbuffer_nDestroy (JNIEnv *env, jclass clazz, jint handle) { PbufferInfo *Pbuffer_info = (PbufferInfo *)handle; - wglDeleteContext(Pbuffer_info->Pbuffer_context); + if (!Pbuffer_info->use_display_context) + wglDeleteContext(Pbuffer_info->Pbuffer_context); wglReleasePbufferDCARB(Pbuffer_info->Pbuffer, Pbuffer_info->Pbuffer_dc); wglDestroyPbufferARB(Pbuffer_info->Pbuffer); free(Pbuffer_info);