summaryrefslogtreecommitdiffstats
path: root/src/jogl/classes/jogamp/opengl/windows
diff options
context:
space:
mode:
Diffstat (limited to 'src/jogl/classes/jogamp/opengl/windows')
-rw-r--r--src/jogl/classes/jogamp/opengl/windows/wgl/WGLGLCapabilities.java243
-rw-r--r--src/jogl/classes/jogamp/opengl/windows/wgl/WindowsBitmapWGLContext.java64
-rw-r--r--src/jogl/classes/jogamp/opengl/windows/wgl/WindowsBitmapWGLDrawable.java175
-rw-r--r--src/jogl/classes/jogamp/opengl/windows/wgl/WindowsDummyWGLDrawable.java171
-rw-r--r--src/jogl/classes/jogamp/opengl/windows/wgl/WindowsExternalWGLContext.java142
-rw-r--r--src/jogl/classes/jogamp/opengl/windows/wgl/WindowsExternalWGLDrawable.java92
-rw-r--r--src/jogl/classes/jogamp/opengl/windows/wgl/WindowsOnscreenWGLContext.java53
-rw-r--r--src/jogl/classes/jogamp/opengl/windows/wgl/WindowsOnscreenWGLDrawable.java56
-rw-r--r--src/jogl/classes/jogamp/opengl/windows/wgl/WindowsPbufferWGLContext.java147
-rw-r--r--src/jogl/classes/jogamp/opengl/windows/wgl/WindowsPbufferWGLDrawable.java265
-rw-r--r--src/jogl/classes/jogamp/opengl/windows/wgl/WindowsWGLContext.java478
-rw-r--r--src/jogl/classes/jogamp/opengl/windows/wgl/WindowsWGLDrawable.java107
-rw-r--r--src/jogl/classes/jogamp/opengl/windows/wgl/WindowsWGLDrawableFactory.java512
-rw-r--r--src/jogl/classes/jogamp/opengl/windows/wgl/WindowsWGLDynamicLibraryBundleInfo.java58
-rw-r--r--src/jogl/classes/jogamp/opengl/windows/wgl/WindowsWGLGraphicsConfiguration.java699
-rw-r--r--src/jogl/classes/jogamp/opengl/windows/wgl/WindowsWGLGraphicsConfigurationFactory.java477
-rw-r--r--src/jogl/classes/jogamp/opengl/windows/wgl/awt/WindowsAWTWGLGraphicsConfigurationFactory.java173
17 files changed, 3912 insertions, 0 deletions
diff --git a/src/jogl/classes/jogamp/opengl/windows/wgl/WGLGLCapabilities.java b/src/jogl/classes/jogamp/opengl/windows/wgl/WGLGLCapabilities.java
new file mode 100644
index 000000000..b5be4bf8d
--- /dev/null
+++ b/src/jogl/classes/jogamp/opengl/windows/wgl/WGLGLCapabilities.java
@@ -0,0 +1,243 @@
+/**
+ * Copyright 2010 JogAmp Community. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without modification, are
+ * permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice, this list of
+ * conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright notice, this list
+ * of conditions and the following disclaimer in the documentation and/or other materials
+ * provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY JogAmp Community ``AS IS'' AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
+ * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL JogAmp Community OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
+ * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * The views and conclusions contained in the software and documentation are those of the
+ * authors and should not be interpreted as representing official policies, either expressed
+ * or implied, of JogAmp Community.
+ */
+
+package com.jogamp.opengl.impl.windows.wgl;
+
+import java.util.Comparator;
+
+import com.jogamp.nativewindow.impl.windows.GDI;
+import com.jogamp.nativewindow.impl.windows.PIXELFORMATDESCRIPTOR;
+import javax.media.opengl.GL;
+import javax.media.opengl.GLCapabilities;
+import javax.media.opengl.GLException;
+import javax.media.opengl.GLProfile;
+
+public class WGLGLCapabilities extends GLCapabilities {
+ PIXELFORMATDESCRIPTOR pfd;
+ int pfdID;
+ int arb_pixelformat; // -1 PFD, 0 NOP, 1 ARB
+
+ /** Comparing pfd id only */
+ public static class PfdIDComparator implements Comparator {
+
+ public int compare(Object o1, Object o2) {
+ if ( ! ( o1 instanceof WGLGLCapabilities ) ) {
+ Class c = (null != o1) ? o1.getClass() : null ;
+ throw new ClassCastException("arg1 not a WGLGLCapabilities object: " + c);
+ }
+ if ( ! ( o2 instanceof WGLGLCapabilities ) ) {
+ Class c = (null != o2) ? o2.getClass() : null ;
+ throw new ClassCastException("arg2 not a WGLGLCapabilities object: " + c);
+ }
+
+ final WGLGLCapabilities caps1 = (WGLGLCapabilities) o1;
+ final long id1 = caps1.getPFDID();
+
+ final WGLGLCapabilities caps2 = (WGLGLCapabilities) o2;
+ final long id2 = caps2.getPFDID();
+
+ if(id1 > id2) {
+ return 1;
+ } else if(id1 < id2) {
+ return -1;
+ }
+ return 0;
+ }
+ }
+
+ public WGLGLCapabilities(PIXELFORMATDESCRIPTOR pfd, int pfdID, GLProfile glp) {
+ super(glp);
+ this.pfd = pfd;
+ this.pfdID = pfdID;
+ this.arb_pixelformat = 0;
+ }
+
+ public boolean setValuesByGDI() {
+ arb_pixelformat = -1;
+
+ setRedBits(pfd.getCRedBits());
+ setGreenBits(pfd.getCGreenBits());
+ setBlueBits(pfd.getCBlueBits());
+ setAlphaBits(pfd.getCAlphaBits());
+ setAccumRedBits(pfd.getCAccumRedBits());
+ setAccumGreenBits(pfd.getCAccumGreenBits());
+ setAccumBlueBits(pfd.getCAccumBlueBits());
+ setAccumAlphaBits(pfd.getCAccumAlphaBits());
+ setDepthBits(pfd.getCDepthBits());
+ setStencilBits(pfd.getCStencilBits());
+ setDoubleBuffered((pfd.getDwFlags() & GDI.PFD_DOUBLEBUFFER) != 0);
+ setStereo((pfd.getDwFlags() & GDI.PFD_STEREO) != 0);
+ setHardwareAccelerated((pfd.getDwFlags() & GDI.PFD_GENERIC_FORMAT) == 0
+ || (pfd.getDwFlags() & GDI.PFD_GENERIC_ACCELERATED) != 0);
+ // n/a with non ARB/GDI method:
+ // multisample
+ // opaque
+ // pbuffer
+
+ return true;
+ }
+
+ public boolean setValuesByARB(final int[] iattribs, final int niattribs, final int[] iresults) {
+ arb_pixelformat = 1;
+
+ for (int i = 0; i < niattribs; i++) {
+ int attr = iattribs[i];
+ switch (attr) {
+ case WGLExt.WGL_DRAW_TO_WINDOW_ARB:
+ case WGLExt.WGL_DRAW_TO_BITMAP_ARB:
+ case WGLExt.WGL_DRAW_TO_PBUFFER_ARB:
+ break;
+
+ case WGLExt.WGL_ACCELERATION_ARB:
+ setHardwareAccelerated(iresults[i] == WGLExt.WGL_FULL_ACCELERATION_ARB);
+ break;
+
+ case WGLExt.WGL_SUPPORT_OPENGL_ARB:
+ if (iresults[i] != GL.GL_TRUE) {
+ return false;
+ }
+ break;
+
+ case WGLExt.WGL_DEPTH_BITS_ARB:
+ setDepthBits(iresults[i]);
+ break;
+
+ case WGLExt.WGL_STENCIL_BITS_ARB:
+ setStencilBits(iresults[i]);
+ break;
+
+ case WGLExt.WGL_DOUBLE_BUFFER_ARB:
+ setDoubleBuffered(iresults[i] == GL.GL_TRUE);
+ break;
+
+ case WGLExt.WGL_STEREO_ARB:
+ setStereo(iresults[i] == GL.GL_TRUE);
+ break;
+
+ case WGLExt.WGL_PIXEL_TYPE_ARB:
+ // Fail softly with unknown results here
+ if (iresults[i] == WGLExt.WGL_TYPE_RGBA_ARB ||
+ iresults[i] == WGLExt.WGL_TYPE_RGBA_FLOAT_ARB) {
+ setPbufferFloatingPointBuffers(true);
+ }
+ break;
+
+ case WGLExt.WGL_FLOAT_COMPONENTS_NV:
+ if (iresults[i] != 0) {
+ setPbufferFloatingPointBuffers(true);
+ }
+ break;
+
+ case WGLExt.WGL_RED_BITS_ARB:
+ setRedBits(iresults[i]);
+ break;
+
+ case WGLExt.WGL_GREEN_BITS_ARB:
+ setGreenBits(iresults[i]);
+ break;
+
+ case WGLExt.WGL_BLUE_BITS_ARB:
+ setBlueBits(iresults[i]);
+ break;
+
+ case WGLExt.WGL_ALPHA_BITS_ARB:
+ setAlphaBits(iresults[i]);
+ break;
+
+ case WGLExt.WGL_ACCUM_RED_BITS_ARB:
+ setAccumRedBits(iresults[i]);
+ break;
+
+ case WGLExt.WGL_ACCUM_GREEN_BITS_ARB:
+ setAccumGreenBits(iresults[i]);
+ break;
+
+ case WGLExt.WGL_ACCUM_BLUE_BITS_ARB:
+ setAccumBlueBits(iresults[i]);
+ break;
+
+ case WGLExt.WGL_ACCUM_ALPHA_BITS_ARB:
+ setAccumAlphaBits(iresults[i]);
+ break;
+
+ case WGLExt.WGL_SAMPLE_BUFFERS_ARB:
+ setSampleBuffers(iresults[i] != 0);
+ break;
+
+ case WGLExt.WGL_SAMPLES_ARB:
+ setNumSamples(iresults[i]);
+ break;
+
+ default:
+ throw new GLException("Unknown pixel format attribute " + iattribs[i]);
+ }
+ }
+ return true;
+ }
+
+ public Object cloneMutable() {
+ return clone();
+ }
+
+ public Object clone() {
+ try {
+ return super.clone();
+ } catch (RuntimeException e) {
+ throw new GLException(e);
+ }
+ }
+
+ final public PIXELFORMATDESCRIPTOR getPFD() { return pfd; }
+ final public int getPFDID() { return pfdID; }
+
+ final public boolean isSetByARB() { return 0 < arb_pixelformat; }
+ final public boolean isSetByGDI() { return 0 > arb_pixelformat; }
+ final public boolean isSet() { return 0 != arb_pixelformat; }
+
+ public StringBuffer toString(StringBuffer sink) {
+ if(null == sink) {
+ sink = new StringBuffer();
+ }
+ sink.append(pfdID).append(" ");
+ switch (arb_pixelformat) {
+ case -1:
+ sink.append("gdi");
+ break;
+ case 0:
+ sink.append("nop");
+ break;
+ case 1:
+ sink.append("arb");
+ break;
+ default:
+ throw new InternalError("invalid arb_pixelformat: " + arb_pixelformat);
+ }
+ sink.append(": ");
+ return super.toString(sink);
+ }
+} \ No newline at end of file
diff --git a/src/jogl/classes/jogamp/opengl/windows/wgl/WindowsBitmapWGLContext.java b/src/jogl/classes/jogamp/opengl/windows/wgl/WindowsBitmapWGLContext.java
new file mode 100644
index 000000000..7b769d971
--- /dev/null
+++ b/src/jogl/classes/jogamp/opengl/windows/wgl/WindowsBitmapWGLContext.java
@@ -0,0 +1,64 @@
+/*
+ * Copyright (c) 2003 Sun Microsystems, Inc. All Rights Reserved.
+ * Copyright (c) 2010 JogAmp Community. 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 com.jogamp.opengl.impl.windows.wgl;
+
+import javax.media.opengl.*;
+
+public class WindowsBitmapWGLContext extends WindowsWGLContext {
+ public WindowsBitmapWGLContext(WindowsBitmapWGLDrawable drawable,
+ GLContext shareWith) {
+ super(drawable, shareWith);
+ }
+
+ public int getOffscreenContextPixelDataType() {
+ return GL.GL_UNSIGNED_BYTE;
+ }
+
+ public int getOffscreenContextReadBuffer() {
+ // On Windows these contexts are always single-buffered
+ return GL.GL_FRONT;
+ }
+
+ public boolean offscreenImageNeedsVerticalFlip() {
+ // We can take care of this in the DIB creation (see below)
+ return false;
+ }
+}
diff --git a/src/jogl/classes/jogamp/opengl/windows/wgl/WindowsBitmapWGLDrawable.java b/src/jogl/classes/jogamp/opengl/windows/wgl/WindowsBitmapWGLDrawable.java
new file mode 100644
index 000000000..c61a8d0e4
--- /dev/null
+++ b/src/jogl/classes/jogamp/opengl/windows/wgl/WindowsBitmapWGLDrawable.java
@@ -0,0 +1,175 @@
+/*
+ * Copyright (c) 2003 Sun Microsystems, Inc. All Rights Reserved.
+ * Copyright (c) 2010 JogAmp Community. 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 com.jogamp.opengl.impl.windows.wgl;
+
+import com.jogamp.common.nio.PointerBuffer;
+import javax.media.nativewindow.NativeSurface;
+import javax.media.nativewindow.SurfaceChangeable;
+import javax.media.opengl.GLContext;
+import javax.media.opengl.GLDrawableFactory;
+import javax.media.opengl.GLException;
+
+import com.jogamp.nativewindow.impl.windows.BITMAPINFO;
+import com.jogamp.nativewindow.impl.windows.BITMAPINFOHEADER;
+import com.jogamp.nativewindow.impl.windows.GDI;
+import javax.media.opengl.GLCapabilitiesImmutable;
+
+public class WindowsBitmapWGLDrawable extends WindowsWGLDrawable {
+ private long origbitmap;
+ private long hbitmap;
+
+ protected WindowsBitmapWGLDrawable(GLDrawableFactory factory, NativeSurface target) {
+ super(factory, target, true);
+ create();
+ }
+
+ protected void setRealizedImpl() {
+ if(realized) {
+ create();
+ } else {
+ destroyImpl();
+ }
+ }
+
+ public GLContext createContext(GLContext shareWith) {
+ return new WindowsBitmapWGLContext(this, shareWith);
+ }
+
+ private void create() {
+ int werr;
+ NativeSurface ns = getNativeSurface();
+ if(DEBUG) {
+ System.err.println("WindowsBitmapWGLDrawable (1): "+ns);
+ }
+ WindowsWGLGraphicsConfiguration config = (WindowsWGLGraphicsConfiguration)ns.getGraphicsConfiguration().getNativeGraphicsConfiguration();
+ GLCapabilitiesImmutable capabilities = (GLCapabilitiesImmutable)config.getRequestedCapabilities();
+ int width = getWidth();
+ int height = getHeight();
+
+ //
+ // 1. Create DIB Section
+ //
+ BITMAPINFO info = BITMAPINFO.create();
+ BITMAPINFOHEADER header = info.getBmiHeader();
+ int bitsPerPixel = (capabilities.getRedBits() +
+ capabilities.getGreenBits() +
+ capabilities.getBlueBits() +
+ capabilities.getAlphaBits());
+ header.setBiSize(header.size());
+ header.setBiWidth(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.setBiHeight(-1 * height);
+ header.setBiPlanes((short) 1);
+ header.setBiBitCount((short) bitsPerPixel);
+ header.setBiXPelsPerMeter(0);
+ header.setBiYPelsPerMeter(0);
+ header.setBiClrUsed(0);
+ header.setBiClrImportant(0);
+ header.setBiCompression(GDI.BI_RGB);
+ int byteNum = width * height * ( bitsPerPixel >> 3 ) ;
+ header.setBiSizeImage(byteNum);
+
+ PointerBuffer pb = PointerBuffer.allocateDirect(1);
+ hbitmap = GDI.CreateDIBSection(0, info, GDI.DIB_RGB_COLORS, pb, 0, 0);
+ werr = GDI.GetLastError();
+ if(DEBUG) {
+ long p = ( pb.capacity() > 0 ) ? pb.get(0) : 0;
+ System.err.println("WindowsBitmapWGLDrawable: pb sz/ptr "+pb.capacity() + ", "+toHexString(p));
+ System.err.println("WindowsBitmapWGLDrawable: " + width+"x"+height +
+ ", bpp " + bitsPerPixel +
+ ", bytes " + byteNum +
+ ", header sz " + header.size() +
+ ", DIB ptr num " + pb.capacity()+
+ ", "+capabilities+
+ ", werr "+werr);
+ }
+ if (hbitmap == 0) {
+ throw new GLException("Error creating offscreen bitmap of " + ns + ", werr " + werr);
+ }
+
+ //
+ // 2. Create memory DC (device context) , and associate it with the DIB.
+ //
+ long hdc = GDI.CreateCompatibleDC(0);
+ werr = GDI.GetLastError();
+ if (hdc == 0) {
+ GDI.DeleteObject(hbitmap);
+ hbitmap = 0;
+ throw new GLException("Error creating device context for offscreen OpenGL context, werr "+werr);
+ }
+ ((SurfaceChangeable)ns).setSurfaceHandle(hdc);
+ if(DEBUG) {
+ System.err.println("WindowsBitmapWGLDrawable (2): "+ns);
+ }
+
+ if ((origbitmap = GDI.SelectObject(hdc, hbitmap)) == 0) {
+ GDI.DeleteObject(hbitmap);
+ hbitmap = 0;
+ GDI.DeleteDC(hdc);
+ hdc = 0;
+ throw new GLException("Error selecting bitmap into new device context");
+ }
+
+ config.updateGraphicsConfiguration(getFactory(), ns, null);
+ }
+
+ protected void destroyImpl() {
+ NativeSurface ns = getNativeSurface();
+ if (ns.getSurfaceHandle() != 0) {
+ // Must destroy bitmap and device context
+ GDI.SelectObject(ns.getSurfaceHandle(), origbitmap);
+ GDI.DeleteObject(hbitmap);
+ GDI.DeleteDC(ns.getSurfaceHandle());
+ origbitmap = 0;
+ hbitmap = 0;
+ ((SurfaceChangeable)ns).setSurfaceHandle(0);
+ }
+ }
+
+ protected void swapBuffersImpl() {
+ if(DEBUG) {
+ System.err.println("unhandled swapBuffersImpl() called for: "+this);
+ }
+ }
+
+}
diff --git a/src/jogl/classes/jogamp/opengl/windows/wgl/WindowsDummyWGLDrawable.java b/src/jogl/classes/jogamp/opengl/windows/wgl/WindowsDummyWGLDrawable.java
new file mode 100644
index 000000000..a307e295d
--- /dev/null
+++ b/src/jogl/classes/jogamp/opengl/windows/wgl/WindowsDummyWGLDrawable.java
@@ -0,0 +1,171 @@
+/*
+ * Copyright (c) 2003 Sun Microsystems, Inc. All Rights Reserved.
+ * Copyright (c) 2010 JogAmp Community. 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 com.jogamp.opengl.impl.windows.wgl;
+
+import javax.media.opengl.GLContext;
+import javax.media.opengl.GLDrawableFactory;
+import javax.media.opengl.GLProfile;
+
+import javax.media.nativewindow.AbstractGraphicsScreen;
+import com.jogamp.nativewindow.impl.ProxySurface;
+import com.jogamp.nativewindow.impl.windows.GDI;
+import javax.media.nativewindow.AbstractGraphicsDevice;
+import javax.media.nativewindow.NativeSurface;
+import javax.media.opengl.GLCapabilities;
+import javax.media.opengl.GLCapabilitiesImmutable;
+import javax.media.opengl.GLException;
+
+public class WindowsDummyWGLDrawable extends WindowsWGLDrawable {
+ private static final int f_dim = 64;
+ private long hwnd, hdc;
+
+ protected WindowsDummyWGLDrawable(GLDrawableFactory factory, GLCapabilitiesImmutable caps, AbstractGraphicsScreen absScreen) {
+ super(factory, new ProxySurface(WindowsWGLGraphicsConfigurationFactory.createDefaultGraphicsConfiguration(caps, absScreen)), true);
+ hwnd = GDI.CreateDummyWindow(0, 0, f_dim, f_dim);
+ if(0 == hwnd) {
+ throw new GLException("Error hwnd 0, werr: "+GDI.GetLastError());
+ }
+ // manual debug only - GDI.ShowWindow(hwnd, GDI.SW_SHOW);
+ ProxySurface ns = (ProxySurface) getNativeSurface();
+ ns.setSize(f_dim, f_dim);
+
+ if(NativeSurface.LOCK_SURFACE_NOT_READY >= lockSurface()) {
+ throw new GLException("WindowsDummyWGLDrawable: surface not ready (lockSurface)");
+ }
+ try {
+ WindowsWGLGraphicsConfiguration config = (WindowsWGLGraphicsConfiguration)ns.getGraphicsConfiguration().getNativeGraphicsConfiguration();
+ config.updateGraphicsConfiguration(factory, ns, null);
+ if (DEBUG) {
+ System.err.println("!!! WindowsDummyWGLDrawable: "+config);
+ }
+ } catch (Throwable t) {
+ destroyImpl();
+ throw new GLException(t);
+ } finally {
+ unlockSurface();
+ }
+ }
+
+ public static WindowsDummyWGLDrawable create(GLDrawableFactory factory, GLProfile glp, AbstractGraphicsScreen absScreen) {
+ GLCapabilities caps = new GLCapabilities(glp);
+ caps.setDepthBits(16);
+ caps.setDoubleBuffered(true);
+ caps.setOnscreen (true);
+ return new WindowsDummyWGLDrawable(factory, caps, absScreen);
+ }
+
+ public int lockSurface() throws GLException {
+ int res = NativeSurface.LOCK_SURFACE_NOT_READY;
+ ProxySurface ns = (ProxySurface) getNativeSurface();
+ AbstractGraphicsDevice adevice = ns.getGraphicsConfiguration().getNativeGraphicsConfiguration().getScreen().getDevice();
+ adevice.lock();
+ try {
+ res = ns.lockSurface();
+ if(NativeSurface.LOCK_SUCCESS == res) {
+ if(0 == hdc) {
+ hdc = GDI.GetDC(hwnd);
+ ns.setSurfaceHandle(hdc);
+ if(0 == hdc) {
+ res = NativeSurface.LOCK_SURFACE_NOT_READY;
+ ns.unlockSurface();
+ throw new GLException("Error hdc 0, werr: "+GDI.GetLastError());
+ // finally will unlock adevice
+ }
+ }
+ } else {
+ Throwable t = new Throwable("Error lock failed - res "+res+", hwnd "+toHexString(hwnd)+", hdc "+toHexString(hdc));
+ t.printStackTrace();
+ }
+ } finally {
+ if( NativeSurface.LOCK_SURFACE_NOT_READY == res ) {
+ adevice.unlock();
+ }
+ }
+ return res;
+ }
+
+ public void unlockSurface() {
+ ProxySurface ns = (ProxySurface) getNativeSurface();
+ ns.validateSurfaceLocked();
+ AbstractGraphicsDevice adevice = ns.getGraphicsConfiguration().getNativeGraphicsConfiguration().getScreen().getDevice();
+
+ try {
+ if ( 0 != hdc && 0 != hwnd && ns.getSurfaceRecursionCount() == 0) {
+ GDI.ReleaseDC(hwnd, hdc);
+ hdc=0;
+ ns.setSurfaceHandle(hdc);
+ }
+ surface.unlockSurface();
+ } finally {
+ adevice.unlock();
+ }
+ }
+
+ public void setSize(int width, int height) {
+ }
+
+ public int getWidth() {
+ return 1;
+ }
+
+ public int getHeight() {
+ return 1;
+ }
+
+ public GLContext createContext(GLContext shareWith) {
+ // FIXME: figure out how to hook back in the Java 2D / JOGL bridge
+ return new WindowsWGLContext(this, shareWith);
+ }
+
+ protected void destroyImpl() {
+ if (hdc != 0) {
+ GDI.ReleaseDC(hwnd, hdc);
+ hdc = 0;
+ ProxySurface ns = (ProxySurface) getNativeSurface();
+ ns.setSurfaceHandle(hdc);
+ }
+ if (hwnd != 0) {
+ GDI.ShowWindow(hwnd, GDI.SW_HIDE);
+ GDI.DestroyDummyWindow(hwnd);
+ hwnd = 0;
+ }
+ }
+}
diff --git a/src/jogl/classes/jogamp/opengl/windows/wgl/WindowsExternalWGLContext.java b/src/jogl/classes/jogamp/opengl/windows/wgl/WindowsExternalWGLContext.java
new file mode 100644
index 000000000..cfe0a7899
--- /dev/null
+++ b/src/jogl/classes/jogamp/opengl/windows/wgl/WindowsExternalWGLContext.java
@@ -0,0 +1,142 @@
+/*
+ * Copyright (c) 2003 Sun Microsystems, Inc. All Rights Reserved.
+ * Copyright (c) 2010 JogAmp Community. 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 com.jogamp.opengl.impl.windows.wgl;
+
+import javax.media.nativewindow.AbstractGraphicsScreen;
+import javax.media.nativewindow.DefaultGraphicsScreen;
+import javax.media.nativewindow.NativeSurface;
+import javax.media.nativewindow.NativeWindowFactory;
+import javax.media.opengl.GLContext;
+import javax.media.opengl.GLDrawableFactory;
+import javax.media.opengl.GLException;
+import javax.media.opengl.GLProfile;
+
+import com.jogamp.nativewindow.impl.ProxySurface;
+import com.jogamp.nativewindow.impl.windows.GDI;
+import com.jogamp.opengl.impl.GLContextShareSet;
+
+
+public class WindowsExternalWGLContext extends WindowsWGLContext {
+ private boolean firstMakeCurrent = true;
+ private GLContext lastContext;
+
+ private WindowsExternalWGLContext(Drawable drawable, long ctx, WindowsWGLGraphicsConfiguration cfg) {
+ super(drawable, null);
+ this.contextHandle = ctx;
+ if (DEBUG) {
+ System.err.println(getThreadName() + ": !!! Created external OpenGL context " + toHexString(ctx) + " for " + this);
+ }
+ GLContextShareSet.contextCreated(this);
+ setGLFunctionAvailability(false, 0, 0, CTX_PROFILE_COMPAT|CTX_OPTION_ANY); // use GL_VERSION
+ getGLStateTracker().setEnabled(false); // external context usage can't track state in Java
+ }
+
+ protected static WindowsExternalWGLContext create(GLDrawableFactory factory, GLProfile glp) {
+ long hdc = WGL.wglGetCurrentDC();
+ if (0==hdc) {
+ throw new GLException("Error: attempted to make an external GLDrawable without a drawable current, werr " + GDI.GetLastError());
+ }
+ long ctx = WGL.wglGetCurrentContext();
+ if (ctx == 0) {
+ throw new GLException("Error: attempted to make an external GLContext without a context current, werr " + GDI.GetLastError());
+ }
+ int pfdID = GDI.GetPixelFormat(hdc);
+ if (pfdID == 0) {
+ throw new GLException("Error: attempted to make an external GLContext without a valid pixelformat, werr " + GDI.GetLastError());
+ }
+
+ AbstractGraphicsScreen aScreen = DefaultGraphicsScreen.createDefault(NativeWindowFactory.TYPE_WINDOWS);
+ WindowsWGLGraphicsConfiguration cfg = WindowsWGLGraphicsConfiguration.createFromCurrent(factory, hdc, pfdID, glp, aScreen, true, true);
+ return new WindowsExternalWGLContext(new Drawable(factory, new ProxySurface(cfg, hdc)), ctx, cfg);
+ }
+
+ public int makeCurrent() throws GLException {
+ // Save last context if necessary to allow external GLContexts to
+ // talk to other GLContexts created by this library
+ GLContext cur = getCurrent();
+ if (cur != null && cur != this) {
+ lastContext = cur;
+ setCurrent(null);
+ }
+ return super.makeCurrent();
+ }
+
+ public void release() throws GLException {
+ super.release();
+ setCurrent(lastContext);
+ lastContext = null;
+ }
+
+ protected void makeCurrentImpl(boolean newCreated) throws GLException {
+ if (firstMakeCurrent) {
+ firstMakeCurrent = false;
+ }
+ }
+
+ protected void releaseImpl() throws GLException {
+ }
+
+ protected void destroyImpl() throws GLException {
+ }
+
+ // Need to provide the display connection to extension querying APIs
+ static class Drawable extends WindowsWGLDrawable {
+ Drawable(GLDrawableFactory factory, NativeSurface comp) {
+ super(factory, comp, true);
+ }
+
+ public GLContext createContext(GLContext shareWith) {
+ throw new GLException("Should not call this");
+ }
+
+ public int getWidth() {
+ throw new GLException("Should not call this");
+ }
+
+ public int getHeight() {
+ throw new GLException("Should not call this");
+ }
+
+ public void setSize(int width, int height) {
+ throw new GLException("Should not call this");
+ }
+ }
+}
diff --git a/src/jogl/classes/jogamp/opengl/windows/wgl/WindowsExternalWGLDrawable.java b/src/jogl/classes/jogamp/opengl/windows/wgl/WindowsExternalWGLDrawable.java
new file mode 100644
index 000000000..2851473d5
--- /dev/null
+++ b/src/jogl/classes/jogamp/opengl/windows/wgl/WindowsExternalWGLDrawable.java
@@ -0,0 +1,92 @@
+/*
+ * Copyright (c) 2003 Sun Microsystems, Inc. All Rights Reserved.
+ * Copyright (c) 2010 JogAmp Community. 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 com.jogamp.opengl.impl.windows.wgl;
+
+import javax.media.nativewindow.AbstractGraphicsScreen;
+import javax.media.nativewindow.DefaultGraphicsScreen;
+import javax.media.nativewindow.NativeSurface;
+import javax.media.nativewindow.NativeWindowFactory;
+import javax.media.opengl.GLContext;
+import javax.media.opengl.GLDrawableFactory;
+import javax.media.opengl.GLException;
+import javax.media.opengl.GLProfile;
+
+import com.jogamp.nativewindow.impl.ProxySurface;
+import com.jogamp.nativewindow.impl.windows.GDI;
+
+public class WindowsExternalWGLDrawable extends WindowsWGLDrawable {
+
+ private WindowsExternalWGLDrawable(GLDrawableFactory factory, NativeSurface component) {
+ super(factory, component, true);
+ }
+
+ protected static WindowsExternalWGLDrawable create(GLDrawableFactory factory, GLProfile glp) {
+ long hdc = WGL.wglGetCurrentDC();
+ if (0==hdc) {
+ throw new GLException("Error: attempted to make an external GLDrawable without a drawable current, werr " + GDI.GetLastError());
+ }
+ int pfdID = GDI.GetPixelFormat(hdc);
+ if (pfdID == 0) {
+ throw new GLException("Error: attempted to make an external GLContext without a valid pixelformat, werr " + GDI.GetLastError());
+ }
+
+ AbstractGraphicsScreen aScreen = DefaultGraphicsScreen.createDefault(NativeWindowFactory.TYPE_WINDOWS);
+ WindowsWGLGraphicsConfiguration cfg = WindowsWGLGraphicsConfiguration.createFromCurrent(factory, hdc, pfdID, glp, aScreen, true, true);
+ return new WindowsExternalWGLDrawable(factory, new ProxySurface(cfg, hdc));
+ }
+
+
+ public GLContext createContext(GLContext shareWith) {
+ return new WindowsWGLContext(this, shareWith);
+ }
+
+ public void setSize(int newWidth, int newHeight) {
+ throw new GLException("Should not call this");
+ }
+
+ public int getWidth() {
+ throw new GLException("Should not call this");
+ }
+
+ public int getHeight() {
+ throw new GLException("Should not call this");
+ }
+}
diff --git a/src/jogl/classes/jogamp/opengl/windows/wgl/WindowsOnscreenWGLContext.java b/src/jogl/classes/jogamp/opengl/windows/wgl/WindowsOnscreenWGLContext.java
new file mode 100644
index 000000000..475faeecc
--- /dev/null
+++ b/src/jogl/classes/jogamp/opengl/windows/wgl/WindowsOnscreenWGLContext.java
@@ -0,0 +1,53 @@
+/*
+ * 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 com.jogamp.opengl.impl.windows.wgl;
+
+import java.util.*;
+
+import javax.media.nativewindow.*;
+import javax.media.opengl.*;
+import com.jogamp.opengl.impl.*;
+
+public class WindowsOnscreenWGLContext extends WindowsWGLContext {
+ public WindowsOnscreenWGLContext(WindowsOnscreenWGLDrawable drawable,
+ GLContext shareWith) {
+ super(drawable, shareWith);
+ }
+}
diff --git a/src/jogl/classes/jogamp/opengl/windows/wgl/WindowsOnscreenWGLDrawable.java b/src/jogl/classes/jogamp/opengl/windows/wgl/WindowsOnscreenWGLDrawable.java
new file mode 100644
index 000000000..b0d62a4e1
--- /dev/null
+++ b/src/jogl/classes/jogamp/opengl/windows/wgl/WindowsOnscreenWGLDrawable.java
@@ -0,0 +1,56 @@
+/*
+ * Copyright (c) 2003 Sun Microsystems, Inc. All Rights Reserved.
+ * Copyright (c) 2010 JogAmp Community. 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 com.jogamp.opengl.impl.windows.wgl;
+
+import javax.media.nativewindow.*;
+import javax.media.opengl.*;
+import com.jogamp.opengl.impl.*;
+
+public class WindowsOnscreenWGLDrawable extends WindowsWGLDrawable {
+ protected WindowsOnscreenWGLDrawable(GLDrawableFactory factory, NativeSurface component) {
+ super(factory, component, false);
+ }
+
+ public GLContext createContext(GLContext shareWith) {
+ return new WindowsOnscreenWGLContext(this, shareWith);
+ }
+
+}
diff --git a/src/jogl/classes/jogamp/opengl/windows/wgl/WindowsPbufferWGLContext.java b/src/jogl/classes/jogamp/opengl/windows/wgl/WindowsPbufferWGLContext.java
new file mode 100644
index 000000000..db86b3232
--- /dev/null
+++ b/src/jogl/classes/jogamp/opengl/windows/wgl/WindowsPbufferWGLContext.java
@@ -0,0 +1,147 @@
+/*
+ * 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 com.jogamp.opengl.impl.windows.wgl;
+
+import javax.media.opengl.*;
+import com.jogamp.opengl.impl.*;
+
+public class WindowsPbufferWGLContext extends WindowsWGLContext {
+ // State for render-to-texture and render-to-texture-rectangle support
+ 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
+
+ public WindowsPbufferWGLContext(WindowsPbufferWGLDrawable drawable,
+ GLContext shareWith) {
+ super(drawable, shareWith);
+ }
+
+ public void bindPbufferToTexture() {
+ if (!rtt) {
+ throw new GLException("Shouldn't try to bind a pbuffer to a texture if render-to-texture hasn't been " +
+ "specified in its GLCapabilities");
+ }
+ GL gl = getGL();
+ WGLExt wglExt = getWGLExt();
+ gl.glBindTexture(textureTarget, texture);
+ if (rtt && hasRTT) {
+ if (!wglExt.wglBindTexImageARB(((WindowsPbufferWGLDrawable)drawable).getPbufferHandle(), WGLExt.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().
+ }
+
+ public void releasePbufferFromTexture() {
+ if (!rtt) {
+ throw new GLException("Shouldn't try to bind a pbuffer to a texture if render-to-texture hasn't been " +
+ "specified in its GLCapabilities");
+ }
+ if (rtt && hasRTT) {
+ WGLExt wglExt = getWGLExt();
+ if (!wglExt.wglReleaseTexImageARB(((WindowsPbufferWGLDrawable)drawable).getPbufferHandle(), WGLExt.WGL_FRONT_LEFT_ARB)) {
+ throw new GLException("Releasing of pbuffer from texture failed: " + wglGetLastError());
+ }
+ }
+ }
+
+ protected void makeCurrentImpl(boolean newCreated) throws GLException {
+ super.makeCurrentImpl(newCreated);
+ if (newCreated) {
+ GLCapabilitiesImmutable capabilities = drawable.getChosenGLCapabilities();
+
+ // Initialize render-to-texture support if requested
+ GL gl = getGL();
+ rtt = capabilities.getPbufferRenderToTexture();
+ rect = gl.isGL2GL3() && capabilities.getPbufferRenderToTextureRectangle();
+
+ if (rtt) {
+ if (DEBUG) {
+ System.err.println("Initializing render-to-texture support");
+ }
+
+ if (!gl.isExtensionAvailable("WGL_ARB_render_texture")) {
+ System.err.println("WindowsPbufferWGLContext: WARNING: WGL_ARB_render_texture extension not " +
+ "supported; implementing render_to_texture support using slow texture readback");
+ } else {
+ hasRTT = true;
+
+ if (rect && !gl.isExtensionAvailable("GL_NV_texture_rectangle")) {
+ System.err.println("WindowsPbufferWGLContext: WARNING: GL_NV_texture_rectangle extension not " +
+ "supported; skipping requested render_to_texture_rectangle support for pbuffer");
+ rect = false;
+ }
+ if (rect) {
+ if (DEBUG) {
+ System.err.println(" Using render-to-texture-rectangle");
+ }
+ textureTarget = GL2.GL_TEXTURE_RECTANGLE_ARB;
+ } else {
+ if (DEBUG) {
+ System.err.println(" Using vanilla render-to-texture");
+ }
+ textureTarget = GL.GL_TEXTURE_2D;
+ }
+ int[] tmp = new int[1];
+ gl.glGenTextures(1, tmp, 0);
+ texture = tmp[0];
+ gl.glBindTexture(textureTarget, texture);
+ gl.glTexParameteri(textureTarget, GL.GL_TEXTURE_MIN_FILTER, GL.GL_NEAREST);
+ 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, drawable.getWidth(), drawable.getHeight(), 0);
+ }
+ }
+ }
+ }
+
+ public int getFloatingPointMode() {
+ return ((WindowsPbufferWGLDrawable)drawable).getFloatingPointMode();
+ }
+
+ private static String wglGetLastError() {
+ return WindowsWGLDrawableFactory.wglGetLastError();
+ }
+}
diff --git a/src/jogl/classes/jogamp/opengl/windows/wgl/WindowsPbufferWGLDrawable.java b/src/jogl/classes/jogamp/opengl/windows/wgl/WindowsPbufferWGLDrawable.java
new file mode 100644
index 000000000..a8d37796e
--- /dev/null
+++ b/src/jogl/classes/jogamp/opengl/windows/wgl/WindowsPbufferWGLDrawable.java
@@ -0,0 +1,265 @@
+/*
+ * Copyright (c) 2003 Sun Microsystems, Inc. All Rights Reserved.
+ * Copyright (c) 2010 JogAmp Community. 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 com.jogamp.opengl.impl.windows.wgl;
+
+import javax.media.nativewindow.NativeSurface;
+import javax.media.nativewindow.SurfaceChangeable;
+import javax.media.opengl.GL;
+import javax.media.opengl.GLContext;
+import javax.media.opengl.GLDrawableFactory;
+import javax.media.opengl.GLException;
+import javax.media.opengl.GLPbuffer;
+import javax.media.opengl.GLProfile;
+
+import com.jogamp.nativewindow.impl.windows.GDI;
+import javax.media.opengl.GLCapabilitiesImmutable;
+
+public class WindowsPbufferWGLDrawable extends WindowsWGLDrawable {
+ private WGLExt cachedWGLExt; // cached WGLExt instance from parent GLCanvas,
+ // needed to destroy pbuffer
+ private long buffer; // pbuffer handle
+
+ private int floatMode;
+
+ public WindowsPbufferWGLDrawable(GLDrawableFactory factory, NativeSurface target,
+ WindowsWGLDrawable dummyDrawable,
+ WindowsWGLContext sharedCtx) {
+ super(factory, target, true);
+
+ if (DEBUG) {
+ System.out.println("Pbuffer config: " + getNativeSurface().getGraphicsConfiguration().getNativeGraphicsConfiguration());
+ }
+
+ createPbuffer(dummyDrawable.getNativeSurface().getSurfaceHandle(), sharedCtx);
+
+ if (DEBUG) {
+ System.err.println("Created pbuffer " + this);
+ }
+ }
+
+ protected void setRealizedImpl() {
+ if(realized) {
+ throw new GLException("Recreation via setRealized not supported.");
+ } else {
+ destroyImpl();
+ }
+ }
+
+ public GLContext createContext(GLContext shareWith) {
+ return new WindowsPbufferWGLContext(this, shareWith);
+ }
+
+ protected void destroyImpl() {
+ NativeSurface ns = getNativeSurface();
+ if(0!=buffer) {
+ WGLExt wglExt = cachedWGLExt;
+ if (ns.getSurfaceHandle() != 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 WindowsOnscreenWGLContext.makeCurrentImpl)
+ if (wglExt.wglReleasePbufferDCARB(buffer, ns.getSurfaceHandle()) == 0) {
+ throw new GLException("Error releasing pbuffer device context: error code " + GDI.GetLastError());
+ }
+ ((SurfaceChangeable)ns).setSurfaceHandle(0);
+ }
+ if (!wglExt.wglDestroyPbufferARB(buffer)) {
+ throw new GLException("Error destroying pbuffer: error code " + GDI.GetLastError());
+ }
+ buffer = 0;
+ }
+ }
+
+ public long getPbufferHandle() {
+ // The actual to-be-used handle for makeCurrent etc,
+ // is the derived DC, set in the NativeSurface surfaceHandle
+ // returned by getHandle().
+ return buffer;
+ }
+
+ public int getFloatingPointMode() {
+ return floatMode;
+ }
+
+ protected void swapBuffersImpl() {
+ if(DEBUG) {
+ System.err.println("unhandled swapBuffersImpl() called for: "+this);
+ }
+ }
+
+ private void createPbuffer(long parentHdc, WindowsWGLContext sharedCtx) {
+ int[] iattributes = new int [2*WindowsWGLGraphicsConfiguration.MAX_ATTRIBS];
+ float[] fattributes = new float[1];
+ int[] floatModeTmp = new int[1];
+ int niattribs = 0;
+ int width, height;
+ WGLExt wglExt = sharedCtx.getWGLExt();
+
+ WindowsWGLGraphicsConfiguration config = (WindowsWGLGraphicsConfiguration) getNativeSurface().getGraphicsConfiguration().getNativeGraphicsConfiguration();
+ GLCapabilitiesImmutable chosenCaps = (GLCapabilitiesImmutable)config.getChosenCapabilities();
+ GLProfile glProfile = chosenCaps.getGLProfile();
+
+ if (DEBUG) {
+ System.out.println("Pbuffer parentHdc = " + toHexString(parentHdc));
+ System.out.println("Pbuffer chosenCaps: " + chosenCaps);
+ }
+
+ if(!WindowsWGLGraphicsConfiguration.GLCapabilities2AttribList(chosenCaps,
+ iattributes, sharedCtx, -1, floatModeTmp)){
+ throw new GLException("Pbuffer-related extensions not supported");
+ }
+
+ floatMode = floatModeTmp[0];
+ boolean rtt = chosenCaps.getPbufferRenderToTexture();
+ boolean rect = chosenCaps.getPbufferRenderToTextureRectangle();
+ boolean useFloat = chosenCaps.getPbufferFloatingPointBuffers();
+ boolean ati = false;
+
+ if (useFloat) {
+ ati = (floatMode == GLPbuffer.ATI_FLOAT);
+ }
+
+ int[] pformats = new int[WindowsWGLGraphicsConfiguration.MAX_PFORMATS];
+ int nformats;
+ int[] nformatsTmp = new int[1];
+ if (!wglExt.wglChoosePixelFormatARB(parentHdc,
+ iattributes, 0,
+ fattributes, 0,
+ WindowsWGLGraphicsConfiguration.MAX_PFORMATS,
+ pformats, 0,
+ nformatsTmp, 0)) {
+ throw new GLException("pbuffer creation error: wglChoosePixelFormat() 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");
+ for (int i = 0; i < nformats; i++) {
+ WGLGLCapabilities dbgCaps = WindowsWGLGraphicsConfiguration.wglARBPFID2GLCapabilities(sharedCtx, parentHdc, pformats[i], glProfile, false, true);
+ System.err.println("pixel format " + pformats[i] + " (index " + i + "): " + dbgCaps);
+ }
+ }
+
+ int pfdid = 0;
+ long tmpBuffer = 0;
+ {
+ int whichFormat;
+ // Loop is a workaround for bugs in NVidia's recent drivers
+ for (whichFormat = 0; whichFormat < nformats; whichFormat++) {
+ int format = pformats[whichFormat];
+
+ // Create the p-buffer.
+ niattribs = 0;
+
+ if (rtt) {
+ iattributes[niattribs++] = WGLExt.WGL_TEXTURE_FORMAT_ARB;
+ if (useFloat) {
+ iattributes[niattribs++] = WGLExt.WGL_TEXTURE_FLOAT_RGB_NV;
+ } else {
+ iattributes[niattribs++] = WGLExt.WGL_TEXTURE_RGBA_ARB;
+ }
+
+ iattributes[niattribs++] = WGLExt.WGL_TEXTURE_TARGET_ARB;
+ iattributes[niattribs++] = rect ? WGLExt.WGL_TEXTURE_RECTANGLE_NV : WGLExt.WGL_TEXTURE_2D_ARB;
+
+ iattributes[niattribs++] = WGLExt.WGL_MIPMAP_TEXTURE_ARB;
+ iattributes[niattribs++] = GL.GL_FALSE;
+
+ iattributes[niattribs++] = WGLExt.WGL_PBUFFER_LARGEST_ARB;
+ iattributes[niattribs++] = GL.GL_FALSE;
+ }
+
+ iattributes[niattribs++] = 0;
+
+ tmpBuffer = wglExt.wglCreatePbufferARB(parentHdc, format, getWidth(), getHeight(), iattributes, 0);
+ if (tmpBuffer != 0) {
+ // Done
+ break;
+ }
+ }
+
+ if (0 == tmpBuffer) {
+ throw new GLException("pbuffer creation error: wglCreatePbuffer() failed: tried " + nformats +
+ " pixel formats, last error was: " + wglGetLastError());
+ }
+ pfdid = pformats[whichFormat];
+ }
+
+ // Get the device context.
+ long tmpHdc = wglExt.wglGetPbufferDCARB(tmpBuffer);
+ if (tmpHdc == 0) {
+ throw new GLException("pbuffer creation error: wglGetPbufferDC() failed");
+ }
+
+ NativeSurface ns = getNativeSurface();
+ // Set up instance variables
+ buffer = tmpBuffer;
+ ((SurfaceChangeable)ns).setSurfaceHandle(tmpHdc);
+ cachedWGLExt = wglExt;
+
+ // Re-query chosen pixel format
+ {
+ WGLGLCapabilities newCaps = WindowsWGLGraphicsConfiguration.wglARBPFID2GLCapabilities(sharedCtx, parentHdc, pfdid, glProfile, false, true);
+ if(null == newCaps) {
+ throw new GLException("pbuffer creation error: unable to re-query chosen PFD ID: " + pfdid + ", hdc " + this.toHexString(tmpHdc));
+ }
+ if(newCaps.isOnscreen() || !newCaps.isPBuffer()) {
+ throw new GLException("Error: Selected Onscreen Caps for PBuffer: "+newCaps);
+ }
+ config.setCapsPFD(newCaps);
+ }
+
+ // Determine the actual width and height we were able to create.
+ int[] tmp = new int[1];
+ wglExt.wglQueryPbufferARB( buffer, WGLExt.WGL_PBUFFER_WIDTH_ARB, tmp, 0 );
+ width = tmp[0];
+ wglExt.wglQueryPbufferARB( buffer, WGLExt.WGL_PBUFFER_HEIGHT_ARB, tmp, 0 );
+ height = tmp[0];
+ ((SurfaceChangeable)ns).setSize(width, height);
+ }
+
+ private static String wglGetLastError() {
+ return WindowsWGLDrawableFactory.wglGetLastError();
+ }
+}
diff --git a/src/jogl/classes/jogamp/opengl/windows/wgl/WindowsWGLContext.java b/src/jogl/classes/jogamp/opengl/windows/wgl/WindowsWGLContext.java
new file mode 100644
index 000000000..7d38f8ee8
--- /dev/null
+++ b/src/jogl/classes/jogamp/opengl/windows/wgl/WindowsWGLContext.java
@@ -0,0 +1,478 @@
+/*
+ * Copyright (c) 2003 Sun Microsystems, Inc. All Rights Reserved.
+ * Copyright (c) 2010 JogAmp Community. 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 com.jogamp.opengl.impl.windows.wgl;
+
+import java.nio.ByteBuffer;
+import java.util.HashMap;
+import java.util.Map;
+
+import javax.media.nativewindow.AbstractGraphicsConfiguration;
+import javax.media.nativewindow.AbstractGraphicsDevice;
+import javax.media.opengl.GLContext;
+import javax.media.opengl.GLException;
+import javax.media.opengl.GLCapabilitiesImmutable;
+
+import com.jogamp.gluegen.runtime.ProcAddressTable;
+import com.jogamp.gluegen.runtime.opengl.GLProcAddressResolver;
+import com.jogamp.nativewindow.impl.windows.GDI;
+import com.jogamp.opengl.impl.GLContextImpl;
+import com.jogamp.opengl.impl.GLContextShareSet;
+import com.jogamp.opengl.impl.GLDrawableImpl;
+
+public class WindowsWGLContext extends GLContextImpl {
+ static final Map/*<String, String>*/ functionNameMap;
+ static final Map/*<String, String>*/ extensionNameMap;
+ private boolean wglGetExtensionsStringEXTInitialized;
+ private boolean wglGetExtensionsStringEXTAvailable;
+ private boolean wglGLReadDrawableAvailableSet;
+ private boolean wglGLReadDrawableAvailable;
+ private WGLExt wglExt;
+ // Table that holds the addresses of the native C-language entry points for
+ // WGL extension functions.
+ private WGLExtProcAddressTable wglExtProcAddressTable;
+
+ static {
+ functionNameMap = new HashMap();
+ functionNameMap.put("glAllocateMemoryNV", "wglAllocateMemoryNV");
+ functionNameMap.put("glFreeMemoryNV", "wglFreeMemoryNV");
+
+ extensionNameMap = new HashMap();
+ extensionNameMap.put("GL_ARB_pbuffer", "WGL_ARB_pbuffer");
+ extensionNameMap.put("GL_ARB_pixel_format", "WGL_ARB_pixel_format");
+ }
+
+ // FIXME: figure out how to hook back in the Java 2D / JOGL bridge
+ WindowsWGLContext(GLDrawableImpl drawable,
+ GLContext shareWith) {
+ super(drawable, shareWith);
+ }
+
+ protected void resetState() {
+ wglGetExtensionsStringEXTInitialized=false;
+ wglGetExtensionsStringEXTAvailable=false;
+ wglGLReadDrawableAvailableSet=false;
+ wglGLReadDrawableAvailable=false;
+ // no inner state _wglExt=null;
+ wglExtProcAddressTable=null;
+ }
+
+ public Object getPlatformGLExtensions() {
+ return getWGLExt();
+ }
+
+ /* package private */ final WGLExt getWGLExt() {
+ if( null == getWGLExtProcAddressTable()) {
+ throw new InternalError("Null WGLExtProcAddressTable");
+ }
+ if (wglExt == null) {
+ wglExt = new WGLExtImpl(this);
+ }
+ return wglExt;
+ }
+
+ public final boolean isGLReadDrawableAvailable() {
+ if(!wglGLReadDrawableAvailableSet && null != getWGLExtProcAddressTable()) {
+ WindowsWGLDrawableFactory factory = (WindowsWGLDrawableFactory)drawable.getFactoryImpl();
+ AbstractGraphicsConfiguration config = drawable.getNativeSurface().getGraphicsConfiguration().getNativeGraphicsConfiguration();
+ AbstractGraphicsDevice device = config.getScreen().getDevice();
+ switch( factory.isReadDrawableAvailable(device) ) {
+ case 1:
+ wglGLReadDrawableAvailable = true;
+ wglGLReadDrawableAvailableSet=true;
+ break;
+ case 0:
+ wglGLReadDrawableAvailable = false;
+ wglGLReadDrawableAvailableSet=true;
+ break;
+ }
+ }
+ return wglGLReadDrawableAvailable;
+ }
+
+ private final boolean wglMakeContextCurrent(long hDrawDC, long hReadDC, long ctx) {
+ boolean ok = false;
+ if(wglGLReadDrawableAvailable) {
+ // needs initilized WGL ProcAddress table
+ ok = getWGLExt().wglMakeContextCurrent(hDrawDC, hReadDC, ctx);
+ } else if ( hDrawDC == hReadDC ) {
+ ok = WGL.wglMakeCurrent(hDrawDC, ctx);
+ } else {
+ // should not happen due to 'isGLReadDrawableAvailable()' query in GLContextImpl
+ throw new InternalError("Given readDrawable but no driver support");
+ }
+ int werr = ( !ok ) ? GDI.GetLastError() : GDI.ERROR_SUCCESS;
+ if(DEBUG && !ok) {
+ Throwable t = new Throwable ("Info: wglMakeContextCurrent draw "+
+ this.toHexString(hDrawDC) + ", read " + this.toHexString(hReadDC) +
+ ", ctx " + this.toHexString(ctx) + ", werr " + werr);
+ t.printStackTrace();
+ }
+ if(!ok && 0==hDrawDC && 0==hReadDC) {
+ // Some GPU's falsely fails with a zero error code (success),
+ // in case this is a release context request we tolerate this
+ return werr == GDI.ERROR_SUCCESS ;
+ }
+ return ok;
+ }
+
+ public final ProcAddressTable getPlatformExtProcAddressTable() {
+ return getWGLExtProcAddressTable();
+ }
+
+ public final WGLExtProcAddressTable getWGLExtProcAddressTable() {
+ return wglExtProcAddressTable;
+ }
+
+ protected Map/*<String, String>*/ getFunctionNameMap() { return functionNameMap; }
+
+ protected Map/*<String, String>*/ getExtensionNameMap() { return extensionNameMap; }
+
+ protected void destroyContextARBImpl(long context) {
+ WGL.wglMakeCurrent(0, 0);
+ WGL.wglDeleteContext(context);
+ }
+
+ protected long createContextARBImpl(long share, boolean direct, int ctp, int major, int minor) {
+ if( null == getWGLExtProcAddressTable()) {
+ updateGLXProcAddressTable();
+ }
+ WGLExt _wglExt = getWGLExt();
+ if(DEBUG) {
+ System.err.println(getThreadName()+" - WindowWGLContext.createContextARBImpl: "+getGLVersion(major, minor, ctp, "@creation") +
+ ", handle "+toHexString(drawable.getHandle()) + ", share "+toHexString(share)+", direct "+direct+
+ ", wglCreateContextAttribsARB: "+toHexString(wglExtProcAddressTable._addressof_wglCreateContextAttribsARB));
+ Thread.dumpStack();
+ }
+
+ boolean ctBwdCompat = 0 != ( CTX_PROFILE_COMPAT & ctp ) ;
+ boolean ctFwdCompat = 0 != ( CTX_OPTION_FORWARD & ctp ) ;
+ boolean ctDebug = 0 != ( CTX_OPTION_DEBUG & ctp ) ;
+
+ long ctx=0;
+
+ final int idx_flags = 4;
+ final int idx_profile = 6;
+
+ /* WGLExt.WGL_CONTEXT_LAYER_PLANE_ARB, WGLExt.WGL_CONTEXT_LAYER_PLANE_ARB, */
+
+ int attribs[] = {
+ /* 0 */ WGLExt.WGL_CONTEXT_MAJOR_VERSION_ARB, major,
+ /* 2 */ WGLExt.WGL_CONTEXT_MINOR_VERSION_ARB, minor,
+ /* 4 */ WGLExt.WGL_CONTEXT_FLAGS_ARB, 0,
+ /* 6 */ 0, 0,
+ /* 8 */ 0
+ };
+
+ if ( major > 3 || major == 3 && minor >= 2 ) {
+ // FIXME: Verify with a None drawable binding (default framebuffer)
+ attribs[idx_profile+0] = WGLExt.WGL_CONTEXT_PROFILE_MASK_ARB;
+ if( ctBwdCompat ) {
+ attribs[idx_profile+1] = WGLExt.WGL_CONTEXT_COMPATIBILITY_PROFILE_BIT_ARB;
+ } else {
+ attribs[idx_profile+1] = WGLExt.WGL_CONTEXT_CORE_PROFILE_BIT_ARB;
+ }
+ }
+
+ if ( major >= 3 ) {
+ if( !ctBwdCompat && ctFwdCompat ) {
+ attribs[idx_flags+1] |= WGLExt.WGL_CONTEXT_FORWARD_COMPATIBLE_BIT_ARB;
+ }
+ if( ctDebug) {
+ attribs[idx_flags+1] |= WGLExt.WGL_CONTEXT_DEBUG_BIT_ARB;
+ }
+ }
+
+ try {
+ ctx = _wglExt.wglCreateContextAttribsARB(drawable.getHandle(), share, attribs, 0);
+ } catch (RuntimeException re) {
+ if(DEBUG) {
+ Throwable t = new Throwable("Info: WindowWGLContext.createContextARBImpl wglCreateContextAttribsARB failed with "+getGLVersion(major, minor, ctp, "@creation"), re);
+ t.printStackTrace();
+ }
+ }
+
+ if(0!=ctx) {
+ if (!wglMakeContextCurrent(drawable.getHandle(), drawableRead.getHandle(), ctx)) {
+ if(DEBUG) {
+ System.err.println("WindowsWGLContext.createContextARB couldn't make current "+getGLVersion(major, minor, ctp, "@creation"));
+ }
+ WGL.wglMakeCurrent(0, 0);
+ WGL.wglDeleteContext(ctx);
+ ctx = 0;
+ } else {
+ if (DEBUG) {
+ System.err.println(getThreadName() + ": createContextARBImpl: OK "+getGLVersion(major, minor, ctp, "@creation")+", share "+share+", direct "+direct);
+ }
+ // the following is issued by the caller 'GLContextImpl.createContextARB()'
+ // setGLFunctionAvailability(true, major, minor, ctp);
+ }
+ } else if (DEBUG) {
+ System.err.println(getThreadName() + ": createContextARBImpl: NO "+getGLVersion(major, minor, ctp, "@creation"));
+ }
+ return ctx;
+ }
+
+ /**
+ * Creates and initializes an appropriate OpenGL context. Should only be
+ * called by {@link #makeCurrentImpl()}.
+ */
+ protected boolean createImpl() {
+ WindowsWGLDrawableFactory factory = (WindowsWGLDrawableFactory)drawable.getFactoryImpl();
+ AbstractGraphicsConfiguration config = drawable.getNativeSurface().getGraphicsConfiguration().getNativeGraphicsConfiguration();
+ AbstractGraphicsDevice device = config.getScreen().getDevice();
+ WindowsWGLContext sharedContext = (WindowsWGLContext) factory.getOrCreateSharedContextImpl(device);
+ GLCapabilitiesImmutable glCaps = drawable.getChosenGLCapabilities();
+
+ isGLReadDrawableAvailable(); // trigger setup wglGLReadDrawableAvailable
+
+ // Windows can set up sharing of display lists after creation time
+ WindowsWGLContext other = (WindowsWGLContext) GLContextShareSet.getShareContext(this);
+ long share = 0;
+ if (other != null) {
+ share = other.getHandle();
+ if (share == 0) {
+ throw new GLException("GLContextShareSet returned an invalid OpenGL context");
+ }
+ }
+
+ int minor[] = new int[1];
+ int major[] = new int[1];
+ int ctp[] = new int[1];
+ boolean createContextARBTried = false;
+
+ // utilize the shared context's GLXExt in case it was using the ARB method and it already exists
+ if( null!=sharedContext && sharedContext.isCreatedWithARBMethod() ) {
+ contextHandle = createContextARB(share, true, major, minor, ctp);
+ createContextARBTried = true;
+ if (DEBUG && 0!=contextHandle) {
+ System.err.println(getThreadName() + ": createImpl: OK (ARB, using sharedContext) share "+share);
+ }
+ }
+
+ long temp_ctx = 0;
+ if(0==contextHandle) {
+ // To use WGL_ARB_create_context, we have to make a temp context current,
+ // so we are able to use GetProcAddress
+ temp_ctx = WGL.wglCreateContext(drawable.getHandle());
+ if (temp_ctx == 0) {
+ throw new GLException("Unable to create temp OpenGL context for device context " + toHexString(drawable.getHandle()));
+ }
+ if (!WGL.wglMakeCurrent(drawable.getHandle(), temp_ctx)) {
+ throw new GLException("Error making temp context current: 0x" + toHexString(temp_ctx) + ", werr: "+GDI.GetLastError());
+ }
+ setGLFunctionAvailability(true, 0, 0, CTX_PROFILE_COMPAT|CTX_OPTION_ANY); // use GL_VERSION
+ boolean isCreateContextAttribsARBAvailable = isFunctionAvailable("wglCreateContextAttribsARB");
+ WGL.wglMakeCurrent(0, 0); // release temp context
+
+ if( !createContextARBTried) {
+ if(isCreateContextAttribsARBAvailable &&
+ isExtensionAvailable("WGL_ARB_create_context") ) {
+ // initial ARB context creation
+ contextHandle = createContextARB(share, true, major, minor, ctp);
+ createContextARBTried=true;
+ if (DEBUG) {
+ if(0!=contextHandle) {
+ System.err.println(getThreadName() + ": createContextImpl: OK (ARB, initial) share "+share);
+ } else {
+ System.err.println(getThreadName() + ": createContextImpl: NOT OK (ARB, initial) - creation failed - share "+share);
+ }
+ }
+ } else if (DEBUG) {
+ System.err.println(getThreadName() + ": createContextImpl: NOT OK (ARB, initial) - extension not available - share "+share);
+ }
+ }
+ }
+
+ if(0!=contextHandle) {
+ share = 0; // mark as shared thx to the ARB create method
+ if(0!=temp_ctx) {
+ WGL.wglMakeCurrent(0, 0);
+ WGL.wglDeleteContext(temp_ctx);
+ if (!wglMakeContextCurrent(drawable.getHandle(), drawableRead.getHandle(), contextHandle)) {
+ throw new GLException("Cannot make previous verified context current: 0x" + toHexString(contextHandle) + ", werr: " + GDI.GetLastError());
+ }
+ }
+ } else {
+ if(glCaps.getGLProfile().isGL3()) {
+ WGL.wglMakeCurrent(0, 0);
+ WGL.wglDeleteContext(temp_ctx);
+ throw new GLException("WindowsWGLContext.createContext failed, but context > GL2 requested "+getGLVersion(major[0], minor[0], ctp[0], "@creation")+", ");
+ }
+ if(DEBUG) {
+ System.err.println("WindowsWGLContext.createContext failed, fall back to !ARB context "+getGLVersion(major[0], minor[0], ctp[0], "@creation"));
+ }
+
+ // continue with temp context for GL < 3.0
+ contextHandle = temp_ctx;
+ if (!wglMakeContextCurrent(drawable.getHandle(), drawableRead.getHandle(), contextHandle)) {
+ WGL.wglMakeCurrent(0, 0);
+ WGL.wglDeleteContext(contextHandle);
+ throw new GLException("Error making old context current: 0x" + toHexString(contextHandle) + ", werr: " + GDI.GetLastError());
+ }
+ if (DEBUG) {
+ System.err.println(getThreadName() + ": createImpl: OK (old) share "+share);
+ }
+ }
+
+ if(0!=share) {
+ if (!WGL.wglShareLists(share, contextHandle)) {
+ throw new GLException("wglShareLists(" + toHexString(share) +
+ ", " + toHexString(contextHandle) + ") failed: werr " + GDI.GetLastError());
+ }
+ }
+ return true;
+ }
+
+ protected void makeCurrentImpl(boolean newCreated) throws GLException {
+ if (WGL.wglGetCurrentContext() != contextHandle) {
+ if (!wglMakeContextCurrent(drawable.getHandle(), drawableRead.getHandle(), contextHandle)) {
+ throw new GLException("Error making context current: 0x" + toHexString(contextHandle) + ", werr: " + GDI.GetLastError() + ", " + this);
+ } else {
+ if (DEBUG && newCreated) {
+ System.err.println(getThreadName() + ": wglMakeCurrent(hdc " + toHexString(drawable.getHandle()) +
+ ", contextHandle " + toHexString(contextHandle) + ") succeeded");
+ }
+ }
+ }
+ }
+
+ protected void releaseImpl() throws GLException {
+ if (!wglMakeContextCurrent(0, 0, 0)) {
+ throw new GLException("Error freeing OpenGL context, werr: " + GDI.GetLastError());
+ }
+ }
+
+ protected void destroyImpl() throws GLException {
+ WGL.wglMakeCurrent(0, 0);
+ if (!WGL.wglDeleteContext(contextHandle)) {
+ throw new GLException("Unable to delete OpenGL context");
+ }
+ }
+
+ protected void copyImpl(GLContext source, int mask) throws GLException {
+ if (!WGL.wglCopyContext(source.getHandle(), getHandle(), mask)) {
+ throw new GLException("wglCopyContext failed");
+ }
+ }
+
+ protected final void updateGLXProcAddressTable() {
+ AbstractGraphicsConfiguration aconfig = drawable.getNativeSurface().getGraphicsConfiguration().getNativeGraphicsConfiguration();
+ AbstractGraphicsDevice adevice = aconfig.getScreen().getDevice();
+ String key = adevice.getUniqueID();
+ if (DEBUG) {
+ System.err.println(getThreadName() + ": !!! Initializing WGL extension address table: "+key);
+ }
+ wglGetExtensionsStringEXTInitialized=false;
+ wglGetExtensionsStringEXTAvailable=false;
+ wglGLReadDrawableAvailableSet=false;
+ wglGLReadDrawableAvailable=false;
+
+ WGLExtProcAddressTable table = null;
+ synchronized(mappedContextTypeObjectLock) {
+ table = (WGLExtProcAddressTable) mappedGLXProcAddress.get( key );
+ }
+ if(null != table) {
+ wglExtProcAddressTable = table;
+ if(DEBUG) {
+ System.err.println(getThreadName() + ": !!! GLContext WGL ProcAddressTable reusing key("+key+") -> "+table.hashCode());
+ }
+ } else {
+ if (wglExtProcAddressTable == null) {
+ // FIXME: cache ProcAddressTables by OpenGL context type bits so we can
+ // share them among contexts classes (GL4, GL4bc, GL3, GL3bc, ..)
+ wglExtProcAddressTable = new WGLExtProcAddressTable(new GLProcAddressResolver());
+ }
+ resetProcAddressTable(wglExtProcAddressTable);
+ synchronized(mappedContextTypeObjectLock) {
+ mappedGLXProcAddress.put(key, getWGLExtProcAddressTable());
+ if(DEBUG) {
+ System.err.println(getThreadName() + ": !!! GLContext WGL ProcAddressTable mapping key("+key+") -> "+getWGLExtProcAddressTable().hashCode());
+ }
+ }
+ }
+ }
+
+ public String getPlatformExtensionsString() {
+ if (!wglGetExtensionsStringEXTInitialized) {
+ wglGetExtensionsStringEXTAvailable = (WGL.wglGetProcAddress("wglGetExtensionsStringEXT") != 0);
+ wglGetExtensionsStringEXTInitialized = true;
+ }
+ if (wglGetExtensionsStringEXTAvailable) {
+ return getWGLExt().wglGetExtensionsStringEXT();
+ } else {
+ return "";
+ }
+ }
+
+ protected void setSwapIntervalImpl(int interval) {
+ WGLExt wglExt = getWGLExt();
+ if (wglExt.isExtensionAvailable("WGL_EXT_swap_control")) {
+ if ( wglExt.wglSwapIntervalEXT(interval) ) {
+ currentSwapInterval = interval ;
+ }
+ }
+ }
+
+ public ByteBuffer glAllocateMemoryNV(int arg0, float arg1, float arg2, float arg3) {
+ return getWGLExt().wglAllocateMemoryNV(arg0, arg1, arg2, arg3);
+ }
+
+ public int getOffscreenContextPixelDataType() {
+ throw new GLException("Should not call this");
+ }
+
+ public int getOffscreenContextReadBuffer() {
+ throw new GLException("Should not call this");
+ }
+
+ public boolean offscreenImageNeedsVerticalFlip() {
+ throw new GLException("Should not call this");
+ }
+
+ public void bindPbufferToTexture() {
+ throw new GLException("Should not call this");
+ }
+
+ public void releasePbufferFromTexture() {
+ throw new GLException("Should not call this");
+ }
+
+}
diff --git a/src/jogl/classes/jogamp/opengl/windows/wgl/WindowsWGLDrawable.java b/src/jogl/classes/jogamp/opengl/windows/wgl/WindowsWGLDrawable.java
new file mode 100644
index 000000000..83b52fbcb
--- /dev/null
+++ b/src/jogl/classes/jogamp/opengl/windows/wgl/WindowsWGLDrawable.java
@@ -0,0 +1,107 @@
+/*
+ * Copyright (c) 2003 Sun Microsystems, Inc. All Rights Reserved.
+ * Copyright (c) 2010 JogAmp Community. 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 com.jogamp.opengl.impl.windows.wgl;
+
+import java.security.AccessController;
+import javax.media.nativewindow.NativeSurface;
+import javax.media.opengl.GLDrawableFactory;
+import javax.media.opengl.GLException;
+
+import com.jogamp.nativewindow.impl.windows.GDI;
+import com.jogamp.opengl.impl.Debug;
+import com.jogamp.opengl.impl.GLDrawableImpl;
+import com.jogamp.opengl.impl.GLDynamicLookupHelper;
+
+
+public abstract class WindowsWGLDrawable extends GLDrawableImpl {
+ private static final boolean PROFILING = Debug.isPropertyDefined("jogl.debug.GLDrawable.profiling", true, AccessController.getContext());
+ private static final int PROFILING_TICKS = 200;
+ private int profilingSwapBuffersTicks;
+ private long profilingSwapBuffersTime;
+
+ public WindowsWGLDrawable(GLDrawableFactory factory, NativeSurface comp, boolean realized) {
+ super(factory, comp, realized);
+ }
+
+ protected void setRealizedImpl() {
+ if(!realized) {
+ return; // nothing todo ..
+ }
+
+ NativeSurface ns = getNativeSurface();
+ WindowsWGLGraphicsConfiguration config = (WindowsWGLGraphicsConfiguration)ns.getGraphicsConfiguration().getNativeGraphicsConfiguration();
+ config.updateGraphicsConfiguration(getFactory(), ns, null);
+ if (DEBUG) {
+ System.err.println("!!! WindowsWGLDrawable.setRealized(true): "+config);
+ }
+ }
+
+ protected void swapBuffersImpl() {
+ long startTime = 0;
+ if (PROFILING) {
+ startTime = System.currentTimeMillis();
+ }
+
+ if (!GDI.SwapBuffers(getHandle()) && (GDI.GetLastError() != GDI.ERROR_SUCCESS)) {
+ throw new GLException("Error swapping buffers");
+ }
+
+ if (PROFILING) {
+ long endTime = System.currentTimeMillis();
+ profilingSwapBuffersTime += (endTime - startTime);
+ int ticks = PROFILING_TICKS;
+ if (++profilingSwapBuffersTicks == ticks) {
+ System.err.println("SwapBuffers calls: " + profilingSwapBuffersTime + " ms / " + ticks + " calls (" +
+ ((float) profilingSwapBuffersTime / (float) ticks) + " ms/call)");
+ profilingSwapBuffersTime = 0;
+ profilingSwapBuffersTicks = 0;
+ }
+ }
+ }
+
+ public GLDynamicLookupHelper getGLDynamicLookupHelper() {
+ return getFactoryImpl().getGLDynamicLookupHelper(0);
+ }
+
+ static String getThreadName() {
+ return Thread.currentThread().getName();
+ }
+}
diff --git a/src/jogl/classes/jogamp/opengl/windows/wgl/WindowsWGLDrawableFactory.java b/src/jogl/classes/jogamp/opengl/windows/wgl/WindowsWGLDrawableFactory.java
new file mode 100644
index 000000000..f44c3c70b
--- /dev/null
+++ b/src/jogl/classes/jogamp/opengl/windows/wgl/WindowsWGLDrawableFactory.java
@@ -0,0 +1,512 @@
+/*
+ * Copyright (c) 2003 Sun Microsystems, Inc. All Rights Reserved.
+ * Copyright (c) 2010 JogAmp Community. 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 com.jogamp.opengl.impl.windows.wgl;
+
+import java.nio.Buffer;
+import java.nio.ShortBuffer;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.HashMap;
+import java.util.List;
+
+import javax.media.nativewindow.AbstractGraphicsDevice;
+import javax.media.nativewindow.AbstractGraphicsScreen;
+import javax.media.nativewindow.DefaultGraphicsScreen;
+import javax.media.nativewindow.NativeSurface;
+import javax.media.nativewindow.NativeWindowFactory;
+import javax.media.nativewindow.windows.WindowsGraphicsDevice;
+import javax.media.nativewindow.AbstractGraphicsConfiguration;
+import javax.media.opengl.GLCapabilitiesImmutable;
+import javax.media.opengl.GLCapabilitiesChooser;
+import javax.media.opengl.GLContext;
+import javax.media.opengl.GLDrawable;
+import javax.media.opengl.GLException;
+import javax.media.opengl.GLProfile;
+
+import com.jogamp.common.JogampRuntimeException;
+import com.jogamp.common.nio.PointerBuffer;
+import com.jogamp.common.util.ReflectionUtil;
+import com.jogamp.nativewindow.impl.ProxySurface;
+import com.jogamp.nativewindow.impl.windows.GDI;
+import com.jogamp.nativewindow.impl.windows.RegisteredClassFactory;
+import com.jogamp.opengl.impl.DesktopGLDynamicLookupHelper;
+import com.jogamp.opengl.impl.GLContextImpl;
+import com.jogamp.opengl.impl.GLDrawableFactoryImpl;
+import com.jogamp.opengl.impl.GLDrawableImpl;
+import com.jogamp.opengl.impl.GLDynamicLookupHelper;
+import com.jogamp.opengl.impl.SharedResourceRunner;
+
+public class WindowsWGLDrawableFactory extends GLDrawableFactoryImpl {
+ private static final DesktopGLDynamicLookupHelper windowsWGLDynamicLookupHelper;
+
+ static {
+ DesktopGLDynamicLookupHelper tmp = null;
+ try {
+ tmp = new DesktopGLDynamicLookupHelper(new WindowsWGLDynamicLibraryBundleInfo());
+ } catch (GLException gle) {
+ if(DEBUG) {
+ gle.printStackTrace();
+ }
+ }
+ windowsWGLDynamicLookupHelper = tmp;
+ if(null!=windowsWGLDynamicLookupHelper) {
+ WGL.getWGLProcAddressTable().reset(windowsWGLDynamicLookupHelper);
+ }
+ }
+
+ public GLDynamicLookupHelper getGLDynamicLookupHelper(int profile) {
+ return windowsWGLDynamicLookupHelper;
+ }
+
+ public WindowsWGLDrawableFactory() {
+ super();
+
+ // Register our GraphicsConfigurationFactory implementations
+ // The act of constructing them causes them to be registered
+ new WindowsWGLGraphicsConfigurationFactory();
+ if(GLProfile.isAWTAvailable()) {
+ try {
+ ReflectionUtil.createInstance("com.jogamp.opengl.impl.windows.wgl.awt.WindowsAWTWGLGraphicsConfigurationFactory",
+ null, getClass().getClassLoader());
+ } catch (JogampRuntimeException jre) { /* n/a .. */ }
+ }
+
+ defaultDevice = new WindowsGraphicsDevice(AbstractGraphicsDevice.DEFAULT_UNIT);
+
+ // Init shared resources off thread
+ // Will be released via ShutdownHook
+ sharedResourceImpl = new SharedResourceImplementation();
+ sharedResourceRunner = new SharedResourceRunner(sharedResourceImpl);
+ sharedResourceThread = new Thread(sharedResourceRunner, Thread.currentThread().getName()+"-SharedResourceRunner");
+ sharedResourceThread.setDaemon(true); // Allow JVM to exit, even if this one is running
+ sharedResourceThread.start();
+ }
+
+ WindowsGraphicsDevice defaultDevice;
+ SharedResourceImplementation sharedResourceImpl;
+ SharedResourceRunner sharedResourceRunner;
+ Thread sharedResourceThread;
+ HashMap/*<connection, SharedResource>*/ sharedMap = new HashMap();
+
+ long processAffinityChanges = 0;
+ PointerBuffer procMask = PointerBuffer.allocateDirect(1);
+ PointerBuffer sysMask = PointerBuffer.allocateDirect(1);
+
+ protected void enterThreadCriticalZone() {
+ synchronized (sysMask) {
+ if( 0 == processAffinityChanges) {
+ long pid = GDI.GetCurrentProcess();
+ if ( GDI.GetProcessAffinityMask(pid, procMask, sysMask) ) {
+ if(DEBUG) {
+ System.err.println("WindowsWGLDrawableFactory.enterThreadCriticalZone() - 0x" + Long.toHexString(pid) + " - " + Thread.currentThread().getName());
+ Thread.dumpStack();
+ }
+ processAffinityChanges = pid;
+ GDI.SetProcessAffinityMask(pid, 1);
+ }
+ }
+ }
+ }
+
+ protected void leaveThreadCriticalZone() {
+ synchronized (sysMask) {
+ if( 0 != processAffinityChanges) {
+ long pid = GDI.GetCurrentProcess();
+ if( pid != processAffinityChanges) {
+ throw new GLException("PID doesn't match: set PID 0x" + Long.toHexString(processAffinityChanges) +
+ " this PID 0x" + Long.toHexString(pid) );
+ }
+ if(DEBUG) {
+ System.err.println("WindowsWGLDrawableFactory.leaveThreadCriticalZone() - 0x" + Long.toHexString(pid) + " - " + Thread.currentThread().getName());
+ }
+ GDI.SetProcessAffinityMask(pid, sysMask.get(0));
+ }
+ }
+ }
+
+ static class SharedResource implements SharedResourceRunner.Resource {
+ private WindowsGraphicsDevice device;
+ private AbstractGraphicsScreen screen;
+ private WindowsDummyWGLDrawable drawable;
+ private WindowsWGLContext context;
+ private boolean canCreateGLPbuffer;
+ private boolean readDrawableAvailable;
+
+ SharedResource(WindowsGraphicsDevice dev, AbstractGraphicsScreen scrn, WindowsDummyWGLDrawable draw, WindowsWGLContext ctx,
+ boolean readBufferAvail, boolean canPbuffer) {
+ device = dev;
+ screen = scrn;
+ drawable = draw;
+ context = ctx;
+ canCreateGLPbuffer = canPbuffer;
+ readDrawableAvailable = readBufferAvail;
+ }
+ final public AbstractGraphicsDevice getDevice() { return device; }
+ final public AbstractGraphicsScreen getScreen() { return screen; }
+ final public GLDrawableImpl getDrawable() { return drawable; }
+ final public GLContextImpl getContext() { return context; }
+
+ final boolean canCreateGLPbuffer() { return canCreateGLPbuffer; }
+ final boolean isReadDrawableAvailable() { return readDrawableAvailable; }
+ }
+
+ class SharedResourceImplementation implements SharedResourceRunner.Implementation {
+ public void clear() {
+ synchronized(sharedMap) {
+ sharedMap.clear();
+ }
+ }
+ public SharedResourceRunner.Resource mapPut(String connection, SharedResourceRunner.Resource resource) {
+ synchronized(sharedMap) {
+ return (SharedResourceRunner.Resource) sharedMap.put(connection, resource);
+ }
+ }
+ public SharedResourceRunner.Resource mapGet(String connection) {
+ synchronized(sharedMap) {
+ return (SharedResourceRunner.Resource) sharedMap.get(connection);
+ }
+ }
+ public Collection/*<Resource>*/ mapValues() {
+ synchronized(sharedMap) {
+ return sharedMap.values();
+ }
+ }
+
+ public SharedResourceRunner.Resource createSharedResource(String connection) {
+ WindowsGraphicsDevice sharedDevice = new WindowsGraphicsDevice(connection, AbstractGraphicsDevice.DEFAULT_UNIT);
+ sharedDevice.lock();
+ try {
+ AbstractGraphicsScreen absScreen = new DefaultGraphicsScreen(sharedDevice, 0);
+ if (null == absScreen) {
+ throw new GLException("Couldn't create shared screen for device: "+sharedDevice+", idx 0");
+ }
+ GLProfile glp = GLProfile.getMinDesktop(sharedDevice);
+ if (null == glp) {
+ throw new GLException("Couldn't get default GLProfile for device: "+sharedDevice);
+ }
+ WindowsDummyWGLDrawable sharedDrawable = WindowsDummyWGLDrawable.create(WindowsWGLDrawableFactory.this, glp, absScreen);
+ if (null == sharedDrawable) {
+ throw new GLException("Couldn't create shared drawable for screen: "+absScreen+", "+glp);
+ }
+ WindowsWGLContext sharedContext = (WindowsWGLContext) sharedDrawable.createContext(null);
+ if (null == sharedContext) {
+ throw new GLException("Couldn't create shared context for drawable: "+sharedDrawable);
+ }
+ sharedContext.setSynchronized(true);
+ boolean canCreateGLPbuffer;
+ boolean readDrawableAvailable;
+ sharedContext.makeCurrent();
+ try {
+ canCreateGLPbuffer = sharedContext.getGL().isExtensionAvailable(GL_ARB_pbuffer);
+ readDrawableAvailable = sharedContext.isExtensionAvailable(WGL_ARB_make_current_read) &&
+ sharedContext.isFunctionAvailable(wglMakeContextCurrent);
+ } finally {
+ sharedContext.release();
+ }
+ if (DEBUG) {
+ System.err.println("!!! SharedDevice: " + sharedDevice);
+ System.err.println("!!! SharedScreen: " + absScreen);
+ System.err.println("!!! SharedContext: " + sharedContext);
+ System.err.println("!!! pbuffer avail: " + canCreateGLPbuffer);
+ System.err.println("!!! readDrawable: " + readDrawableAvailable);
+ }
+ return new SharedResource(sharedDevice, absScreen, sharedDrawable, sharedContext, readDrawableAvailable, canCreateGLPbuffer);
+ } catch (Throwable t) {
+ throw new GLException("WindowsWGLDrawableFactory - Could not initialize shared resources for "+connection, t);
+ } finally {
+ sharedDevice.unlock();
+ }
+ }
+
+ public void releaseSharedResource(SharedResourceRunner.Resource shared) {
+ SharedResource sr = (SharedResource) shared;
+ if (DEBUG) {
+ System.err.println("!!! Shutdown Shared:");
+ System.err.println("!!! Device : " + sr.device);
+ System.err.println("!!! Screen : " + sr.screen);
+ System.err.println("!!! Drawable: " + sr.drawable);
+ System.err.println("!!! CTX : " + sr.context);
+ }
+
+ if (null != sr.context) {
+ // may cause JVM SIGSEGV: sharedContext.destroy();
+ sr.context = null;
+ }
+
+ if (null != sr.drawable) {
+ sr.drawable.destroy();
+ sr.drawable = null;
+ }
+
+ if (null != sr.screen) {
+ sr.screen = null;
+ }
+
+ if (null != sr.device) {
+ sr.device.close();
+ sr.device = null;
+ }
+ }
+ }
+
+ public final AbstractGraphicsDevice getDefaultDevice() {
+ return defaultDevice;
+ }
+
+ public final boolean getIsDeviceCompatible(AbstractGraphicsDevice device) {
+ if(device instanceof WindowsGraphicsDevice) {
+ return true;
+ }
+ return false;
+ }
+
+ final static String GL_ARB_pbuffer = "GL_ARB_pbuffer";
+ final static String WGL_ARB_make_current_read = "WGL_ARB_make_current_read";
+ final static String wglMakeContextCurrent = "wglMakeContextCurrent";
+
+ protected final GLContext getSharedContextImpl(AbstractGraphicsDevice device) {
+ SharedResourceRunner.Resource sr = sharedResourceRunner.getShared(device);
+ if(null!=sr) {
+ return sr.getContext();
+ }
+ return null;
+ }
+
+ protected final boolean hasSharedContextImpl(AbstractGraphicsDevice device) {
+ return null != getSharedContextImpl(device);
+ }
+
+ protected final GLContext getOrCreateSharedContextImpl(AbstractGraphicsDevice device) {
+ SharedResourceRunner.Resource sr = sharedResourceRunner.getOrCreateShared(device);
+ if(null!=sr) {
+ return sr.getContext();
+ }
+ return null;
+ }
+
+ protected AbstractGraphicsDevice getOrCreateSharedDeviceImpl(AbstractGraphicsDevice device) {
+ SharedResourceRunner.Resource sr = sharedResourceRunner.getOrCreateShared(device);
+ if(null!=sr) {
+ return sr.getDevice();
+ }
+ return null;
+ }
+
+ protected WindowsWGLDrawable getOrCreateSharedDrawable(AbstractGraphicsDevice device) {
+ SharedResourceRunner.Resource sr = sharedResourceRunner.getOrCreateShared(device);
+ if(null!=sr) {
+ return (WindowsWGLDrawable) sr.getDrawable();
+ }
+ return null;
+ }
+
+ SharedResource getOrCreateSharedResource(AbstractGraphicsDevice device) {
+ return (SharedResource) sharedResourceRunner.getOrCreateShared(device);
+ }
+
+ protected final void shutdownInstance() {
+ sharedResourceRunner.releaseAndWait();
+ RegisteredClassFactory.shutdownSharedClasses();
+ }
+
+ protected List/*GLCapabilitiesImmutable*/ getAvailableCapabilitiesImpl(AbstractGraphicsDevice device) {
+ return WindowsWGLGraphicsConfigurationFactory.getAvailableCapabilities(this, device);
+ }
+
+ protected final GLDrawableImpl createOnscreenDrawableImpl(NativeSurface target) {
+ if (target == null) {
+ throw new IllegalArgumentException("Null target");
+ }
+ return new WindowsOnscreenWGLDrawable(this, target);
+ }
+
+ protected final GLDrawableImpl createOffscreenDrawableImpl(final NativeSurface target) {
+ if (target == null) {
+ throw new IllegalArgumentException("Null target");
+ }
+ AbstractGraphicsConfiguration config = target.getGraphicsConfiguration().getNativeGraphicsConfiguration();
+ GLCapabilitiesImmutable chosenCaps = (GLCapabilitiesImmutable) config.getChosenCapabilities();
+ if(!chosenCaps.isPBuffer()) {
+ return new WindowsBitmapWGLDrawable(this, target);
+ }
+
+ // PBuffer GLDrawable Creation
+ final AbstractGraphicsDevice device = config.getScreen().getDevice();
+
+ final SharedResource sr = (SharedResource) sharedResourceRunner.getOrCreateShared(device);
+ if(null==sr) {
+ throw new IllegalArgumentException("No shared resource for "+device);
+ }
+ final List returnList = new ArrayList();
+ Runnable r = new Runnable() {
+ public void run() {
+ GLContext lastContext = GLContext.getCurrent();
+ if (lastContext != null) {
+ lastContext.release();
+ }
+ sr.context.makeCurrent();
+ try {
+ GLDrawableImpl pbufferDrawable = new WindowsPbufferWGLDrawable(WindowsWGLDrawableFactory.this, target,
+ sr.drawable,
+ sr.context);
+ returnList.add(pbufferDrawable);
+ } finally {
+ sr.context.release();
+ if (lastContext != null) {
+ lastContext.makeCurrent();
+ }
+ }
+ }
+ };
+ maybeDoSingleThreadedWorkaround(r);
+ return (GLDrawableImpl) returnList.get(0);
+ }
+
+ /**
+ * @return 1 if read drawable extension is available, 0 if not
+ * and -1 if undefined yet, ie no shared device exist at this point.
+ */
+ public final int isReadDrawableAvailable(AbstractGraphicsDevice device) {
+ SharedResource sr = (SharedResource) sharedResourceRunner.getOrCreateShared((null!=device)?device:defaultDevice);
+ if(null!=sr) {
+ return sr.isReadDrawableAvailable() ? 1 : 0 ;
+ }
+ return -1; // undefined
+ }
+
+ public final boolean canCreateGLPbuffer(AbstractGraphicsDevice device) {
+ SharedResource sr = (SharedResource) sharedResourceRunner.getOrCreateShared((null!=device)?device:defaultDevice);
+ if(null!=sr) {
+ return sr.canCreateGLPbuffer();
+ }
+ return false;
+ }
+
+ protected final NativeSurface createOffscreenSurfaceImpl(AbstractGraphicsDevice device,GLCapabilitiesImmutable capsChosen, GLCapabilitiesImmutable capsRequested, GLCapabilitiesChooser chooser, int width, int height) {
+ AbstractGraphicsScreen screen = DefaultGraphicsScreen.createDefault(NativeWindowFactory.TYPE_WINDOWS);
+ ProxySurface ns = new ProxySurface(WindowsWGLGraphicsConfigurationFactory.chooseGraphicsConfigurationStatic(
+ capsChosen, capsRequested, chooser, screen) );
+ ns.setSize(width, height);
+ return ns;
+ }
+
+ protected final GLContext createExternalGLContextImpl() {
+ return WindowsExternalWGLContext.create(this, null);
+ }
+
+ public final boolean canCreateExternalGLDrawable(AbstractGraphicsDevice device) {
+ return true;
+ }
+
+ protected final GLDrawable createExternalGLDrawableImpl() {
+ return WindowsExternalWGLDrawable.create(this, null);
+ }
+
+ static String wglGetLastError() {
+ long err = GDI.GetLastError();
+ String detail = null;
+ switch ((int) err) {
+ case GDI.ERROR_SUCCESS: detail = "ERROR_SUCCESS"; break;
+ case GDI.ERROR_INVALID_PIXEL_FORMAT: detail = "ERROR_INVALID_PIXEL_FORMAT"; break;
+ case GDI.ERROR_NO_SYSTEM_RESOURCES: detail = "ERROR_NO_SYSTEM_RESOURCES"; break;
+ case GDI.ERROR_INVALID_DATA: detail = "ERROR_INVALID_DATA"; break;
+ case GDI.ERROR_PROC_NOT_FOUND: detail = "ERROR_PROC_NOT_FOUND"; break;
+ case GDI.ERROR_INVALID_WINDOW_HANDLE:detail = "ERROR_INVALID_WINDOW_HANDLE"; break;
+ default: detail = "(Unknown error code " + err + ")"; break;
+ }
+ return detail;
+ }
+
+ public final boolean canCreateContextOnJava2DSurface(AbstractGraphicsDevice device) {
+ return false;
+ }
+
+ public final GLContext createContextOnJava2DSurface(Object graphics, GLContext shareWith)
+ throws GLException {
+ throw new GLException("Unimplemented on this platform");
+ }
+
+ //------------------------------------------------------
+ // Gamma-related functionality
+ //
+
+ private static final int GAMMA_RAMP_LENGTH = 256;
+
+ protected final int getGammaRampLength() {
+ return GAMMA_RAMP_LENGTH;
+ }
+
+ protected final boolean setGammaRamp(float[] ramp) {
+ short[] rampData = new short[3 * GAMMA_RAMP_LENGTH];
+ for (int i = 0; i < GAMMA_RAMP_LENGTH; i++) {
+ short scaledValue = (short) (ramp[i] * 65535);
+ rampData[i] = scaledValue;
+ rampData[i + GAMMA_RAMP_LENGTH] = scaledValue;
+ rampData[i + 2 * GAMMA_RAMP_LENGTH] = scaledValue;
+ }
+
+ long screenDC = GDI.GetDC(0);
+ boolean res = GDI.SetDeviceGammaRamp(screenDC, ShortBuffer.wrap(rampData));
+ GDI.ReleaseDC(0, screenDC);
+ return res;
+ }
+
+ protected final Buffer getGammaRamp() {
+ ShortBuffer rampData = ShortBuffer.wrap(new short[3 * GAMMA_RAMP_LENGTH]);
+ long screenDC = GDI.GetDC(0);
+ boolean res = GDI.GetDeviceGammaRamp(screenDC, rampData);
+ GDI.ReleaseDC(0, screenDC);
+ if (!res) {
+ return null;
+ }
+ return rampData;
+ }
+
+ protected final void resetGammaRamp(Buffer originalGammaRamp) {
+ if (originalGammaRamp == null) {
+ // getGammaRamp failed earlier
+ return;
+ }
+ long screenDC = GDI.GetDC(0);
+ GDI.SetDeviceGammaRamp(screenDC, originalGammaRamp);
+ GDI.ReleaseDC(0, screenDC);
+ }
+}
diff --git a/src/jogl/classes/jogamp/opengl/windows/wgl/WindowsWGLDynamicLibraryBundleInfo.java b/src/jogl/classes/jogamp/opengl/windows/wgl/WindowsWGLDynamicLibraryBundleInfo.java
new file mode 100644
index 000000000..153680f8e
--- /dev/null
+++ b/src/jogl/classes/jogamp/opengl/windows/wgl/WindowsWGLDynamicLibraryBundleInfo.java
@@ -0,0 +1,58 @@
+/**
+ * Copyright 2010 JogAmp Community. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without modification, are
+ * permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice, this list of
+ * conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright notice, this list
+ * of conditions and the following disclaimer in the documentation and/or other materials
+ * provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY JogAmp Community ``AS IS'' AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
+ * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL JogAmp Community OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
+ * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * The views and conclusions contained in the software and documentation are those of the
+ * authors and should not be interpreted as representing official policies, either expressed
+ * or implied, of JogAmp Community.
+ */
+
+package com.jogamp.opengl.impl.windows.wgl;
+
+import com.jogamp.opengl.impl.*;
+import java.util.*;
+
+public class WindowsWGLDynamicLibraryBundleInfo extends DesktopGLDynamicLibraryBundleInfo {
+ protected WindowsWGLDynamicLibraryBundleInfo() {
+ super();
+ }
+
+ public List getToolLibNames() {
+ List/*<String>*/ libNamesList = new ArrayList();
+
+ libNamesList.add("OpenGL32");
+
+ return libNamesList;
+ }
+
+
+ public final List getToolGetProcAddressFuncNameList() {
+ List res = new ArrayList();
+ res.add("wglGetProcAddress");
+ return res;
+ }
+
+ public final long toolDynamicLookupFunction(long toolGetProcAddressHandle, String funcName) {
+ return WGL.wglGetProcAddress(toolGetProcAddressHandle, funcName);
+ }
+}
+
diff --git a/src/jogl/classes/jogamp/opengl/windows/wgl/WindowsWGLGraphicsConfiguration.java b/src/jogl/classes/jogamp/opengl/windows/wgl/WindowsWGLGraphicsConfiguration.java
new file mode 100644
index 000000000..f844bad76
--- /dev/null
+++ b/src/jogl/classes/jogamp/opengl/windows/wgl/WindowsWGLGraphicsConfiguration.java
@@ -0,0 +1,699 @@
+/*
+ * Copyright (c) 2008 Sun Microsystems, Inc. All Rights Reserved.
+ * Copyright (c) 2010 JogAmp Community. 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.
+ */
+
+package com.jogamp.opengl.impl.windows.wgl;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import javax.media.nativewindow.AbstractGraphicsScreen;
+import javax.media.nativewindow.DefaultGraphicsConfiguration;
+import javax.media.nativewindow.NativeSurface;
+import javax.media.nativewindow.AbstractGraphicsDevice;
+import javax.media.opengl.GL;
+import javax.media.opengl.GLCapabilitiesImmutable;
+import javax.media.opengl.GLCapabilitiesChooser;
+import javax.media.opengl.GLDrawableFactory;
+import javax.media.opengl.GLException;
+import javax.media.opengl.GLPbuffer;
+import javax.media.opengl.GLProfile;
+
+import com.jogamp.nativewindow.impl.windows.GDI;
+import com.jogamp.nativewindow.impl.windows.PIXELFORMATDESCRIPTOR;
+import com.jogamp.opengl.impl.GLContextImpl;
+import com.jogamp.opengl.impl.GLGraphicsConfigurationUtil;
+
+public class WindowsWGLGraphicsConfiguration extends DefaultGraphicsConfiguration implements Cloneable {
+ // Keep this under the same debug flag as the drawable factory for convenience
+ protected static final boolean DEBUG = com.jogamp.opengl.impl.Debug.debug("GraphicsConfiguration");
+
+ final static String WGL_ARB_pixel_format = "WGL_ARB_pixel_format";
+ final static String WGL_ARB_multisample = "WGL_ARB_multisample";
+
+ protected static final int MAX_PFORMATS = 256;
+ protected static final int MAX_ATTRIBS = 256;
+
+ private GLCapabilitiesChooser chooser;
+ private boolean isChosen = false;
+
+ WindowsWGLGraphicsConfiguration(AbstractGraphicsScreen screen,
+ GLCapabilitiesImmutable capsChosen, GLCapabilitiesImmutable capsRequested,
+ GLCapabilitiesChooser chooser) {
+ super(screen, capsChosen, capsRequested);
+ this.chooser=chooser;
+ this.isChosen = false;
+ }
+
+ WindowsWGLGraphicsConfiguration(AbstractGraphicsScreen screen,
+ WGLGLCapabilities capsChosen, GLCapabilitiesImmutable capsRequested) {
+ super(screen, capsChosen, capsRequested);
+ setCapsPFD(capsChosen);
+ this.chooser=null;
+ }
+
+
+ static WindowsWGLGraphicsConfiguration createFromCurrent(GLDrawableFactory _factory, long hdc, int pfdID,
+ GLProfile glp, AbstractGraphicsScreen screen, boolean onscreen, boolean usePBuffer)
+ {
+ if(_factory==null) {
+ throw new GLException("Null factory");
+ }
+ if(hdc==0) {
+ throw new GLException("Null HDC");
+ }
+ if(pfdID<=0) {
+ throw new GLException("Invalid pixelformat id "+pfdID);
+ }
+ if(null==glp) {
+ glp = GLProfile.getDefault(screen.getDevice());
+ }
+ WindowsWGLDrawableFactory factory = (WindowsWGLDrawableFactory) _factory;
+ AbstractGraphicsDevice device = screen.getDevice();
+ WindowsWGLContext sharedContext = (WindowsWGLContext) factory.getOrCreateSharedContextImpl(device);
+ boolean hasARB = null != sharedContext && sharedContext.isExtensionAvailable(WGL_ARB_pixel_format) ;
+
+ WGLGLCapabilities caps = null;
+
+ if(hasARB) {
+ caps = wglARBPFID2GLCapabilities(sharedContext, hdc, pfdID, glp, onscreen, usePBuffer);
+ } else if(!usePBuffer) {
+ caps = PFD2GLCapabilities(glp, hdc, pfdID, onscreen);
+ }
+ if(null==caps) {
+ throw new GLException("Couldn't choose Capabilities by: HDC 0x"+Long.toHexString(hdc)+", pfdID "+pfdID+", hasARB "+hasARB);
+ }
+
+ return new WindowsWGLGraphicsConfiguration(screen, caps, caps);
+ }
+
+ public Object clone() {
+ return super.clone();
+ }
+
+ /**
+ * Updates the graphics configuration in case it has been determined yet.<br>
+ * Uses the NativeSurface's HDC.<br>
+ * Ensures that a PIXELFORMAT is set.
+ *
+ * @param factory
+ * @param ns
+ * @param pfIDs optional pool of preselected PixelFormat IDs, maybe null for unrestricted selection
+ *
+ * @see #isDetermined()
+ */
+ public final void updateGraphicsConfiguration(GLDrawableFactory factory, NativeSurface ns, int[] pfIDs) {
+ WindowsWGLGraphicsConfigurationFactory.updateGraphicsConfiguration(chooser, factory, ns, pfIDs);
+ }
+
+ /**
+ * Preselect the graphics configuration in case it has been determined yet.<br>
+ * Uses a shared device's HDC and the given pfdIDs to preselect the pfd.
+ * No PIXELFORMAT is set.
+ *
+ * @param factory
+ * @param pfIDs optional pool of preselected PixelFormat IDs, maybe null for unrestricted selection
+ *
+ * @see #isDetermined()
+ */
+ public final void preselectGraphicsConfiguration(GLDrawableFactory factory, int[] pfdIDs) {
+ AbstractGraphicsDevice device = getNativeGraphicsConfiguration().getScreen().getDevice();
+ WindowsWGLGraphicsConfigurationFactory.preselectGraphicsConfiguration(chooser, factory, device, this, pfdIDs);
+ }
+
+ final void setCapsPFD(WGLGLCapabilities caps) {
+ setChosenCapabilities(caps);
+ this.isChosen=true;
+ if (DEBUG) {
+ System.err.println("*** setCapsPFD: "+caps);
+ }
+ }
+
+ public final boolean isDetermined() { return isChosen; }
+ public final PIXELFORMATDESCRIPTOR getPixelFormat() { return isChosen ? ((WGLGLCapabilities)capabilitiesChosen).getPFD() : null; }
+ public final int getPixelFormatID() { return isChosen ? ((WGLGLCapabilities)capabilitiesChosen).getPFDID() : 0; }
+ public final boolean isChoosenByARB() { return isChosen ? ((WGLGLCapabilities)capabilitiesChosen).isSetByARB() : false; }
+
+ static int fillAttribsForGeneralWGLARBQuery(boolean haveWGLARBMultisample, int[] iattributes) {
+ int niattribs = 0;
+ iattributes[niattribs++] = WGLExt.WGL_DRAW_TO_WINDOW_ARB;
+ iattributes[niattribs++] = WGLExt.WGL_DRAW_TO_PBUFFER_ARB;
+ iattributes[niattribs++] = WGLExt.WGL_DRAW_TO_BITMAP_ARB;
+ iattributes[niattribs++] = WGLExt.WGL_ACCELERATION_ARB;
+ iattributes[niattribs++] = WGLExt.WGL_SUPPORT_OPENGL_ARB;
+ iattributes[niattribs++] = WGLExt.WGL_DEPTH_BITS_ARB;
+ iattributes[niattribs++] = WGLExt.WGL_STENCIL_BITS_ARB;
+ iattributes[niattribs++] = WGLExt.WGL_DOUBLE_BUFFER_ARB;
+ iattributes[niattribs++] = WGLExt.WGL_STEREO_ARB;
+ iattributes[niattribs++] = WGLExt.WGL_PIXEL_TYPE_ARB;
+ iattributes[niattribs++] = WGLExt.WGL_RED_BITS_ARB;
+ iattributes[niattribs++] = WGLExt.WGL_GREEN_BITS_ARB;
+ iattributes[niattribs++] = WGLExt.WGL_BLUE_BITS_ARB;
+ iattributes[niattribs++] = WGLExt.WGL_ALPHA_BITS_ARB;
+ iattributes[niattribs++] = WGLExt.WGL_ACCUM_RED_BITS_ARB;
+ iattributes[niattribs++] = WGLExt.WGL_ACCUM_GREEN_BITS_ARB;
+ iattributes[niattribs++] = WGLExt.WGL_ACCUM_BLUE_BITS_ARB;
+ iattributes[niattribs++] = WGLExt.WGL_ACCUM_ALPHA_BITS_ARB;
+ if (haveWGLARBMultisample) {
+ iattributes[niattribs++] = WGLExt.WGL_SAMPLE_BUFFERS_ARB;
+ iattributes[niattribs++] = WGLExt.WGL_SAMPLES_ARB;
+ }
+ // pbo float buffer
+ iattributes[niattribs++] = WGLExt.WGL_PIXEL_TYPE_ARB; // ati
+ iattributes[niattribs++] = WGLExt.WGL_FLOAT_COMPONENTS_NV; // nvidia
+
+ return niattribs;
+ }
+
+ static boolean wglARBPFIDValid(WindowsWGLContext sharedCtx, long hdc, int pfdID) {
+ int[] in = new int[1];
+ int[] out = new int[1];
+ in[0] = WGLExt.WGL_COLOR_BITS_ARB;
+ if (!sharedCtx.getWGLExt().wglGetPixelFormatAttribivARB(hdc, pfdID, 0, 1, in, 0, out, 0)) {
+ // Some GPU's falsely fails with a zero error code (success)
+ return GDI.GetLastError() == GDI.ERROR_SUCCESS ;
+ }
+ return true;
+ }
+
+ static int[] wglAllARBPFIDs(WindowsWGLContext sharedCtx, long hdc) {
+ int[] iattributes = new int[1];
+ int[] iresults = new int[1];
+
+ WGLExt wglExt = sharedCtx.getWGLExt();
+ iattributes[0] = WGLExt.WGL_NUMBER_PIXEL_FORMATS_ARB;
+ if (!wglExt.wglGetPixelFormatAttribivARB(hdc, 0, 0, 1, iattributes, 0, iresults, 0)) {
+ if(DEBUG) {
+ System.err.println("GetPixelFormatAttribivARB: Failed - HDC 0x" + Long.toHexString(hdc) +
+ ", LastError: " + GDI.GetLastError());
+ Thread.dumpStack();
+ }
+ return null;
+ }
+ int numFormats = iresults[0];
+ if(0 == numFormats) {
+ if(DEBUG) {
+ System.err.println("GetPixelFormatAttribivARB: No formats - HDC 0x" + Long.toHexString(hdc) +
+ ", LastError: " + GDI.GetLastError());
+ Thread.dumpStack();
+ }
+ return null;
+ }
+ int[] pfdIDs = new int[numFormats];
+ for (int i = 0; i < numFormats; i++) {
+ pfdIDs[i] = 1 + i;
+ }
+ return pfdIDs;
+ }
+
+ static WGLGLCapabilities wglARBPFID2GLCapabilities(WindowsWGLContext sharedCtx, long hdc, int pfdID,
+ GLProfile glp, boolean onscreen, boolean usePBuffer) {
+ boolean haveWGLChoosePixelFormatARB = sharedCtx.isExtensionAvailable(WGL_ARB_pixel_format);
+ if (!haveWGLChoosePixelFormatARB) {
+ return null;
+ }
+ boolean haveWGLARBMultisample = sharedCtx.isExtensionAvailable(WGL_ARB_multisample);
+
+ int[] iattributes = new int [2*MAX_ATTRIBS];
+ int[] iresults = new int [2*MAX_ATTRIBS];
+
+ int niattribs = fillAttribsForGeneralWGLARBQuery(haveWGLARBMultisample, iattributes);
+
+ if (!sharedCtx.getWGLExt().wglGetPixelFormatAttribivARB(hdc, pfdID, 0, niattribs, iattributes, 0, iresults, 0)) {
+ throw new GLException("wglARBPFID2GLCapabilities: Error getting pixel format attributes for pixel format " + pfdID + " of device context");
+ }
+ ArrayList bucket = new ArrayList(1);
+ final int winattrbits = GLGraphicsConfigurationUtil.getWinAttributeBits(onscreen, usePBuffer);
+ if(AttribList2GLCapabilities(bucket, glp, hdc, pfdID, iattributes, niattribs, iresults, winattrbits)) {
+ return (WGLGLCapabilities) bucket.get(0);
+ }
+ return null;
+ }
+
+ static int[] wglChoosePixelFormatARB(long hdc, WindowsWGLContext sharedContext,
+ GLCapabilitiesImmutable capabilities,
+ int[] iattributes, int accelerationMode, float[] fattributes)
+ {
+
+ if ( !WindowsWGLGraphicsConfiguration.GLCapabilities2AttribList(capabilities,
+ iattributes, sharedContext, accelerationMode, null))
+ {
+ if (DEBUG) {
+ System.err.println("wglChoosePixelFormatARB: GLCapabilities2AttribList failed: " + GDI.GetLastError());
+ Thread.dumpStack();
+ }
+ return null;
+ }
+
+ int[] pformatsTmp = new int[WindowsWGLGraphicsConfiguration.MAX_PFORMATS];
+ int[] numFormatsTmp = new int[1];
+ if ( !sharedContext.getWGLExt().wglChoosePixelFormatARB(hdc, iattributes, 0,
+ fattributes, 0,
+ WindowsWGLGraphicsConfiguration.MAX_PFORMATS,
+ pformatsTmp, 0, numFormatsTmp, 0))
+ {
+ if (DEBUG) {
+ System.err.println("wglChoosePixelFormatARB: wglChoosePixelFormatARB failed: " + GDI.GetLastError());
+ Thread.dumpStack();
+ }
+ return null;
+ }
+ int numFormats = numFormatsTmp[0];
+ int[] pformats = null;
+ if( 0 < numFormats ) {
+ pformats = new int[numFormats];
+ System.arraycopy(pformatsTmp, 0, pformats, 0, numFormats);
+ }
+ if (DEBUG) {
+ System.err.println("wglChoosePixelFormatARB: NumFormats (wglChoosePixelFormatARB) accelMode 0x"
+ + Integer.toHexString(accelerationMode) + ": " + numFormats);
+ for (int i = 0; i < numFormats; i++) {
+ WGLGLCapabilities dbgCaps0 = WindowsWGLGraphicsConfiguration.wglARBPFID2GLCapabilities(
+ sharedContext, hdc, pformats[i],
+ capabilities.getGLProfile(), capabilities.isOnscreen(), capabilities.isPBuffer());
+ System.err.println("pixel format " + pformats[i] + " (index " + i + "): " + dbgCaps0);
+ }
+ }
+ return pformats;
+ }
+
+ static List /*<GLCapabilitiesImmutable>*/ wglARBPFIDs2GLCapabilities(WindowsWGLContext sharedCtx, long hdc, int[] pfdIDs,
+ GLProfile glp, boolean onscreen, boolean usePBuffer) {
+ final int winattrbits = GLGraphicsConfigurationUtil.getWinAttributeBits(onscreen, usePBuffer);
+ return wglARBPFIDs2GLCapabilitiesImpl(sharedCtx, hdc, pfdIDs, glp, winattrbits);
+ }
+
+ static List /*<GLCapabilitiesImmutable>*/ wglARBPFIDs2AllGLCapabilities(WindowsWGLContext sharedCtx, long hdc, int[] pfdIDs,
+ GLProfile glp) {
+ return wglARBPFIDs2GLCapabilitiesImpl(sharedCtx, hdc, pfdIDs, glp, GLGraphicsConfigurationUtil.ALL_BITS);
+ }
+
+ private static List /*<GLCapabilitiesImmutable>*/ wglARBPFIDs2GLCapabilitiesImpl(WindowsWGLContext sharedCtx, long hdc, int[] pfdIDs,
+ GLProfile glp, int winattrbits) {
+ boolean haveWGLChoosePixelFormatARB = sharedCtx.isExtensionAvailable(WGL_ARB_pixel_format);
+ if (!haveWGLChoosePixelFormatARB) {
+ return null;
+ }
+ boolean haveWGLARBMultisample = sharedCtx.isExtensionAvailable(WGL_ARB_multisample);
+ final int numFormats = pfdIDs.length;
+
+ int[] iattributes = new int [2*MAX_ATTRIBS];
+ int[] iresults = new int [2*MAX_ATTRIBS];
+ int niattribs = fillAttribsForGeneralWGLARBQuery(haveWGLARBMultisample, iattributes);
+
+ ArrayList bucket = new ArrayList();
+
+ for(int i = 0; i<numFormats; i++) {
+ if ( pfdIDs[i] >= 1 &&
+ sharedCtx.getWGLExt().wglGetPixelFormatAttribivARB(hdc, pfdIDs[i], 0, niattribs, iattributes, 0, iresults, 0) ) {
+ AttribList2GLCapabilities(bucket, glp, hdc, pfdIDs[i], iattributes, niattribs, iresults, winattrbits);
+ } else if (DEBUG) {
+ System.err.println("wglARBPFIDs2GLCapabilities: Cannot get pixel format attributes for pixel format " +
+ i + "/" + numFormats + ": " + pfdIDs[i] + ", " +
+ GLGraphicsConfigurationUtil.winAttributeBits2String(null, winattrbits).toString());
+ }
+ }
+ return bucket;
+ }
+
+ static boolean GLCapabilities2AttribList(GLCapabilitiesImmutable caps,
+ int[] iattributes,
+ GLContextImpl sharedCtx,
+ int accelerationValue,
+ int[] floatMode) throws GLException {
+ boolean haveWGLChoosePixelFormatARB = sharedCtx.isExtensionAvailable(WGL_ARB_pixel_format);
+ boolean haveWGLARBMultisample = sharedCtx.isExtensionAvailable(WGL_ARB_multisample);
+ if(DEBUG) {
+ System.err.println("HDC2GLCapabilities: ARB_pixel_format: "+haveWGLChoosePixelFormatARB);
+ System.err.println("HDC2GLCapabilities: ARB_multisample : "+haveWGLARBMultisample);
+ }
+
+ if (!haveWGLChoosePixelFormatARB) {
+ return false;
+ }
+
+ boolean onscreen = caps.isOnscreen();
+ boolean pbuffer = caps.isPBuffer();
+
+ int niattribs = 0;
+
+ iattributes[niattribs++] = WGLExt.WGL_SUPPORT_OPENGL_ARB;
+ iattributes[niattribs++] = GL.GL_TRUE;
+ if(accelerationValue>0) {
+ iattributes[niattribs++] = WGLExt.WGL_ACCELERATION_ARB;
+ iattributes[niattribs++] = accelerationValue;
+ }
+ if (onscreen) {
+ iattributes[niattribs++] = WGLExt.WGL_DRAW_TO_WINDOW_ARB;
+ iattributes[niattribs++] = GL.GL_TRUE;
+ } else if (pbuffer) {
+ iattributes[niattribs++] = WGLExt.WGL_DRAW_TO_PBUFFER_ARB;
+ iattributes[niattribs++] = GL.GL_TRUE;
+ } else {
+ iattributes[niattribs++] = WGLExt.WGL_DRAW_TO_BITMAP_ARB;
+ iattributes[niattribs++] = GL.GL_TRUE;
+ }
+
+ iattributes[niattribs++] = WGLExt.WGL_DOUBLE_BUFFER_ARB;
+ if (caps.getDoubleBuffered()) {
+ iattributes[niattribs++] = GL.GL_TRUE;
+ } else {
+ iattributes[niattribs++] = GL.GL_FALSE;
+ }
+
+ iattributes[niattribs++] = WGLExt.WGL_STEREO_ARB;
+ if (caps.getStereo()) {
+ iattributes[niattribs++] = GL.GL_TRUE;
+ } else {
+ iattributes[niattribs++] = GL.GL_FALSE;
+ }
+
+ iattributes[niattribs++] = WGLExt.WGL_DEPTH_BITS_ARB;
+ iattributes[niattribs++] = caps.getDepthBits();
+ iattributes[niattribs++] = WGLExt.WGL_RED_BITS_ARB;
+ iattributes[niattribs++] = caps.getRedBits();
+ iattributes[niattribs++] = WGLExt.WGL_GREEN_BITS_ARB;
+ iattributes[niattribs++] = caps.getGreenBits();
+ iattributes[niattribs++] = WGLExt.WGL_BLUE_BITS_ARB;
+ iattributes[niattribs++] = caps.getBlueBits();
+ iattributes[niattribs++] = WGLExt.WGL_ALPHA_BITS_ARB;
+ iattributes[niattribs++] = caps.getAlphaBits();
+ iattributes[niattribs++] = WGLExt.WGL_STENCIL_BITS_ARB;
+ iattributes[niattribs++] = caps.getStencilBits();
+ if (caps.getAccumRedBits() > 0 ||
+ caps.getAccumGreenBits() > 0 ||
+ caps.getAccumBlueBits() > 0 ||
+ caps.getAccumAlphaBits() > 0) {
+ iattributes[niattribs++] = WGLExt.WGL_ACCUM_BITS_ARB;
+ iattributes[niattribs++] = (caps.getAccumRedBits() +
+ caps.getAccumGreenBits() +
+ caps.getAccumBlueBits() +
+ caps.getAccumAlphaBits());
+ iattributes[niattribs++] = WGLExt.WGL_ACCUM_RED_BITS_ARB;
+ iattributes[niattribs++] = caps.getAccumRedBits();
+ iattributes[niattribs++] = WGLExt.WGL_ACCUM_GREEN_BITS_ARB;
+ iattributes[niattribs++] = caps.getAccumGreenBits();
+ iattributes[niattribs++] = WGLExt.WGL_ACCUM_BLUE_BITS_ARB;
+ iattributes[niattribs++] = caps.getAccumBlueBits();
+ iattributes[niattribs++] = WGLExt.WGL_ACCUM_ALPHA_BITS_ARB;
+ iattributes[niattribs++] = caps.getAccumAlphaBits();
+ }
+
+ if (caps.getSampleBuffers() && haveWGLARBMultisample) {
+ iattributes[niattribs++] = WGLExt.WGL_SAMPLE_BUFFERS_ARB;
+ iattributes[niattribs++] = GL.GL_TRUE;
+ iattributes[niattribs++] = WGLExt.WGL_SAMPLES_ARB;
+ iattributes[niattribs++] = caps.getNumSamples();
+ }
+
+ boolean rtt = caps.getPbufferRenderToTexture();
+ boolean rect = caps.getPbufferRenderToTextureRectangle();
+ boolean useFloat = caps.getPbufferFloatingPointBuffers();
+ boolean ati = false;
+ if (pbuffer) {
+ // Check some invariants and set up some state
+ if (rect && !rtt) {
+ throw new GLException("Render-to-texture-rectangle requires render-to-texture to be specified");
+ }
+
+ if (rect) {
+ if (!sharedCtx.isExtensionAvailable("GL_NV_texture_rectangle")) {
+ throw new GLException("Render-to-texture-rectangle requires GL_NV_texture_rectangle extension");
+ }
+ }
+
+ if (useFloat) {
+ if (!sharedCtx.isExtensionAvailable("WGL_ATI_pixel_format_float") &&
+ !sharedCtx.isExtensionAvailable("WGL_NV_float_buffer")) {
+ throw new GLException("Floating-point pbuffers not supported by this hardware");
+ }
+
+ // Prefer NVidia extension over ATI
+ if (sharedCtx.isExtensionAvailable("WGL_NV_float_buffer")) {
+ ati = false;
+ floatMode[0] = GLPbuffer.NV_FLOAT;
+ } else {
+ ati = true;
+ floatMode[0] = GLPbuffer.ATI_FLOAT;
+ }
+ if (DEBUG) {
+ System.err.println("Using " + (ati ? "ATI" : "NVidia") + " floating-point extension");
+ }
+ }
+
+ // See whether we need to change the pixel type to support ATI's
+ // floating-point pbuffers
+ if (useFloat && ati) {
+ if (rtt) {
+ throw new GLException("Render-to-floating-point-texture not supported on ATI hardware");
+ } else {
+ iattributes[niattribs++] = WGLExt.WGL_PIXEL_TYPE_ARB;
+ iattributes[niattribs++] = WGLExt.WGL_TYPE_RGBA_FLOAT_ARB;
+ }
+ } 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++] = WGLExt.WGL_PIXEL_TYPE_ARB;
+ iattributes[niattribs++] = WGLExt.WGL_TYPE_RGBA_ARB;
+ }
+ }
+
+ if (useFloat && !ati) {
+ iattributes[niattribs++] = WGLExt.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++] = WGLExt.WGL_BIND_TO_TEXTURE_RECTANGLE_FLOAT_RGB_NV;
+ iattributes[niattribs++] = GL.GL_TRUE;
+ } else {
+ iattributes[niattribs++] = rect ? WGLExt.WGL_BIND_TO_TEXTURE_RECTANGLE_RGB_NV : WGLExt.WGL_BIND_TO_TEXTURE_RGB_ARB;
+ iattributes[niattribs++] = GL.GL_TRUE;
+ }
+ }
+ } else {
+ iattributes[niattribs++] = WGLExt.WGL_PIXEL_TYPE_ARB;
+ iattributes[niattribs++] = WGLExt.WGL_TYPE_RGBA_ARB;
+ }
+ iattributes[niattribs++] = 0;
+
+ return true;
+ }
+
+ static int AttribList2DrawableTypeBits(final int[] iattribs, final int niattribs, final int[] iresults) {
+ int val = 0;
+
+ for (int i = 0; i < niattribs; i++) {
+ int attr = iattribs[i];
+ switch (attr) {
+ case WGLExt.WGL_DRAW_TO_WINDOW_ARB:
+ if(iresults[i] == GL.GL_TRUE) val |= GLGraphicsConfigurationUtil.WINDOW_BIT;
+ break;
+ case WGLExt.WGL_DRAW_TO_BITMAP_ARB:
+ if(iresults[i] == GL.GL_TRUE) val |= GLGraphicsConfigurationUtil.BITMAP_BIT;
+ break;
+ case WGLExt.WGL_DRAW_TO_PBUFFER_ARB:
+ if(iresults[i] == GL.GL_TRUE) val |= GLGraphicsConfigurationUtil.PBUFFER_BIT;
+ break;
+ }
+ }
+ return val;
+ }
+
+ static boolean AttribList2GLCapabilities( ArrayList capsBucket,
+ final GLProfile glp, final long hdc, final int pfdID, final int[] iattribs,
+ final int niattribs,
+ final int[] iresults, final int winattrmask) {
+ final int allDrawableTypeBits = AttribList2DrawableTypeBits(iattribs, niattribs, iresults);
+ int drawableTypeBits = winattrmask & allDrawableTypeBits;
+
+ if( 0 == drawableTypeBits ) {
+ return false;
+ }
+ PIXELFORMATDESCRIPTOR pfd = createPixelFormatDescriptor();
+
+ if (GDI.DescribePixelFormat(hdc, pfdID, pfd.size(), pfd) == 0) {
+ // remove displayable bits, since pfdID is non displayable
+ drawableTypeBits = drawableTypeBits & ~(GLGraphicsConfigurationUtil.WINDOW_BIT | GLGraphicsConfigurationUtil.BITMAP_BIT);
+ if( 0 == drawableTypeBits ) {
+ return false;
+ }
+ // non displayable requested (pbuffer)
+ }
+ WGLGLCapabilities res = new WGLGLCapabilities(pfd, pfdID, glp);
+ res.setValuesByARB(iattribs, niattribs, iresults);
+
+ return GLGraphicsConfigurationUtil.addGLCapabilitiesPermutations(capsBucket, res, drawableTypeBits );
+ }
+
+ //
+ // GDI PIXELFORMAT
+ //
+
+ static int[] wglAllGDIPFIDs(long hdc) {
+ int numFormats = GDI.DescribePixelFormat(hdc, 1, 0, null);
+ if (numFormats == 0) {
+ throw new GLException("DescribePixelFormat: No formats - HDC 0x" + Long.toHexString(hdc) +
+ ", LastError: " + GDI.GetLastError());
+ }
+ int[] pfdIDs = new int[numFormats];
+ for (int i = 0; i < numFormats; i++) {
+ pfdIDs[i] = 1 + i;
+ }
+ return pfdIDs;
+ }
+
+ static int PFD2DrawableTypeBits(PIXELFORMATDESCRIPTOR pfd) {
+ int val = 0;
+
+ int dwFlags = pfd.getDwFlags();
+
+ if( 0 != (GDI.PFD_DRAW_TO_WINDOW & dwFlags ) ) {
+ val |= GLGraphicsConfigurationUtil.WINDOW_BIT;
+ }
+ if( 0 != (GDI.PFD_DRAW_TO_BITMAP & dwFlags ) ) {
+ val |= GLGraphicsConfigurationUtil.BITMAP_BIT;
+ }
+ return val;
+ }
+
+ static WGLGLCapabilities PFD2GLCapabilities(GLProfile glp, long hdc, int pfdID, boolean onscreen) {
+ final int winattrmask = GLGraphicsConfigurationUtil.getWinAttributeBits(onscreen, false);
+ ArrayList capsBucket = new ArrayList(1);
+ if( PFD2GLCapabilities(capsBucket, glp, hdc, pfdID, winattrmask) ) {
+ return (WGLGLCapabilities) capsBucket.get(0);
+ }
+ return null;
+ }
+
+ static boolean PFD2GLCapabilities(ArrayList capsBucket, final GLProfile glp, final long hdc, final int pfdID, final int winattrmask) {
+ PIXELFORMATDESCRIPTOR pfd = createPixelFormatDescriptor(hdc, pfdID);
+ if(null == pfd) {
+ return false;
+ }
+ if ((pfd.getDwFlags() & GDI.PFD_SUPPORT_OPENGL) == 0) {
+ return false;
+ }
+ final int allDrawableTypeBits = PFD2DrawableTypeBits(pfd);
+ final int drawableTypeBits = winattrmask & allDrawableTypeBits;
+
+ if( 0 == drawableTypeBits ) {
+ return false;
+ }
+
+ WGLGLCapabilities res = new WGLGLCapabilities(pfd, pfdID, glp);
+ res.setValuesByGDI();
+
+ return GLGraphicsConfigurationUtil.addGLCapabilitiesPermutations(capsBucket, res, drawableTypeBits );
+ }
+
+ static PIXELFORMATDESCRIPTOR GLCapabilities2PFD(GLCapabilitiesImmutable caps, PIXELFORMATDESCRIPTOR pfd) {
+ int colorDepth = (caps.getRedBits() +
+ caps.getGreenBits() +
+ caps.getBlueBits());
+ if (colorDepth < 15) {
+ throw new GLException("Bit depths < 15 (i.e., non-true-color) not supported");
+ }
+ int pfdFlags = (GDI.PFD_SUPPORT_OPENGL |
+ GDI.PFD_GENERIC_ACCELERATED);
+ if (caps.getDoubleBuffered()) {
+ pfdFlags |= GDI.PFD_DOUBLEBUFFER;
+ }
+ if (caps.isOnscreen()) {
+ pfdFlags |= GDI.PFD_DRAW_TO_WINDOW;
+ } else {
+ pfdFlags |= GDI.PFD_DRAW_TO_BITMAP;
+ }
+ if (caps.getStereo()) {
+ pfdFlags |= GDI.PFD_STEREO;
+ }
+ pfd.setDwFlags(pfdFlags);
+ pfd.setIPixelType((byte) GDI.PFD_TYPE_RGBA);
+ pfd.setCColorBits((byte) colorDepth);
+ pfd.setCRedBits ((byte) caps.getRedBits());
+ pfd.setCGreenBits((byte) caps.getGreenBits());
+ pfd.setCBlueBits ((byte) caps.getBlueBits());
+ pfd.setCAlphaBits((byte) caps.getAlphaBits());
+ int accumDepth = (caps.getAccumRedBits() +
+ caps.getAccumGreenBits() +
+ caps.getAccumBlueBits());
+ pfd.setCAccumBits ((byte) accumDepth);
+ pfd.setCAccumRedBits ((byte) caps.getAccumRedBits());
+ pfd.setCAccumGreenBits((byte) caps.getAccumGreenBits());
+ pfd.setCAccumBlueBits ((byte) caps.getAccumBlueBits());
+ pfd.setCAccumAlphaBits((byte) caps.getAccumAlphaBits());
+ pfd.setCDepthBits((byte) caps.getDepthBits());
+ pfd.setCStencilBits((byte) caps.getStencilBits());
+ pfd.setILayerType((byte) GDI.PFD_MAIN_PLANE);
+
+ // n/a with non ARB/GDI method:
+ // multisample
+ // opaque
+ // pbuffer
+ return pfd;
+ }
+
+ static PIXELFORMATDESCRIPTOR createPixelFormatDescriptor(long hdc, int pfdID) {
+ PIXELFORMATDESCRIPTOR pfd = PIXELFORMATDESCRIPTOR.create();
+ pfd.setNSize((short) pfd.size());
+ pfd.setNVersion((short) 1);
+ if(0 != hdc && 1 <= pfdID) {
+ if (GDI.DescribePixelFormat(hdc, pfdID, pfd.size(), pfd) == 0) {
+ // Accelerated pixel formats that are non displayable
+ if(DEBUG) {
+ System.err.println("Info: Non displayable pixel format " + pfdID + " of device context: error code " + GDI.GetLastError());
+ }
+ return null;
+ }
+ }
+ return pfd;
+ }
+
+ static PIXELFORMATDESCRIPTOR createPixelFormatDescriptor() {
+ return createPixelFormatDescriptor(0, 0);
+ }
+
+ public String toString() {
+ return "WindowsWGLGraphicsConfiguration["+getScreen()+", pfdID " + getPixelFormatID() + ", ARB-Choosen " + isChoosenByARB() +
+ ",\n\trequested " + getRequestedCapabilities() +
+ ",\n\tchosen " + getChosenCapabilities() +
+ "]";
+ }
+}
+
diff --git a/src/jogl/classes/jogamp/opengl/windows/wgl/WindowsWGLGraphicsConfigurationFactory.java b/src/jogl/classes/jogamp/opengl/windows/wgl/WindowsWGLGraphicsConfigurationFactory.java
new file mode 100644
index 000000000..a66d62485
--- /dev/null
+++ b/src/jogl/classes/jogamp/opengl/windows/wgl/WindowsWGLGraphicsConfigurationFactory.java
@@ -0,0 +1,477 @@
+/*
+ * Copyright (c) 2008 Sun Microsystems, Inc. All Rights Reserved.
+ * Copyright (c) 2010 JogAmp Community. 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.
+ */
+
+package com.jogamp.opengl.impl.windows.wgl;
+
+import javax.media.nativewindow.AbstractGraphicsConfiguration;
+import javax.media.nativewindow.AbstractGraphicsDevice;
+import javax.media.nativewindow.AbstractGraphicsScreen;
+import javax.media.nativewindow.CapabilitiesChooser;
+import javax.media.nativewindow.DefaultGraphicsScreen;
+import javax.media.nativewindow.GraphicsConfigurationFactory;
+import javax.media.nativewindow.CapabilitiesImmutable;
+import javax.media.nativewindow.NativeSurface;
+import javax.media.nativewindow.NativeWindowFactory;
+import javax.media.opengl.GLCapabilitiesImmutable;
+import javax.media.opengl.GLCapabilitiesChooser;
+import javax.media.opengl.GLDrawableFactory;
+import javax.media.opengl.GLException;
+import javax.media.opengl.GLProfile;
+
+import com.jogamp.nativewindow.impl.windows.GDI;
+import com.jogamp.nativewindow.impl.windows.PIXELFORMATDESCRIPTOR;
+import com.jogamp.opengl.impl.GLGraphicsConfigurationFactory;
+import com.jogamp.opengl.impl.GLGraphicsConfigurationUtil;
+import com.jogamp.opengl.impl.SharedResourceRunner;
+
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
+
+/** Subclass of GraphicsConfigurationFactory used when non-AWT tookits
+ are used on Windows platforms. Toolkits will likely need to delegate
+ to this one to change the accepted and returned types of the
+ GraphicsDevice and GraphicsConfiguration abstractions. */
+
+public class WindowsWGLGraphicsConfigurationFactory extends GLGraphicsConfigurationFactory {
+ protected static final boolean DEBUG = com.jogamp.opengl.impl.Debug.debug("GraphicsConfiguration");
+ static WGLGLCapabilities.PfdIDComparator PfdIDComparator = new WGLGLCapabilities.PfdIDComparator();
+
+ WindowsWGLGraphicsConfigurationFactory() {
+ GraphicsConfigurationFactory.registerFactory(javax.media.nativewindow.windows.WindowsGraphicsDevice.class, this);
+ }
+
+ protected AbstractGraphicsConfiguration chooseGraphicsConfigurationImpl(
+ CapabilitiesImmutable capsChosen, CapabilitiesImmutable capsRequested, CapabilitiesChooser chooser, AbstractGraphicsScreen absScreen) {
+
+ if (! (capsChosen instanceof GLCapabilitiesImmutable) ) {
+ throw new IllegalArgumentException("This NativeWindowFactory accepts only GLCapabilities objects - chosen");
+ }
+
+ if (! (capsRequested instanceof GLCapabilitiesImmutable) ) {
+ throw new IllegalArgumentException("This NativeWindowFactory accepts only GLCapabilities objects - requested");
+ }
+
+ return chooseGraphicsConfigurationStatic((GLCapabilitiesImmutable)capsChosen, (GLCapabilitiesImmutable)capsRequested, chooser, absScreen);
+ }
+
+ static WindowsWGLGraphicsConfiguration createDefaultGraphicsConfiguration(GLCapabilitiesImmutable caps,
+ AbstractGraphicsScreen absScreen) {
+ return chooseGraphicsConfigurationStatic(caps, caps, null, absScreen);
+ }
+
+ static WindowsWGLGraphicsConfiguration chooseGraphicsConfigurationStatic(GLCapabilitiesImmutable capsChosen,
+ GLCapabilitiesImmutable capsReq,
+ CapabilitiesChooser chooser,
+ AbstractGraphicsScreen absScreen) {
+ if(null==absScreen) {
+ absScreen = DefaultGraphicsScreen.createDefault(NativeWindowFactory.TYPE_WINDOWS);
+ }
+ AbstractGraphicsDevice absDevice = absScreen.getDevice();
+
+ capsChosen = GLGraphicsConfigurationUtil.fixGLCapabilities(
+ capsChosen, GLDrawableFactory.getDesktopFactory().canCreateGLPbuffer(absDevice) );
+
+ return new WindowsWGLGraphicsConfiguration( absScreen, capsChosen, capsReq, (GLCapabilitiesChooser)chooser );
+ }
+
+ protected static List/*<WGLGLCapabilities>*/ getAvailableCapabilities(WindowsWGLDrawableFactory factory, AbstractGraphicsDevice device) {
+ SharedResourceRunner.Resource sharedResource = factory.getOrCreateSharedResource(device);
+ if(null == sharedResource) {
+ throw new GLException("Shared resource for device n/a: "+device);
+ }
+ WindowsWGLDrawable sharedDrawable = (WindowsWGLDrawable) sharedResource.getDrawable();
+ GLCapabilitiesImmutable capsChosen = sharedDrawable.getChosenGLCapabilities();
+ WindowsWGLContext sharedContext = (WindowsWGLContext) sharedResource.getContext();
+ List availableCaps = null;
+
+ sharedDrawable.lockSurface();
+ try {
+ long hdc = sharedDrawable.getHandle();
+ if (0 == hdc) {
+ throw new GLException("Error: HDC is null");
+ }
+ if (sharedContext.isExtensionAvailable(WindowsWGLGraphicsConfiguration.WGL_ARB_pixel_format)) {
+ availableCaps = getAvailableGLCapabilitiesARB(hdc, sharedContext, capsChosen.getGLProfile());
+ }
+ if( null == availableCaps || 0 == availableCaps.size() ) {
+ availableCaps = getAvailableGLCapabilitiesGDI(hdc, capsChosen);
+ }
+ } finally {
+ sharedDrawable.unlockSurface();
+ }
+
+ if( null != availableCaps ) {
+ Collections.sort(availableCaps, PfdIDComparator);
+ }
+ return availableCaps;
+ }
+
+ static List/*<WGLGLCapabilities>*/ getAvailableGLCapabilitiesARB(long hdc, WindowsWGLContext sharedContext, GLProfile glProfile) {
+ int[] pformats = WindowsWGLGraphicsConfiguration.wglAllARBPFIDs(sharedContext, hdc);
+ return WindowsWGLGraphicsConfiguration.wglARBPFIDs2AllGLCapabilities(sharedContext, hdc, pformats, glProfile);
+ }
+
+ static List/*<WGLGLCapabilities>*/ getAvailableGLCapabilitiesGDI(long hdc, GLCapabilitiesImmutable capsChosen) {
+ boolean onscreen = capsChosen.isOnscreen();
+ if(capsChosen.isPBuffer()) {
+ return null;
+ }
+ GLProfile glProfile = capsChosen.getGLProfile();
+
+ int[] pformats = WindowsWGLGraphicsConfiguration.wglAllGDIPFIDs(hdc);
+ int numFormats = pformats.length;
+ ArrayList bucket = new ArrayList(numFormats);
+ for (int i = 0; i < numFormats; i++) {
+ bucket.add( WindowsWGLGraphicsConfiguration.PFD2GLCapabilities(glProfile, hdc, pformats[i], onscreen) );
+ }
+ return bucket;
+ }
+
+ /**
+ *
+ * @param chooser
+ * @param _factory
+ * @param ns
+ * @param pfIDs optional pool of preselected PixelFormat IDs, maybe null for unrestricted selection
+ */
+ static void updateGraphicsConfiguration(CapabilitiesChooser chooser,
+ GLDrawableFactory factory, NativeSurface ns, int[] pfdIDs) {
+ if (chooser != null && !(chooser instanceof GLCapabilitiesChooser)) {
+ throw new IllegalArgumentException("This NativeWindowFactory accepts only GLCapabilitiesChooser objects");
+ }
+ if (factory == null) {
+ throw new IllegalArgumentException("GLDrawableFactory is null");
+ }
+ if (ns == null) {
+ throw new IllegalArgumentException("NativeSurface is null");
+ }
+
+ if(NativeSurface.LOCK_SURFACE_NOT_READY >= ns.lockSurface()) {
+ throw new GLException("Surface not ready (lockSurface)");
+ }
+ try {
+ long hdc = ns.getSurfaceHandle();
+ if (0 == hdc) {
+ throw new GLException("Error: HDC is null");
+ }
+ WindowsWGLGraphicsConfiguration config = (WindowsWGLGraphicsConfiguration) ns.getGraphicsConfiguration().getNativeGraphicsConfiguration();
+
+ if(!config.isDetermined()) {
+ updateGraphicsConfiguration(config, chooser, factory, hdc, false, pfdIDs);
+ } else {
+ // set PFD if not set yet
+ int pfdID = -1;
+ boolean set = false;
+ if ( 1 > ( pfdID = GDI.GetPixelFormat(hdc) ) ) {
+ if (!GDI.SetPixelFormat(hdc, config.getPixelFormatID(), config.getPixelFormat())) {
+ throw new GLException("Unable to set pixel format " + config.getPixelFormatID() +
+ " for device context " + toHexString(hdc) +
+ ": error code " + GDI.GetLastError());
+ }
+ set = true;
+ pfdID = config.getPixelFormatID();
+ }
+ if (DEBUG) {
+ System.err.println("!!! setPixelFormat (post): hdc "+toHexString(hdc) +", "+config.getPixelFormatID()+" -> "+pfdID+", set: "+set);
+ Thread.dumpStack();
+ }
+ }
+ } finally {
+ ns.unlockSurface();
+ }
+ }
+
+ static void preselectGraphicsConfiguration(CapabilitiesChooser chooser,
+ GLDrawableFactory _factory, AbstractGraphicsDevice device,
+ WindowsWGLGraphicsConfiguration config, int[] pfdIDs) {
+ if (chooser != null && !(chooser instanceof GLCapabilitiesChooser)) {
+ throw new IllegalArgumentException("This NativeWindowFactory accepts only GLCapabilitiesChooser objects");
+ }
+ if (_factory == null) {
+ throw new IllegalArgumentException("GLDrawableFactory is null");
+ }
+ if (config == null) {
+ throw new IllegalArgumentException("WindowsWGLGraphicsConfiguration is null");
+ }
+ WindowsWGLDrawableFactory factory = (WindowsWGLDrawableFactory) _factory;
+ WindowsWGLDrawable sharedDrawable = factory.getOrCreateSharedDrawable(device);
+ if(null == sharedDrawable) {
+ throw new IllegalArgumentException("Shared Drawable is null");
+ }
+
+ if(NativeSurface.LOCK_SURFACE_NOT_READY >= sharedDrawable.lockSurface()) {
+ throw new GLException("Surface not ready (lockSurface)");
+ }
+ try {
+ long hdc = sharedDrawable.getHandle();
+ if (0 == hdc) {
+ throw new GLException("Error: HDC is null");
+ }
+ updateGraphicsConfiguration(config, chooser, factory, hdc, true, pfdIDs);
+ } finally {
+ sharedDrawable.unlockSurface();
+ }
+ }
+
+ private static void updateGraphicsConfiguration(WindowsWGLGraphicsConfiguration config, CapabilitiesChooser chooser,
+ GLDrawableFactory factory, long hdc, boolean extHDC, int[] pfdIDs) {
+ if (DEBUG) {
+ if(extHDC) {
+ System.err.println("updateGraphicsConfiguration(using shared): hdc "+toHexString(hdc));
+ } else {
+ System.err.println("updateGraphicsConfiguration(using target): hdc "+toHexString(hdc));
+ }
+ System.err.println("!!! user chosen caps " + config.getChosenCapabilities());
+ }
+ if( !updateGraphicsConfigurationARB(hdc, extHDC, config, chooser, (WindowsWGLDrawableFactory)factory, pfdIDs) ) {
+ updateGraphicsConfigurationGDI(hdc, extHDC, config, chooser, pfdIDs);
+ }
+ }
+
+ private static boolean updateGraphicsConfigurationARB(long hdc, boolean extHDC, WindowsWGLGraphicsConfiguration config,
+ CapabilitiesChooser chooser, WindowsWGLDrawableFactory factory, int[] pformats) {
+ AbstractGraphicsDevice device = config.getScreen().getDevice();
+ WindowsWGLContext sharedContext = (WindowsWGLContext) factory.getOrCreateSharedContextImpl(device);
+ if (null == sharedContext) {
+ if (DEBUG) {
+ System.err.println("updateGraphicsConfigurationARB: SharedContext is null: "+device);
+ }
+ return false;
+ }
+ if (!sharedContext.isExtensionAvailable(WindowsWGLGraphicsConfiguration.WGL_ARB_pixel_format)) {
+ if (DEBUG) {
+ System.err.println("updateGraphicsConfigurationARB: "+WindowsWGLGraphicsConfiguration.WGL_ARB_pixel_format+" not available");
+ }
+ return false;
+ }
+
+ GLCapabilitiesImmutable capsChosen = (GLCapabilitiesImmutable) config.getChosenCapabilities();
+ boolean onscreen = capsChosen.isOnscreen();
+ boolean usePBuffer = capsChosen.isPBuffer();
+ GLProfile glProfile = capsChosen.getGLProfile();
+
+ WGLGLCapabilities pixelFormatCaps = null; // chosen or preset PFD ID's caps
+ boolean pixelFormatSet = false; // indicates a preset PFD ID [caps]
+ final int presetPFDID = extHDC ? -1 : GDI.GetPixelFormat(hdc) ;
+ if ( 1 <= presetPFDID ) {
+ // Pixelformat already set by either
+ // - a previous preselectGraphicsConfiguration() call on the same HDC,
+ // - the graphics driver, copying the HDC's pixelformat to the new one,
+ // - or the Java2D/OpenGL pipeline's configuration
+ if (DEBUG) {
+ System.err.println("updateGraphicsConfigurationARB: Pixel format already chosen for HDC: " + toHexString(hdc)
+ + ", pixelformat " + presetPFDID);
+ }
+ pixelFormatSet = true;
+ pixelFormatCaps = WindowsWGLGraphicsConfiguration.wglARBPFID2GLCapabilities(sharedContext, hdc, presetPFDID, glProfile, onscreen, usePBuffer);
+ } else {
+ int recommendedIndex = -1; // recommended index
+
+ if(null == pformats) {
+ // No given PFD IDs
+ //
+ // 1st choice: get GLCapabilities based on users GLCapabilities setting recommendedIndex as preferred choice
+ int[] iattributes = new int[2 * WindowsWGLGraphicsConfiguration.MAX_ATTRIBS];
+ float[] fattributes = new float[1];
+ int accelerationMode = WGLExt.WGL_FULL_ACCELERATION_ARB;
+ pformats = WindowsWGLGraphicsConfiguration.wglChoosePixelFormatARB(hdc, sharedContext, capsChosen,
+ iattributes, accelerationMode, fattributes);
+ if (null == pformats) {
+ accelerationMode = WGLExt.WGL_GENERIC_ACCELERATION_ARB;
+ pformats = WindowsWGLGraphicsConfiguration.wglChoosePixelFormatARB(hdc, sharedContext, capsChosen,
+ iattributes, accelerationMode, fattributes);
+ }
+ if (null == pformats) {
+ accelerationMode = -1; // use what we are offered ..
+ pformats = WindowsWGLGraphicsConfiguration.wglChoosePixelFormatARB(hdc, sharedContext, capsChosen,
+ iattributes, accelerationMode, fattributes);
+ }
+ if (null != pformats) {
+ recommendedIndex = 0;
+ } else {
+ if(DEBUG) {
+ System.err.println("updateGraphicsConfigurationARB: wglChoosePixelFormatARB failed with: "+capsChosen);
+ }
+ // 2nd choice: get all GLCapabilities available, no preferred recommendedIndex available
+ pformats = WindowsWGLGraphicsConfiguration.wglAllARBPFIDs(sharedContext, hdc);
+ if (DEBUG) {
+ final int len = ( null != pformats ) ? pformats.length : 0;
+ System.err.println("updateGraphicsConfigurationARB: NumFormats (wglAllARBPFIDs) " + len);
+ }
+ }
+ if (null == pformats) {
+ if (DEBUG) {
+ Thread.dumpStack();
+ }
+ return false;
+ }
+ }
+
+ List /*<WGLGLCapabilities>*/ availableCaps =
+ WindowsWGLGraphicsConfiguration.wglARBPFIDs2GLCapabilities(sharedContext, hdc, pformats,
+ glProfile, onscreen, usePBuffer);
+ if( null == availableCaps || 0 == availableCaps.size() ) {
+ if (DEBUG) {
+ System.err.println("updateGraphicsConfigurationARB: wglARBPFIDs2GLCapabilities failed with " + pformats.length +
+ " pfd ids, onscreen " + onscreen + ", pbuffer " + usePBuffer);
+ Thread.dumpStack();
+ }
+ return false;
+ }
+
+ if (DEBUG) {
+ System.err.println("updateGraphicsConfigurationARB: " + pformats.length +
+ " pfd ids, onscreen " + onscreen + ", pbuffer " + usePBuffer + ", " + availableCaps.size() + " glcaps");
+ if(0 <= recommendedIndex) {
+ System.err.println("updateGraphicsConfigurationARB: Used wglChoosePixelFormatARB to recommend pixel format " +
+ pformats[recommendedIndex] + ", idx " + recommendedIndex +", "+availableCaps.get(recommendedIndex));
+ }
+ }
+
+ int chosenIndex = chooseCapabilities(chooser, capsChosen, availableCaps, recommendedIndex);
+ if ( 0 > chosenIndex ) {
+ if (DEBUG) {
+ Thread.dumpStack();
+ }
+ return false;
+ }
+ pixelFormatCaps = (WGLGLCapabilities) availableCaps.get(chosenIndex);
+ if( null == pixelFormatCaps) {
+ throw new GLException("Null Capabilities with "+
+ " chosen pfdID: native recommended "+ (recommendedIndex+1) +
+ " chosen "+pixelFormatCaps.getPFDID());
+ }
+ if (DEBUG) {
+ System.err.println("!!! chosen pfdID (ARB): native recommended "+ (recommendedIndex+1) +
+ " chosen "+pixelFormatCaps);
+ }
+ }
+
+ if ( !extHDC && !pixelFormatSet ) {
+ if (!GDI.SetPixelFormat(hdc, pixelFormatCaps.getPFDID(), pixelFormatCaps.getPFD())) {
+ throw new GLException("Unable to set pixel format " + pixelFormatCaps.getPFDID() +
+ " for device context " + toHexString(hdc) +
+ ": error code " + GDI.GetLastError());
+ }
+ if (DEBUG) {
+ System.err.println("!!! setPixelFormat (ARB): hdc "+toHexString(hdc) +", "+config.getPixelFormatID()+" -> "+pixelFormatCaps.getPFDID());
+ }
+ }
+ config.setCapsPFD(pixelFormatCaps);
+ return true;
+ }
+
+ private static boolean updateGraphicsConfigurationGDI(long hdc, boolean extHDC, WindowsWGLGraphicsConfiguration config,
+ CapabilitiesChooser chooser, int[] pformats) {
+ GLCapabilitiesImmutable capsChosen = (GLCapabilitiesImmutable) config.getChosenCapabilities();
+ if(capsChosen.isPBuffer()) {
+ if (DEBUG) {
+ System.err.println("updateGraphicsConfigurationGDI: no pbuffer supported on GDI: " + capsChosen);
+ }
+ return false;
+ }
+ boolean onscreen = capsChosen.isOnscreen();
+ GLProfile glProfile = capsChosen.getGLProfile();
+
+ ArrayList/*<WGLGLCapabilities>*/ availableCaps = new ArrayList();
+ int pfdID; // chosen or preset PFD ID
+ WGLGLCapabilities pixelFormatCaps = null; // chosen or preset PFD ID's caps
+ boolean pixelFormatSet = false; // indicates a preset PFD ID [caps]
+
+ if ( !extHDC && 1 <= ( pfdID = GDI.GetPixelFormat(hdc) ) ) {
+ // Pixelformat already set by either
+ // - a previous preselectGraphicsConfiguration() call on the same HDC,
+ // - the graphics driver, copying the HDC's pixelformat to the new one,
+ // - or the Java2D/OpenGL pipeline's configuration
+ if (DEBUG) {
+ System.err.println("updateGraphicsConfigurationGDI: NOTE: pixel format already chosen for HDC: " + toHexString(hdc)
+ + ", pixelformat " + pfdID);
+ }
+ pixelFormatSet = true;
+ pixelFormatCaps = WindowsWGLGraphicsConfiguration.PFD2GLCapabilities(glProfile, hdc, pfdID, onscreen);
+ } else {
+ if(null == pformats) {
+ pformats = WindowsWGLGraphicsConfiguration.wglAllGDIPFIDs(hdc);
+ }
+ final int winattrmask = GLGraphicsConfigurationUtil.getWinAttributeBits(onscreen, false);
+
+ for (int i = 0; i < pformats.length; i++) {
+ WindowsWGLGraphicsConfiguration.PFD2GLCapabilities(availableCaps, glProfile, hdc, pformats[i], winattrmask);
+ }
+
+ // 1st choice: get GLCapabilities based on users GLCapabilities setting recommendedIndex as preferred choice
+ PIXELFORMATDESCRIPTOR pfd = WindowsWGLGraphicsConfiguration.createPixelFormatDescriptor();
+ pfd = WindowsWGLGraphicsConfiguration.GLCapabilities2PFD(capsChosen, pfd);
+ pfdID = GDI.ChoosePixelFormat(hdc, pfd);
+ int recommendedIndex = -1 ;
+ if( 1 <= pfdID ) {
+ // seek index ..
+ for (recommendedIndex = availableCaps.size() - 1 ;
+ 0 <= recommendedIndex && pfdID != ((WGLGLCapabilities) availableCaps.get(recommendedIndex)).getPFDID();
+ recommendedIndex--)
+ { /* nop */ }
+ }
+ // 2nd choice: if no preferred recommendedIndex available
+ if (DEBUG) {
+ System.err.println("updateGraphicsConfigurationGDI: ChoosePixelFormat(HDC " + toHexString(hdc) + ") = " + pfdID + ", idx " + recommendedIndex + " (LastError: " + GDI.GetLastError() + ")");
+ }
+ int chosenIndex = chooseCapabilities(chooser, capsChosen, availableCaps, recommendedIndex);
+ if ( 0 > chosenIndex ) {
+ if (DEBUG) {
+ Thread.dumpStack();
+ }
+ return false;
+ }
+ pixelFormatCaps = (WGLGLCapabilities) availableCaps.get(chosenIndex);
+ if (DEBUG) {
+ System.err.println("!!! chosen pfdID (GDI): native recommended "+ (recommendedIndex+1) +
+ ", caps " + pixelFormatCaps);
+ }
+ }
+
+ if ( !extHDC && !pixelFormatSet ) {
+ if (!GDI.SetPixelFormat(hdc, pixelFormatCaps.getPFDID(), pixelFormatCaps.getPFD())) {
+ throw new GLException("Unable to set pixel format " + pixelFormatCaps.getPFDID() +
+ " for device context " + toHexString(hdc) +
+ ": error code " + GDI.GetLastError());
+ }
+ if (DEBUG) {
+ System.err.println("!!! setPixelFormat (GDI): hdc "+toHexString(hdc) +", "+config.getPixelFormatID()+" -> " + pixelFormatCaps.getPFDID());
+ }
+ }
+ config.setCapsPFD(pixelFormatCaps);
+ return true;
+ }
+}
+
diff --git a/src/jogl/classes/jogamp/opengl/windows/wgl/awt/WindowsAWTWGLGraphicsConfigurationFactory.java b/src/jogl/classes/jogamp/opengl/windows/wgl/awt/WindowsAWTWGLGraphicsConfigurationFactory.java
new file mode 100644
index 000000000..f753c08c5
--- /dev/null
+++ b/src/jogl/classes/jogamp/opengl/windows/wgl/awt/WindowsAWTWGLGraphicsConfigurationFactory.java
@@ -0,0 +1,173 @@
+/*
+ * Copyright (c) 2008 Sun Microsystems, Inc. All Rights Reserved.
+ * Copyright (c) 2010 JogAmp Community. 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.
+ */
+
+package com.jogamp.opengl.impl.windows.wgl.awt;
+
+
+import com.jogamp.common.util.ArrayHashSet;
+import com.jogamp.nativewindow.impl.jawt.windows.Win32SunJDKReflection;
+import com.jogamp.opengl.impl.GLGraphicsConfigurationFactory;
+import java.awt.GraphicsConfiguration;
+import java.awt.GraphicsDevice;
+
+import javax.media.nativewindow.AbstractGraphicsConfiguration;
+import javax.media.nativewindow.AbstractGraphicsDevice;
+import javax.media.nativewindow.AbstractGraphicsScreen;
+import javax.media.nativewindow.CapabilitiesChooser;
+import javax.media.nativewindow.CapabilitiesImmutable;
+import javax.media.nativewindow.DefaultGraphicsScreen;
+import javax.media.nativewindow.GraphicsConfigurationFactory;
+import javax.media.nativewindow.awt.AWTGraphicsConfiguration;
+import javax.media.nativewindow.awt.AWTGraphicsDevice;
+import javax.media.nativewindow.awt.AWTGraphicsScreen;
+import javax.media.nativewindow.windows.WindowsGraphicsDevice;
+
+import javax.media.opengl.GLCapabilitiesChooser;
+import javax.media.opengl.GLCapabilitiesImmutable;
+import javax.media.opengl.GLException;
+
+import com.jogamp.opengl.impl.windows.wgl.WindowsWGLGraphicsConfiguration;
+import javax.media.opengl.GLDrawableFactory;
+
+public class WindowsAWTWGLGraphicsConfigurationFactory extends GLGraphicsConfigurationFactory {
+ protected static final boolean DEBUG = com.jogamp.opengl.impl.Debug.debug("GraphicsConfiguration");
+
+ public WindowsAWTWGLGraphicsConfigurationFactory() {
+ GraphicsConfigurationFactory.registerFactory(javax.media.nativewindow.awt.AWTGraphicsDevice.class, this);
+ }
+
+ protected AbstractGraphicsConfiguration chooseGraphicsConfigurationImpl(
+ CapabilitiesImmutable capsChosen, CapabilitiesImmutable capsRequested,
+ CapabilitiesChooser chooser, AbstractGraphicsScreen absScreen) {
+ GraphicsDevice device = null;
+ if (absScreen != null &&
+ !(absScreen instanceof AWTGraphicsScreen)) {
+ throw new IllegalArgumentException("This GraphicsConfigurationFactory accepts only AWTGraphicsScreen objects");
+ }
+
+ if(null==absScreen) {
+ absScreen = AWTGraphicsScreen.createScreenDevice(-1, AbstractGraphicsDevice.DEFAULT_UNIT);
+ if(DEBUG) {
+ System.err.println("WindowsAWTWGLGraphicsConfigurationFactory: creating default device: "+absScreen);
+ }
+ }
+ AWTGraphicsScreen awtScreen = (AWTGraphicsScreen) absScreen;
+ device = ((AWTGraphicsDevice)awtScreen.getDevice()).getGraphicsDevice();
+
+ if ( !(capsChosen instanceof GLCapabilitiesImmutable) ) {
+ throw new IllegalArgumentException("This GraphicsConfigurationFactory accepts only GLCapabilities objects - chosen");
+ }
+
+ if ( !(capsRequested instanceof GLCapabilitiesImmutable) ) {
+ throw new IllegalArgumentException("This GraphicsConfigurationFactory accepts only GLCapabilities objects - requested");
+ }
+
+ if (chooser != null &&
+ !(chooser instanceof GLCapabilitiesChooser)) {
+ throw new IllegalArgumentException("This GraphicsConfigurationFactory accepts only GLCapabilitiesChooser objects");
+ }
+
+ if(DEBUG) {
+ System.err.println("WindowsAWTWGLGraphicsConfigurationFactory: got "+absScreen);
+ }
+
+ WindowsGraphicsDevice winDevice = new WindowsGraphicsDevice(AbstractGraphicsDevice.DEFAULT_UNIT);
+ DefaultGraphicsScreen winScreen = new DefaultGraphicsScreen(winDevice, awtScreen.getIndex());
+ GraphicsConfigurationFactory configFactory = GraphicsConfigurationFactory.getFactory(winDevice);
+ GLDrawableFactory drawableFactory = GLDrawableFactory.getFactory( ((GLCapabilitiesImmutable)capsChosen).getGLProfile() );
+
+ WindowsWGLGraphicsConfiguration winConfig = (WindowsWGLGraphicsConfiguration)
+ configFactory.chooseGraphicsConfiguration(capsChosen,
+ capsRequested,
+ chooser, winScreen);
+ if (winConfig == null) {
+ throw new GLException("Unable to choose a GraphicsConfiguration: "+capsChosen+",\n\t"+chooser+"\n\t"+winScreen);
+ }
+
+ GraphicsConfiguration chosenGC = null;
+
+ // 1st Choice: Create an AWT GraphicsConfiguration with the desired PFD
+ // This gc will probably not be able to support GDI (WGL_SUPPORT_GDI_ARB, PFD_SUPPORT_GDI)
+ // however on most GPUs this is the current situation for Windows,
+ // otherwise no hardware accelerated PFD could be achieved.
+ // - preselect with no constrains
+ // - try to create dedicated GC
+ winConfig.preselectGraphicsConfiguration(drawableFactory, null);
+ if ( 1 <= winConfig.getPixelFormatID() ) {
+ chosenGC = Win32SunJDKReflection.graphicsConfigurationGet(device, winConfig.getPixelFormatID());
+ if(DEBUG) {
+ System.err.println("WindowsAWTWGLGraphicsConfigurationFactory: Found new AWT PFD ID "+winConfig.getPixelFormatID()+" -> "+winConfig);
+ }
+ }
+
+ if( null == chosenGC ) {
+ // 2nd Choice: Choose and match the GL Visual with AWT:
+ // - collect all AWT PFDs
+ // - choose a GL config from the pool of AWT PFDs
+ //
+ // The resulting GraphicsConfiguration has to be 'forced' on the AWT native peer,
+ // ie. returned by GLCanvas's getGraphicsConfiguration() befor call by super.addNotify().
+ //
+
+ // collect all available PFD IDs
+ GraphicsConfiguration[] configs = device.getConfigurations();
+ int[] pfdIDs = new int[configs.length];
+ ArrayHashSet pfdIDOSet = new ArrayHashSet();
+ for (int i = 0; i < configs.length; i++) {
+ GraphicsConfiguration gc = configs[i];
+ pfdIDs[i] = Win32SunJDKReflection.graphicsConfigurationGetPixelFormatID(gc);
+ pfdIDOSet.add(new Integer(pfdIDs[i]));
+ if(DEBUG) {
+ System.err.println("AWT pfd["+i+"] "+pfdIDs[i]);
+ }
+ }
+ if(DEBUG) {
+ System.err.println("WindowsAWTWGLGraphicsConfigurationFactory: PFD IDs: "+pfdIDs.length+", unique: "+pfdIDOSet.size());
+ }
+ winConfig.preselectGraphicsConfiguration(drawableFactory, pfdIDs);
+ int gcIdx = pfdIDOSet.indexOf(new Integer(winConfig.getPixelFormatID()));
+ if( 0 > gcIdx ) {
+ chosenGC = configs[gcIdx];
+ if(DEBUG) {
+ System.err.println("WindowsAWTWGLGraphicsConfigurationFactory: Found matching AWT PFD ID "+winConfig.getPixelFormatID()+" -> "+winConfig);
+ }
+ }
+ }
+
+ if ( null == chosenGC ) {
+ throw new GLException("Unable to determine GraphicsConfiguration: "+winConfig);
+ }
+ return new AWTGraphicsConfiguration(awtScreen, winConfig.getChosenCapabilities(), winConfig.getRequestedCapabilities(),
+ chosenGC, winConfig);
+ }
+}