diff options
author | Kevin Rushforth <[email protected]> | 2004-10-20 16:41:33 +0000 |
---|---|---|
committer | Kevin Rushforth <[email protected]> | 2004-10-20 16:41:33 +0000 |
commit | a736c7431516159a3db499f7bb13a4a6235af1cb (patch) | |
tree | 075a35f69494a0788a2008c79387aae41385235d /src | |
parent | 14b52db7ab4c4be2bd39ff944cec056c291f999a (diff) |
FIxed 4 problems with off-screen rendering:
1) modified Canvas3D.setOffScreenBuffer to accept "null", allowing users to reclaim pbuffer resources.
2) added cleanup code to destroy dummy window and class in a couple of places where we were getting an error return
3) fixed a bug caused by not properly keeping track of whether a speficic pixel format supports pbuffers.
4) only return HW accelerated pixel formats from getBestConfiguration
The first fix applies to all platforms. The last 3 are Windows only.
git-svn-id: https://svn.java.net/svn/j3d-core~svn/trunk@57 ba19aa83-45c5-6ac9-afd3-db810772062c
Diffstat (limited to 'src')
-rw-r--r-- | src/classes/share/javax/media/j3d/Canvas3D.java | 42 | ||||
-rw-r--r-- | src/classes/share/javax/media/j3d/GraphicsConfigTemplate3D.java | 33 | ||||
-rw-r--r-- | src/native/ogl/Canvas3D.c | 87 | ||||
-rw-r--r-- | src/native/ogl/NativeConfigTemplate3D.c | 29 | ||||
-rw-r--r-- | src/native/ogl/gldefs.h | 9 |
5 files changed, 136 insertions, 64 deletions
diff --git a/src/classes/share/javax/media/j3d/Canvas3D.java b/src/classes/share/javax/media/j3d/Canvas3D.java index 50ee073..5f351ce 100644 --- a/src/classes/share/javax/media/j3d/Canvas3D.java +++ b/src/classes/share/javax/media/j3d/Canvas3D.java @@ -1768,8 +1768,7 @@ public class Canvas3D extends Canvas { * @since Java 3D 1.2 */ public void setOffScreenBuffer(ImageComponent2D buffer) { - ImageComponent2DRetained bufferRetained = - (ImageComponent2DRetained)buffer.retained; + int width, height; if (!offScreen) throw new IllegalStateException(J3dI18N.getString("Canvas3D1")); @@ -1777,21 +1776,32 @@ public class Canvas3D extends Canvas { if (offScreenRendering) throw new RestrictedAccessException(J3dI18N.getString("Canvas3D2")); - if (bufferRetained.byReference && - !(bufferRetained.bImage[0] instanceof BufferedImage)) { + if (buffer != null) { + ImageComponent2DRetained bufferRetained = + (ImageComponent2DRetained)buffer.retained; - throw new IllegalArgumentException(J3dI18N.getString("Canvas3D15")); - } + if (bufferRetained.byReference && + !(bufferRetained.bImage[0] instanceof BufferedImage)) { + + throw new IllegalArgumentException(J3dI18N.getString("Canvas3D15")); + } - if (bufferRetained.format == ImageComponent.FORMAT_CHANNEL8) { - throw new IllegalArgumentException(J3dI18N.getString("Canvas3D16")); + if (bufferRetained.format == ImageComponent.FORMAT_CHANNEL8) { + throw new IllegalArgumentException(J3dI18N.getString("Canvas3D16")); + } + + width = bufferRetained.width; + height = bufferRetained.height; + } + else { + width = height = 0; } // TODO: illegalSharing - if ((offScreenCanvasSize.width != bufferRetained.width) || - (offScreenCanvasSize.height != bufferRetained.height)) { - + if ((offScreenCanvasSize.width != width) || + (offScreenCanvasSize.height != height)) { + if (window != 0) { // Fix for Issue 18. // Will do destroyOffScreenBuffer in the Renderer thread. @@ -1800,15 +1810,16 @@ public class Canvas3D extends Canvas { } // set the canvas dimension according to the buffer dimension - offScreenCanvasSize.setSize(bufferRetained.width, - bufferRetained.height); + offScreenCanvasSize.setSize(width, height); this.setSize(offScreenCanvasSize); - VirtualUniverse.mc.sendCreateOffScreenBuffer(this); + if (width > 0 && height > 0) { + VirtualUniverse.mc.sendCreateOffScreenBuffer(this); + } ctx = 0; } - if (ctx != 0) { + else if (ctx != 0) { removeCtx(false); } @@ -1817,7 +1828,6 @@ public class Canvas3D extends Canvas { synchronized(dirtyMaskLock) { cvDirtyMask |= Canvas3D.MOVED_OR_RESIZED_DIRTY; } - } diff --git a/src/classes/share/javax/media/j3d/GraphicsConfigTemplate3D.java b/src/classes/share/javax/media/j3d/GraphicsConfigTemplate3D.java index 8799c1a..2b423fa 100644 --- a/src/classes/share/javax/media/j3d/GraphicsConfigTemplate3D.java +++ b/src/classes/share/javax/media/j3d/GraphicsConfigTemplate3D.java @@ -160,7 +160,7 @@ public class GraphicsConfigTemplate3D extends GraphicsConfigTemplate { if (value < 0) return; - depthSize = value; + depthSize = value; } /** @@ -369,4 +369,35 @@ public class GraphicsConfigTemplate3D extends GraphicsConfigTemplate { } } } + + + // Return a string representing the value, one of: + // REQUIRED, PREFERRED, or UNNECESSARY + private static final String enumStr(int val) { + switch (val) { + case REQUIRED: + return "REQUIRED"; + case PREFERRED: + return "PREFERRED"; + case UNNECESSARY: + return "UNNECESSARY"; + } + + return "UNDEFINED"; + } + + /** + * Returns a string representation of this object. + * @return a string representation of this object. + */ + public String toString() { + return + "redSize : " + redSize + ", " + + "greenSize : " + greenSize + ", " + + "blueSize : " + blueSize + ", " + + "depthSize : " + depthSize + ", " + + "doubleBuffer : " + enumStr(doubleBuffer) + ", " + + "sceneAntialiasing : " + enumStr(sceneAntialiasing) + ", " + + "stereo : " + enumStr(stereo); + } } diff --git a/src/native/ogl/Canvas3D.c b/src/native/ogl/Canvas3D.c index 4ce2b9f..e440354 100644 --- a/src/native/ogl/Canvas3D.c +++ b/src/native/ogl/Canvas3D.c @@ -2753,10 +2753,11 @@ jint JNICALL Java_javax_media_j3d_Canvas3D_createOffScreenBuffer( JNIEnv table = *env; /* - fprintf(stderr, "****** CreateOffScreenBuffer ******\n"); - fprintf(stderr, "display 0x%x, pFormat %d, width %d, height %d\n", - (int) display, pFormatInfoPtr->offScreenPFormat, width, height); + fprintf(stderr, "****** CreateOffScreenBuffer ******\n"); + fprintf(stderr, "display 0x%x, pFormat %d, width %d, height %d\n", + (int) display, pFormatInfoPtr->offScreenPFormat, width, height); */ + cv_class = (jclass) (*(table->GetObjectClass))(env, obj); offScreenBuffer_field = (jfieldID) (*(table->GetFieldID))(env, cv_class, "offScreenBufferInfo", "J"); @@ -2802,7 +2803,7 @@ jint JNICALL Java_javax_media_j3d_Canvas3D_createOffScreenBuffer( return 0; } - if (pFormatInfoPtr->supportPbuffer) { + if (pFormatInfoPtr->drawToPbuffer) { /* fprintf(stderr, "***** Use PBuffer for offscreen ******\n"); */ @@ -2814,6 +2815,10 @@ jint JNICALL Java_javax_media_j3d_Canvas3D_createOffScreenBuffer( if(hpbuf == NULL) { printErrorMessage("In Canvas3D : wglCreatePbufferARB FAIL."); + ReleaseDC(hwnd, hdc); + wglDeleteContext(hrc); + DestroyWindow(hwnd); + UnregisterClass(szAppName, (HINSTANCE)NULL); return 0; } @@ -2821,9 +2826,19 @@ jint JNICALL Java_javax_media_j3d_Canvas3D_createOffScreenBuffer( if(hpbufdc == NULL) { printErrorMessage("In Canvas3D : Can't get pbuffer's device context."); + ReleaseDC(hwnd, hdc); + wglDeleteContext(hrc); + DestroyWindow(hwnd); + UnregisterClass(szAppName, (HINSTANCE)NULL); return 0; } + /* + fprintf(stderr, + "Successfully created PBuffer = 0x%x, hdc = 0x%x\n", + (int)hpbuf, (int)hpbufdc); + */ + /* Destroy all dummy objects */ ReleaseDC(hwnd, hdc); wglDeleteContext(hrc); @@ -2930,15 +2945,19 @@ void JNICALL Java_javax_media_j3d_Canvas3D_destroyOffScreenBuffer( offScreenBufferInfo = (OffScreenBufferInfo *) (*(table->GetLongField))(env, obj, offScreenBuffer_field); - /* fprintf(stderr,"Canvas3D_destroyOffScreenBuffer : offScreenBufferInfo 0x%x\n", - offScreenBufferInfo); + /* + fprintf(stderr,"Canvas3D_destroyOffScreenBuffer : offScreenBufferInfo 0x%x\n", + offScreenBufferInfo); */ + if(offScreenBufferInfo == NULL) { return; } if(offScreenBufferInfo->isPbuffer) { - /* fprintf(stderr,"Canvas3D_destroyOffScreenBuffer : Pbuffer\n"); */ + /* + fprintf(stderr,"Canvas3D_destroyOffScreenBuffer : Pbuffer\n"); + */ pFormatInfoPtr->wglReleasePbufferDCARB(offScreenBufferInfo->hpbuf, hpbufdc); pFormatInfoPtr->wglDestroyPbufferARB(offScreenBufferInfo->hpbuf); @@ -3149,7 +3168,7 @@ void cleanupCtxInfo(GraphicsContextPropertiesInfo* ctxInfo){ #ifdef WIN32 HWND createDummyWindow(const char* szAppName) { - static char szTitle[]="A Simple C OpenGL Program"; + static const char *szTitle = "Dummy Window"; WNDCLASS wc; /* windows class sruct */ HWND hWnd; @@ -3176,8 +3195,10 @@ HWND createDummyWindow(const char* szAppName) { /* Register the window class */ - if(RegisterClass( &wc )==0) - fprintf(stdout, "Couldn't register class\n"); + if(RegisterClass( &wc )==0) { + printErrorMessage("createDummyWindow: couldn't register class"); + return NULL; + } /* Create a main window for this application instance. */ @@ -3196,7 +3217,8 @@ HWND createDummyWindow(const char* szAppName) { /* If window could not be created, return zero */ if ( !hWnd ){ - fprintf(stdout, "Couldn't Create window\n"); + printErrorMessage("createDummyWindow: couldn't create window"); + UnregisterClass(szAppName, (HINSTANCE)NULL); return NULL; } return hWnd; @@ -3218,7 +3240,7 @@ void JNICALL Java_javax_media_j3d_Canvas3D_createQueryContext( JNIEnv table = *env; jlong gctx; int stencilSize=0; - long newWin; + jint newWin; int PixelFormatID=0; GraphicsContextPropertiesInfo* ctxInfo = (GraphicsContextPropertiesInfo *)malloc(sizeof(GraphicsContextPropertiesInfo)); @@ -3280,7 +3302,7 @@ void JNICALL Java_javax_media_j3d_Canvas3D_createQueryContext( glWin = XCreateWindow((Display *)display, root, 0, 0, width, height, 0, vinfo->depth, InputOutput, vinfo->visual, win_mask, &win_attrs); - newWin = (unsigned long)glWin; + newWin = (jint)glWin; } } else if(window == 0 && offScreen){ @@ -3309,7 +3331,7 @@ void JNICALL Java_javax_media_j3d_Canvas3D_createQueryContext( HDC hdc; /* HW Device Context */ DWORD err; LPTSTR errString; - HWND hWnd; + HWND hDummyWnd = 0; static char szAppName[] = "OpenGL"; jlong vinfo = 0; jboolean result; @@ -3321,13 +3343,25 @@ void JNICALL Java_javax_media_j3d_Canvas3D_createQueryContext( fprintf(stderr, "window is 0x%x, offScreen %d\n", window, offScreen); */ + /* + * vid must be valid PixelFormat returned + * by wglChoosePixelFormat() or wglChoosePixelFormatARB. + */ + if (vid <= 0) { + printErrorMessage("Canvas3D_createQueryContext: PixelFormat is invalid"); + return; + } + + PixelFormatID = (int)vid; + /* onscreen rendering and window is 0 now */ if(window == 0 && !offScreen){ /* fprintf(stderr, "CreateQueryContext : window == 0 && !offScreen\n"); */ - hWnd = createDummyWindow((const char *)szAppName); - if (!hWnd) - return; - hdc = GetDC(hWnd); + hDummyWnd = createDummyWindow(szAppName); + if (!hDummyWnd) { + return; + } + hdc = GetDC(hDummyWnd); } else if(window == 0 && offScreen){ /* fprintf(stderr, "CreateQueryContext : window == 0 && offScreen\n"); */ @@ -3340,19 +3374,8 @@ void JNICALL Java_javax_media_j3d_Canvas3D_createQueryContext( hdc = (HDC) window; } - newWin = (int)hdc; + newWin = (jint)hdc; - /* - * vid must be a PixelFormat returned - * by wglChoosePixelFormat() or wglChoosePixelFormatARB. - */ - if (vid <= 0) { - printErrorMessage("Canvas3D_createQueryContext: PixelFormat is invalid"); - return; - } - else { - PixelFormatID = vid; - } SetPixelFormat(hdc, PixelFormatID, NULL); hrc = wglCreateContext( hdc ); @@ -3401,11 +3424,11 @@ void JNICALL Java_javax_media_j3d_Canvas3D_createQueryContext( #endif /* SOLARIS */ #ifdef WIN32 /* Release DC */ - ReleaseDC(hWnd, hdc); + ReleaseDC(hDummyWnd, hdc); /* Destroy context */ /* This will free ctxInfo also */ Java_javax_media_j3d_Canvas3D_destroyContext(env, obj, display,newWin, (jlong)ctxInfo); - DestroyWindow(hWnd); + DestroyWindow(hDummyWnd); UnregisterClass(szAppName, (HINSTANCE)NULL); #endif /* WIN32 */ } diff --git a/src/native/ogl/NativeConfigTemplate3D.c b/src/native/ogl/NativeConfigTemplate3D.c index 11c3b6e..3c938dd 100644 --- a/src/native/ogl/NativeConfigTemplate3D.c +++ b/src/native/ogl/NativeConfigTemplate3D.c @@ -674,7 +674,7 @@ void printErrorMessage(char *message) } /* Fix for issue 76 */ -#define MAX_WGL_ATTRS_LENGTH 30 +#define MAX_WGL_ATTRS_LENGTH 100 int find_Stencil_PixelFormat(HDC hdc, PixelFormatInfo * pFormatInfo, @@ -1068,7 +1068,8 @@ PixelFormatInfo * newPixelFormatInfo(HDC hdc) /* Initialize pFormatInfo */ pFormatInfo->onScreenPFormat = -1; pFormatInfo->offScreenPFormat = -1; - + pFormatInfo->drawToPbuffer = GL_FALSE; + pFormatInfo->supportARB = GL_FALSE; pFormatInfo->supportPbuffer = GL_FALSE; pFormatInfo->supportedExtensions = NULL; @@ -1144,6 +1145,7 @@ PixelFormatInfo * newPixelFormatInfo(HDC hdc) return pFormatInfo; } + JNIEXPORT jint JNICALL Java_javax_media_j3d_NativeConfigTemplate3D_choosePixelFormat( JNIEnv *env, @@ -1216,7 +1218,7 @@ jint JNICALL Java_javax_media_j3d_NativeConfigTemplate3D_choosePixelFormat( offScreenPFListPtr = (*env)->GetLongArrayElements(env, offScreenPFArray, NULL); - if(pFormatInfo->supportARB) { + if (pFormatInfo->supportARB) { mx_ptr = (*env)->GetIntArrayElements(env, attrList, NULL); @@ -1227,6 +1229,8 @@ jint JNICALL Java_javax_media_j3d_NativeConfigTemplate3D_choosePixelFormat( wglAttrs[index++] = WGL_SUPPORT_OPENGL_ARB; wglAttrs[index++] = TRUE; + wglAttrs[index++] = WGL_ACCELERATION_ARB; + wglAttrs[index++] = WGL_FULL_ACCELERATION_ARB; wglAttrs[index++] = WGL_DRAW_TO_WINDOW_ARB; wglAttrs[index++] = TRUE; wglAttrs[index++] = WGL_RED_BITS_ARB; @@ -1263,9 +1267,10 @@ jint JNICALL Java_javax_media_j3d_NativeConfigTemplate3D_choosePixelFormat( antialiasVal, index); if(pFormatInfo->onScreenPFormat >= 0) { - + /* Since the return pixel format support pbuffer, copy OnScreenPFormat to offScreenPFormat */ + pFormatInfo->drawToPbuffer = GL_TRUE; pFormatInfo->offScreenPFormat = pFormatInfo->onScreenPFormat; offScreenPFListPtr[0] = (jlong) pFormatInfo; (*env)->ReleaseLongArrayElements(env, offScreenPFArray, offScreenPFListPtr, 0); @@ -1278,10 +1283,10 @@ jint JNICALL Java_javax_media_j3d_NativeConfigTemplate3D_choosePixelFormat( return (jint) pFormatInfo->onScreenPFormat; } - } /* Create a onScreen without Pbuffer */ + pFormatInfo->drawToPbuffer = GL_FALSE; index = lastIndex; /* @@ -1294,21 +1299,19 @@ jint JNICALL Java_javax_media_j3d_NativeConfigTemplate3D_choosePixelFormat( pFormatInfo->onScreenPFormat = find_DB_AA_S_PixelFormat( hdc, pFormatInfo, wglAttrs, sVal, dbVal, antialiasVal, index); - } - - - if(pFormatInfo->onScreenPFormat < 0) { /* Fallback to use standard ChoosePixelFormat. */ + else { /* fprintf(stderr, "Fallback to use standard ChoosePixelFormat.\n"); */ - + pFormatInfo->onScreenPFormat = (jint) chooseSTDPixelFormat( env, screen, attrList, hdc, GL_FALSE); - } - + if(pFormatInfo->onScreenPFormat < 0) { + /* printErrorMessage("In NativeConfigTemplate : Can't choose a onScreen pixel format"); - + */ + offScreenPFListPtr[0] = (jlong) pFormatInfo; (*env)->ReleaseLongArrayElements(env, offScreenPFArray, offScreenPFListPtr, 0); diff --git a/src/native/ogl/gldefs.h b/src/native/ogl/gldefs.h index a79762a..36e1a2b 100644 --- a/src/native/ogl/gldefs.h +++ b/src/native/ogl/gldefs.h @@ -628,11 +628,16 @@ typedef struct { typedef struct PixelFormatInfoRec PixelFormatInfo; struct PixelFormatInfoRec { + /* Information about pixel format(s) */ int onScreenPFormat; /* PixelFormat for onScreen */ int offScreenPFormat; /* PixelFormat for offScreen */ - GLboolean supportARB; /* TRUE if ARB is supported */ - GLboolean supportPbuffer; /* TRUE if Pbuffer is supported */ + GLboolean drawToPbuffer; /* value of DRAW_TO_PBUFFER attr for offScreenPFormat */ + + /* Information about extension support */ + GLboolean supportARB; /* TRUE if wgl*PixelFormat*ARB functions supported */ + GLboolean supportPbuffer; /* TRUE if wgl*Pbuffer functions supported */ char* supportedExtensions; /* list of supported ARB extensions */ + /* handle to ARB functions */ PFNWGLCHOOSEPIXELFORMATARBPROC wglChoosePixelFormatARB; PFNWGLGETPIXELFORMATATTRIBIVARBPROC wglGetPixelFormatAttribivARB; |