Win32 part of fast Pbuffer

This commit is contained in:
Elias Naur 2004-07-24 21:19:08 +00:00
parent afe90249cf
commit 79813c8f5a
5 changed files with 104 additions and 94 deletions

View File

@ -130,10 +130,4 @@
* convert bit-per-pixel to bits-per-element * convert bit-per-pixel to bits-per-element
*/ */
extern int convertToBPE(int bpp); extern int convertToBPE(int bpp);
/*
* Return the current OpenGL window context
*/
GLXContext getCurrentContext(void);
#endif /* _LWJGL_WINDOW_H_INCLUDED_ */ #endif /* _LWJGL_WINDOW_H_INCLUDED_ */

View File

@ -108,7 +108,7 @@ static bool createPbufferUsingUniqueContext(JNIEnv *env, PbufferInfo *pbuffer_in
XFree(configs); XFree(configs);
return false; 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) { if (context == NULL) {
XFree(configs); XFree(configs);
throwException(env, "Could not create a GLX context"); throwException(env, "Could not create a GLX context");

View File

@ -53,15 +53,21 @@
#define WINDOW_H_API extern #define WINDOW_H_API extern
extern HWND display_hwnd; // Handle to the window 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 isFullScreen; // Whether we're fullscreen or not
extern bool isMinimized; // Whether we're minimized or not extern bool isMinimized; // Whether we're minimized or not
extern bool isFocused; // Whether we're focused or not extern bool isFocused; // Whether we're focused or not
extern bool isDirty; // Whether we're dirty or not extern bool isDirty; // Whether we're dirty or not
extern RECT clientSize; extern RECT clientSize;
extern HGLRC display_hglrc; // extern HGLRC display_hglrc;
#endif /* _PRIVATE_WINDOW_H_ */ #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 bool applyPixelFormat(JNIEnv *env, HDC hdc, int iPixelFormat);
WINDOW_H_API void closeWindow(HWND hwnd, HDC hdc); 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 * 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 * Create a window with the specified title, position, size, and

View File

@ -50,8 +50,8 @@
static bool oneShotInitialised = false; // Registers the LWJGL window class static bool oneShotInitialised = false; // Registers the LWJGL window class
HWND display_hwnd = NULL; // Handle to the window HWND display_hwnd = NULL; // Handle to the window
HDC display_hdc = NULL; // Device context static HDC display_hdc = NULL; // Device context
HGLRC display_hglrc = NULL; // OpenGL context static HGLRC display_hglrc = NULL; // OpenGL context
static bool isFullScreen = false; // Whether we're fullscreen or not static bool isFullScreen = false; // Whether we're fullscreen or not
static bool isMinimized = false; // Whether we're minimized or not static bool isMinimized = false; // Whether we're minimized or not
static bool isFocused = false; // whether we're focused 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; 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); jclass cls_pixel_format = env->GetObjectClass(pixel_format);
int alpha = (int)env->GetIntField(pixel_format, env->GetFieldID(cls_pixel_format, "alpha", "I")); 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 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); initAttribList(&attrib_list);
if (window) { if (window) {
putAttrib(&attrib_list, WGL_DRAW_TO_WINDOW_ARB); putAttrib(&attrib_list, TRUE); 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_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_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); putAttrib(&attrib_list, WGL_AUX_BUFFERS_ARB); putAttrib(&attrib_list, num_aux_buffers);
if ( pixelFormatCaps != NULL ) { if ( pixelFormatCaps != NULL ) {
if ( !extgl_Extensions.WGL_ARB_render_texture ) { if ( !extgl_Extensions.WGL_ARB_render_texture ) {
throwException(env, "The render-to-texture extension is not supported.");
return -1; 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); BOOL result = wglChoosePixelFormatARB(hdc, attrib_list.attribs, NULL, 1, &iPixelFormat, &num_formats_returned);
if (result == FALSE || num_formats_returned < 1) { if (result == FALSE || num_formats_returned < 1) {
throwException(env, "Could not choose ARB pixel formats.");
return -1; return -1;
} }
return iPixelFormat; 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; int bpp;
jclass cls_pixel_format = env->GetObjectClass(pixel_format); jclass cls_pixel_format = env->GetObjectClass(pixel_format);
if (use_hdc_bpp) { if (use_hdc_bpp) {
bpp = GetDeviceCaps(hdc, BITSPIXEL); 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) if (iPixelFormat == -1)
bpp = 16; bpp = 16;
else else
return iPixelFormat; return iPixelFormat;
} else } else
bpp = (int)env->GetIntField(pixel_format, env->GetFieldID(cls_pixel_format, "bpp", "I")); 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; return;
} }
extgl_InitWGL(env); 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 // 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 // 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. // rendering context and start over, using the ARB extension instead to pick the context.
if (samples > 0 && extgl_Extensions.WGL_ARB_pixel_format) { if (extgl_Extensions.WGL_ARB_pixel_format) {
pixel_format_index = findPixelFormatARB(env, dummy_hdc, pixel_format, NULL, true, true, true); pixel_format_index = findPixelFormatARB(env, dummy_hdc, pixel_format, NULL, true, true, true, true);
wglMakeCurrent(NULL, NULL); if (pixel_format_index == -1) {
wglDeleteContext(display_hglrc); pixel_format_index = findPixelFormatARB(env, dummy_hdc, pixel_format, NULL, true, true, false, true);
}
closeWindow(dummy_hwnd, dummy_hdc); closeWindow(dummy_hwnd, dummy_hdc);
if (pixel_format_index == -1) { 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; return;
} }
wglDeleteContext(display_hglrc);
dummy_hwnd = createWindow(env, 1, 1, false, false); dummy_hwnd = createWindow(env, 1, 1, false, false);
if (dummy_hwnd == NULL) { if (dummy_hwnd == NULL) {
return; 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)"); throwException(env, "Failed to create OpenGL rendering context (ARB)");
return; return;
} }
} else } else {
closeWindow(dummy_hwnd, dummy_hdc); closeWindow(dummy_hwnd, dummy_hdc);
}
} }
JNIEXPORT void JNICALL Java_org_lwjgl_opengl_Display_destroyContext(JNIEnv *env, jclass clazz) { JNIEXPORT void JNICALL Java_org_lwjgl_opengl_Display_destroyContext(JNIEnv *env, jclass clazz) {

View File

@ -49,13 +49,10 @@
#include "common_tools.h" #include "common_tools.h"
typedef struct _PbufferInfo { typedef struct _PbufferInfo {
HGLRC Pbuffer_context; HGLRC Pbuffer_context;
HPBUFFERARB Pbuffer; HPBUFFERARB Pbuffer;
HDC Pbuffer_dc; HDC Pbuffer_dc;
bool use_display_context;
} PbufferInfo; } PbufferInfo;
/* /*
@ -82,72 +79,80 @@ JNIEXPORT jint JNICALL Java_org_lwjgl_opengl_Pbuffer_getPbufferCaps
return caps; return caps;
} }
/* static HPBUFFERARB createPbuffer(JNIEnv *env, int width, int height, jobject pixel_format, jobject pixelFormatCaps, const int *pBufferAttribs_ptr) {
* 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)
{
HWND dummy_hwnd = createWindow(env, 1, 1, false, false); HWND dummy_hwnd = createWindow(env, 1, 1, false, false);
if (dummy_hwnd == NULL) { if (dummy_hwnd == NULL) {
return (jint)NULL; return NULL;
} }
HDC dummy_hdc = GetDC(dummy_hwnd); HDC dummy_hdc = GetDC(dummy_hwnd);
int iPixelFormat = findPixelFormat(env, dummy_hdc, pixel_format); int iPixelFormat = findPixelFormat(env, dummy_hdc, pixel_format);
if (iPixelFormat == -1) { if (iPixelFormat == -1) {
return (jint)NULL; return NULL;
} }
if (!applyPixelFormat(env, dummy_hdc, iPixelFormat)) { if (!applyPixelFormat(env, dummy_hdc, iPixelFormat)) {
closeWindow(dummy_hwnd, dummy_hdc); closeWindow(dummy_hwnd, dummy_hdc);
return (jint)NULL; return NULL;
} }
HGLRC dummy_hglrc = wglCreateContext(dummy_hdc); HGLRC dummy_hglrc = wglCreateContext(dummy_hdc);
if (dummy_hglrc == NULL) { if (dummy_hglrc == NULL) {
closeWindow(dummy_hwnd, dummy_hdc); closeWindow(dummy_hwnd, dummy_hdc);
throwException(env, "Failed to create OpenGL rendering context"); throwException(env, "Failed to create OpenGL rendering context");
return (jint)NULL; return NULL;
} }
BOOL result = wglMakeCurrent(dummy_hdc, dummy_hglrc); BOOL result = wglMakeCurrent(dummy_hdc, dummy_hglrc);
if (!result) { if (!result) {
wglDeleteContext(dummy_hglrc); wglDeleteContext(dummy_hglrc);
closeWindow(dummy_hwnd, dummy_hdc); closeWindow(dummy_hwnd, dummy_hdc);
throwException(env, "Could not bind context to dummy window"); throwException(env, "Could not bind context to dummy window");
return (jint)NULL; return NULL;
} }
extgl_InitWGL(env); extgl_InitWGL(env);
iPixelFormat = findPixelFormatARB(env, dummy_hdc, pixel_format, pixelFormatCaps, false, false, false); iPixelFormat = findPixelFormatARB(env, dummy_hdc, pixel_format, pixelFormatCaps, false, false, true, 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);
}
wglDeleteContext(dummy_hglrc); 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); 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) { if (Pbuffer == NULL) {
throwException(env, "Could not create Pbuffer."); 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."); throwException(env, "Could not get Pbuffer dc.");
return (jint)NULL; return (jint)NULL;
} }
HGLRC Pbuffer_context;
// Create a rendering context if (use_display_context) {
HGLRC Pbuffer_context = wglCreateContext(Pbuffer_dc); Pbuffer_context = getCurrentContext();
if (Pbuffer_context == NULL) { } else {
wglReleasePbufferDCARB(Pbuffer, Pbuffer_dc); Pbuffer_context = createPbufferContext(env, Pbuffer_dc);
wglDestroyPbufferARB(Pbuffer); if (Pbuffer_context == NULL) {
throwException(env, "Failed to create Pbuffer rendering context"); wglReleasePbufferDCARB(Pbuffer, Pbuffer_dc);
return (jint)NULL; wglDestroyPbufferARB(Pbuffer);
} 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;
} }
PbufferInfo *Pbuffer_info = (PbufferInfo *)malloc(sizeof(PbufferInfo)); PbufferInfo *Pbuffer_info = (PbufferInfo *)malloc(sizeof(PbufferInfo));
Pbuffer_info->Pbuffer = Pbuffer; Pbuffer_info->Pbuffer = Pbuffer;
Pbuffer_info->Pbuffer_context = Pbuffer_context; Pbuffer_info->Pbuffer_context = Pbuffer_context;
Pbuffer_info->Pbuffer_dc = Pbuffer_dc; Pbuffer_info->Pbuffer_dc = Pbuffer_dc;
Pbuffer_info->use_display_context = use_display_context == JNI_TRUE;
return (jint)Pbuffer_info; 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 JNIEXPORT jboolean JNICALL Java_org_lwjgl_opengl_Pbuffer_nIsBufferLost
(JNIEnv *env, jclass clazz, jint handle) (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) (JNIEnv *env, jclass clazz, jint handle)
{ {
PbufferInfo *Pbuffer_info = (PbufferInfo *)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); wglReleasePbufferDCARB(Pbuffer_info->Pbuffer, Pbuffer_info->Pbuffer_dc);
wglDestroyPbufferARB(Pbuffer_info->Pbuffer); wglDestroyPbufferARB(Pbuffer_info->Pbuffer);
free(Pbuffer_info); free(Pbuffer_info);