aboutsummaryrefslogtreecommitdiffstats
path: root/src/net/java/games/jogl/impl/windows
diff options
context:
space:
mode:
Diffstat (limited to 'src/net/java/games/jogl/impl/windows')
-rw-r--r--src/net/java/games/jogl/impl/windows/WindowsGLContext.java515
-rw-r--r--src/net/java/games/jogl/impl/windows/WindowsGLContextFactory.java71
-rw-r--r--src/net/java/games/jogl/impl/windows/WindowsGLDrawable.java497
-rw-r--r--src/net/java/games/jogl/impl/windows/WindowsOffscreenGLContext.java103
-rw-r--r--src/net/java/games/jogl/impl/windows/WindowsOffscreenGLDrawable.java133
-rw-r--r--src/net/java/games/jogl/impl/windows/WindowsOnscreenGLContext.java193
-rw-r--r--src/net/java/games/jogl/impl/windows/WindowsOnscreenGLDrawable.java181
-rw-r--r--src/net/java/games/jogl/impl/windows/WindowsPbufferGLContext.java399
-rw-r--r--src/net/java/games/jogl/impl/windows/WindowsPbufferGLDrawable.java393
9 files changed, 1366 insertions, 1119 deletions
diff --git a/src/net/java/games/jogl/impl/windows/WindowsGLContext.java b/src/net/java/games/jogl/impl/windows/WindowsGLContext.java
index 338b11e6a..44f2894eb 100644
--- a/src/net/java/games/jogl/impl/windows/WindowsGLContext.java
+++ b/src/net/java/games/jogl/impl/windows/WindowsGLContext.java
@@ -39,19 +39,14 @@
package net.java.games.jogl.impl.windows;
-import java.awt.Component;
-import java.awt.GraphicsConfiguration;
-import java.awt.GraphicsDevice;
-import java.awt.Rectangle;
import java.util.*;
import net.java.games.gluegen.runtime.*; // for PROCADDRESS_VAR_PREFIX
import net.java.games.jogl.*;
import net.java.games.jogl.impl.*;
public abstract class WindowsGLContext extends GLContextImpl {
- private static JAWT jawt;
+ protected WindowsGLDrawable drawable;
protected long hglrc;
- protected long hdc;
private boolean wglGetExtensionsStringEXTInitialized;
private boolean wglGetExtensionsStringEXTAvailable;
private static final Map/*<String, String>*/ functionNameMap;
@@ -63,9 +58,6 @@ public abstract class WindowsGLContext extends GLContextImpl {
private long hglu32;
private boolean haveWGLARBPbuffer = true;
- private static final int MAX_PFORMATS = 256;
- private static final int MAX_ATTRIBS = 256;
-
static {
functionNameMap = new HashMap();
functionNameMap.put("glAllocateMemoryNV", "wglAllocateMemoryNV");
@@ -76,11 +68,10 @@ public abstract class WindowsGLContext extends GLContextImpl {
extensionNameMap.put("GL_ARB_pixel_format", "WGL_ARB_pixel_format");
}
- public WindowsGLContext(Component component,
- GLCapabilities capabilities,
- GLCapabilitiesChooser chooser,
+ public WindowsGLContext(WindowsGLDrawable drawable,
GLContext shareWith) {
- super(component, capabilities, chooser, shareWith);
+ super(shareWith);
+ this.drawable = drawable;
}
protected GL createGL()
@@ -104,16 +95,6 @@ public abstract class WindowsGLContext extends GLContextImpl {
return glExtensionName;
}
- protected abstract boolean isOffscreen();
-
- public int getOffscreenContextWidth() {
- throw new GLException("Should not call this");
- }
-
- public int getOffscreenContextHeight() {
- throw new GLException("Should not call this");
- }
-
public int getOffscreenContextPixelDataType() {
throw new GLException("Should not call this");
}
@@ -126,7 +107,32 @@ public abstract class WindowsGLContext extends GLContextImpl {
* Creates and initializes an appropriate OpenGL context. Should only be
* called by {@link #makeCurrentImpl()}.
*/
- protected abstract void create();
+ protected void create() {
+ if (drawable.getHDC() == 0) {
+ throw new GLException("Internal error: attempted to create OpenGL context without an associated drawable");
+ }
+ hglrc = WGL.wglCreateContext(drawable.getHDC());
+ if (hglrc == 0) {
+ throw new GLException("Unable to create OpenGL context");
+ }
+ // Windows can set up sharing of display lists after creation time
+ WindowsGLContext other = (WindowsGLContext) GLContextShareSet.getShareContext(this);
+ if (other != null) {
+ long hglrc2 = other.getHGLRC();
+ if (hglrc2 == 0) {
+ throw new GLException("GLContextShareSet returned an invalid OpenGL context");
+ }
+ if (!WGL.wglShareLists(hglrc2, hglrc)) {
+ throw new GLException("wglShareLists(0x" + Long.toHexString(hglrc2) +
+ ", 0x" + Long.toHexString(hglrc) + ") failed: error code " +
+ WGL.GetLastError());
+ }
+ }
+ GLContextShareSet.contextCreated(this);
+ if (DEBUG) {
+ System.err.println(getThreadName() + ": !!! Created OpenGL context " + toHexString(hglrc) + " for " + this + ", device context " + toHexString(drawable.getHDC()));
+ }
+ }
protected int makeCurrentImpl() throws GLException {
boolean created = false;
@@ -149,12 +155,12 @@ public abstract class WindowsGLContext extends GLContextImpl {
}
if (!skipMakeCurrent) {
- if (!WGL.wglMakeCurrent(hdc, hglrc)) {
+ if (!WGL.wglMakeCurrent(drawable.getHDC(), hglrc)) {
throw new GLException("Error making context current: " + WGL.GetLastError());
} else {
if (DEBUG && VERBOSE) {
- System.err.println(getThreadName() + ": wglMakeCurrent(hdc " + hdcToString(hdc) +
- ", hglrc " + hdcToString(hglrc) + ") succeeded");
+ System.err.println(getThreadName() + ": wglMakeCurrent(hdc " + toHexString(drawable.getHDC()) +
+ ", hglrc " + toHexString(hglrc) + ") succeeded");
}
}
}
@@ -163,20 +169,6 @@ public abstract class WindowsGLContext extends GLContextImpl {
resetGLFunctionAvailability();
haveWGLARBPbuffer = (isExtensionAvailable("WGL_ARB_pbuffer") &&
isExtensionAvailable("WGL_ARB_pixel_format"));
- // Windows can set up sharing of display lists after creation time
- WindowsGLContext other = (WindowsGLContext) GLContextShareSet.getShareContext(this);
- if (other != null) {
- long hglrc2 = other.getHGLRC();
- if (hglrc2 == 0) {
- throw new GLException("GLContextShareSet returned an invalid OpenGL context");
- }
- if (!WGL.wglShareLists(hglrc2, hglrc)) {
- throw new GLException("wglShareLists(0x" + Long.toHexString(hglrc2) +
- ", 0x" + Long.toHexString(hglrc) + ") failed: error code " +
- WGL.GetLastError());
- }
- }
- GLContextShareSet.contextCreated(this);
return CONTEXT_CURRENT_NEW;
}
return CONTEXT_CURRENT;
@@ -195,15 +187,14 @@ public abstract class WindowsGLContext extends GLContextImpl {
if (!WGL.wglDeleteContext(hglrc)) {
throw new GLException("Unable to delete OpenGL context");
}
+ hglrc = 0;
+ GLContextShareSet.contextDestroyed(this);
if (DEBUG) {
- System.err.println(getThreadName() + ": !!! Destroyed OpenGL context " + hglrc);
+ System.err.println(getThreadName() + ": !!! Destroyed OpenGL context " + toHexString(hglrc));
}
- hglrc = 0;
}
}
- public abstract void swapBuffers() throws GLException;
-
protected long dynamicLookupFunction(String glFuncName) {
long res = WGL.wglGetProcAddress(glFuncName);
if (res == 0) {
@@ -272,444 +263,10 @@ public abstract class WindowsGLContext extends GLContextImpl {
// Internals only below this point
//
- protected JAWT getJAWT() {
- if (jawt == null) {
- JAWT j = new JAWT();
- j.version(JAWTFactory.JAWT_VERSION_1_4);
- if (!JAWTFactory.JAWT_GetAWT(j)) {
- throw new RuntimeException("Unable to initialize JAWT");
- }
- jawt = j;
- }
- return jawt;
- }
-
- // Helper routine for the overridden create() to call
- protected void choosePixelFormatAndCreateContext(boolean onscreen) {
- PIXELFORMATDESCRIPTOR pfd = null;
- int pixelFormat = 0;
- if (onscreen) {
- GLCapabilities[] availableCaps = null;
- int numFormats = 0;
- pfd = newPixelFormatDescriptor();
- GraphicsConfiguration config = component.getGraphicsConfiguration();
- GraphicsDevice device = config.getDevice();
- // Produce a recommended pixel format selection for the GLCapabilitiesChooser.
- // Use wglChoosePixelFormatARB if user requested multisampling and if we have it available
- GL dummyGL = null;
- if (capabilities.getSampleBuffers()) {
- dummyGL = WindowsGLContextFactory.getDummyGL(device);
- }
- int recommendedPixelFormat = -1;
- boolean haveWGLChoosePixelFormatARB = false;
- boolean haveWGLARBMultisample = false;
- if (dummyGL != null) {
- String availableWGLExtensions = WindowsGLContextFactory.getDummyGLExtensions(device);
- if (availableWGLExtensions.indexOf("WGL_ARB_pixel_format") >= 0) {
- haveWGLChoosePixelFormatARB = true;
- if (availableWGLExtensions.indexOf("WGL_ARB_multisample") >= 0) {
- haveWGLARBMultisample = true;
- }
- }
- }
- Rectangle rect = config.getBounds();
- long dc = 0;
- long rc = 0;
- boolean freeWGLC = false;
- if( dummyGL != null ) {
- dc = WindowsGLContextFactory.getDummyGLContext( device ).hdc;
- rc = WindowsGLContextFactory.getDummyGLContext( device ).hglrc;
- if( !WGL.wglMakeCurrent( dc, rc ) ) {
- System.err.println(getThreadName() + ": Error Making WGLC Current: " + WGL.GetLastError() );
- } else {
- freeWGLC = true;
- }
- }
- // Fallback path for older cards, in particular Intel Extreme motherboard graphics
- boolean gotAvailableCaps = false;
- if (dummyGL != null && haveWGLChoosePixelFormatARB) {
- int[] iattributes = new int [2 * MAX_ATTRIBS];
- int[] iresults = new int [2 * MAX_ATTRIBS];
- float[] fattributes = new float[2 * MAX_ATTRIBS];
- int niattribs = 0;
- int nfattribs = 0;
- iattributes[niattribs++] = GL.WGL_SUPPORT_OPENGL_ARB;
- iattributes[niattribs++] = GL.GL_TRUE;
- iattributes[niattribs++] = GL.WGL_DRAW_TO_WINDOW_ARB;
- iattributes[niattribs++] = GL.GL_TRUE;
- iattributes[niattribs++] = GL.WGL_PIXEL_TYPE_ARB;
- iattributes[niattribs++] = GL.WGL_TYPE_RGBA_ARB;
- iattributes[niattribs++] = GL.WGL_DOUBLE_BUFFER_ARB;
- if (capabilities.getDoubleBuffered()) {
- iattributes[niattribs++] = GL.GL_TRUE;
- } else {
- iattributes[niattribs++] = GL.GL_FALSE;
- }
- iattributes[niattribs++] = GL.WGL_STEREO_ARB;
- if (capabilities.getStereo()) {
- iattributes[niattribs++] = GL.GL_TRUE;
- } else {
- iattributes[niattribs++] = GL.GL_FALSE;
- }
- iattributes[niattribs++] = GL.WGL_DEPTH_BITS_ARB;
- iattributes[niattribs++] = capabilities.getDepthBits();
- iattributes[niattribs++] = GL.WGL_RED_BITS_ARB;
- iattributes[niattribs++] = capabilities.getRedBits();
- iattributes[niattribs++] = GL.WGL_GREEN_BITS_ARB;
- iattributes[niattribs++] = capabilities.getGreenBits();
- iattributes[niattribs++] = GL.WGL_BLUE_BITS_ARB;
- iattributes[niattribs++] = capabilities.getBlueBits();
- iattributes[niattribs++] = GL.WGL_ALPHA_BITS_ARB;
- iattributes[niattribs++] = capabilities.getAlphaBits();
- iattributes[niattribs++] = GL.WGL_STENCIL_BITS_ARB;
- iattributes[niattribs++] = capabilities.getStencilBits();
- if (capabilities.getAccumRedBits() > 0 ||
- capabilities.getAccumGreenBits() > 0 ||
- capabilities.getAccumBlueBits() > 0 ||
- capabilities.getAccumAlphaBits() > 0) {
- iattributes[niattribs++] = GL.WGL_ACCUM_BITS_ARB;
- iattributes[niattribs++] = (capabilities.getAccumRedBits() +
- capabilities.getAccumGreenBits() +
- capabilities.getAccumBlueBits() +
- capabilities.getAccumAlphaBits());
- iattributes[niattribs++] = GL.WGL_ACCUM_RED_BITS_ARB;
- iattributes[niattribs++] = capabilities.getAccumRedBits();
- iattributes[niattribs++] = GL.WGL_ACCUM_GREEN_BITS_ARB;
- iattributes[niattribs++] = capabilities.getAccumGreenBits();
- iattributes[niattribs++] = GL.WGL_ACCUM_BLUE_BITS_ARB;
- iattributes[niattribs++] = capabilities.getAccumBlueBits();
- iattributes[niattribs++] = GL.WGL_ACCUM_ALPHA_BITS_ARB;
- iattributes[niattribs++] = capabilities.getAccumAlphaBits();
- }
- if (haveWGLARBMultisample) {
- if (capabilities.getSampleBuffers()) {
- iattributes[niattribs++] = GL.WGL_SAMPLE_BUFFERS_ARB;
- iattributes[niattribs++] = GL.GL_TRUE;
- iattributes[niattribs++] = GL.WGL_SAMPLES_ARB;
- iattributes[niattribs++] = capabilities.getNumSamples();
- }
- }
-
- int[] pformats = new int[MAX_PFORMATS];
- int[] numFormatsTmp = new int[1];
- if (dummyGL.wglChoosePixelFormatARB(hdc,
- iattributes, 0,
- fattributes, 0,
- MAX_PFORMATS,
- pformats, 0,
- numFormatsTmp, 0)) {
- numFormats = numFormatsTmp[0];
- if (numFormats > 0) {
- // Remove one-basing of pixel format (added on later)
- recommendedPixelFormat = pformats[0] - 1;
- if (DEBUG) {
- System.err.println(getThreadName() + ": Used wglChoosePixelFormatARB to recommend pixel format " + recommendedPixelFormat);
- }
- }
- } else {
- if (DEBUG) {
- System.err.println(getThreadName() + ": wglChoosePixelFormatARB failed: " + WGL.GetLastError() );
- Thread.dumpStack();
- }
- }
- if (DEBUG) {
- if (recommendedPixelFormat < 0) {
- System.err.print(getThreadName() + ": wglChoosePixelFormatARB didn't recommend a pixel format");
- if (capabilities.getSampleBuffers()) {
- System.err.print(" for multisampled GLCapabilities");
- }
- System.err.println();
- }
- }
-
- // Produce a list of GLCapabilities to give to the
- // GLCapabilitiesChooser.
- // Use wglGetPixelFormatAttribivARB instead of
- // DescribePixelFormat to get higher-precision information
- // about the pixel format (should make the GLCapabilities
- // more precise as well...i.e., remove the
- // "HardwareAccelerated" bit, which is basically
- // meaningless, and put in whether it can render to a
- // window, to a pbuffer, or to a pixmap)
- niattribs = 0;
- iattributes[0] = GL.WGL_NUMBER_PIXEL_FORMATS_ARB;
- if (dummyGL.wglGetPixelFormatAttribivARB(hdc, 0, 0, 1, iattributes, 0, iresults, 0)) {
- numFormats = iresults[0];
- // Should we be filtering out the pixel formats which aren't
- // applicable, as we are doing here?
- // We don't have enough information in the GLCapabilities to
- // represent those that aren't...
- iattributes[niattribs++] = GL.WGL_DRAW_TO_WINDOW_ARB;
- iattributes[niattribs++] = GL.WGL_ACCELERATION_ARB;
- iattributes[niattribs++] = GL.WGL_SUPPORT_OPENGL_ARB;
- iattributes[niattribs++] = GL.WGL_DEPTH_BITS_ARB;
- iattributes[niattribs++] = GL.WGL_STENCIL_BITS_ARB;
- iattributes[niattribs++] = GL.WGL_DOUBLE_BUFFER_ARB;
- iattributes[niattribs++] = GL.WGL_STEREO_ARB;
- iattributes[niattribs++] = GL.WGL_PIXEL_TYPE_ARB;
- iattributes[niattribs++] = GL.WGL_RED_BITS_ARB;
- iattributes[niattribs++] = GL.WGL_GREEN_BITS_ARB;
- iattributes[niattribs++] = GL.WGL_BLUE_BITS_ARB;
- iattributes[niattribs++] = GL.WGL_ALPHA_BITS_ARB;
- iattributes[niattribs++] = GL.WGL_ACCUM_RED_BITS_ARB;
- iattributes[niattribs++] = GL.WGL_ACCUM_GREEN_BITS_ARB;
- iattributes[niattribs++] = GL.WGL_ACCUM_BLUE_BITS_ARB;
- iattributes[niattribs++] = GL.WGL_ACCUM_ALPHA_BITS_ARB;
- if (haveWGLARBMultisample) {
- iattributes[niattribs++] = GL.WGL_SAMPLE_BUFFERS_ARB;
- iattributes[niattribs++] = GL.WGL_SAMPLES_ARB;
- }
-
- availableCaps = new GLCapabilities[numFormats];
- for (int i = 0; i < numFormats; i++) {
- if (!dummyGL.wglGetPixelFormatAttribivARB(hdc, i+1, 0, niattribs, iattributes, 0, iresults, 0)) {
- throw new GLException("Error getting pixel format attributes for pixel format " + (i + 1) + " of device context");
- }
- availableCaps[i] = iattributes2GLCapabilities(iattributes, iresults, niattribs, true);
- }
- if( freeWGLC ) {
- WGL.wglMakeCurrent( 0, 0 );
- }
- gotAvailableCaps = true;
- } else {
- int lastErr = WGL.GetLastError();
- // Intel Extreme graphics fails with a zero error code
- if (lastErr != 0) {
- throw new GLException("Unable to enumerate pixel formats of window using wglGetPixelFormatAttribivARB: error code " + WGL.GetLastError());
- }
- }
- }
-
- if (!gotAvailableCaps) {
- if (DEBUG) {
- if (!capabilities.getSampleBuffers()) {
- System.err.println(getThreadName() + ": Using ChoosePixelFormat because multisampling not requested");
- } else {
- System.err.println(getThreadName() + ": Using ChoosePixelFormat because no wglChoosePixelFormatARB: dummyGL = " + dummyGL);
- }
- }
- pfd = glCapabilities2PFD(capabilities, onscreen);
- // Remove one-basing of pixel format (added on later)
- recommendedPixelFormat = WGL.ChoosePixelFormat(hdc, pfd) - 1;
-
- numFormats = WGL.DescribePixelFormat(hdc, 1, 0, null);
- if (numFormats == 0) {
- throw new GLException("Unable to enumerate pixel formats of window for GLCapabilitiesChooser");
- }
- availableCaps = new GLCapabilities[numFormats];
- for (int i = 0; i < numFormats; i++) {
- if (WGL.DescribePixelFormat(hdc, 1 + i, pfd.size(), pfd) == 0) {
- throw new GLException("Error describing pixel format " + (1 + i) + " of device context");
- }
- availableCaps[i] = pfd2GLCapabilities(pfd);
- }
- }
-
- // Supply information to chooser
- pixelFormat = chooser.chooseCapabilities(capabilities, availableCaps, recommendedPixelFormat);
- if ((pixelFormat < 0) || (pixelFormat >= numFormats)) {
- throw new GLException("Invalid result " + pixelFormat +
- " from GLCapabilitiesChooser (should be between 0 and " +
- (numFormats - 1) + ")");
- }
- if (DEBUG) {
- System.err.println(getThreadName() + ": Chosen pixel format (" + pixelFormat + "):");
- System.err.println(availableCaps[pixelFormat]);
- }
- pixelFormat += 1; // one-base the index
- if (WGL.DescribePixelFormat(hdc, pixelFormat, pfd.size(), pfd) == 0) {
- throw new GLException("Error re-describing the chosen pixel format: " + WGL.GetLastError());
- }
- } else {
- // For now, use ChoosePixelFormat for offscreen surfaces until
- // we figure out how to properly choose an offscreen-
- // compatible pixel format
- pfd = glCapabilities2PFD(capabilities, onscreen);
- pixelFormat = WGL.ChoosePixelFormat(hdc, pfd);
- }
- if (!WGL.SetPixelFormat(hdc, pixelFormat, pfd)) {
- int lastError = WGL.GetLastError();
- if (DEBUG) {
- System.err.println(getThreadName() + ": SetPixelFormat failed: current context = " + WGL.wglGetCurrentContext() +
- ", current DC = " + WGL.wglGetCurrentDC());
- System.err.println(getThreadName() + ": GetPixelFormat(hdc " + hdcToString(hdc) + ") returns " + WGL.GetPixelFormat(hdc));
- }
- throw new GLException("Unable to set pixel format " + pixelFormat + " for device context " + hdcToString(hdc) + ": error code " + lastError);
- }
- hglrc = WGL.wglCreateContext(hdc);
- if (DEBUG) {
- System.err.println(getThreadName() + ": !!! Created OpenGL context " + hglrc + " for device context " + hdcToString(hdc) + " using pixel format " + pixelFormat);
- }
- if (hglrc == 0) {
- throw new GLException("Unable to create OpenGL context");
- }
- }
-
protected long getHGLRC() {
return hglrc;
}
- static PIXELFORMATDESCRIPTOR glCapabilities2PFD(GLCapabilities caps, boolean onscreen) {
- int colorDepth = (caps.getRedBits() +
- caps.getGreenBits() +
- caps.getBlueBits());
- if (colorDepth < 15) {
- throw new GLException("Bit depths < 15 (i.e., non-true-color) not supported");
- }
- PIXELFORMATDESCRIPTOR pfd = newPixelFormatDescriptor();
- int pfdFlags = (WGL.PFD_SUPPORT_OPENGL |
- WGL.PFD_GENERIC_ACCELERATED);
- if (caps.getDoubleBuffered()) {
- pfdFlags |= WGL.PFD_DOUBLEBUFFER;
- }
- if (onscreen) {
- pfdFlags |= WGL.PFD_DRAW_TO_WINDOW;
- } else {
- pfdFlags |= WGL.PFD_DRAW_TO_BITMAP;
- }
- pfd.dwFlags(pfdFlags);
- pfd.iPixelType((byte) WGL.PFD_TYPE_RGBA);
- pfd.cColorBits((byte) colorDepth);
- pfd.cRedBits ((byte) caps.getRedBits());
- pfd.cGreenBits((byte) caps.getGreenBits());
- pfd.cBlueBits ((byte) caps.getBlueBits());
- pfd.cAlphaBits((byte) caps.getAlphaBits());
- int accumDepth = (caps.getAccumRedBits() +
- caps.getAccumGreenBits() +
- caps.getAccumBlueBits());
- pfd.cAccumBits ((byte) accumDepth);
- pfd.cAccumRedBits ((byte) caps.getAccumRedBits());
- pfd.cAccumGreenBits((byte) caps.getAccumGreenBits());
- pfd.cAccumBlueBits ((byte) caps.getAccumBlueBits());
- pfd.cAccumAlphaBits((byte) caps.getAccumAlphaBits());
- pfd.cDepthBits((byte) caps.getDepthBits());
- pfd.cStencilBits((byte) caps.getStencilBits());
- pfd.iLayerType((byte) WGL.PFD_MAIN_PLANE);
- return pfd;
- }
-
- static PIXELFORMATDESCRIPTOR newPixelFormatDescriptor() {
- PIXELFORMATDESCRIPTOR pfd = new PIXELFORMATDESCRIPTOR();
- pfd.nSize((short) pfd.size());
- pfd.nVersion((short) 1);
- return pfd;
- }
-
- static GLCapabilities pfd2GLCapabilities(PIXELFORMATDESCRIPTOR pfd) {
- if ((pfd.dwFlags() & WGL.PFD_SUPPORT_OPENGL) == 0) {
- return null;
- }
- GLCapabilities res = new GLCapabilities();
- res.setRedBits (pfd.cRedBits());
- res.setGreenBits (pfd.cGreenBits());
- res.setBlueBits (pfd.cBlueBits());
- res.setAlphaBits (pfd.cAlphaBits());
- res.setAccumRedBits (pfd.cAccumRedBits());
- res.setAccumGreenBits(pfd.cAccumGreenBits());
- res.setAccumBlueBits (pfd.cAccumBlueBits());
- res.setAccumAlphaBits(pfd.cAccumAlphaBits());
- res.setDepthBits (pfd.cDepthBits());
- res.setStencilBits (pfd.cStencilBits());
- res.setDoubleBuffered((pfd.dwFlags() & WGL.PFD_DOUBLEBUFFER) != 0);
- res.setStereo ((pfd.dwFlags() & WGL.PFD_STEREO) != 0);
- res.setHardwareAccelerated(((pfd.dwFlags() & WGL.PFD_GENERIC_FORMAT) == 0) ||
- ((pfd.dwFlags() & WGL.PFD_GENERIC_ACCELERATED) != 0));
- return res;
- }
-
- static GLCapabilities iattributes2GLCapabilities(int[] iattribs,
- int[] iresults,
- int niattribs,
- boolean requireRenderToWindow) {
- GLCapabilities res = new GLCapabilities();
- for (int i = 0; i < niattribs; i++) {
- switch (iattribs[i]) {
- case GL.WGL_DRAW_TO_WINDOW_ARB:
- if (iresults[i] != GL.GL_TRUE)
- return null;
- break;
-
- case GL.WGL_ACCELERATION_ARB:
- res.setHardwareAccelerated(iresults[i] == GL.WGL_FULL_ACCELERATION_ARB);
- break;
-
- case GL.WGL_SUPPORT_OPENGL_ARB:
- if (iresults[i] != GL.GL_TRUE)
- return null;
- break;
-
- case GL.WGL_DEPTH_BITS_ARB:
- res.setDepthBits(iresults[i]);
- break;
-
- case GL.WGL_STENCIL_BITS_ARB:
- res.setStencilBits(iresults[i]);
- break;
-
- case GL.WGL_DOUBLE_BUFFER_ARB:
- res.setDoubleBuffered(iresults[i] == GL.GL_TRUE);
- break;
-
- case GL.WGL_STEREO_ARB:
- res.setStereo(iresults[i] == GL.GL_TRUE);
- break;
-
- case GL.WGL_PIXEL_TYPE_ARB:
- if (iresults[i] != GL.WGL_TYPE_RGBA_ARB)
- return null;
- break;
-
- case GL.WGL_RED_BITS_ARB:
- res.setRedBits(iresults[i]);
- break;
-
- case GL.WGL_GREEN_BITS_ARB:
- res.setGreenBits(iresults[i]);
- break;
-
- case GL.WGL_BLUE_BITS_ARB:
- res.setBlueBits(iresults[i]);
- break;
-
- case GL.WGL_ALPHA_BITS_ARB:
- res.setAlphaBits(iresults[i]);
- break;
-
- case GL.WGL_ACCUM_RED_BITS_ARB:
- res.setAccumRedBits(iresults[i]);
- break;
-
- case GL.WGL_ACCUM_GREEN_BITS_ARB:
- res.setAccumGreenBits(iresults[i]);
- break;
-
- case GL.WGL_ACCUM_BLUE_BITS_ARB:
- res.setAccumBlueBits(iresults[i]);
- break;
-
- case GL.WGL_ACCUM_ALPHA_BITS_ARB:
- res.setAccumAlphaBits(iresults[i]);
- break;
-
- case GL.WGL_SAMPLE_BUFFERS_ARB:
- res.setSampleBuffers(iresults[i] == GL.GL_TRUE);
- break;
-
- case GL.WGL_SAMPLES_ARB:
- res.setNumSamples(iresults[i]);
- break;
-
- default:
- throw new GLException("Unknown pixel format attribute " + iattribs[i]);
- }
- }
- return res;
- }
-
- protected static String hdcToString(long hdc) {
- return "0x" + Long.toHexString(hdc);
- }
-
protected boolean haveWGLARBPbuffer() {
return haveWGLARBPbuffer;
}
diff --git a/src/net/java/games/jogl/impl/windows/WindowsGLContextFactory.java b/src/net/java/games/jogl/impl/windows/WindowsGLContextFactory.java
index dd6f8daca..d99554fcf 100644
--- a/src/net/java/games/jogl/impl/windows/WindowsGLContextFactory.java
+++ b/src/net/java/games/jogl/impl/windows/WindowsGLContextFactory.java
@@ -59,6 +59,10 @@ public class WindowsGLContextFactory extends GLContextFactory {
private static final boolean DEBUG = Debug.debug("WindowsGLContextFactory");
private static final boolean VERBOSE = Debug.verbose();
+ static {
+ NativeLibLoader.load();
+ }
+
// On Windows we want to be able to use some extension routines like
// wglChoosePixelFormatARB during the creation of the user's first
// GLContext. However, this and other routines' function pointers
@@ -139,17 +143,31 @@ public class WindowsGLContextFactory extends GLContextFactory {
return null;
}
- public GLContext createGLContext(Component component,
- GLCapabilities capabilities,
- GLCapabilitiesChooser chooser,
- GLContext shareWith) {
- if (component != null) {
- return new WindowsOnscreenGLContext(component, capabilities, chooser, shareWith);
- } else {
- return new WindowsOffscreenGLContext(capabilities, chooser, shareWith);
+ public GLDrawable getGLDrawable(Object target,
+ GLCapabilities capabilities,
+ GLCapabilitiesChooser chooser) {
+ if (target == null) {
+ throw new IllegalArgumentException("Null target");
+ }
+ if (!(target instanceof Component)) {
+ throw new IllegalArgumentException("GLDrawables not supported for objects of type " +
+ target.getClass().getName() + " (only Components are supported in this implementation)");
}
+ return new WindowsOnscreenGLDrawable((Component) target, capabilities, chooser);
}
-
+
+ public GLDrawableImpl createOffscreenDrawable(GLCapabilities capabilities,
+ GLCapabilitiesChooser chooser) {
+ return new WindowsOffscreenGLDrawable(capabilities, chooser);
+ }
+
+ // Return cached GL drawable
+ public static WindowsGLDrawable getDummyGLDrawable( final GraphicsDevice device ) {
+ checkForDummyContext( device );
+ NativeWindowStruct nws = (NativeWindowStruct) dummyContextMap.get(device);
+ return nws.getWindowsDrawable();
+ }
+
// Return cached GL context
public static WindowsGLContext getDummyGLContext( final GraphicsDevice device ) {
checkForDummyContext( device );
@@ -188,7 +206,9 @@ public class WindowsGLContextFactory extends GLContextFactory {
GLCapabilities caps = new GLCapabilities();
caps.setDepthBits( 16 );
// Create a context that we use to query pixel formats
- WindowsOnscreenGLContext context = new WindowsOnscreenGLContext( null, caps, null, null );
+
+ WindowsOnscreenGLDrawable drawable = new WindowsOnscreenGLDrawable(null, caps, null);
+ WindowsOnscreenGLContext context = new WindowsOnscreenGLContext( drawable, null );
// Start a native thread and grab native screen resources from the thread
NativeWindowThread nwt = new NativeWindowThread( rect );
nwt.start();
@@ -198,7 +218,7 @@ public class WindowsGLContextFactory extends GLContextFactory {
Thread.yield();
}
// Choose a hardware accelerated pixel format
- PIXELFORMATDESCRIPTOR pfd = context.glCapabilities2PFD( caps, true );
+ PIXELFORMATDESCRIPTOR pfd = drawable.glCapabilities2PFD( caps, true );
int pixelFormat = WGL.ChoosePixelFormat( tempHDC, pfd );
if( pixelFormat == 0 ) {
System.err.println("Pixel Format is Zero");
@@ -220,6 +240,7 @@ public class WindowsGLContextFactory extends GLContextFactory {
// Store native handles for later use
NativeWindowStruct nws = new NativeWindowStruct();
nws.setHWND( hWnd );
+ nws.setWindowsDrawable( drawable );
nws.setWindowsContext( context );
nws.setWindowThread( nwt );
long currentHDC = WGL.wglGetCurrentDC();
@@ -230,7 +251,7 @@ public class WindowsGLContextFactory extends GLContextFactory {
return;
}
// Grab function pointers
- context.hdc = tempHDC;
+ drawable.hdc = tempHDC;
context.hglrc = tempHGLRC;
context.resetGLFunctionAvailability();
context.createGL();
@@ -259,6 +280,7 @@ public class WindowsGLContextFactory extends GLContextFactory {
*/
static class NativeWindowStruct {
private long HWND;
+ private WindowsGLDrawable windowsDrawable;
private WindowsGLContext windowsContext;
private Thread windowThread;
@@ -266,7 +288,7 @@ public class WindowsGLContextFactory extends GLContextFactory {
}
public long getHDC() {
- return( windowsContext.hdc );
+ return( windowsDrawable.hdc );
}
public long getHGLRC() {
@@ -281,10 +303,18 @@ public class WindowsGLContextFactory extends GLContextFactory {
return( HWND );
}
+ public void setWindowsDrawable( WindowsGLDrawable drawable ) {
+ windowsDrawable = drawable;
+ }
+
public void setWindowsContext( WindowsGLContext context ) {
windowsContext = context;
}
+ public WindowsGLDrawable getWindowsDrawable() {
+ return( windowsDrawable );
+ }
+
public WindowsGLContext getWindowsContext() {
return( windowsContext );
}
@@ -358,4 +388,19 @@ public class WindowsGLContextFactory extends GLContextFactory {
}
}
}
+
+
+ static String wglGetLastError() {
+ int err = WGL.GetLastError();
+ String detail = null;
+ switch (err) {
+ case WGL.ERROR_INVALID_PIXEL_FORMAT: detail = "ERROR_INVALID_PIXEL_FORMAT"; break;
+ case WGL.ERROR_NO_SYSTEM_RESOURCES: detail = "ERROR_NO_SYSTEM_RESOURCES"; break;
+ case WGL.ERROR_INVALID_DATA: detail = "ERROR_INVALID_DATA"; break;
+ case WGL.ERROR_PROC_NOT_FOUND: detail = "ERROR_PROC_NOT_FOUND"; break;
+ case WGL.ERROR_INVALID_WINDOW_HANDLE:detail = "ERROR_INVALID_WINDOW_HANDLE"; break;
+ default: detail = "(Unknown error code " + err + ")"; break;
+ }
+ return detail;
+ }
}
diff --git a/src/net/java/games/jogl/impl/windows/WindowsGLDrawable.java b/src/net/java/games/jogl/impl/windows/WindowsGLDrawable.java
new file mode 100644
index 000000000..42e83c05d
--- /dev/null
+++ b/src/net/java/games/jogl/impl/windows/WindowsGLDrawable.java
@@ -0,0 +1,497 @@
+/*
+ * Copyright (c) 2003 Sun Microsystems, Inc. All Rights Reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * - Redistribution of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * - Redistribution 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 Sun Microsystems, Inc. or the names of
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * This software is provided "AS IS," without a warranty of any kind. ALL
+ * EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND WARRANTIES,
+ * INCLUDING ANY IMPLIED WARRANTY OF MERCHANTABILITY, FITNESS FOR A
+ * PARTICULAR PURPOSE OR NON-INFRINGEMENT, ARE HEREBY EXCLUDED. SUN
+ * MICROSYSTEMS, INC. ("SUN") AND ITS LICENSORS SHALL NOT BE LIABLE FOR
+ * ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF USING, MODIFYING OR
+ * DISTRIBUTING THIS SOFTWARE OR ITS DERIVATIVES. IN NO EVENT WILL SUN OR
+ * ITS LICENSORS BE LIABLE FOR ANY LOST REVENUE, PROFIT OR DATA, OR FOR
+ * DIRECT, INDIRECT, SPECIAL, CONSEQUENTIAL, INCIDENTAL OR PUNITIVE
+ * DAMAGES, HOWEVER CAUSED AND REGARDLESS OF THE THEORY OF LIABILITY,
+ * ARISING OUT OF THE USE OF OR INABILITY TO USE THIS SOFTWARE, EVEN IF
+ * SUN HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.
+ *
+ * You acknowledge that this software is not designed or intended for use
+ * in the design, construction, operation or maintenance of any nuclear
+ * facility.
+ *
+ * Sun gratefully acknowledges that this software was originally authored
+ * and developed by Kenneth Bradley Russell and Christopher John Kline.
+ */
+
+package net.java.games.jogl.impl.windows;
+
+import java.awt.Component;
+import java.awt.GraphicsConfiguration;
+import java.awt.GraphicsDevice;
+
+import net.java.games.jogl.*;
+import net.java.games.jogl.impl.*;
+
+public abstract class WindowsGLDrawable extends GLDrawableImpl {
+ protected static final boolean DEBUG = Debug.debug("WindowsGLDrawable");
+
+ protected long hdc;
+ protected Component component;
+ protected GLCapabilities capabilities;
+ protected GLCapabilitiesChooser chooser;
+ protected boolean pixelFormatChosen;
+
+ protected static final int MAX_PFORMATS = 256;
+ protected static final int MAX_ATTRIBS = 256;
+
+ public WindowsGLDrawable(Component component,
+ GLCapabilities capabilities,
+ GLCapabilitiesChooser chooser) {
+ this.component = component;
+ this.capabilities = (GLCapabilities) capabilities.clone();
+ this.chooser = chooser;
+ }
+
+ public void setRealized(boolean val) {
+ throw new GLException("Should not call this (should only be called for onscreen GLDrawables)");
+ }
+
+ public void destroy() {
+ throw new GLException("Should not call this (should only be called for offscreen GLDrawables)");
+ }
+
+ public void swapBuffers() throws GLException {
+ }
+
+ public long getHDC() {
+ return hdc;
+ }
+
+ public void choosePixelFormat(boolean onscreen) {
+ PIXELFORMATDESCRIPTOR pfd = null;
+ int pixelFormat = 0;
+ if (onscreen) {
+ GLCapabilities[] availableCaps = null;
+ int numFormats = 0;
+ pfd = newPixelFormatDescriptor();
+ GraphicsConfiguration config = component.getGraphicsConfiguration();
+ GraphicsDevice device = config.getDevice();
+ // Produce a recommended pixel format selection for the GLCapabilitiesChooser.
+ // Use wglChoosePixelFormatARB if user requested multisampling and if we have it available
+ GL dummyGL = null;
+ if (capabilities.getSampleBuffers()) {
+ dummyGL = WindowsGLContextFactory.getDummyGL(device);
+ }
+ int recommendedPixelFormat = -1;
+ boolean haveWGLChoosePixelFormatARB = false;
+ boolean haveWGLARBMultisample = false;
+ if (dummyGL != null) {
+ String availableWGLExtensions = WindowsGLContextFactory.getDummyGLExtensions(device);
+ if (availableWGLExtensions.indexOf("WGL_ARB_pixel_format") >= 0) {
+ haveWGLChoosePixelFormatARB = true;
+ if (availableWGLExtensions.indexOf("WGL_ARB_multisample") >= 0) {
+ haveWGLARBMultisample = true;
+ }
+ }
+ }
+ long dc = 0;
+ long rc = 0;
+ boolean freeWGLC = false;
+ if( dummyGL != null ) {
+ dc = WindowsGLContextFactory.getDummyGLDrawable( device ).hdc;
+ rc = WindowsGLContextFactory.getDummyGLContext( device ).hglrc;
+ if( !WGL.wglMakeCurrent( dc, rc ) ) {
+ System.err.println(getThreadName() + ": Error Making WGLC Current: " + WGL.GetLastError() );
+ } else {
+ freeWGLC = true;
+ }
+ }
+ // Fallback path for older cards, in particular Intel Extreme motherboard graphics
+ boolean gotAvailableCaps = false;
+ if (dummyGL != null && haveWGLChoosePixelFormatARB) {
+ int[] iattributes = new int [2 * MAX_ATTRIBS];
+ int[] iresults = new int [2 * MAX_ATTRIBS];
+ float[] fattributes = new float[2 * MAX_ATTRIBS];
+ int niattribs = 0;
+ int nfattribs = 0;
+ iattributes[niattribs++] = GL.WGL_SUPPORT_OPENGL_ARB;
+ iattributes[niattribs++] = GL.GL_TRUE;
+ iattributes[niattribs++] = GL.WGL_DRAW_TO_WINDOW_ARB;
+ iattributes[niattribs++] = GL.GL_TRUE;
+ iattributes[niattribs++] = GL.WGL_PIXEL_TYPE_ARB;
+ iattributes[niattribs++] = GL.WGL_TYPE_RGBA_ARB;
+ iattributes[niattribs++] = GL.WGL_DOUBLE_BUFFER_ARB;
+ if (capabilities.getDoubleBuffered()) {
+ iattributes[niattribs++] = GL.GL_TRUE;
+ } else {
+ iattributes[niattribs++] = GL.GL_FALSE;
+ }
+ iattributes[niattribs++] = GL.WGL_STEREO_ARB;
+ if (capabilities.getStereo()) {
+ iattributes[niattribs++] = GL.GL_TRUE;
+ } else {
+ iattributes[niattribs++] = GL.GL_FALSE;
+ }
+ iattributes[niattribs++] = GL.WGL_DEPTH_BITS_ARB;
+ iattributes[niattribs++] = capabilities.getDepthBits();
+ iattributes[niattribs++] = GL.WGL_RED_BITS_ARB;
+ iattributes[niattribs++] = capabilities.getRedBits();
+ iattributes[niattribs++] = GL.WGL_GREEN_BITS_ARB;
+ iattributes[niattribs++] = capabilities.getGreenBits();
+ iattributes[niattribs++] = GL.WGL_BLUE_BITS_ARB;
+ iattributes[niattribs++] = capabilities.getBlueBits();
+ iattributes[niattribs++] = GL.WGL_ALPHA_BITS_ARB;
+ iattributes[niattribs++] = capabilities.getAlphaBits();
+ iattributes[niattribs++] = GL.WGL_STENCIL_BITS_ARB;
+ iattributes[niattribs++] = capabilities.getStencilBits();
+ if (capabilities.getAccumRedBits() > 0 ||
+ capabilities.getAccumGreenBits() > 0 ||
+ capabilities.getAccumBlueBits() > 0 ||
+ capabilities.getAccumAlphaBits() > 0) {
+ iattributes[niattribs++] = GL.WGL_ACCUM_BITS_ARB;
+ iattributes[niattribs++] = (capabilities.getAccumRedBits() +
+ capabilities.getAccumGreenBits() +
+ capabilities.getAccumBlueBits() +
+ capabilities.getAccumAlphaBits());
+ iattributes[niattribs++] = GL.WGL_ACCUM_RED_BITS_ARB;
+ iattributes[niattribs++] = capabilities.getAccumRedBits();
+ iattributes[niattribs++] = GL.WGL_ACCUM_GREEN_BITS_ARB;
+ iattributes[niattribs++] = capabilities.getAccumGreenBits();
+ iattributes[niattribs++] = GL.WGL_ACCUM_BLUE_BITS_ARB;
+ iattributes[niattribs++] = capabilities.getAccumBlueBits();
+ iattributes[niattribs++] = GL.WGL_ACCUM_ALPHA_BITS_ARB;
+ iattributes[niattribs++] = capabilities.getAccumAlphaBits();
+ }
+ if (haveWGLARBMultisample) {
+ if (capabilities.getSampleBuffers()) {
+ iattributes[niattribs++] = GL.WGL_SAMPLE_BUFFERS_ARB;
+ iattributes[niattribs++] = GL.GL_TRUE;
+ iattributes[niattribs++] = GL.WGL_SAMPLES_ARB;
+ iattributes[niattribs++] = capabilities.getNumSamples();
+ }
+ }
+
+ int[] pformats = new int[MAX_PFORMATS];
+ int[] numFormatsTmp = new int[1];
+ if (dummyGL.wglChoosePixelFormatARB(hdc,
+ iattributes, 0,
+ fattributes, 0,
+ MAX_PFORMATS,
+ pformats, 0,
+ numFormatsTmp, 0)) {
+ numFormats = numFormatsTmp[0];
+ if (numFormats > 0) {
+ // Remove one-basing of pixel format (added on later)
+ recommendedPixelFormat = pformats[0] - 1;
+ if (DEBUG) {
+ System.err.println(getThreadName() + ": Used wglChoosePixelFormatARB to recommend pixel format " + recommendedPixelFormat);
+ }
+ }
+ } else {
+ if (DEBUG) {
+ System.err.println(getThreadName() + ": wglChoosePixelFormatARB failed: " + WGL.GetLastError() );
+ Thread.dumpStack();
+ }
+ }
+ if (DEBUG) {
+ if (recommendedPixelFormat < 0) {
+ System.err.print(getThreadName() + ": wglChoosePixelFormatARB didn't recommend a pixel format");
+ if (capabilities.getSampleBuffers()) {
+ System.err.print(" for multisampled GLCapabilities");
+ }
+ System.err.println();
+ }
+ }
+
+ // Produce a list of GLCapabilities to give to the
+ // GLCapabilitiesChooser.
+ // Use wglGetPixelFormatAttribivARB instead of
+ // DescribePixelFormat to get higher-precision information
+ // about the pixel format (should make the GLCapabilities
+ // more precise as well...i.e., remove the
+ // "HardwareAccelerated" bit, which is basically
+ // meaningless, and put in whether it can render to a
+ // window, to a pbuffer, or to a pixmap)
+ niattribs = 0;
+ iattributes[0] = GL.WGL_NUMBER_PIXEL_FORMATS_ARB;
+ if (dummyGL.wglGetPixelFormatAttribivARB(hdc, 0, 0, 1, iattributes, 0, iresults, 0)) {
+ numFormats = iresults[0];
+ // Should we be filtering out the pixel formats which aren't
+ // applicable, as we are doing here?
+ // We don't have enough information in the GLCapabilities to
+ // represent those that aren't...
+ iattributes[niattribs++] = GL.WGL_DRAW_TO_WINDOW_ARB;
+ iattributes[niattribs++] = GL.WGL_ACCELERATION_ARB;
+ iattributes[niattribs++] = GL.WGL_SUPPORT_OPENGL_ARB;
+ iattributes[niattribs++] = GL.WGL_DEPTH_BITS_ARB;
+ iattributes[niattribs++] = GL.WGL_STENCIL_BITS_ARB;
+ iattributes[niattribs++] = GL.WGL_DOUBLE_BUFFER_ARB;
+ iattributes[niattribs++] = GL.WGL_STEREO_ARB;
+ iattributes[niattribs++] = GL.WGL_PIXEL_TYPE_ARB;
+ iattributes[niattribs++] = GL.WGL_RED_BITS_ARB;
+ iattributes[niattribs++] = GL.WGL_GREEN_BITS_ARB;
+ iattributes[niattribs++] = GL.WGL_BLUE_BITS_ARB;
+ iattributes[niattribs++] = GL.WGL_ALPHA_BITS_ARB;
+ iattributes[niattribs++] = GL.WGL_ACCUM_RED_BITS_ARB;
+ iattributes[niattribs++] = GL.WGL_ACCUM_GREEN_BITS_ARB;
+ iattributes[niattribs++] = GL.WGL_ACCUM_BLUE_BITS_ARB;
+ iattributes[niattribs++] = GL.WGL_ACCUM_ALPHA_BITS_ARB;
+ if (haveWGLARBMultisample) {
+ iattributes[niattribs++] = GL.WGL_SAMPLE_BUFFERS_ARB;
+ iattributes[niattribs++] = GL.WGL_SAMPLES_ARB;
+ }
+
+ availableCaps = new GLCapabilities[numFormats];
+ for (int i = 0; i < numFormats; i++) {
+ if (!dummyGL.wglGetPixelFormatAttribivARB(hdc, i+1, 0, niattribs, iattributes, 0, iresults, 0)) {
+ throw new GLException("Error getting pixel format attributes for pixel format " + (i + 1) + " of device context");
+ }
+ availableCaps[i] = iattributes2GLCapabilities(iattributes, iresults, niattribs, true);
+ }
+ if( freeWGLC ) {
+ WGL.wglMakeCurrent( 0, 0 );
+ }
+ gotAvailableCaps = true;
+ } else {
+ int lastErr = WGL.GetLastError();
+ // Intel Extreme graphics fails with a zero error code
+ if (lastErr != 0) {
+ throw new GLException("Unable to enumerate pixel formats of window using wglGetPixelFormatAttribivARB: error code " + WGL.GetLastError());
+ }
+ }
+ }
+
+ if (!gotAvailableCaps) {
+ if (DEBUG) {
+ if (!capabilities.getSampleBuffers()) {
+ System.err.println(getThreadName() + ": Using ChoosePixelFormat because multisampling not requested");
+ } else {
+ System.err.println(getThreadName() + ": Using ChoosePixelFormat because no wglChoosePixelFormatARB: dummyGL = " + dummyGL);
+ }
+ }
+ pfd = glCapabilities2PFD(capabilities, onscreen);
+ // Remove one-basing of pixel format (added on later)
+ recommendedPixelFormat = WGL.ChoosePixelFormat(hdc, pfd) - 1;
+
+ numFormats = WGL.DescribePixelFormat(hdc, 1, 0, null);
+ if (numFormats == 0) {
+ throw new GLException("Unable to enumerate pixel formats of window for GLCapabilitiesChooser");
+ }
+ availableCaps = new GLCapabilities[numFormats];
+ for (int i = 0; i < numFormats; i++) {
+ if (WGL.DescribePixelFormat(hdc, 1 + i, pfd.size(), pfd) == 0) {
+ throw new GLException("Error describing pixel format " + (1 + i) + " of device context");
+ }
+ availableCaps[i] = pfd2GLCapabilities(pfd);
+ }
+ }
+
+ // Supply information to chooser
+ pixelFormat = chooser.chooseCapabilities(capabilities, availableCaps, recommendedPixelFormat);
+ if ((pixelFormat < 0) || (pixelFormat >= numFormats)) {
+ throw new GLException("Invalid result " + pixelFormat +
+ " from GLCapabilitiesChooser (should be between 0 and " +
+ (numFormats - 1) + ")");
+ }
+ if (DEBUG) {
+ System.err.println(getThreadName() + ": Chosen pixel format (" + pixelFormat + "):");
+ System.err.println(availableCaps[pixelFormat]);
+ }
+ pixelFormat += 1; // one-base the index
+ if (WGL.DescribePixelFormat(hdc, pixelFormat, pfd.size(), pfd) == 0) {
+ throw new GLException("Error re-describing the chosen pixel format: " + WGL.GetLastError());
+ }
+ } else {
+ // For now, use ChoosePixelFormat for offscreen surfaces until
+ // we figure out how to properly choose an offscreen-
+ // compatible pixel format
+ pfd = glCapabilities2PFD(capabilities, onscreen);
+ pixelFormat = WGL.ChoosePixelFormat(hdc, pfd);
+ }
+ if (!WGL.SetPixelFormat(hdc, pixelFormat, pfd)) {
+ int lastError = WGL.GetLastError();
+ if (DEBUG) {
+ System.err.println(getThreadName() + ": SetPixelFormat failed: current context = " + WGL.wglGetCurrentContext() +
+ ", current DC = " + WGL.wglGetCurrentDC());
+ System.err.println(getThreadName() + ": GetPixelFormat(hdc " + toHexString(hdc) + ") returns " + WGL.GetPixelFormat(hdc));
+ }
+ throw new GLException("Unable to set pixel format " + pixelFormat + " for device context " + toHexString(hdc) + ": error code " + lastError);
+ }
+ pixelFormatChosen = true;
+ }
+
+ static PIXELFORMATDESCRIPTOR glCapabilities2PFD(GLCapabilities caps, boolean onscreen) {
+ int colorDepth = (caps.getRedBits() +
+ caps.getGreenBits() +
+ caps.getBlueBits());
+ if (colorDepth < 15) {
+ throw new GLException("Bit depths < 15 (i.e., non-true-color) not supported");
+ }
+ PIXELFORMATDESCRIPTOR pfd = newPixelFormatDescriptor();
+ int pfdFlags = (WGL.PFD_SUPPORT_OPENGL |
+ WGL.PFD_GENERIC_ACCELERATED);
+ if (caps.getDoubleBuffered()) {
+ pfdFlags |= WGL.PFD_DOUBLEBUFFER;
+ }
+ if (onscreen) {
+ pfdFlags |= WGL.PFD_DRAW_TO_WINDOW;
+ } else {
+ pfdFlags |= WGL.PFD_DRAW_TO_BITMAP;
+ }
+ pfd.dwFlags(pfdFlags);
+ pfd.iPixelType((byte) WGL.PFD_TYPE_RGBA);
+ pfd.cColorBits((byte) colorDepth);
+ pfd.cRedBits ((byte) caps.getRedBits());
+ pfd.cGreenBits((byte) caps.getGreenBits());
+ pfd.cBlueBits ((byte) caps.getBlueBits());
+ pfd.cAlphaBits((byte) caps.getAlphaBits());
+ int accumDepth = (caps.getAccumRedBits() +
+ caps.getAccumGreenBits() +
+ caps.getAccumBlueBits());
+ pfd.cAccumBits ((byte) accumDepth);
+ pfd.cAccumRedBits ((byte) caps.getAccumRedBits());
+ pfd.cAccumGreenBits((byte) caps.getAccumGreenBits());
+ pfd.cAccumBlueBits ((byte) caps.getAccumBlueBits());
+ pfd.cAccumAlphaBits((byte) caps.getAccumAlphaBits());
+ pfd.cDepthBits((byte) caps.getDepthBits());
+ pfd.cStencilBits((byte) caps.getStencilBits());
+ pfd.iLayerType((byte) WGL.PFD_MAIN_PLANE);
+ return pfd;
+ }
+
+ static PIXELFORMATDESCRIPTOR newPixelFormatDescriptor() {
+ PIXELFORMATDESCRIPTOR pfd = new PIXELFORMATDESCRIPTOR();
+ pfd.nSize((short) pfd.size());
+ pfd.nVersion((short) 1);
+ return pfd;
+ }
+
+ static GLCapabilities pfd2GLCapabilities(PIXELFORMATDESCRIPTOR pfd) {
+ if ((pfd.dwFlags() & WGL.PFD_SUPPORT_OPENGL) == 0) {
+ return null;
+ }
+ GLCapabilities res = new GLCapabilities();
+ res.setRedBits (pfd.cRedBits());
+ res.setGreenBits (pfd.cGreenBits());
+ res.setBlueBits (pfd.cBlueBits());
+ res.setAlphaBits (pfd.cAlphaBits());
+ res.setAccumRedBits (pfd.cAccumRedBits());
+ res.setAccumGreenBits(pfd.cAccumGreenBits());
+ res.setAccumBlueBits (pfd.cAccumBlueBits());
+ res.setAccumAlphaBits(pfd.cAccumAlphaBits());
+ res.setDepthBits (pfd.cDepthBits());
+ res.setStencilBits (pfd.cStencilBits());
+ res.setDoubleBuffered((pfd.dwFlags() & WGL.PFD_DOUBLEBUFFER) != 0);
+ res.setStereo ((pfd.dwFlags() & WGL.PFD_STEREO) != 0);
+ res.setHardwareAccelerated(((pfd.dwFlags() & WGL.PFD_GENERIC_FORMAT) == 0) ||
+ ((pfd.dwFlags() & WGL.PFD_GENERIC_ACCELERATED) != 0));
+ return res;
+ }
+
+ static GLCapabilities iattributes2GLCapabilities(int[] iattribs,
+ int[] iresults,
+ int niattribs,
+ boolean requireRenderToWindow) {
+ GLCapabilities res = new GLCapabilities();
+ for (int i = 0; i < niattribs; i++) {
+ switch (iattribs[i]) {
+ case GL.WGL_DRAW_TO_WINDOW_ARB:
+ if (iresults[i] != GL.GL_TRUE)
+ return null;
+ break;
+
+ case GL.WGL_ACCELERATION_ARB:
+ res.setHardwareAccelerated(iresults[i] == GL.WGL_FULL_ACCELERATION_ARB);
+ break;
+
+ case GL.WGL_SUPPORT_OPENGL_ARB:
+ if (iresults[i] != GL.GL_TRUE)
+ return null;
+ break;
+
+ case GL.WGL_DEPTH_BITS_ARB:
+ res.setDepthBits(iresults[i]);
+ break;
+
+ case GL.WGL_STENCIL_BITS_ARB:
+ res.setStencilBits(iresults[i]);
+ break;
+
+ case GL.WGL_DOUBLE_BUFFER_ARB:
+ res.setDoubleBuffered(iresults[i] == GL.GL_TRUE);
+ break;
+
+ case GL.WGL_STEREO_ARB:
+ res.setStereo(iresults[i] == GL.GL_TRUE);
+ break;
+
+ case GL.WGL_PIXEL_TYPE_ARB:
+ if (iresults[i] != GL.WGL_TYPE_RGBA_ARB)
+ return null;
+ break;
+
+ case GL.WGL_RED_BITS_ARB:
+ res.setRedBits(iresults[i]);
+ break;
+
+ case GL.WGL_GREEN_BITS_ARB:
+ res.setGreenBits(iresults[i]);
+ break;
+
+ case GL.WGL_BLUE_BITS_ARB:
+ res.setBlueBits(iresults[i]);
+ break;
+
+ case GL.WGL_ALPHA_BITS_ARB:
+ res.setAlphaBits(iresults[i]);
+ break;
+
+ case GL.WGL_ACCUM_RED_BITS_ARB:
+ res.setAccumRedBits(iresults[i]);
+ break;
+
+ case GL.WGL_ACCUM_GREEN_BITS_ARB:
+ res.setAccumGreenBits(iresults[i]);
+ break;
+
+ case GL.WGL_ACCUM_BLUE_BITS_ARB:
+ res.setAccumBlueBits(iresults[i]);
+ break;
+
+ case GL.WGL_ACCUM_ALPHA_BITS_ARB:
+ res.setAccumAlphaBits(iresults[i]);
+ break;
+
+ case GL.WGL_SAMPLE_BUFFERS_ARB:
+ res.setSampleBuffers(iresults[i] == GL.GL_TRUE);
+ break;
+
+ case GL.WGL_SAMPLES_ARB:
+ res.setNumSamples(iresults[i]);
+ break;
+
+ default:
+ throw new GLException("Unknown pixel format attribute " + iattribs[i]);
+ }
+ }
+ return res;
+ }
+
+ protected static String getThreadName() {
+ return Thread.currentThread().getName();
+ }
+}
diff --git a/src/net/java/games/jogl/impl/windows/WindowsOffscreenGLContext.java b/src/net/java/games/jogl/impl/windows/WindowsOffscreenGLContext.java
index d944a8684..a2fae5971 100644
--- a/src/net/java/games/jogl/impl/windows/WindowsOffscreenGLContext.java
+++ b/src/net/java/games/jogl/impl/windows/WindowsOffscreenGLContext.java
@@ -39,38 +39,13 @@
package net.java.games.jogl.impl.windows;
-import java.awt.image.BufferedImage;
import net.java.games.jogl.*;
import net.java.games.jogl.impl.*;
public class WindowsOffscreenGLContext extends WindowsGLContext {
- private long origbitmap;
- private long hbitmap;
- // Width and height of the underlying bitmap
- private int width;
- private int height;
-
- public WindowsOffscreenGLContext(GLCapabilities capabilities,
- GLCapabilitiesChooser chooser,
+ public WindowsOffscreenGLContext(WindowsOffscreenGLDrawable drawable,
GLContext shareWith) {
- super(null, capabilities, chooser, shareWith);
- }
-
- protected GL createGL()
- {
- return new WindowsGLImpl(this);
- }
-
- protected boolean isOffscreen() {
- return true;
- }
-
- public int getOffscreenContextWidth() {
- return width;
- }
-
- public int getOffscreenContextHeight() {
- return height;
+ super(drawable, shareWith);
}
public int getOffscreenContextPixelDataType() {
@@ -92,9 +67,9 @@ public class WindowsOffscreenGLContext extends WindowsGLContext {
return false;
}
- public GLContext createPbufferContext(GLCapabilities capabilities,
- int initialWidth,
- int initialHeight) {
+ public GLDrawableImpl createPbufferDrawable(GLCapabilities capabilities,
+ int initialWidth,
+ int initialHeight) {
throw new GLException("Not supported");
}
@@ -105,72 +80,4 @@ public class WindowsOffscreenGLContext extends WindowsGLContext {
public void releasePbufferFromTexture() {
throw new GLException("Should not call this");
}
-
- protected int makeCurrentImpl() throws GLException {
- if (pendingOffscreenResize) {
- if (pendingOffscreenWidth != width || pendingOffscreenHeight != height) {
- if (hglrc != 0) {
- destroyImpl();
- }
- width = pendingOffscreenWidth;
- height = pendingOffscreenHeight;
- pendingOffscreenResize = false;
- }
- }
- return super.makeCurrentImpl();
- }
-
- protected void destroyImpl() {
- if (hglrc != 0) {
- super.destroyImpl();
- // Must destroy OpenGL context, bitmap and device context
- WGL.SelectObject(hdc, origbitmap);
- WGL.DeleteObject(hbitmap);
- WGL.DeleteDC(hdc);
- origbitmap = 0;
- hbitmap = 0;
- hdc = 0;
- }
- }
-
- public void swapBuffers() throws GLException {
- }
-
- protected void create() {
- BITMAPINFO info = new BITMAPINFO();
- BITMAPINFOHEADER header = info.bmiHeader();
- int bitsPerPixel = (capabilities.getRedBits() +
- capabilities.getGreenBits() +
- capabilities.getBlueBits());
- header.biSize(header.size());
- header.biWidth(width);
- // NOTE: negating the height causes the DIB to be in top-down row
- // order rather than bottom-up; ends up being correct during pixel
- // readback
- header.biHeight(-1 * height);
- header.biPlanes((short) 1);
- header.biBitCount((short) bitsPerPixel);
- header.biXPelsPerMeter(0);
- header.biYPelsPerMeter(0);
- header.biClrUsed(0);
- header.biClrImportant(0);
- header.biCompression(WGL.BI_RGB);
- header.biSizeImage(width * height * bitsPerPixel / 8);
-
- hdc = WGL.CreateCompatibleDC(0);
- if (hdc == 0) {
- System.out.println("LastError: " + WGL.GetLastError());
- throw new GLException("Error creating device context for offscreen OpenGL context");
- }
- hbitmap = WGL.CreateDIBSection(hdc, info, WGL.DIB_RGB_COLORS, 0, 0, 0);
- if (hbitmap == 0) {
- throw new GLException("Error creating offscreen bitmap of width " + width +
- ", height " + height);
- }
- if ((origbitmap = WGL.SelectObject(hdc, hbitmap)) == 0) {
- throw new GLException("Error selecting bitmap into new device context");
- }
-
- choosePixelFormatAndCreateContext(false);
- }
}
diff --git a/src/net/java/games/jogl/impl/windows/WindowsOffscreenGLDrawable.java b/src/net/java/games/jogl/impl/windows/WindowsOffscreenGLDrawable.java
new file mode 100644
index 000000000..03d76574a
--- /dev/null
+++ b/src/net/java/games/jogl/impl/windows/WindowsOffscreenGLDrawable.java
@@ -0,0 +1,133 @@
+/*
+ * Copyright (c) 2003 Sun Microsystems, Inc. All Rights Reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * - Redistribution of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * - Redistribution 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 Sun Microsystems, Inc. or the names of
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * This software is provided "AS IS," without a warranty of any kind. ALL
+ * EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND WARRANTIES,
+ * INCLUDING ANY IMPLIED WARRANTY OF MERCHANTABILITY, FITNESS FOR A
+ * PARTICULAR PURPOSE OR NON-INFRINGEMENT, ARE HEREBY EXCLUDED. SUN
+ * MICROSYSTEMS, INC. ("SUN") AND ITS LICENSORS SHALL NOT BE LIABLE FOR
+ * ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF USING, MODIFYING OR
+ * DISTRIBUTING THIS SOFTWARE OR ITS DERIVATIVES. IN NO EVENT WILL SUN OR
+ * ITS LICENSORS BE LIABLE FOR ANY LOST REVENUE, PROFIT OR DATA, OR FOR
+ * DIRECT, INDIRECT, SPECIAL, CONSEQUENTIAL, INCIDENTAL OR PUNITIVE
+ * DAMAGES, HOWEVER CAUSED AND REGARDLESS OF THE THEORY OF LIABILITY,
+ * ARISING OUT OF THE USE OF OR INABILITY TO USE THIS SOFTWARE, EVEN IF
+ * SUN HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.
+ *
+ * You acknowledge that this software is not designed or intended for use
+ * in the design, construction, operation or maintenance of any nuclear
+ * facility.
+ *
+ * Sun gratefully acknowledges that this software was originally authored
+ * and developed by Kenneth Bradley Russell and Christopher John Kline.
+ */
+
+package net.java.games.jogl.impl.windows;
+
+import net.java.games.jogl.*;
+import net.java.games.jogl.impl.*;
+
+public class WindowsOffscreenGLDrawable extends WindowsGLDrawable {
+ private long origbitmap;
+ private long hbitmap;
+ // Width and height of the underlying bitmap
+ private int width;
+ private int height;
+
+ public WindowsOffscreenGLDrawable(GLCapabilities capabilities,
+ GLCapabilitiesChooser chooser) {
+ super(null, capabilities, chooser);
+ }
+
+ public GLContext createContext(GLContext shareWith) {
+ return new WindowsOffscreenGLContext(this, shareWith);
+ }
+
+ public void setSize(int newWidth, int newHeight) {
+ width = newWidth;
+ height = newHeight;
+ if (hdc != 0) {
+ destroy();
+ }
+ create();
+ }
+
+ public int getWidth() {
+ return width;
+ }
+
+ public int getHeight() {
+ return height;
+ }
+
+ private void create() {
+ BITMAPINFO info = new BITMAPINFO();
+ BITMAPINFOHEADER header = info.bmiHeader();
+ int bitsPerPixel = (capabilities.getRedBits() +
+ capabilities.getGreenBits() +
+ capabilities.getBlueBits());
+ header.biSize(header.size());
+ header.biWidth(width);
+ // NOTE: negating the height causes the DIB to be in top-down row
+ // order rather than bottom-up; ends up being correct during pixel
+ // readback
+ header.biHeight(-1 * height);
+ header.biPlanes((short) 1);
+ header.biBitCount((short) bitsPerPixel);
+ header.biXPelsPerMeter(0);
+ header.biYPelsPerMeter(0);
+ header.biClrUsed(0);
+ header.biClrImportant(0);
+ header.biCompression(WGL.BI_RGB);
+ header.biSizeImage(width * height * bitsPerPixel / 8);
+
+ hdc = WGL.CreateCompatibleDC(0);
+ if (hdc == 0) {
+ System.out.println("LastError: " + WGL.GetLastError());
+ throw new GLException("Error creating device context for offscreen OpenGL context");
+ }
+ hbitmap = WGL.CreateDIBSection(hdc, info, WGL.DIB_RGB_COLORS, 0, 0, 0);
+ if (hbitmap == 0) {
+ WGL.DeleteDC(hdc);
+ hdc = 0;
+ throw new GLException("Error creating offscreen bitmap of width " + width +
+ ", height " + height);
+ }
+ if ((origbitmap = WGL.SelectObject(hdc, hbitmap)) == 0) {
+ WGL.DeleteObject(hbitmap);
+ hbitmap = 0;
+ WGL.DeleteDC(hdc);
+ hdc = 0;
+ throw new GLException("Error selecting bitmap into new device context");
+ }
+
+ choosePixelFormat(false);
+ }
+
+ public void destroy() {
+ if (hdc != 0) {
+ // Must destroy bitmap and device context
+ WGL.SelectObject(hdc, origbitmap);
+ WGL.DeleteObject(hbitmap);
+ WGL.DeleteDC(hdc);
+ origbitmap = 0;
+ hbitmap = 0;
+ hdc = 0;
+ }
+ }
+}
diff --git a/src/net/java/games/jogl/impl/windows/WindowsOnscreenGLContext.java b/src/net/java/games/jogl/impl/windows/WindowsOnscreenGLContext.java
index d4af4b3b7..c71f35ff0 100644
--- a/src/net/java/games/jogl/impl/windows/WindowsOnscreenGLContext.java
+++ b/src/net/java/games/jogl/impl/windows/WindowsOnscreenGLContext.java
@@ -39,68 +39,20 @@
package net.java.games.jogl.impl.windows;
-import java.awt.Component;
import java.util.*;
import net.java.games.jogl.*;
import net.java.games.jogl.impl.*;
public class WindowsOnscreenGLContext extends WindowsGLContext {
- // Variables for lockSurface/unlockSurface
- JAWT_DrawingSurface ds;
- JAWT_DrawingSurfaceInfo dsi;
- JAWT_Win32DrawingSurfaceInfo win32dsi;
-
- // Indicates whether the component (if an onscreen context) has been
- // realized. Plausibly, before the component is realized the JAWT
- // should return an error or NULL object from some of its
- // operations; this appears to be the case on Win32 but is not true
- // at least with Sun's current X11 implementation (1.4.x), which
- // crashes with no other error reported if the DrawingSurfaceInfo is
- // fetched from a locked DrawingSurface during the validation as a
- // result of calling show() on the main thread. To work around this
- // we prevent any JAWT or OpenGL operations from being done until
- // addNotify() is called on the component.
- protected boolean realized;
-
+ protected WindowsOnscreenGLDrawable drawable;
// Variables for pbuffer support
- List pbuffersToInstantiate = new ArrayList();
+ protected List pbuffersToInstantiate = new ArrayList();
- public WindowsOnscreenGLContext(Component component,
- GLCapabilities capabilities,
- GLCapabilitiesChooser chooser,
+ public WindowsOnscreenGLContext(WindowsOnscreenGLDrawable drawable,
GLContext shareWith) {
- super(component, capabilities, chooser, shareWith);
- }
-
- /*
- public void invokeGL(Runnable runnable, boolean isReshape, Runnable initAction) throws GLException {
- // Unfortunately, invokeGL can be called with the AWT tree lock
- // held, and the Windows onscreen implementation of
- // choosePixelFormatAndCreateContext calls
- // Component.getGraphicsConfiguration(), which grabs the tree
- // lock. To avoid deadlock we have to lock the tree lock before
- // grabbing the GLContext's lock if we're going to create an
- // OpenGL context during this call. This code might not be
- // completely correct, and we might need to uniformly grab the AWT
- // tree lock, which might become a performance issue...
- if (hglrc == 0) {
- synchronized(component.getTreeLock()) {
- super.invokeGL(runnable, isReshape, initAction);
- }
- } else {
- super.invokeGL(runnable, isReshape, initAction);
- }
- }
- */
-
- protected GL createGL()
- {
- return new WindowsGLImpl(this);
- }
-
- protected boolean isOffscreen() {
- return false;
+ super(drawable, shareWith);
+ this.drawable = drawable;
}
public int getOffscreenContextReadBuffer() {
@@ -115,13 +67,12 @@ public class WindowsOnscreenGLContext extends WindowsGLContext {
return haveWGLARBPbuffer();
}
- public GLContext createPbufferContext(GLCapabilities capabilities,
- int initialWidth,
- int initialHeight) {
- WindowsPbufferGLContext ctx = new WindowsPbufferGLContext(capabilities, initialWidth, initialHeight);
- ctx.setSynchronized(true);
- pbuffersToInstantiate.add(ctx);
- return ctx;
+ public GLDrawableImpl createPbufferDrawable(GLCapabilities capabilities,
+ int initialWidth,
+ int initialHeight) {
+ WindowsPbufferGLDrawable buf = new WindowsPbufferGLDrawable(capabilities, initialWidth, initialHeight);
+ pbuffersToInstantiate.add(buf);
+ return buf;
}
public void bindPbufferToTexture() {
@@ -132,32 +83,47 @@ public class WindowsOnscreenGLContext extends WindowsGLContext {
throw new GLException("Should not call this");
}
- public void setRealized() {
- realized = true;
- }
-
protected int makeCurrentImpl() throws GLException {
try {
- if (!realized) {
+ int lockRes = drawable.lockSurface();
+ if (lockRes == WindowsOnscreenGLDrawable.LOCK_SURFACE_NOT_READY) {
return CONTEXT_NOT_CURRENT;
}
- if (!lockSurface()) {
- return CONTEXT_NOT_CURRENT;
+ if (lockRes == WindowsOnscreenGLDrawable.LOCK_SURFACE_CHANGED) {
+ if (hglrc != 0) {
+ if (!WGL.wglDeleteContext(hglrc)) {
+ throw new GLException("Unable to delete old GL context after surface changed");
+ }
+ GLContextShareSet.contextDestroyed(this);
+ if (DEBUG) {
+ System.err.println(getThreadName() + ": !!! Destroyed OpenGL context " + toHexString(hglrc) + " due to JAWT_LOCK_SURFACE_CHANGED");
+ }
+ hglrc = 0;
+ }
}
int ret = super.makeCurrentImpl();
if ((ret == CONTEXT_CURRENT) ||
(ret == CONTEXT_CURRENT_NEW)) {
// Instantiate any pending pbuffers
- while (!pbuffersToInstantiate.isEmpty()) {
- WindowsPbufferGLContext ctx =
- (WindowsPbufferGLContext) pbuffersToInstantiate.remove(pbuffersToInstantiate.size() - 1);
- ctx.createPbuffer(hdc, hglrc);
+ // NOTE that we supply the drawable a GL instance for our
+ // context and that we eliminate all pipelines for it -- see
+ // WindowsPbufferGLDrawable.destroy()
+ if (!pbuffersToInstantiate.isEmpty()) {
+ GL tmpGL = createGL();
+ while (!pbuffersToInstantiate.isEmpty()) {
+ WindowsPbufferGLDrawable buf =
+ (WindowsPbufferGLDrawable) pbuffersToInstantiate.remove(pbuffersToInstantiate.size() - 1);
+ buf.createPbuffer(tmpGL, drawable.getHDC());
+ if (DEBUG) {
+ System.err.println(getThreadName() + ": created pbuffer " + buf);
+ }
+ }
}
}
return ret;
} catch (RuntimeException e) {
try {
- unlockSurface();
+ drawable.unlockSurface();
} catch (Exception e2) {
// do nothing if unlockSurface throws
}
@@ -169,88 +135,7 @@ public class WindowsOnscreenGLContext extends WindowsGLContext {
try {
super.releaseImpl();
} finally {
- unlockSurface();
- }
- }
-
- protected void destroyImpl() throws GLException {
- realized = false;
- super.destroyImpl();
- }
-
- public void swapBuffers() throws GLException {
- if (!WGL.SwapBuffers(hdc) && (WGL.GetLastError() != 0)) {
- throw new GLException("Error swapping buffers");
+ drawable.unlockSurface();
}
}
-
- private boolean lockSurface() throws GLException {
- if (hdc != 0) {
- throw new GLException("Surface already locked");
- }
- ds = getJAWT().GetDrawingSurface(component);
- if (ds == null) {
- // Widget not yet realized
- return false;
- }
- int res = ds.Lock();
- if ((res & JAWTFactory.JAWT_LOCK_ERROR) != 0) {
- throw new GLException("Unable to lock surface");
- }
- // See whether the surface changed and if so destroy the old
- // OpenGL context so it will be recreated (NOTE: removeNotify
- // should handle this case, but it may be possible that race
- // conditions can cause this code to be triggered -- should test
- // more)
- if ((res & JAWTFactory.JAWT_LOCK_SURFACE_CHANGED) != 0) {
- if (hglrc != 0) {
- if (!WGL.wglDeleteContext(hglrc)) {
- throw new GLException("Unable to delete old GL context after surface changed");
- }
- GLContextShareSet.contextDestroyed(this);
- if (DEBUG) {
- System.err.println(getThreadName() + ": !!! Destroyed OpenGL context " + hglrc + " due to JAWT_LOCK_SURFACE_CHANGED");
- }
- hglrc = 0;
- }
- }
- dsi = ds.GetDrawingSurfaceInfo();
- if (dsi == null) {
- // Widget not yet realized
- ds.Unlock();
- getJAWT().FreeDrawingSurface(ds);
- ds = null;
- return false;
- }
- win32dsi = (JAWT_Win32DrawingSurfaceInfo) dsi.platformInfo();
- hdc = win32dsi.hdc();
- if (hdc == 0) {
- // Widget not yet realized
- ds.FreeDrawingSurfaceInfo(dsi);
- ds.Unlock();
- getJAWT().FreeDrawingSurface(ds);
- ds = null;
- dsi = null;
- win32dsi = null;
- return false;
- }
- return true;
- }
-
- private void unlockSurface() {
- if (hdc == 0) {
- throw new GLException("Surface already unlocked");
- }
- ds.FreeDrawingSurfaceInfo(dsi);
- ds.Unlock();
- getJAWT().FreeDrawingSurface(ds);
- ds = null;
- dsi = null;
- win32dsi = null;
- hdc = 0;
- }
-
- protected void create() {
- choosePixelFormatAndCreateContext(true);
- }
}
diff --git a/src/net/java/games/jogl/impl/windows/WindowsOnscreenGLDrawable.java b/src/net/java/games/jogl/impl/windows/WindowsOnscreenGLDrawable.java
new file mode 100644
index 000000000..50cf5c9f4
--- /dev/null
+++ b/src/net/java/games/jogl/impl/windows/WindowsOnscreenGLDrawable.java
@@ -0,0 +1,181 @@
+/*
+ * Copyright (c) 2003 Sun Microsystems, Inc. All Rights Reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * - Redistribution of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * - Redistribution 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 Sun Microsystems, Inc. or the names of
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * This software is provided "AS IS," without a warranty of any kind. ALL
+ * EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND WARRANTIES,
+ * INCLUDING ANY IMPLIED WARRANTY OF MERCHANTABILITY, FITNESS FOR A
+ * PARTICULAR PURPOSE OR NON-INFRINGEMENT, ARE HEREBY EXCLUDED. SUN
+ * MICROSYSTEMS, INC. ("SUN") AND ITS LICENSORS SHALL NOT BE LIABLE FOR
+ * ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF USING, MODIFYING OR
+ * DISTRIBUTING THIS SOFTWARE OR ITS DERIVATIVES. IN NO EVENT WILL SUN OR
+ * ITS LICENSORS BE LIABLE FOR ANY LOST REVENUE, PROFIT OR DATA, OR FOR
+ * DIRECT, INDIRECT, SPECIAL, CONSEQUENTIAL, INCIDENTAL OR PUNITIVE
+ * DAMAGES, HOWEVER CAUSED AND REGARDLESS OF THE THEORY OF LIABILITY,
+ * ARISING OUT OF THE USE OF OR INABILITY TO USE THIS SOFTWARE, EVEN IF
+ * SUN HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.
+ *
+ * You acknowledge that this software is not designed or intended for use
+ * in the design, construction, operation or maintenance of any nuclear
+ * facility.
+ *
+ * Sun gratefully acknowledges that this software was originally authored
+ * and developed by Kenneth Bradley Russell and Christopher John Kline.
+ */
+
+package net.java.games.jogl.impl.windows;
+
+import java.awt.Component;
+
+import net.java.games.jogl.*;
+import net.java.games.jogl.impl.*;
+
+public class WindowsOnscreenGLDrawable extends WindowsGLDrawable {
+ public static final int LOCK_SURFACE_NOT_READY = 1;
+ public static final int LOCK_SURFACE_CHANGED = 2;
+ public static final int LOCK_SUCCESS = 3;
+ private static JAWT jawt;
+
+ // Variables for lockSurface/unlockSurface
+ private JAWT_DrawingSurface ds;
+ private JAWT_DrawingSurfaceInfo dsi;
+ private JAWT_Win32DrawingSurfaceInfo win32dsi;
+
+ // Indicates whether the component (if an onscreen context) has been
+ // realized. Plausibly, before the component is realized the JAWT
+ // should return an error or NULL object from some of its
+ // operations; this appears to be the case on Win32 but is not true
+ // at least with Sun's current X11 implementation (1.4.x), which
+ // crashes with no other error reported if the DrawingSurfaceInfo is
+ // fetched from a locked DrawingSurface during the validation as a
+ // result of calling show() on the main thread. To work around this
+ // we prevent any JAWT or OpenGL operations from being done until
+ // addNotify() is called on the component.
+ protected boolean realized;
+
+ public WindowsOnscreenGLDrawable(Component component,
+ GLCapabilities capabilities,
+ GLCapabilitiesChooser chooser) {
+ super(component, capabilities, chooser);
+ }
+
+ public GLContext createContext(GLContext shareWith) {
+ return new WindowsOnscreenGLContext(this, shareWith);
+ }
+
+ public void setRealized(boolean realized) {
+ this.realized = realized;
+ }
+
+ public void setSize(int width, int height) {
+ component.setSize(width, height);
+ }
+
+ public int getWidth() {
+ return component.getWidth();
+ }
+
+ public int getHeight() {
+ return component.getHeight();
+ }
+
+ public void swapBuffers() throws GLException {
+ if (!WGL.SwapBuffers(hdc) && (WGL.GetLastError() != 0)) {
+ throw new GLException("Error swapping buffers");
+ }
+ }
+
+ public int lockSurface() throws GLException {
+ if (!realized) {
+ return LOCK_SURFACE_NOT_READY;
+ }
+ if (hdc != 0) {
+ throw new GLException("Surface already locked");
+ }
+ ds = getJAWT().GetDrawingSurface(component);
+ if (ds == null) {
+ // Widget not yet realized
+ return LOCK_SURFACE_NOT_READY;
+ }
+ int res = ds.Lock();
+ if ((res & JAWTFactory.JAWT_LOCK_ERROR) != 0) {
+ throw new GLException("Unable to lock surface");
+ }
+ // See whether the surface changed and if so destroy the old
+ // OpenGL context so it will be recreated (NOTE: removeNotify
+ // should handle this case, but it may be possible that race
+ // conditions can cause this code to be triggered -- should test
+ // more)
+ int ret = LOCK_SUCCESS;
+ if ((res & JAWTFactory.JAWT_LOCK_SURFACE_CHANGED) != 0) {
+ ret = LOCK_SURFACE_CHANGED;
+ }
+ dsi = ds.GetDrawingSurfaceInfo();
+ if (dsi == null) {
+ // Widget not yet realized
+ ds.Unlock();
+ getJAWT().FreeDrawingSurface(ds);
+ ds = null;
+ return LOCK_SURFACE_NOT_READY;
+ }
+ win32dsi = (JAWT_Win32DrawingSurfaceInfo) dsi.platformInfo();
+ hdc = win32dsi.hdc();
+ if (hdc == 0) {
+ // Widget not yet realized
+ ds.FreeDrawingSurfaceInfo(dsi);
+ ds.Unlock();
+ getJAWT().FreeDrawingSurface(ds);
+ ds = null;
+ dsi = null;
+ win32dsi = null;
+ return LOCK_SURFACE_NOT_READY;
+ }
+ if (!pixelFormatChosen) {
+ choosePixelFormat(true);
+ }
+ return ret;
+ }
+
+ public void unlockSurface() {
+ if (hdc == 0) {
+ throw new GLException("Surface already unlocked");
+ }
+ ds.FreeDrawingSurfaceInfo(dsi);
+ ds.Unlock();
+ getJAWT().FreeDrawingSurface(ds);
+ ds = null;
+ dsi = null;
+ win32dsi = null;
+ hdc = 0;
+ }
+
+ //----------------------------------------------------------------------
+ // Internals only below this point
+ //
+
+ private JAWT getJAWT() {
+ if (jawt == null) {
+ JAWT j = new JAWT();
+ j.version(JAWTFactory.JAWT_VERSION_1_4);
+ if (!JAWTFactory.JAWT_GetAWT(j)) {
+ throw new RuntimeException("Unable to initialize JAWT");
+ }
+ jawt = j;
+ }
+ return jawt;
+ }
+}
diff --git a/src/net/java/games/jogl/impl/windows/WindowsPbufferGLContext.java b/src/net/java/games/jogl/impl/windows/WindowsPbufferGLContext.java
index d58d15d02..ca2f4aaa9 100644
--- a/src/net/java/games/jogl/impl/windows/WindowsPbufferGLContext.java
+++ b/src/net/java/games/jogl/impl/windows/WindowsPbufferGLContext.java
@@ -43,55 +43,27 @@ import net.java.games.jogl.*;
import net.java.games.jogl.impl.*;
public class WindowsPbufferGLContext extends WindowsGLContext {
- private static final boolean DEBUG = Debug.debug("WindowsPbufferGLContext");
-
- private int initWidth;
- private int initHeight;
-
- private long buffer; // pbuffer handle
- private int width;
- private int height;
-
- // FIXME: kept around because we create the OpenGL context lazily to
- // better integrate with the WindowsGLContext framework
- private long parentHglrc;
-
- private static final int MAX_PFORMATS = 256;
- private static final int MAX_ATTRIBS = 256;
-
// State for render-to-texture and render-to-texture-rectangle support
- private boolean created;
+ private WindowsPbufferGLDrawable drawable;
private boolean rtt; // render-to-texture?
private boolean hasRTT; // render-to-texture extension available?
private boolean rect; // render-to-texture-rectangle?
private int textureTarget; // e.g. GL_TEXTURE_2D, GL_TEXTURE_RECTANGLE_NV
private int texture; // actual texture object
- private int floatMode;
-
- public WindowsPbufferGLContext(GLCapabilities capabilities, int initialWidth, int initialHeight) {
- super(null, capabilities, null, null);
- this.initWidth = initialWidth;
- this.initHeight = initialHeight;
- if (initWidth <= 0 || initHeight <= 0) {
- throw new GLException("Initial width and height of pbuffer must be positive (were (" +
- initWidth + ", " + initHeight + "))");
- }
- if (DEBUG) {
- System.out.println("Pbuffer caps on init: " + capabilities +
- (capabilities.getOffscreenRenderToTexture() ? " [rtt]" : "") +
- (capabilities.getOffscreenRenderToTextureRectangle() ? " [rect]" : "") +
- (capabilities.getOffscreenFloatingPointBuffers() ? " [float]" : ""));
- }
+ public WindowsPbufferGLContext(WindowsPbufferGLDrawable drawable,
+ GLContext shareWith) {
+ super(drawable, shareWith);
+ this.drawable = drawable;
}
public boolean canCreatePbufferContext() {
return false;
}
- public GLContext createPbufferContext(GLCapabilities capabilities,
- int initialWidth,
- int initialHeight) {
+ public GLDrawableImpl createPbufferDrawable(GLCapabilities capabilities,
+ int initialWidth,
+ int initialHeight) {
throw new GLException("Not supported");
}
@@ -103,10 +75,11 @@ public class WindowsPbufferGLContext extends WindowsGLContext {
GL gl = getGL();
gl.glBindTexture(textureTarget, texture);
if (rtt && hasRTT) {
- if (!gl.wglBindTexImageARB(buffer, GL.WGL_FRONT_LEFT_ARB)) {
+ if (!gl.wglBindTexImageARB(drawable.getPbuffer(), GL.WGL_FRONT_LEFT_ARB)) {
throw new GLException("Binding of pbuffer to texture failed: " + wglGetLastError());
}
}
+ // FIXME: comment is wrong now
// Note that if the render-to-texture extension is not supported,
// we perform a glCopyTexImage2D in swapBuffers().
}
@@ -118,289 +91,32 @@ public class WindowsPbufferGLContext extends WindowsGLContext {
}
if (rtt && hasRTT) {
GL gl = getGL();
- if (!gl.wglReleaseTexImageARB(buffer, GL.WGL_FRONT_LEFT_ARB)) {
+ if (!gl.wglReleaseTexImageARB(drawable.getPbuffer(), GL.WGL_FRONT_LEFT_ARB)) {
throw new GLException("Releasing of pbuffer from texture failed: " + wglGetLastError());
}
}
}
- public void createPbuffer(long parentHdc, long parentHglrc) {
- GL gl = getGL();
- // Must initally grab OpenGL function pointers while parent's
- // context is current because otherwise we don't have the wgl
- // extensions available to us
- resetGLFunctionAvailability();
-
- int[] iattributes = new int [2*MAX_ATTRIBS];
- float[] fattributes = new float[2*MAX_ATTRIBS];
- int nfattribs = 0;
- int niattribs = 0;
-
- if (DEBUG) {
- System.out.println("Pbuffer caps: " + capabilities +
- (capabilities.getOffscreenRenderToTexture() ? " [rtt]" : "") +
- (capabilities.getOffscreenRenderToTextureRectangle() ? " [rect]" : "") +
- (capabilities.getOffscreenFloatingPointBuffers() ? " [float]" : ""));
- }
-
- rtt = capabilities.getOffscreenRenderToTexture();
- rect = capabilities.getOffscreenRenderToTextureRectangle();
- boolean useFloat = capabilities.getOffscreenFloatingPointBuffers();
- boolean ati = false;
-
- // Since we are trying to create a pbuffer, the pixel format we
- // request (and subsequently use) must be "p-buffer capable".
- iattributes[niattribs++] = GL.WGL_DRAW_TO_PBUFFER_ARB;
- iattributes[niattribs++] = GL.GL_TRUE;
-
- if (rtt && !rect) {
- throw new GLException("Render-to-texture-rectangle requires render-to-texture to be specified");
- }
-
- if (rect) {
- if (!gl.isExtensionAvailable("GL_NV_texture_rectangle")) {
- throw new GLException("Render-to-texture-rectangle requires GL_NV_texture_rectangle extension");
- }
- }
-
- if (useFloat) {
- if (!gl.isExtensionAvailable("WGL_ATI_pixel_format_float") &&
- !gl.isExtensionAvailable("WGL_NV_float_buffer")) {
- throw new GLException("Floating-point pbuffers not supported by this hardware");
- }
-
- // Prefer NVidia extension over ATI
- if (gl.isExtensionAvailable("WGL_NV_float_buffer")) {
- ati = false;
- floatMode = GLPbuffer.NV_FLOAT;
- } else {
- ati = true;
- floatMode = GLPbuffer.ATI_FLOAT;
- }
- if (DEBUG) {
- System.err.println("Using " + (ati ? "ATI" : "NVidia") + " floating-point extension");
- }
- }
-
- if (useFloat && ati) {
- if (rtt) {
- throw new GLException("Render-to-floating-point-texture not supported on ATI hardware");
- } else {
- iattributes[niattribs++] = GL.WGL_PIXEL_TYPE_ARB;
- iattributes[niattribs++] = GL.WGL_TYPE_RGBA_FLOAT_ATI;
- }
- } else {
- if (!rtt) {
- // Currently we don't support non-truecolor visuals in the
- // GLCapabilities, so we don't offer the option of making
- // color-index pbuffers.
- iattributes[niattribs++] = GL.WGL_PIXEL_TYPE_ARB;
- iattributes[niattribs++] = GL.WGL_TYPE_RGBA_ARB;
- }
- }
-
- iattributes[niattribs++] = GL.WGL_DOUBLE_BUFFER_ARB;
- if (capabilities.getDoubleBuffered()) {
- iattributes[niattribs++] = GL.GL_TRUE;
- } else {
- iattributes[niattribs++] = GL.GL_FALSE;
- }
-
- iattributes[niattribs++] = GL.WGL_DEPTH_BITS_ARB;
- iattributes[niattribs++] = capabilities.getDepthBits();
-
- iattributes[niattribs++] = GL.WGL_RED_BITS_ARB;
- iattributes[niattribs++] = capabilities.getRedBits();
-
- iattributes[niattribs++] = GL.WGL_GREEN_BITS_ARB;
- iattributes[niattribs++] = capabilities.getGreenBits();
-
- iattributes[niattribs++] = GL.WGL_BLUE_BITS_ARB;
- iattributes[niattribs++] = capabilities.getBlueBits();
-
- iattributes[niattribs++] = GL.WGL_ALPHA_BITS_ARB;
- iattributes[niattribs++] = capabilities.getAlphaBits();
-
- iattributes[niattribs++] = GL.WGL_STENCIL_BITS_ARB;
- if (capabilities.getStencilBits() > 0) {
- iattributes[niattribs++] = GL.GL_TRUE;
- } else {
- iattributes[niattribs++] = GL.GL_FALSE;
- }
-
- if (capabilities.getAccumRedBits() > 0 ||
- capabilities.getAccumGreenBits() > 0 ||
- capabilities.getAccumBlueBits() > 0) {
- iattributes[niattribs++] = GL.WGL_ACCUM_BITS_ARB;
- iattributes[niattribs++] = GL.GL_TRUE;
- }
-
- if (useFloat && !ati) {
- iattributes[niattribs++] = GL.WGL_FLOAT_COMPONENTS_NV;
- iattributes[niattribs++] = GL.GL_TRUE;
- }
-
- if (rtt) {
- if (useFloat) {
- assert(!ati);
- if (!rect) {
- throw new GLException("Render-to-floating-point-texture only supported on NVidia hardware with render-to-texture-rectangle");
- }
- iattributes[niattribs++] = GL.WGL_BIND_TO_TEXTURE_RECTANGLE_FLOAT_RGB_NV;
- iattributes[niattribs++] = GL.GL_TRUE;
- } else {
- iattributes[niattribs++] = rect ? GL.WGL_BIND_TO_TEXTURE_RECTANGLE_RGB_NV : GL.WGL_BIND_TO_TEXTURE_RGB_ARB;
- iattributes[niattribs++] = GL.GL_TRUE;
- }
- }
-
- iattributes[niattribs++] = GL.WGL_SUPPORT_OPENGL_ARB;
- iattributes[niattribs++] = GL.GL_TRUE;
-
- int[] pformats = new int[MAX_PFORMATS];
- int nformats;
- int[] nformatsTmp = new int[1];
- if (!gl.wglChoosePixelFormatARB(parentHdc,
- iattributes, 0,
- fattributes, 0,
- MAX_PFORMATS,
- pformats, 0,
- nformatsTmp, 0)) {
- throw new GLException("pbuffer creation error: wglChoosePixelFormatARB() failed");
- }
- nformats = nformatsTmp[0];
- if (nformats <= 0) {
- throw new GLException("pbuffer creation error: Couldn't find a suitable pixel format");
- }
-
- if (DEBUG) {
- System.err.println("" + nformats + " suitable pixel formats found");
- // query pixel format
- iattributes[0] = GL.WGL_RED_BITS_ARB;
- iattributes[1] = GL.WGL_GREEN_BITS_ARB;
- iattributes[2] = GL.WGL_BLUE_BITS_ARB;
- iattributes[3] = GL.WGL_ALPHA_BITS_ARB;
- iattributes[4] = GL.WGL_DEPTH_BITS_ARB;
- iattributes[5] = (useFloat ? (ati ? GL.WGL_PIXEL_TYPE_ARB : GL.WGL_FLOAT_COMPONENTS_NV) : GL.WGL_RED_BITS_ARB);
- iattributes[6] = GL.WGL_SAMPLE_BUFFERS_EXT;
- iattributes[7] = GL.WGL_SAMPLES_EXT;
- iattributes[8] = GL.WGL_DRAW_TO_PBUFFER_ARB;
- int[] ivalues = new int[9];
- for (int i = 0; i < nformats; i++) {
- if (!gl.wglGetPixelFormatAttribivARB(parentHdc, pformats[i], 0, 9, iattributes, 0, ivalues, 0)) {
- throw new GLException("Error while querying pixel format " + pformats[i] +
- "'s (index " + i + "'s) capabilities for debugging");
- }
- System.err.print("pixel format " + pformats[i] + " (index " + i + "): ");
- System.err.print( "r: " + ivalues[0]);
- System.err.print(" g: " + ivalues[1]);
- System.err.print(" b: " + ivalues[2]);
- System.err.print(" a: " + ivalues[3]);
- System.err.print(" depth: " + ivalues[4]);
- System.err.print(" multisample: " + ivalues[6]);
- System.err.print(" samples: " + ivalues[7]);
- if (useFloat) {
- if (ati) {
- if (ivalues[5] == GL.WGL_TYPE_RGBA_FLOAT_ATI) {
- System.err.print(" [ati float]");
- } else if (ivalues[5] != GL.WGL_TYPE_RGBA_ARB) {
- System.err.print(" [unknown pixel type " + ivalues[5] + "]");
- }
- } else {
- if (ivalues[5] != 0) {
- System.err.print(" [float]");
- }
- }
- }
-
- if (ivalues[8] != 0) {
- System.err.print(" [pbuffer]");
- }
- System.err.println();
- }
- }
-
- long tmpBuffer = 0;
- int whichFormat = 0;
- // Loop is a workaround for bugs in NVidia's recent drivers
- do {
- int format = pformats[whichFormat];
-
- // Create the p-buffer.
- niattribs = 0;
-
- if (rtt) {
- iattributes[niattribs++] = GL.WGL_TEXTURE_FORMAT_ARB;
- if (useFloat) {
- iattributes[niattribs++] = GL.WGL_TEXTURE_FLOAT_RGB_NV;
- } else {
- iattributes[niattribs++] = GL.WGL_TEXTURE_RGBA_ARB;
- }
-
- iattributes[niattribs++] = GL.WGL_TEXTURE_TARGET_ARB;
- iattributes[niattribs++] = rect ? GL.WGL_TEXTURE_RECTANGLE_NV : GL.WGL_TEXTURE_2D_ARB;
-
- iattributes[niattribs++] = GL.WGL_MIPMAP_TEXTURE_ARB;
- iattributes[niattribs++] = GL.GL_FALSE;
-
- iattributes[niattribs++] = GL.WGL_PBUFFER_LARGEST_ARB;
- iattributes[niattribs++] = GL.GL_FALSE;
- }
-
- iattributes[niattribs++] = 0;
-
- tmpBuffer = gl.wglCreatePbufferARB(parentHdc, format, initWidth, initHeight, iattributes, 0);
- ++whichFormat;
- } while ((tmpBuffer == 0) && (whichFormat < nformats));
-
- if (tmpBuffer == 0) {
- throw new GLException("pbuffer creation error: wglCreatePbufferARB() failed: tried " + nformats +
- " pixel formats, last error was: " + wglGetLastError());
- }
-
- // Get the device context.
- long tmpHdc = gl.wglGetPbufferDCARB(tmpBuffer);
- if (tmpHdc == 0) {
- throw new GLException("pbuffer creation error: wglGetPbufferDCARB() failed");
- }
-
- this.parentHglrc = parentHglrc;
-
- // Set up instance variables
- buffer = tmpBuffer;
- hdc = tmpHdc;
-
- // Determine the actual width and height we were able to create.
- int[] tmp = new int[1];
- gl.wglQueryPbufferARB( buffer, GL.WGL_PBUFFER_WIDTH_ARB, tmp, 0 );
- width = tmp[0];
- gl.wglQueryPbufferARB( buffer, GL.WGL_PBUFFER_HEIGHT_ARB, tmp, 0 );
- height = tmp[0];
-
- if (DEBUG) {
- System.err.println("Created pbuffer " + width + " x " + height);
- }
- }
-
protected int makeCurrentImpl() throws GLException {
- created = false;
-
- if (buffer == 0) {
- // pbuffer not instantiated yet
+ if (drawable.getHDC() == 0) {
+ // pbuffer not instantiated (yet?)
if (DEBUG) {
- System.err.println("pbuffer not instantiated yet");
+ System.err.println("pbuffer not instantiated");
}
return CONTEXT_NOT_CURRENT;
}
int res = super.makeCurrentImpl();
- if (DEBUG) {
- System.err.println("super.makeCurrent() = " + res + ", created = " + created);
+ if (DEBUG && VERBOSE) {
+ System.err.println("super.makeCurrent() = " + res);
}
- if (created) {
+ if (res == CONTEXT_CURRENT_NEW) {
+ GLCapabilities capabilities = drawable.getCapabilities();
+
// Initialize render-to-texture support if requested
rtt = capabilities.getOffscreenRenderToTexture();
rect = capabilities.getOffscreenRenderToTextureRectangle();
+ GL gl = getGL();
if (rtt) {
if (DEBUG) {
@@ -412,7 +128,6 @@ public class WindowsPbufferGLContext extends WindowsGLContext {
"supported; implementing render_to_texture support using slow texture readback");
} else {
hasRTT = true;
- GL gl = getGL();
if (rect && !gl.isExtensionAvailable("GL_NV_texture_rectangle")) {
System.err.println("WindowsPbufferGLContext: WARNING: GL_NV_texture_rectangle extension not " +
@@ -438,23 +153,13 @@ public class WindowsPbufferGLContext extends WindowsGLContext {
gl.glTexParameteri(textureTarget, GL.GL_TEXTURE_MAG_FILTER, GL.GL_NEAREST);
gl.glTexParameteri(textureTarget, GL.GL_TEXTURE_WRAP_S, GL.GL_CLAMP_TO_EDGE);
gl.glTexParameteri(textureTarget, GL.GL_TEXTURE_WRAP_T, GL.GL_CLAMP_TO_EDGE);
- gl.glCopyTexImage2D(textureTarget, 0, GL.GL_RGB, 0, 0, width, height, 0);
+ gl.glCopyTexImage2D(textureTarget, 0, GL.GL_RGB, 0, 0, drawable.getWidth(), drawable.getHeight(), 0);
}
}
}
return res;
}
- public void handleModeSwitch(long parentHdc, long parentHglrc) {
- throw new GLException("Not yet implemented");
- }
-
- protected boolean isOffscreen() {
- // FIXME: currently the only caller of this won't cause proper
- // resizing of the pbuffer anyway.
- return false;
- }
-
public int getOffscreenContextReadBuffer() {
throw new GLException("Should not call this");
}
@@ -463,67 +168,11 @@ public class WindowsPbufferGLContext extends WindowsGLContext {
throw new GLException("Should not call this");
}
- protected void create() {
- created = true;
- // Create a gl context for the p-buffer.
- hglrc = WGL.wglCreateContext(hdc);
- if (hglrc == 0) {
- throw new GLException("pbuffer creation error: wglCreateContext() failed");
- }
-
- // FIXME: provide option to not share display lists with subordinate pbuffer?
- if (!WGL.wglShareLists(parentHglrc, hglrc)) {
- throw new GLException("pbuffer: wglShareLists() failed");
- }
- }
-
- protected void destroyImpl() throws GLException {
- if (hglrc != 0) {
- super.destroyImpl();
- // Must release DC and pbuffer
- // NOTE that since the context is not current, glGetError() can
- // not be called here, so we skip the use of any composable
- // pipelines
- GL gl = createGL();
- if (gl.wglReleasePbufferDCARB(buffer, hdc) == 0) {
- throw new GLException("Error releasing pbuffer device context: error code " + WGL.GetLastError());
- }
- hdc = 0;
- if (!gl.wglDestroyPbufferARB(buffer)) {
- throw new GLException("Error destroying pbuffer: error code " + WGL.GetLastError());
- }
- buffer = 0;
- }
- }
-
- public void swapBuffers() throws GLException {
- // FIXME: do we need to do anything if the pbuffer is double-buffered?
- // For now, just grab the pixels for the render-to-texture support.
- if (rtt && !hasRTT) {
- if (DEBUG) {
- System.err.println("Copying pbuffer data to GL_TEXTURE_2D state");
- }
-
- GL gl = getGL();
- gl.glCopyTexSubImage2D(textureTarget, 0, 0, 0, 0, 0, width, height);
- }
- }
-
public int getFloatingPointMode() {
- return floatMode;
+ return drawable.getFloatingPointMode();
}
- private String wglGetLastError() {
- int err = WGL.GetLastError();
- String detail = null;
- switch (err) {
- case WGL.ERROR_INVALID_PIXEL_FORMAT: detail = "ERROR_INVALID_PIXEL_FORMAT"; break;
- case WGL.ERROR_NO_SYSTEM_RESOURCES: detail = "ERROR_NO_SYSTEM_RESOURCES"; break;
- case WGL.ERROR_INVALID_DATA: detail = "ERROR_INVALID_DATA"; break;
- case WGL.ERROR_PROC_NOT_FOUND: detail = "ERROR_PROC_NOT_FOUND"; break;
- case WGL.ERROR_INVALID_WINDOW_HANDLE:detail = "ERROR_INVALID_WINDOW_HANDLE"; break;
- default: detail = "(Unknown error code " + err + ")"; break;
- }
- return detail;
+ private static String wglGetLastError() {
+ return WindowsGLContextFactory.wglGetLastError();
}
}
diff --git a/src/net/java/games/jogl/impl/windows/WindowsPbufferGLDrawable.java b/src/net/java/games/jogl/impl/windows/WindowsPbufferGLDrawable.java
new file mode 100644
index 000000000..6917b281d
--- /dev/null
+++ b/src/net/java/games/jogl/impl/windows/WindowsPbufferGLDrawable.java
@@ -0,0 +1,393 @@
+/*
+ * Copyright (c) 2003 Sun Microsystems, Inc. All Rights Reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * - Redistribution of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * - Redistribution 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 Sun Microsystems, Inc. or the names of
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * This software is provided "AS IS," without a warranty of any kind. ALL
+ * EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND WARRANTIES,
+ * INCLUDING ANY IMPLIED WARRANTY OF MERCHANTABILITY, FITNESS FOR A
+ * PARTICULAR PURPOSE OR NON-INFRINGEMENT, ARE HEREBY EXCLUDED. SUN
+ * MICROSYSTEMS, INC. ("SUN") AND ITS LICENSORS SHALL NOT BE LIABLE FOR
+ * ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF USING, MODIFYING OR
+ * DISTRIBUTING THIS SOFTWARE OR ITS DERIVATIVES. IN NO EVENT WILL SUN OR
+ * ITS LICENSORS BE LIABLE FOR ANY LOST REVENUE, PROFIT OR DATA, OR FOR
+ * DIRECT, INDIRECT, SPECIAL, CONSEQUENTIAL, INCIDENTAL OR PUNITIVE
+ * DAMAGES, HOWEVER CAUSED AND REGARDLESS OF THE THEORY OF LIABILITY,
+ * ARISING OUT OF THE USE OF OR INABILITY TO USE THIS SOFTWARE, EVEN IF
+ * SUN HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.
+ *
+ * You acknowledge that this software is not designed or intended for use
+ * in the design, construction, operation or maintenance of any nuclear
+ * facility.
+ *
+ * Sun gratefully acknowledges that this software was originally authored
+ * and developed by Kenneth Bradley Russell and Christopher John Kline.
+ */
+
+package net.java.games.jogl.impl.windows;
+
+import net.java.games.jogl.*;
+import net.java.games.jogl.impl.*;
+
+public class WindowsPbufferGLDrawable extends WindowsGLDrawable {
+ private int initWidth;
+ private int initHeight;
+
+ private GL cachedGL; // cached GL instance from parent GLCanvas,
+ // needed to destroy pbuffer
+ private long buffer; // pbuffer handle
+ private int width;
+ private int height;
+
+ private int floatMode;
+
+ public WindowsPbufferGLDrawable(GLCapabilities capabilities, int initialWidth, int initialHeight) {
+ super(null, capabilities, null);
+ this.initWidth = initialWidth;
+ this.initHeight = initialHeight;
+ if (initWidth <= 0 || initHeight <= 0) {
+ throw new GLException("Initial width and height of pbuffer must be positive (were (" +
+ initWidth + ", " + initHeight + "))");
+ }
+
+ if (DEBUG) {
+ System.out.println("Pbuffer caps on init: " + capabilities +
+ (capabilities.getOffscreenRenderToTexture() ? " [rtt]" : "") +
+ (capabilities.getOffscreenRenderToTextureRectangle() ? " [rect]" : "") +
+ (capabilities.getOffscreenFloatingPointBuffers() ? " [float]" : ""));
+ }
+ }
+
+ public GLContext createContext(GLContext shareWith) {
+ return new WindowsPbufferGLContext(this, shareWith);
+ }
+
+ public void destroy() {
+ if (hdc != 0) {
+ // Must release DC and pbuffer
+ // NOTE that since the context is not current, glGetError() can
+ // not be called here, so we skip the use of any composable
+ // pipelines (see WindowsOnscreenGLContext.makeCurrentImpl)
+ GL gl = cachedGL;
+ if (gl.wglReleasePbufferDCARB(buffer, hdc) == 0) {
+ throw new GLException("Error releasing pbuffer device context: error code " + WGL.GetLastError());
+ }
+ hdc = 0;
+ if (!gl.wglDestroyPbufferARB(buffer)) {
+ throw new GLException("Error destroying pbuffer: error code " + WGL.GetLastError());
+ }
+ buffer = 0;
+ }
+ }
+
+ public void setSize(int width, int height) {
+ // FIXME
+ throw new GLException("Not yet implemented");
+ }
+
+ public int getWidth() {
+ return width;
+ }
+
+ public int getHeight() {
+ return height;
+ }
+
+ public void createPbuffer(GL gl, long parentHdc) {
+ int[] iattributes = new int [2*MAX_ATTRIBS];
+ float[] fattributes = new float[2*MAX_ATTRIBS];
+ int nfattribs = 0;
+ int niattribs = 0;
+
+ if (DEBUG) {
+ System.out.println("Pbuffer parentHdc = " + toHexString(parentHdc));
+ System.out.println("Pbuffer caps: " + capabilities +
+ (capabilities.getOffscreenRenderToTexture() ? " [rtt]" : "") +
+ (capabilities.getOffscreenRenderToTextureRectangle() ? " [rect]" : "") +
+ (capabilities.getOffscreenFloatingPointBuffers() ? " [float]" : ""));
+ }
+
+ boolean rtt = capabilities.getOffscreenRenderToTexture();
+ boolean rect = capabilities.getOffscreenRenderToTextureRectangle();
+ boolean useFloat = capabilities.getOffscreenFloatingPointBuffers();
+ boolean ati = false;
+
+ // Since we are trying to create a pbuffer, the pixel format we
+ // request (and subsequently use) must be "p-buffer capable".
+ iattributes[niattribs++] = GL.WGL_DRAW_TO_PBUFFER_ARB;
+ iattributes[niattribs++] = GL.GL_TRUE;
+
+ if (rtt && !rect) {
+ throw new GLException("Render-to-texture-rectangle requires render-to-texture to be specified");
+ }
+
+ if (rect) {
+ if (!gl.isExtensionAvailable("GL_NV_texture_rectangle")) {
+ throw new GLException("Render-to-texture-rectangle requires GL_NV_texture_rectangle extension");
+ }
+ }
+
+ if (useFloat) {
+ if (!gl.isExtensionAvailable("WGL_ATI_pixel_format_float") &&
+ !gl.isExtensionAvailable("WGL_NV_float_buffer")) {
+ throw new GLException("Floating-point pbuffers not supported by this hardware");
+ }
+
+ // Prefer NVidia extension over ATI
+ if (gl.isExtensionAvailable("WGL_NV_float_buffer")) {
+ ati = false;
+ floatMode = GLPbuffer.NV_FLOAT;
+ } else {
+ ati = true;
+ floatMode = GLPbuffer.ATI_FLOAT;
+ }
+ if (DEBUG) {
+ System.err.println("Using " + (ati ? "ATI" : "NVidia") + " floating-point extension");
+ }
+ }
+
+ if (useFloat && ati) {
+ if (rtt) {
+ throw new GLException("Render-to-floating-point-texture not supported on ATI hardware");
+ } else {
+ iattributes[niattribs++] = GL.WGL_PIXEL_TYPE_ARB;
+ iattributes[niattribs++] = GL.WGL_TYPE_RGBA_FLOAT_ATI;
+ }
+ } else {
+ if (!rtt) {
+ // Currently we don't support non-truecolor visuals in the
+ // GLCapabilities, so we don't offer the option of making
+ // color-index pbuffers.
+ iattributes[niattribs++] = GL.WGL_PIXEL_TYPE_ARB;
+ iattributes[niattribs++] = GL.WGL_TYPE_RGBA_ARB;
+ }
+ }
+
+ iattributes[niattribs++] = GL.WGL_DOUBLE_BUFFER_ARB;
+ if (capabilities.getDoubleBuffered()) {
+ iattributes[niattribs++] = GL.GL_TRUE;
+ } else {
+ iattributes[niattribs++] = GL.GL_FALSE;
+ }
+
+ iattributes[niattribs++] = GL.WGL_DEPTH_BITS_ARB;
+ iattributes[niattribs++] = capabilities.getDepthBits();
+
+ iattributes[niattribs++] = GL.WGL_RED_BITS_ARB;
+ iattributes[niattribs++] = capabilities.getRedBits();
+
+ iattributes[niattribs++] = GL.WGL_GREEN_BITS_ARB;
+ iattributes[niattribs++] = capabilities.getGreenBits();
+
+ iattributes[niattribs++] = GL.WGL_BLUE_BITS_ARB;
+ iattributes[niattribs++] = capabilities.getBlueBits();
+
+ iattributes[niattribs++] = GL.WGL_ALPHA_BITS_ARB;
+ iattributes[niattribs++] = capabilities.getAlphaBits();
+
+ iattributes[niattribs++] = GL.WGL_STENCIL_BITS_ARB;
+ if (capabilities.getStencilBits() > 0) {
+ iattributes[niattribs++] = GL.GL_TRUE;
+ } else {
+ iattributes[niattribs++] = GL.GL_FALSE;
+ }
+
+ if (capabilities.getAccumRedBits() > 0 ||
+ capabilities.getAccumGreenBits() > 0 ||
+ capabilities.getAccumBlueBits() > 0) {
+ iattributes[niattribs++] = GL.WGL_ACCUM_BITS_ARB;
+ iattributes[niattribs++] = GL.GL_TRUE;
+ }
+
+ if (useFloat && !ati) {
+ iattributes[niattribs++] = GL.WGL_FLOAT_COMPONENTS_NV;
+ iattributes[niattribs++] = GL.GL_TRUE;
+ }
+
+ if (rtt) {
+ if (useFloat) {
+ assert(!ati);
+ if (!rect) {
+ throw new GLException("Render-to-floating-point-texture only supported on NVidia hardware with render-to-texture-rectangle");
+ }
+ iattributes[niattribs++] = GL.WGL_BIND_TO_TEXTURE_RECTANGLE_FLOAT_RGB_NV;
+ iattributes[niattribs++] = GL.GL_TRUE;
+ } else {
+ iattributes[niattribs++] = rect ? GL.WGL_BIND_TO_TEXTURE_RECTANGLE_RGB_NV : GL.WGL_BIND_TO_TEXTURE_RGB_ARB;
+ iattributes[niattribs++] = GL.GL_TRUE;
+ }
+ }
+
+ iattributes[niattribs++] = GL.WGL_SUPPORT_OPENGL_ARB;
+ iattributes[niattribs++] = GL.GL_TRUE;
+
+ int[] pformats = new int[MAX_PFORMATS];
+ int nformats;
+ int[] nformatsTmp = new int[1];
+ if (!gl.wglChoosePixelFormatARB(parentHdc,
+ iattributes, 0,
+ fattributes, 0,
+ MAX_PFORMATS,
+ pformats, 0,
+ nformatsTmp, 0)) {
+ throw new GLException("pbuffer creation error: wglChoosePixelFormatARB() failed");
+ }
+ nformats = nformatsTmp[0];
+ if (nformats <= 0) {
+ throw new GLException("pbuffer creation error: Couldn't find a suitable pixel format");
+ }
+
+ if (DEBUG) {
+ System.err.println("" + nformats + " suitable pixel formats found");
+ // query pixel format
+ iattributes[0] = GL.WGL_RED_BITS_ARB;
+ iattributes[1] = GL.WGL_GREEN_BITS_ARB;
+ iattributes[2] = GL.WGL_BLUE_BITS_ARB;
+ iattributes[3] = GL.WGL_ALPHA_BITS_ARB;
+ iattributes[4] = GL.WGL_DEPTH_BITS_ARB;
+ iattributes[5] = (useFloat ? (ati ? GL.WGL_PIXEL_TYPE_ARB : GL.WGL_FLOAT_COMPONENTS_NV) : GL.WGL_RED_BITS_ARB);
+ iattributes[6] = GL.WGL_SAMPLE_BUFFERS_EXT;
+ iattributes[7] = GL.WGL_SAMPLES_EXT;
+ iattributes[8] = GL.WGL_DRAW_TO_PBUFFER_ARB;
+ int[] ivalues = new int[9];
+ for (int i = 0; i < nformats; i++) {
+ if (!gl.wglGetPixelFormatAttribivARB(parentHdc, pformats[i], 0, 9, iattributes, 0, ivalues, 0)) {
+ throw new GLException("Error while querying pixel format " + pformats[i] +
+ "'s (index " + i + "'s) capabilities for debugging");
+ }
+ System.err.print("pixel format " + pformats[i] + " (index " + i + "): ");
+ System.err.print( "r: " + ivalues[0]);
+ System.err.print(" g: " + ivalues[1]);
+ System.err.print(" b: " + ivalues[2]);
+ System.err.print(" a: " + ivalues[3]);
+ System.err.print(" depth: " + ivalues[4]);
+ System.err.print(" multisample: " + ivalues[6]);
+ System.err.print(" samples: " + ivalues[7]);
+ if (useFloat) {
+ if (ati) {
+ if (ivalues[5] == GL.WGL_TYPE_RGBA_FLOAT_ATI) {
+ System.err.print(" [ati float]");
+ } else if (ivalues[5] != GL.WGL_TYPE_RGBA_ARB) {
+ System.err.print(" [unknown pixel type " + ivalues[5] + "]");
+ }
+ } else {
+ if (ivalues[5] != 0) {
+ System.err.print(" [float]");
+ }
+ }
+ }
+
+ if (ivalues[8] != 0) {
+ System.err.print(" [pbuffer]");
+ }
+ System.err.println();
+ }
+ }
+
+ long tmpBuffer = 0;
+ int whichFormat = 0;
+ // Loop is a workaround for bugs in NVidia's recent drivers
+ do {
+ int format = pformats[whichFormat];
+
+ // Create the p-buffer.
+ niattribs = 0;
+
+ if (rtt) {
+ iattributes[niattribs++] = GL.WGL_TEXTURE_FORMAT_ARB;
+ if (useFloat) {
+ iattributes[niattribs++] = GL.WGL_TEXTURE_FLOAT_RGB_NV;
+ } else {
+ iattributes[niattribs++] = GL.WGL_TEXTURE_RGBA_ARB;
+ }
+
+ iattributes[niattribs++] = GL.WGL_TEXTURE_TARGET_ARB;
+ iattributes[niattribs++] = rect ? GL.WGL_TEXTURE_RECTANGLE_NV : GL.WGL_TEXTURE_2D_ARB;
+
+ iattributes[niattribs++] = GL.WGL_MIPMAP_TEXTURE_ARB;
+ iattributes[niattribs++] = GL.GL_FALSE;
+
+ iattributes[niattribs++] = GL.WGL_PBUFFER_LARGEST_ARB;
+ iattributes[niattribs++] = GL.GL_FALSE;
+ }
+
+ iattributes[niattribs++] = 0;
+
+ tmpBuffer = gl.wglCreatePbufferARB(parentHdc, format, initWidth, initHeight, iattributes, 0);
+ ++whichFormat;
+ } while ((tmpBuffer == 0) && (whichFormat < nformats));
+
+ if (tmpBuffer == 0) {
+ throw new GLException("pbuffer creation error: wglCreatePbufferARB() failed: tried " + nformats +
+ " pixel formats, last error was: " + wglGetLastError());
+ }
+
+ // Get the device context.
+ long tmpHdc = gl.wglGetPbufferDCARB(tmpBuffer);
+ if (tmpHdc == 0) {
+ throw new GLException("pbuffer creation error: wglGetPbufferDCARB() failed");
+ }
+
+ // Set up instance variables
+ buffer = tmpBuffer;
+ hdc = tmpHdc;
+ cachedGL = gl;
+
+ // Determine the actual width and height we were able to create.
+ int[] tmp = new int[1];
+ gl.wglQueryPbufferARB( buffer, GL.WGL_PBUFFER_WIDTH_ARB, tmp, 0 );
+ width = tmp[0];
+ gl.wglQueryPbufferARB( buffer, GL.WGL_PBUFFER_HEIGHT_ARB, tmp, 0 );
+ height = tmp[0];
+
+ if (DEBUG) {
+ System.err.println("Created pbuffer " + width + " x " + height);
+ }
+ }
+
+ public GLCapabilities getCapabilities() {
+ return capabilities;
+ }
+
+ public long getPbuffer() {
+ return buffer;
+ }
+
+ public int getFloatingPointMode() {
+ return floatMode;
+ }
+
+ public void swapBuffers() throws GLException {
+ // FIXME: this doesn't make sense any more because we don't have
+ // access to our OpenGL context here
+ /*
+ // FIXME: do we need to do anything if the pbuffer is double-buffered?
+ // For now, just grab the pixels for the render-to-texture support.
+ if (rtt && !hasRTT) {
+ if (DEBUG) {
+ System.err.println("Copying pbuffer data to GL_TEXTURE_2D state");
+ }
+
+ GL gl = getGL();
+ gl.glCopyTexSubImage2D(textureTarget, 0, 0, 0, 0, 0, width, height);
+ }
+ */
+ }
+
+ private static String wglGetLastError() {
+ return WindowsGLContextFactory.wglGetLastError();
+ }
+}