aboutsummaryrefslogtreecommitdiffstats
path: root/src/classes/com/sun/opengl/impl/windows
diff options
context:
space:
mode:
Diffstat (limited to 'src/classes/com/sun/opengl/impl/windows')
-rw-r--r--src/classes/com/sun/opengl/impl/windows/awt/WindowsJAWTWindow.java108
-rw-r--r--src/classes/com/sun/opengl/impl/windows/wgl/WindowsDummyWGLDrawable.java100
-rwxr-xr-xsrc/classes/com/sun/opengl/impl/windows/wgl/WindowsExternalWGLContext.java102
-rwxr-xr-xsrc/classes/com/sun/opengl/impl/windows/wgl/WindowsExternalWGLDrawable.java79
-rw-r--r--src/classes/com/sun/opengl/impl/windows/wgl/WindowsOffscreenWGLContext.java64
-rw-r--r--src/classes/com/sun/opengl/impl/windows/wgl/WindowsOffscreenWGLDrawable.java138
-rw-r--r--src/classes/com/sun/opengl/impl/windows/wgl/WindowsOnscreenWGLContext.java88
-rw-r--r--src/classes/com/sun/opengl/impl/windows/wgl/WindowsOnscreenWGLDrawable.java113
-rw-r--r--src/classes/com/sun/opengl/impl/windows/wgl/WindowsPbufferWGLContext.java155
-rw-r--r--src/classes/com/sun/opengl/impl/windows/wgl/WindowsPbufferWGLDrawable.java343
-rw-r--r--src/classes/com/sun/opengl/impl/windows/wgl/WindowsWGLContext.java300
-rw-r--r--src/classes/com/sun/opengl/impl/windows/wgl/WindowsWGLDrawable.java662
-rw-r--r--src/classes/com/sun/opengl/impl/windows/wgl/WindowsWGLDrawableFactory.java276
13 files changed, 2521 insertions, 7 deletions
diff --git a/src/classes/com/sun/opengl/impl/windows/awt/WindowsJAWTWindow.java b/src/classes/com/sun/opengl/impl/windows/awt/WindowsJAWTWindow.java
index 68ef2702b..bebd1e4dc 100644
--- a/src/classes/com/sun/opengl/impl/windows/awt/WindowsJAWTWindow.java
+++ b/src/classes/com/sun/opengl/impl/windows/awt/WindowsJAWTWindow.java
@@ -47,22 +47,116 @@ import com.sun.opengl.impl.*;
public class WindowsJAWTWindow extends JAWTWindow {
- // Variables for lockSurface/unlockSurface
- //private JAWT_DrawingSurface ds;
- //private JAWT_DrawingSurfaceInfo dsi;
- //private JAWT_WindowsDrawingSurfaceInfo x11dsi;
-
+ public static final boolean PROFILING = false; // FIXME
+ public static final int PROFILING_TICKS = 600; // FIXME
+
public WindowsJAWTWindow(Object comp) {
super(comp);
}
+ protected void initNative() throws NativeWindowException {
+ }
+
public int lockSurface() throws NativeWindowException {
- super.lockSurface();
- return 0;
+ int ret = super.lockSurface();
+ if(LOCK_SUCCESS != ret) {
+ return ret;
+ }
+
+ long startTime;
+ if (PROFILING) {
+ startTime = System.currentTimeMillis();
+ }
+ ds = JAWT.getJAWT().GetDrawingSurface(component);
+ if (ds == null) {
+ // Widget not yet realized
+ return LOCK_SURFACE_NOT_READY;
+ }
+ int res = ds.Lock();
+ if ((res & JAWTFactory.JAWT_LOCK_ERROR) != 0) {
+ throw new GLException("Unable to lock surface");
+ }
+ // See whether the surface changed and if so destroy the old
+ // OpenGL context so it will be recreated (NOTE: removeNotify
+ // should handle this case, but it may be possible that race
+ // conditions can cause this code to be triggered -- should test
+ // more)
+ if ((res & JAWTFactory.JAWT_LOCK_SURFACE_CHANGED) != 0) {
+ ret = LOCK_SURFACE_CHANGED;
+ }
+ dsi = ds.GetDrawingSurfaceInfo();
+ if (dsi == null) {
+ // Widget not yet realized
+ ds.Unlock();
+ JAWT.getJAWT().FreeDrawingSurface(ds);
+ ds = null;
+ return LOCK_SURFACE_NOT_READY;
+ }
+ win32dsi = (JAWT_Win32DrawingSurfaceInfo) dsi.platformInfo();
+ drawable = win32dsi.hdc();
+ // FIXME: Are the followup abstractions available ? would it be usefull ?
+ display = 0;
+ visualID = 0;
+ screen= 0;
+ screenIndex = 0;
+
+ if (drawable == 0) {
+ // Widget not yet realized
+ ds.FreeDrawingSurfaceInfo(dsi);
+ ds.Unlock();
+ JAWT.getJAWT().FreeDrawingSurface(ds);
+ ds = null;
+ dsi = null;
+ win32dsi = null;
+ return LOCK_SURFACE_NOT_READY;
+ }
+ if (PROFILING) {
+ long endTime = System.currentTimeMillis();
+ profilingLockSurfaceTime += (endTime - startTime);
+ if (++profilingLockSurfaceTicks == PROFILING_TICKS) {
+ System.err.println("LockSurface calls: " + profilingLockSurfaceTime + " ms / " + PROFILING_TICKS + " calls (" +
+ ((float) profilingLockSurfaceTime / (float) PROFILING_TICKS) + " ms/call)");
+ profilingLockSurfaceTime = 0;
+ profilingLockSurfaceTicks = 0;
+ }
+ }
+ return ret;
}
public void unlockSurface() {
+ if(!isSurfaceLocked()) return;
+ long startTime = 0;
+ if (PROFILING) {
+ startTime = System.currentTimeMillis();
+ }
+ ds.FreeDrawingSurfaceInfo(dsi);
+ ds.Unlock();
+ JAWT.getJAWT().FreeDrawingSurface(ds);
+ ds = null;
+ dsi = null;
+ win32dsi = null;
+ drawable = 0;
super.unlockSurface();
+ if (PROFILING) {
+ long endTime = System.currentTimeMillis();
+ profilingUnlockSurfaceTime += (endTime - startTime);
+ if (++profilingUnlockSurfaceTicks == PROFILING_TICKS) {
+ System.err.println("UnlockSurface calls: " + profilingUnlockSurfaceTime + " ms / " + PROFILING_TICKS + " calls (" +
+ ((float) profilingUnlockSurfaceTime / (float) PROFILING_TICKS) + " ms/call)");
+ profilingUnlockSurfaceTime = 0;
+ profilingUnlockSurfaceTicks = 0;
+ }
+ }
}
+
+ // Variables for lockSurface/unlockSurface
+ private JAWT_DrawingSurface ds;
+ private JAWT_DrawingSurfaceInfo dsi;
+ private JAWT_Win32DrawingSurfaceInfo win32dsi;
+ private long profilingLockSurfaceTime = 0;
+ private int profilingLockSurfaceTicks = 0;
+ private long profilingUnlockSurfaceTime = 0;
+ private int profilingUnlockSurfaceTicks = 0;
+
}
diff --git a/src/classes/com/sun/opengl/impl/windows/wgl/WindowsDummyWGLDrawable.java b/src/classes/com/sun/opengl/impl/windows/wgl/WindowsDummyWGLDrawable.java
new file mode 100644
index 000000000..5324a0c55
--- /dev/null
+++ b/src/classes/com/sun/opengl/impl/windows/wgl/WindowsDummyWGLDrawable.java
@@ -0,0 +1,100 @@
+/*
+ * 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.sun.opengl.impl.windows.wgl;
+
+import javax.media.opengl.*;
+import com.sun.opengl.impl.*;
+
+public class WindowsDummyWGLDrawable extends WindowsWGLDrawable {
+ private long hwnd, hdc;
+
+ public WindowsDummyWGLDrawable(GLDrawableFactory factory) {
+ super(factory, new NullWindow(), true, new GLCapabilities(), null);
+ // All entries to CreateDummyWindow must synchronize on one object
+ // to avoid accidentally registering the dummy window class twice
+ synchronized (WindowsDummyWGLDrawable.class) {
+ hwnd = WGL.CreateDummyWindow(0, 0, 1, 1);
+ }
+ hdc = WGL.GetDC(hwnd);
+ NullWindow nw = (NullWindow) getNativeWindow();
+ nw.setWindowHandle(hdc);
+ // Choose a (hopefully hardware-accelerated) OpenGL pixel format for this device context
+ GLCapabilities caps = new GLCapabilities();
+ caps.setDepthBits(16);
+ PIXELFORMATDESCRIPTOR pfd = glCapabilities2PFD(caps, true);
+ int pixelFormat = WGL.ChoosePixelFormat(hdc, pfd);
+ if ((pixelFormat == 0) ||
+ (!WGL.SetPixelFormat(hdc, pixelFormat, pfd))) {
+ destroy();
+ }
+ }
+
+ public void setSize(int width, int height) {
+ }
+
+ public int getWidth() {
+ return 1;
+ }
+
+ public int getHeight() {
+ return 1;
+ }
+
+ public GLContext createContext(GLContext shareWith) {
+ if (hdc == 0) {
+ // Construction failed
+ return null;
+ }
+ // FIXME: figure out how to hook back in the Java 2D / JOGL bridge
+ return new WindowsWGLContext(this, shareWith);
+ }
+
+ public void destroy() {
+ if (hdc != 0) {
+ WGL.ReleaseDC(hwnd, hdc);
+ hdc = 0;
+ }
+ if (hwnd != 0) {
+ WGL.ShowWindow(hwnd, WGL.SW_HIDE);
+ WGL.DestroyWindow(hwnd);
+ hwnd = 0;
+ }
+ }
+}
diff --git a/src/classes/com/sun/opengl/impl/windows/wgl/WindowsExternalWGLContext.java b/src/classes/com/sun/opengl/impl/windows/wgl/WindowsExternalWGLContext.java
new file mode 100755
index 000000000..493b38061
--- /dev/null
+++ b/src/classes/com/sun/opengl/impl/windows/wgl/WindowsExternalWGLContext.java
@@ -0,0 +1,102 @@
+/*
+ * 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.sun.opengl.impl.windows.wgl;
+
+import java.nio.*;
+import java.util.*;
+import javax.media.opengl.*;
+import com.sun.opengl.impl.*;
+
+public class WindowsExternalWGLContext extends WindowsWGLContext {
+ private boolean firstMakeCurrent = true;
+ private boolean created = true;
+ private GLContext lastContext;
+
+ public WindowsExternalWGLContext() {
+ // FIXME: figure out how to hook back in the Java 2D / JOGL bridge
+ super(null, null);
+ hglrc = WGL.wglGetCurrentContext();
+ if (hglrc == 0) {
+ throw new GLException("Error: attempted to make an external GLContext without a drawable/context current");
+ }
+ if (DEBUG) {
+ System.err.println(getThreadName() + ": !!! Created external OpenGL context " + toHexString(hglrc) + " for " + this);
+ }
+ GLContextShareSet.contextCreated(this);
+ resetGLFunctionAvailability();
+ }
+
+ 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 int makeCurrentImpl() throws GLException {
+ if (firstMakeCurrent) {
+ firstMakeCurrent = false;
+ return CONTEXT_CURRENT_NEW;
+ }
+ return CONTEXT_CURRENT;
+ }
+
+ protected void releaseImpl() throws GLException {
+ }
+
+ protected void destroyImpl() throws GLException {
+ created = false;
+ GLContextShareSet.contextDestroyed(this);
+ }
+
+ public boolean isCreated() {
+ return created;
+ }
+}
diff --git a/src/classes/com/sun/opengl/impl/windows/wgl/WindowsExternalWGLDrawable.java b/src/classes/com/sun/opengl/impl/windows/wgl/WindowsExternalWGLDrawable.java
new file mode 100755
index 000000000..2c89e1dd0
--- /dev/null
+++ b/src/classes/com/sun/opengl/impl/windows/wgl/WindowsExternalWGLDrawable.java
@@ -0,0 +1,79 @@
+/*
+ * 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.sun.opengl.impl.windows.wgl;
+
+import javax.media.opengl.*;
+import com.sun.opengl.impl.*;
+
+public class WindowsExternalWGLDrawable extends WindowsWGLDrawable {
+
+ public WindowsExternalWGLDrawable(GLDrawableFactory factory, NativeWindow component) {
+ super(factory, component, true, new GLCapabilities(), null);
+ }
+
+ public static WindowsExternalWGLDrawable create(GLDrawableFactory factory) {
+ long hdc = WGL.wglGetCurrentDC();
+ NullWindow nw = new NullWindow();
+ nw.setWindowHandle(hdc);
+ if (nw.getWindowHandle() == 0) {
+ throw new GLException("Error: attempted to make an external GLDrawable without a drawable/context current");
+ }
+ return new WindowsExternalWGLDrawable(factory, nw);
+ }
+
+ 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");
+ }
+
+ public void destroy() {
+ }
+}
diff --git a/src/classes/com/sun/opengl/impl/windows/wgl/WindowsOffscreenWGLContext.java b/src/classes/com/sun/opengl/impl/windows/wgl/WindowsOffscreenWGLContext.java
new file mode 100644
index 000000000..9f0a5d2a6
--- /dev/null
+++ b/src/classes/com/sun/opengl/impl/windows/wgl/WindowsOffscreenWGLContext.java
@@ -0,0 +1,64 @@
+/*
+ * 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.sun.opengl.impl.windows.wgl;
+
+import javax.media.opengl.*;
+import com.sun.opengl.impl.*;
+
+public class WindowsOffscreenWGLContext extends WindowsWGLContext {
+ public WindowsOffscreenWGLContext(WindowsOffscreenWGLDrawable 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/classes/com/sun/opengl/impl/windows/wgl/WindowsOffscreenWGLDrawable.java b/src/classes/com/sun/opengl/impl/windows/wgl/WindowsOffscreenWGLDrawable.java
new file mode 100644
index 000000000..84928ae6c
--- /dev/null
+++ b/src/classes/com/sun/opengl/impl/windows/wgl/WindowsOffscreenWGLDrawable.java
@@ -0,0 +1,138 @@
+/*
+ * 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.sun.opengl.impl.windows.wgl;
+
+import javax.media.opengl.*;
+import com.sun.opengl.impl.*;
+
+public class WindowsOffscreenWGLDrawable extends WindowsWGLDrawable {
+ private long origbitmap;
+ private long hbitmap;
+
+ public WindowsOffscreenWGLDrawable(GLDrawableFactory factory,
+ GLCapabilities capabilities,
+ GLCapabilitiesChooser chooser) {
+ super(factory, new NullWindow(), true, capabilities, chooser);
+ }
+
+ public GLContext createContext(GLContext shareWith) {
+ return new WindowsOffscreenWGLContext(this, shareWith);
+ }
+
+ public void setSize(int newWidth, int newHeight) {
+ super.setSize(newWidth, newHeight);
+ destroy();
+ create();
+ }
+
+ private void create() {
+ getFactory().lockToolkit();
+ try {
+ NullWindow nw = (NullWindow) getNativeWindow();
+ GLCapabilities capabilities = getCapabilities();
+ int width = getWidth();
+ int height = getHeight();
+ BITMAPINFO info = BITMAPINFO.create();
+ BITMAPINFOHEADER header = info.bmiHeader();
+ int bitsPerPixel = (capabilities.getRedBits() +
+ capabilities.getGreenBits() +
+ capabilities.getBlueBits());
+ header.biSize(header.size());
+ header.biWidth(width);
+ // NOTE: negating the height causes the DIB to be in top-down row
+ // order rather than bottom-up; ends up being correct during pixel
+ // readback
+ header.biHeight(-1 * height);
+ header.biPlanes((short) 1);
+ header.biBitCount((short) bitsPerPixel);
+ header.biXPelsPerMeter(0);
+ header.biYPelsPerMeter(0);
+ header.biClrUsed(0);
+ header.biClrImportant(0);
+ header.biCompression(WGL.BI_RGB);
+ header.biSizeImage(width * height * bitsPerPixel / 8);
+
+ long hdc = WGL.CreateCompatibleDC(0);
+ if (hdc == 0) {
+ System.out.println("LastError: " + WGL.GetLastError());
+ throw new GLException("Error creating device context for offscreen OpenGL context");
+ }
+ nw.setWindowHandle(hdc);
+
+ hbitmap = WGL.CreateDIBSection(hdc, info, WGL.DIB_RGB_COLORS, 0, 0, 0);
+ if (hbitmap == 0) {
+ WGL.DeleteDC(hdc);
+ hdc = 0;
+ throw new GLException("Error creating offscreen bitmap of width " + width +
+ ", height " + height);
+ }
+ if ((origbitmap = WGL.SelectObject(hdc, hbitmap)) == 0) {
+ WGL.DeleteObject(hbitmap);
+ hbitmap = 0;
+ WGL.DeleteDC(hdc);
+ hdc = 0;
+ throw new GLException("Error selecting bitmap into new device context");
+ }
+
+ choosePixelFormat(false);
+ } finally {
+ getFactory().unlockToolkit();
+ }
+ }
+
+ public void destroy() {
+ getFactory().lockToolkit();
+ try {
+ NullWindow nw = (NullWindow) getNativeWindow();
+ if (nw.getWindowHandle() != 0) {
+ // Must destroy bitmap and device context
+ WGL.SelectObject(nw.getWindowHandle(), origbitmap);
+ WGL.DeleteObject(hbitmap);
+ WGL.DeleteDC(nw.getWindowHandle());
+ origbitmap = 0;
+ hbitmap = 0;
+ nw.setWindowHandle(0);
+ setChosenGLCapabilities(null);
+ }
+ } finally {
+ getFactory().unlockToolkit();
+ }
+ }
+}
diff --git a/src/classes/com/sun/opengl/impl/windows/wgl/WindowsOnscreenWGLContext.java b/src/classes/com/sun/opengl/impl/windows/wgl/WindowsOnscreenWGLContext.java
new file mode 100644
index 000000000..02459f590
--- /dev/null
+++ b/src/classes/com/sun/opengl/impl/windows/wgl/WindowsOnscreenWGLContext.java
@@ -0,0 +1,88 @@
+/*
+ * 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.sun.opengl.impl.windows.wgl;
+
+import java.util.*;
+
+import javax.media.opengl.*;
+import com.sun.opengl.impl.*;
+
+public class WindowsOnscreenWGLContext extends WindowsWGLContext {
+ protected WindowsOnscreenWGLDrawable drawable;
+
+ public WindowsOnscreenWGLContext(WindowsOnscreenWGLDrawable drawable,
+ GLContext shareWith) {
+ super(drawable, shareWith);
+ this.drawable = drawable;
+ }
+
+ protected int makeCurrentImpl() throws GLException {
+ int lockRes = drawable.lockSurface();
+ boolean exceptionOccurred = false;
+ try {
+ if (lockRes == NativeWindow.LOCK_SURFACE_NOT_READY) {
+ return CONTEXT_NOT_CURRENT;
+ }
+ if (lockRes == NativeWindow.LOCK_SURFACE_CHANGED) {
+ destroyImpl();
+ }
+ int ret = super.makeCurrentImpl();
+ return ret;
+ } catch (RuntimeException e) {
+ exceptionOccurred = true;
+ throw e;
+ } finally {
+ if (exceptionOccurred ||
+ (isOptimizable() && lockRes != NativeWindow.LOCK_SURFACE_NOT_READY)) {
+ drawable.unlockSurface();
+ }
+ }
+ }
+
+ protected void releaseImpl() throws GLException {
+ try {
+ super.releaseImpl();
+ } finally {
+ if (!isOptimizable()) {
+ drawable.unlockSurface();
+ }
+ }
+ }
+}
diff --git a/src/classes/com/sun/opengl/impl/windows/wgl/WindowsOnscreenWGLDrawable.java b/src/classes/com/sun/opengl/impl/windows/wgl/WindowsOnscreenWGLDrawable.java
new file mode 100644
index 000000000..767928f16
--- /dev/null
+++ b/src/classes/com/sun/opengl/impl/windows/wgl/WindowsOnscreenWGLDrawable.java
@@ -0,0 +1,113 @@
+/*
+ * 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.sun.opengl.impl.windows.wgl;
+
+import javax.media.opengl.*;
+import com.sun.opengl.impl.*;
+
+public class WindowsOnscreenWGLDrawable extends WindowsWGLDrawable {
+ private static final boolean PROFILING = Debug.debug("WindowsOnscreenWGLDrawable.profiling");
+ private static final int PROFILING_TICKS = 200;
+ private int profilingLockSurfaceTicks;
+ private long profilingLockSurfaceTime;
+ private int profilingUnlockSurfaceTicks;
+ private long profilingUnlockSurfaceTime;
+ private int profilingSwapBuffersTicks;
+ private long profilingSwapBuffersTime;
+
+ protected WindowsOnscreenWGLDrawable(GLDrawableFactory factory, NativeWindow component,
+ GLCapabilities capabilities,
+ GLCapabilitiesChooser chooser) {
+ super(factory, component, false, capabilities, chooser);
+ }
+
+ public GLContext createContext(GLContext shareWith) {
+ return new WindowsOnscreenWGLContext(this, shareWith);
+ }
+
+ public void setSize(int width, int height) {
+ component.setSize(width, height);
+ }
+
+ public int getWidth() {
+ return component.getWidth();
+ }
+
+ public int getHeight() {
+ return component.getHeight();
+ }
+
+ public void swapBuffers() throws GLException {
+ boolean didLock = false;
+
+ if (getNativeWindow().getWindowHandle() == 0) {
+ if (lockSurface() == NativeWindow.LOCK_SURFACE_NOT_READY) {
+ return;
+ }
+ didLock = true;
+ }
+
+ long startTime = 0;
+ if (PROFILING) {
+ startTime = System.currentTimeMillis();
+ }
+
+ if (!WGL.SwapBuffers(getNativeWindow().getWindowHandle()) && (WGL.GetLastError() != 0)) {
+ 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;
+ }
+ }
+
+ if (didLock) {
+ unlockSurface();
+ }
+ }
+
+}
diff --git a/src/classes/com/sun/opengl/impl/windows/wgl/WindowsPbufferWGLContext.java b/src/classes/com/sun/opengl/impl/windows/wgl/WindowsPbufferWGLContext.java
new file mode 100644
index 000000000..7af3cbfc9
--- /dev/null
+++ b/src/classes/com/sun/opengl/impl/windows/wgl/WindowsPbufferWGLContext.java
@@ -0,0 +1,155 @@
+/*
+ * 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.sun.opengl.impl.windows.wgl;
+
+import javax.media.opengl.*;
+import com.sun.opengl.impl.*;
+
+public class WindowsPbufferWGLContext extends WindowsWGLContext {
+ private static final boolean DEBUG = Debug.debug("WindowsPbufferWGLContext");
+
+ // State for render-to-texture and render-to-texture-rectangle support
+ private WindowsPbufferWGLDrawable drawable;
+ private boolean rtt; // render-to-texture?
+ private boolean hasRTT; // render-to-texture extension available?
+ private boolean rect; // render-to-texture-rectangle?
+ private int textureTarget; // e.g. GL_TEXTURE_2D, GL_TEXTURE_RECTANGLE_NV
+ private int texture; // actual texture object
+
+ public WindowsPbufferWGLContext(WindowsPbufferWGLDrawable drawable,
+ GLContext shareWith) {
+ super(drawable, shareWith);
+ this.drawable = drawable;
+ }
+
+ 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(drawable.getPbuffer(), 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(drawable.getPbuffer(), WGLExt.WGL_FRONT_LEFT_ARB)) {
+ throw new GLException("Releasing of pbuffer from texture failed: " + wglGetLastError());
+ }
+ }
+ }
+
+ protected int makeCurrentImpl() throws GLException {
+ int res = super.makeCurrentImpl();
+ if (DEBUG && VERBOSE) {
+ System.err.println("WindowsPbufferWGLContext: super.makeCurrentImpl() = " + res);
+ }
+ if (res == CONTEXT_CURRENT_NEW) {
+ GLCapabilities capabilities = drawable.getCapabilities();
+
+ // Initialize render-to-texture support if requested
+ GL gl = getGL();
+ rtt = capabilities.getPbufferRenderToTexture();
+ rect = gl.isGL2() && 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_EXT;
+ } 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);
+ }
+ }
+ }
+ return res;
+ }
+
+ public int getFloatingPointMode() {
+ return drawable.getFloatingPointMode();
+ }
+
+ private static String wglGetLastError() {
+ return WindowsWGLDrawableFactory.wglGetLastError();
+ }
+}
diff --git a/src/classes/com/sun/opengl/impl/windows/wgl/WindowsPbufferWGLDrawable.java b/src/classes/com/sun/opengl/impl/windows/wgl/WindowsPbufferWGLDrawable.java
new file mode 100644
index 000000000..a7af86001
--- /dev/null
+++ b/src/classes/com/sun/opengl/impl/windows/wgl/WindowsPbufferWGLDrawable.java
@@ -0,0 +1,343 @@
+/*
+ * 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.sun.opengl.impl.windows.wgl;
+
+import javax.media.opengl.*;
+import com.sun.opengl.impl.*;
+
+public class WindowsPbufferWGLDrawable extends WindowsWGLDrawable {
+ private long cachedParentHdc;
+ 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,
+ GLCapabilities capabilities,
+ int initialWidth,
+ int initialHeight,
+ WindowsWGLDrawable dummyDrawable,
+ WGLExt wglExt) {
+ super(factory, new NullWindow(), true, capabilities, null);
+ if (initialWidth <= 0 || initialHeight <= 0) {
+ throw new GLException("Initial width and height of pbuffer must be positive (were (" +
+ initialWidth + ", " + initialHeight + "))");
+ }
+ NullWindow nw = (NullWindow) getNativeWindow();
+ nw.setSize(initialWidth, initialHeight);
+
+ if (DEBUG) {
+ System.out.println("Pbuffer caps on init: " + capabilities +
+ (capabilities.getPbufferRenderToTexture() ? " [rtt]" : "") +
+ (capabilities.getPbufferRenderToTextureRectangle() ? " [rect]" : "") +
+ (capabilities.getPbufferFloatingPointBuffers() ? " [float]" : ""));
+ }
+
+ createPbuffer(dummyDrawable.getNativeWindow().getWindowHandle(), wglExt);
+ }
+
+ public GLContext createContext(GLContext shareWith) {
+ return new WindowsPbufferWGLContext(this, shareWith);
+ }
+
+ public void destroy() {
+ getFactory().lockToolkit();
+ try {
+ NullWindow nw = (NullWindow) getNativeWindow();
+ if (nw.getWindowHandle() != 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)
+ WGLExt wglExt = cachedWGLExt;
+ if (wglExt.wglReleasePbufferDCARB(buffer, nw.getWindowHandle()) == 0) {
+ throw new GLException("Error releasing pbuffer device context: error code " + WGL.GetLastError());
+ }
+ nw.setWindowHandle(0);
+ if (!wglExt.wglDestroyPbufferARB(buffer)) {
+ throw new GLException("Error destroying pbuffer: error code " + WGL.GetLastError());
+ }
+ buffer = 0;
+ setChosenGLCapabilities(null);
+ }
+ } finally {
+ getFactory().unlockToolkit();
+ }
+ }
+
+ public void setSize(int newWidth, int newHeight) {
+ super.setSize(newWidth, newHeight);
+ destroy();
+ if(cachedParentHdc!=0 && cachedWGLExt!=null) {
+ createPbuffer(cachedParentHdc, cachedWGLExt);
+ }
+ }
+
+ public long getPbuffer() {
+ return buffer;
+ }
+
+ public int getFloatingPointMode() {
+ return floatMode;
+ }
+
+ public void swapBuffers() throws GLException {
+ // FIXME: this doesn't make sense any more because we don't have
+ // access to our OpenGL context here
+ /*
+ // FIXME: do we need to do anything if the pbuffer is double-buffered?
+ // For now, just grab the pixels for the render-to-texture support.
+ if (rtt && !hasRTT) {
+ if (DEBUG) {
+ System.err.println("Copying pbuffer data to GL_TEXTURE_2D state");
+ }
+
+ GL gl = getGL();
+ gl.glCopyTexSubImage2D(textureTarget, 0, 0, 0, 0, 0, width, height);
+ }
+ */
+ }
+
+ private void createPbuffer(long parentHdc, WGLExt wglExt) {
+ int[] iattributes = new int [2*MAX_ATTRIBS];
+ float[] fattributes = new float[1];
+ int[] floatModeTmp = new int[1];
+ int niattribs = 0;
+ int width, height;
+
+ GLCapabilities capabilities = getCapabilities();
+
+ if (DEBUG) {
+ System.out.println("Pbuffer parentHdc = " + toHexString(parentHdc));
+ System.out.println("Pbuffer caps: " + capabilities +
+ (capabilities.getPbufferRenderToTexture() ? " [rtt]" : "") +
+ (capabilities.getPbufferRenderToTextureRectangle() ? " [rect]" : "") +
+ (capabilities.getPbufferFloatingPointBuffers() ? " [float]" : ""));
+ }
+
+ getFactory().lockToolkit();
+ try {
+ if (!glCapabilities2iattributes(capabilities,
+ iattributes,
+ wglExt,
+ true,
+ floatModeTmp)) {
+ throw new GLException("Pbuffer-related extensions not supported");
+ }
+
+ floatMode = floatModeTmp[0];
+ boolean rtt = capabilities.getPbufferRenderToTexture();
+ boolean rect = capabilities.getPbufferRenderToTextureRectangle();
+ boolean useFloat = capabilities.getPbufferFloatingPointBuffers();
+ boolean ati = false;
+
+ if (useFloat) {
+ ati = (floatMode == GLPbuffer.ATI_FLOAT);
+ }
+
+ int[] pformats = new int[MAX_PFORMATS];
+ int nformats;
+ int[] nformatsTmp = new int[1];
+ if (!wglExt.wglChoosePixelFormatARB(parentHdc,
+ iattributes, 0,
+ fattributes, 0,
+ MAX_PFORMATS,
+ pformats, 0,
+ nformatsTmp, 0)) {
+ throw new GLException("pbuffer creation error: wglChoosePixelFormatARB() failed");
+ }
+ nformats = nformatsTmp[0];
+ if (nformats <= 0) {
+ throw new GLException("pbuffer creation error: Couldn't find a suitable pixel format");
+ }
+
+ boolean haveMultisample = wglExt.isExtensionAvailable("WGL_ARB_multisample");
+
+ if (DEBUG) {
+ System.err.println("" + nformats + " suitable pixel formats found");
+ // query pixel format
+ iattributes[0] = WGLExt.WGL_RED_BITS_ARB;
+ iattributes[1] = WGLExt.WGL_GREEN_BITS_ARB;
+ iattributes[2] = WGLExt.WGL_BLUE_BITS_ARB;
+ iattributes[3] = WGLExt.WGL_ALPHA_BITS_ARB;
+ iattributes[4] = WGLExt.WGL_DEPTH_BITS_ARB;
+ iattributes[5] = (useFloat ? (ati ? WGLExt.WGL_PIXEL_TYPE_ARB : WGLExt.WGL_FLOAT_COMPONENTS_NV) : WGLExt.WGL_RED_BITS_ARB);
+ iattributes[6] = (haveMultisample ? WGLExt.WGL_SAMPLE_BUFFERS_ARB : WGLExt.WGL_RED_BITS_ARB);
+ iattributes[7] = (haveMultisample ? WGLExt.WGL_SAMPLES_ARB : WGLExt.WGL_RED_BITS_ARB);
+ iattributes[8] = WGLExt.WGL_DRAW_TO_PBUFFER_ARB;
+ int[] ivalues = new int[9];
+ for (int i = 0; i < nformats; i++) {
+ if (!wglExt.wglGetPixelFormatAttribivARB(parentHdc, pformats[i], 0, 9, iattributes, 0, ivalues, 0)) {
+ throw new GLException("Error while querying pixel format " + pformats[i] +
+ "'s (index " + i + "'s) capabilities for debugging");
+ }
+ System.err.print("pixel format " + pformats[i] + " (index " + i + "): ");
+ System.err.print( "r: " + ivalues[0]);
+ System.err.print(" g: " + ivalues[1]);
+ System.err.print(" b: " + ivalues[2]);
+ System.err.print(" a: " + ivalues[3]);
+ System.err.print(" depth: " + ivalues[4]);
+ if (haveMultisample) {
+ System.err.print(" multisample: " + ivalues[6]);
+ }
+ System.err.print(" samples: " + ivalues[7]);
+ if (useFloat) {
+ if (ati) {
+ if (ivalues[5] == WGLExt.WGL_TYPE_RGBA_FLOAT_ATI) {
+ System.err.print(" [ati float]");
+ } else if (ivalues[5] != WGLExt.WGL_TYPE_RGBA_ARB) {
+ System.err.print(" [unknown pixel type " + ivalues[5] + "]");
+ }
+ } else {
+ if (ivalues[5] != 0) {
+ System.err.print(" [float]");
+ }
+ }
+ }
+
+ if (ivalues[8] != 0) {
+ System.err.print(" [pbuffer]");
+ }
+ System.err.println();
+ }
+ }
+
+ long tmpBuffer = 0;
+ int whichFormat = -1;
+ // 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 (tmpBuffer == 0) {
+ throw new GLException("pbuffer creation error: wglCreatePbufferARB() failed: tried " + nformats +
+ " pixel formats, last error was: " + wglGetLastError());
+ }
+
+ // Get the device context.
+ long tmpHdc = wglExt.wglGetPbufferDCARB(tmpBuffer);
+ if (tmpHdc == 0) {
+ throw new GLException("pbuffer creation error: wglGetPbufferDCARB() failed");
+ }
+
+ NullWindow nw = (NullWindow) getNativeWindow();
+ // Set up instance variables
+ buffer = tmpBuffer;
+ nw.setWindowHandle(tmpHdc);
+ cachedWGLExt = wglExt;
+ cachedParentHdc = parentHdc;
+
+ // Re-query chosen pixel format
+ {
+ niattribs = 0;
+ iattributes[niattribs++] = WGLExt.WGL_ACCELERATION_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_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_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;
+ iattributes[niattribs++] = (useFloat ? (ati ? WGLExt.WGL_PIXEL_TYPE_ARB : WGLExt.WGL_FLOAT_COMPONENTS_NV) : WGLExt.WGL_RED_BITS_ARB);
+ iattributes[niattribs++] = (haveMultisample ? WGLExt.WGL_SAMPLE_BUFFERS_ARB : WGLExt.WGL_RED_BITS_ARB);
+ iattributes[niattribs++] = (haveMultisample ? WGLExt.WGL_SAMPLES_ARB : WGLExt.WGL_RED_BITS_ARB);
+ iattributes[niattribs++] = WGLExt.WGL_DRAW_TO_PBUFFER_ARB;
+ int[] ivalues = new int[niattribs];
+ // FIXME: usually prefer to throw exceptions, but failure here is not critical
+ if (wglExt.wglGetPixelFormatAttribivARB(parentHdc, pformats[whichFormat], 0, niattribs, iattributes, 0, ivalues, 0)) {
+ setChosenGLCapabilities(iattributes2GLCapabilities(iattributes, niattribs, ivalues, false));
+ }
+ }
+
+ // 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];
+ nw.setSize(width, height);
+ } finally {
+ getFactory().unlockToolkit();
+ }
+
+ if (DEBUG) {
+ System.err.println("Created pbuffer " + width + " x " + height);
+ }
+ }
+
+ private static String wglGetLastError() {
+ return WindowsWGLDrawableFactory.wglGetLastError();
+ }
+}
diff --git a/src/classes/com/sun/opengl/impl/windows/wgl/WindowsWGLContext.java b/src/classes/com/sun/opengl/impl/windows/wgl/WindowsWGLContext.java
new file mode 100644
index 000000000..c6676d36d
--- /dev/null
+++ b/src/classes/com/sun/opengl/impl/windows/wgl/WindowsWGLContext.java
@@ -0,0 +1,300 @@
+/*
+ * 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.sun.opengl.impl.windows.wgl;
+
+import java.nio.*;
+import java.util.*;
+import javax.media.opengl.*;
+import com.sun.opengl.impl.*;
+
+public class WindowsWGLContext extends GLContextImpl {
+ protected WindowsWGLDrawable drawable;
+ protected long hglrc;
+ private boolean wglGetExtensionsStringEXTInitialized;
+ private boolean wglGetExtensionsStringEXTAvailable;
+ private static final Map/*<String, String>*/ functionNameMap;
+ private static final Map/*<String, String>*/ extensionNameMap;
+ 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
+ public WindowsWGLContext(WindowsWGLDrawable drawable,
+ GLContext shareWith) {
+ super(shareWith);
+ }
+
+ public Object getPlatformGLExtensions() {
+ return getWGLExt();
+ }
+
+ public WGLExt getWGLExt() {
+ if (wglExt == null) {
+ wglExt = new WGLExtImpl(this);
+ }
+ return wglExt;
+ }
+
+ public GLDrawable getGLDrawable() {
+ return drawable;
+ }
+
+ protected String mapToRealGLFunctionName(String glFunctionName) {
+ String lookup = (String) functionNameMap.get(glFunctionName);
+ if (lookup != null) {
+ return lookup;
+ }
+ return glFunctionName;
+ }
+
+ protected String mapToRealGLExtensionName(String glExtensionName) {
+ String lookup = (String) extensionNameMap.get(glExtensionName);
+ if (lookup != null) {
+ return lookup;
+ }
+ return glExtensionName;
+ }
+
+ /**
+ * Creates and initializes an appropriate OpenGL context. Should only be
+ * called by {@link #makeCurrentImpl()}.
+ */
+ protected void create() {
+ if (drawable.getNativeWindow().getWindowHandle() == 0) {
+ throw new GLException("Internal error: attempted to create OpenGL context without an associated drawable");
+ }
+ hglrc = WGL.wglCreateContext(drawable.getNativeWindow().getWindowHandle());
+ if (hglrc == 0) {
+ throw new GLException("Unable to create OpenGL context for device context " + toHexString(drawable.getNativeWindow().getWindowHandle()));
+ }
+ if (DEBUG) {
+ System.err.println(getThreadName() + ": !!! Created OpenGL context " + toHexString(hglrc) + " for " + this + ", device context " + toHexString(drawable.getNativeWindow().getWindowHandle()) + ", not yet sharing");
+ }
+ // Windows can set up sharing of display lists after creation time
+ WindowsWGLContext other = (WindowsWGLContext) GLContextShareSet.getShareContext(this);
+ long hglrc2 = 0;
+ if (other != null) {
+ hglrc2 = other.getHGLRC();
+ if (hglrc2 == 0) {
+ throw new GLException("GLContextShareSet returned an invalid OpenGL context");
+ }
+ if (!WGL.wglShareLists(hglrc2, hglrc)) {
+ throw new GLException("wglShareLists(" + toHexString(hglrc2) +
+ ", " + toHexString(hglrc) + ") failed: error code " +
+ WGL.GetLastError());
+ }
+ }
+ GLContextShareSet.contextCreated(this);
+ if (DEBUG) {
+ System.err.println(getThreadName() + ": !!! Created OpenGL context " + toHexString(hglrc) + " for " + this + ", device context " + toHexString(drawable.getNativeWindow().getWindowHandle()) + ", sharing with " + toHexString(hglrc2));
+ }
+ }
+
+ protected int makeCurrentImpl() throws GLException {
+ if (drawable.getNativeWindow().getWindowHandle() == 0) {
+ if (DEBUG) {
+ System.err.println("drawable not properly initialized");
+ }
+ return CONTEXT_NOT_CURRENT;
+ }
+ boolean created = false;
+ if (hglrc == 0) {
+ create();
+ if (DEBUG) {
+ System.err.println(getThreadName() + ": !!! Created GL context for " + getClass().getName());
+ }
+ created = true;
+ }
+
+ if (WGL.wglGetCurrentContext() != hglrc) {
+ if (!WGL.wglMakeCurrent(drawable.getNativeWindow().getWindowHandle(), hglrc)) {
+ throw new GLException("Error making context current: " + WGL.GetLastError());
+ } else {
+ if (DEBUG && VERBOSE) {
+ System.err.println(getThreadName() + ": wglMakeCurrent(hdc " + toHexString(drawable.getNativeWindow().getWindowHandle()) +
+ ", hglrc " + toHexString(hglrc) + ") succeeded");
+ }
+ }
+ }
+
+ if (created) {
+ resetGLFunctionAvailability();
+ return CONTEXT_CURRENT_NEW;
+ }
+ return CONTEXT_CURRENT;
+ }
+
+ protected void releaseImpl() throws GLException {
+ if (!NO_FREE) {
+ if (!WGL.wglMakeCurrent(0, 0)) {
+ throw new GLException("Error freeing OpenGL context: " + WGL.GetLastError());
+ }
+ }
+ }
+
+ protected void destroyImpl() throws GLException {
+ if (hglrc != 0) {
+ if (!WGL.wglDeleteContext(hglrc)) {
+ throw new GLException("Unable to delete OpenGL context");
+ }
+ if (DEBUG) {
+ System.err.println(getThreadName() + ": !!! Destroyed OpenGL context " + toHexString(hglrc));
+ }
+ hglrc = 0;
+ GLContextShareSet.contextDestroyed(this);
+ }
+ }
+
+ public boolean isCreated() {
+ return (hglrc != 0);
+ }
+
+ public void copy(GLContext source, int mask) throws GLException {
+ long dst = getHGLRC();
+ long src = ((WindowsWGLContext) source).getHGLRC();
+ if (src == 0) {
+ throw new GLException("Source OpenGL context has not been created");
+ }
+ if (dst == 0) {
+ throw new GLException("Destination OpenGL context has not been created");
+ }
+ if (!WGL.wglCopyContext(src, dst, mask)) {
+ throw new GLException("wglCopyContext failed");
+ }
+ }
+
+ protected void resetGLFunctionAvailability() {
+ super.resetGLFunctionAvailability();
+ if (DEBUG) {
+ System.err.println(getThreadName() + ": !!! Initializing WGL extension address table for " + this);
+ }
+ if (wglExtProcAddressTable == null) {
+ // FIXME: cache ProcAddressTables by capability bits so we can
+ // share them among contexts with the same capabilities
+ wglExtProcAddressTable = new WGLExtProcAddressTable();
+ }
+ resetProcAddressTable(getWGLExtProcAddressTable());
+ }
+
+ public final WGLExtProcAddressTable getWGLExtProcAddressTable() {
+ return wglExtProcAddressTable;
+ }
+
+ public String getPlatformExtensionsString() {
+ if (!wglGetExtensionsStringEXTInitialized) {
+ wglGetExtensionsStringEXTAvailable = (WGL.wglGetProcAddress("wglGetExtensionsStringEXT") != 0);
+ wglGetExtensionsStringEXTInitialized = true;
+ }
+ if (wglGetExtensionsStringEXTAvailable) {
+ return getWGLExt().wglGetExtensionsStringEXT();
+ } else {
+ return "";
+ }
+ }
+
+ public boolean isFunctionAvailable(String glFunctionName)
+ {
+ boolean available = super.isFunctionAvailable(glFunctionName);
+
+ // Sanity check for implementations that use proc addresses for run-time
+ // linking: if the function IS available, then make sure there's a proc
+ // address for it if it's an extension or not part of the OpenGL 1.1 core
+ // (post GL 1.1 functions are run-time linked on windows).
+ /* FIXME:
+ assert(!available ||
+ (getGLProcAddressTable().getAddressFor(mapToRealGLFunctionName(glFunctionName)) != 0 ||
+ FunctionAvailabilityCache.isPartOfGLCore("1.1", mapToRealGLFunctionName(glFunctionName)))
+ ); */
+
+ return available;
+ }
+
+ public void setSwapInterval(int interval) {
+ // FIXME: make the context current first? Currently assumes that
+ // will not be necessary. Make the caller do this?
+ WGLExt wglExt = getWGLExt();
+ if (wglExt.isExtensionAvailable("WGL_EXT_swap_control")) {
+ wglExt.wglSwapIntervalEXT(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");
+ }
+
+ //----------------------------------------------------------------------
+ // Internals only below this point
+ //
+
+ public long getHGLRC() {
+ return hglrc;
+ }
+}
diff --git a/src/classes/com/sun/opengl/impl/windows/wgl/WindowsWGLDrawable.java b/src/classes/com/sun/opengl/impl/windows/wgl/WindowsWGLDrawable.java
new file mode 100644
index 000000000..1b1805e91
--- /dev/null
+++ b/src/classes/com/sun/opengl/impl/windows/wgl/WindowsWGLDrawable.java
@@ -0,0 +1,662 @@
+/*
+ * 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.sun.opengl.impl.windows.wgl;
+
+import javax.media.opengl.*;
+import com.sun.opengl.impl.*;
+
+public abstract class WindowsWGLDrawable extends GLDrawableImpl {
+ protected static final boolean DEBUG = Debug.debug("WindowsWGLDrawable");
+
+ protected GLCapabilitiesChooser chooser;
+ protected boolean pixelFormatChosen;
+
+ // Workaround for problems on Intel 82855 cards
+ private int setPixelFormatFailCount;
+ private static final int MAX_SET_PIXEL_FORMAT_FAIL_COUNT = 5;
+
+ protected static final int MAX_PFORMATS = 256;
+ protected static final int MAX_ATTRIBS = 256;
+
+ public WindowsWGLDrawable(GLDrawableFactory factory, NativeWindow comp, boolean realized,
+ GLCapabilities capabilities,
+ GLCapabilitiesChooser chooser) {
+ super(factory, comp, realized);
+ setChosenGLCapabilities(capabilities);
+ this.chooser = chooser;
+ }
+
+ public int lockSurface() throws GLException {
+ int ret = super.lockSurface();
+ if(NativeWindow.LOCK_SURFACE_NOT_READY == ret) {
+ return ret;
+ }
+ if (!pixelFormatChosen) {
+ try {
+ choosePixelFormat(true);
+ setPixelFormatFailCount = 0;
+ } catch (RuntimeException e) {
+ // Workaround for problems seen on Intel 82855 cards in particular
+ // Make it look like the lockSurface() call didn't succeed
+ unlockSurface();
+ if (e instanceof GLException) {
+ if (++setPixelFormatFailCount == MAX_SET_PIXEL_FORMAT_FAIL_COUNT) {
+ setPixelFormatFailCount = 0;
+ throw e;
+ }
+ return NativeWindow.LOCK_SURFACE_NOT_READY;
+ } else {
+ // Probably a user error in the GLCapabilitiesChooser or similar.
+ // Don't propagate non-GLExceptions out because calling code
+ // expects to catch only that exception type
+ throw new GLException(e);
+ }
+ }
+ }
+ return ret;
+ }
+
+
+ protected void choosePixelFormat(boolean onscreen) {
+ PIXELFORMATDESCRIPTOR pfd = null;
+ int pixelFormat = 0;
+ GLCapabilities chosenCaps = null;
+ GLCapabilities capabilities = getCapabilities();
+ long hdc = getNativeWindow().getWindowHandle();
+ if (onscreen) {
+ if ((pixelFormat = WGL.GetPixelFormat(hdc)) != 0) {
+ // The Java2D/OpenGL pipeline probably already set a pixel
+ // format for this canvas.
+ if (DEBUG) {
+ System.err.println("NOTE: pixel format already chosen (by Java2D/OpenGL pipeline?) for window: " +
+ WGL.GetPixelFormat(hdc));
+ }
+ pfd = newPixelFormatDescriptor();
+ if (WGL.DescribePixelFormat(hdc, pixelFormat, pfd.size(), pfd) == 0) {
+ // FIXME: should this just be a warning? Not really critical...
+ throw new GLException("Unable to describe pixel format " + pixelFormat +
+ " of window set by Java2D/OpenGL pipeline");
+ }
+ setChosenGLCapabilities(pfd2GLCapabilities(pfd));
+ pixelFormatChosen = true;
+ return;
+ }
+
+ GLCapabilities[] availableCaps = null;
+ int numFormats = 0;
+ pfd = newPixelFormatDescriptor();
+ // Produce a recommended pixel format selection for the GLCapabilitiesChooser.
+ // Use wglChoosePixelFormatARB if user requested multisampling and if we have it available
+ WindowsWGLDrawable dummyDrawable = null;
+ GLContextImpl dummyContext = null;
+ WGLExt dummyWGLExt = null;
+ if (capabilities.getSampleBuffers()) {
+ dummyDrawable = new WindowsDummyWGLDrawable(getFactory());
+ dummyContext = (GLContextImpl) dummyDrawable.createContext(null);
+ if (dummyContext != null) {
+ dummyContext.makeCurrent();
+ dummyWGLExt = (WGLExt) dummyContext.getPlatformGLExtensions();
+ }
+ }
+ int recommendedPixelFormat = -1;
+ boolean haveWGLChoosePixelFormatARB = false;
+ boolean haveWGLARBMultisample = false;
+ boolean gotAvailableCaps = false;
+ if (dummyWGLExt != null) {
+ try {
+ haveWGLChoosePixelFormatARB = dummyWGLExt.isExtensionAvailable("WGL_ARB_pixel_format");
+ if (haveWGLChoosePixelFormatARB) {
+ haveWGLARBMultisample = dummyWGLExt.isExtensionAvailable("WGL_ARB_multisample");
+
+ int[] iattributes = new int [2 * MAX_ATTRIBS];
+ int[] iresults = new int [2 * MAX_ATTRIBS];
+ float[] fattributes = new float[1];
+
+ if (glCapabilities2iattributes(capabilities,
+ iattributes,
+ dummyWGLExt,
+ false,
+ null)) {
+ int[] pformats = new int[MAX_PFORMATS];
+ int[] numFormatsTmp = new int[1];
+ if (dummyWGLExt.wglChoosePixelFormatARB(hdc,
+ iattributes, 0,
+ fattributes, 0,
+ MAX_PFORMATS,
+ pformats, 0,
+ numFormatsTmp, 0)) {
+ numFormats = numFormatsTmp[0];
+ if (numFormats > 0) {
+ // Remove one-basing of pixel format (added on later)
+ recommendedPixelFormat = pformats[0] - 1;
+ if (DEBUG) {
+ System.err.println(getThreadName() + ": Used wglChoosePixelFormatARB to recommend pixel format " + recommendedPixelFormat);
+ }
+ }
+ } else {
+ if (DEBUG) {
+ System.err.println(getThreadName() + ": wglChoosePixelFormatARB failed: " + WGL.GetLastError() );
+ Thread.dumpStack();
+ }
+ }
+ if (DEBUG) {
+ if (recommendedPixelFormat < 0) {
+ System.err.print(getThreadName() + ": wglChoosePixelFormatARB didn't recommend a pixel format");
+ if (capabilities.getSampleBuffers()) {
+ System.err.print(" for multisampled GLCapabilities");
+ }
+ System.err.println();
+ }
+ }
+
+ // Produce a list of GLCapabilities to give to the
+ // GLCapabilitiesChooser.
+ // Use wglGetPixelFormatAttribivARB instead of
+ // DescribePixelFormat to get higher-precision information
+ // about the pixel format (should make the GLCapabilities
+ // more precise as well...i.e., remove the
+ // "HardwareAccelerated" bit, which is basically
+ // meaningless, and put in whether it can render to a
+ // window, to a pbuffer, or to a pixmap)
+ int niattribs = 0;
+ iattributes[0] = WGLExt.WGL_NUMBER_PIXEL_FORMATS_ARB;
+ if (dummyWGLExt.wglGetPixelFormatAttribivARB(hdc, 0, 0, 1, iattributes, 0, iresults, 0)) {
+ numFormats = iresults[0];
+
+ if (DEBUG) {
+ System.err.println("wglGetPixelFormatAttribivARB reported WGL_NUMBER_PIXEL_FORMATS_ARB = " + numFormats);
+ }
+
+ // Should we be filtering out the pixel formats which aren't
+ // applicable, as we are doing here?
+ // We don't have enough information in the GLCapabilities to
+ // represent those that aren't...
+ iattributes[niattribs++] = WGLExt.WGL_DRAW_TO_WINDOW_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;
+ }
+
+ availableCaps = new GLCapabilities[numFormats];
+ for (int i = 0; i < numFormats; i++) {
+ if (!dummyWGLExt.wglGetPixelFormatAttribivARB(hdc, i+1, 0, niattribs, iattributes, 0, iresults, 0)) {
+ throw new GLException("Error getting pixel format attributes for pixel format " + (i + 1) + " of device context");
+ }
+ availableCaps[i] = iattributes2GLCapabilities(iattributes, niattribs, iresults, true);
+ }
+ gotAvailableCaps = true;
+ } else {
+ long lastErr = WGL.GetLastError();
+ // Intel Extreme graphics fails with a zero error code
+ if (lastErr != 0) {
+ throw new GLException("Unable to enumerate pixel formats of window using wglGetPixelFormatAttribivARB: error code " + WGL.GetLastError());
+ }
+ }
+ }
+ }
+ } finally {
+ dummyContext.release();
+ dummyContext.destroy();
+ dummyDrawable.destroy();
+ }
+ }
+
+ // Fallback path for older cards, in particular Intel Extreme motherboard graphics
+ if (!gotAvailableCaps) {
+ if (DEBUG) {
+ if (!capabilities.getSampleBuffers()) {
+ System.err.println(getThreadName() + ": Using ChoosePixelFormat because multisampling not requested");
+ } else {
+ System.err.println(getThreadName() + ": Using ChoosePixelFormat because no wglChoosePixelFormatARB");
+ }
+ }
+ pfd = glCapabilities2PFD(capabilities, onscreen);
+ // Remove one-basing of pixel format (added on later)
+ recommendedPixelFormat = WGL.ChoosePixelFormat(hdc, pfd) - 1;
+
+ numFormats = WGL.DescribePixelFormat(hdc, 1, 0, null);
+ if (numFormats == 0) {
+ throw new GLException("Unable to enumerate pixel formats of window for GLCapabilitiesChooser");
+ }
+ availableCaps = new GLCapabilities[numFormats];
+ for (int i = 0; i < numFormats; i++) {
+ if (WGL.DescribePixelFormat(hdc, 1 + i, pfd.size(), pfd) == 0) {
+ throw new GLException("Error describing pixel format " + (1 + i) + " of device context");
+ }
+ availableCaps[i] = pfd2GLCapabilities(pfd);
+ }
+ }
+
+ // NOTE: officially, should make a copy of all of these
+ // GLCapabilities to avoid mutation by the end user during the
+ // chooseCapabilities call, but for the time being, assume they
+ // won't be changed
+
+ // Supply information to chooser
+ pixelFormat = chooser.chooseCapabilities(capabilities, availableCaps, recommendedPixelFormat);
+ if ((pixelFormat < 0) || (pixelFormat >= numFormats)) {
+ throw new GLException("Invalid result " + pixelFormat +
+ " from GLCapabilitiesChooser (should be between 0 and " +
+ (numFormats - 1) + ")");
+ }
+ if (DEBUG) {
+ System.err.println(getThreadName() + ": Chosen pixel format (" + pixelFormat + "):");
+ System.err.println(availableCaps[pixelFormat]);
+ }
+ chosenCaps = availableCaps[pixelFormat];
+ pixelFormat += 1; // one-base the index
+ if (WGL.DescribePixelFormat(hdc, pixelFormat, pfd.size(), pfd) == 0) {
+ throw new GLException("Error re-describing the chosen pixel format: " + WGL.GetLastError());
+ }
+ } else {
+ // For now, use ChoosePixelFormat for offscreen surfaces until
+ // we figure out how to properly choose an offscreen-
+ // compatible pixel format
+ pfd = glCapabilities2PFD(capabilities, onscreen);
+ pixelFormat = WGL.ChoosePixelFormat(hdc, pfd);
+ }
+ if (!WGL.SetPixelFormat(hdc, pixelFormat, pfd)) {
+ long lastError = WGL.GetLastError();
+ if (DEBUG) {
+ System.err.println(getThreadName() + ": SetPixelFormat failed: current context = " + WGL.wglGetCurrentContext() +
+ ", current DC = " + WGL.wglGetCurrentDC());
+ System.err.println(getThreadName() + ": GetPixelFormat(hdc " + toHexString(hdc) + ") returns " + WGL.GetPixelFormat(hdc));
+ }
+ throw new GLException("Unable to set pixel format " + pixelFormat + " for device context " + toHexString(hdc) + ": error code " + lastError);
+ }
+ // Reuse the previously-constructed GLCapabilities because it
+ // turns out that using DescribePixelFormat on some pixel formats
+ // (which, for example, support full-scene antialiasing) for some
+ // reason return that they are not OpenGL-capable
+ if (chosenCaps != null) {
+ setChosenGLCapabilities(chosenCaps);
+ } else {
+ setChosenGLCapabilities(pfd2GLCapabilities(pfd));
+ }
+ pixelFormatChosen = true;
+ }
+
+ protected static PIXELFORMATDESCRIPTOR glCapabilities2PFD(GLCapabilities caps, boolean onscreen) {
+ int colorDepth = (caps.getRedBits() +
+ caps.getGreenBits() +
+ caps.getBlueBits());
+ if (colorDepth < 15) {
+ throw new GLException("Bit depths < 15 (i.e., non-true-color) not supported");
+ }
+ PIXELFORMATDESCRIPTOR pfd = newPixelFormatDescriptor();
+ int pfdFlags = (WGL.PFD_SUPPORT_OPENGL |
+ WGL.PFD_GENERIC_ACCELERATED);
+ if (caps.getDoubleBuffered()) {
+ pfdFlags |= WGL.PFD_DOUBLEBUFFER;
+ }
+ if (onscreen) {
+ pfdFlags |= WGL.PFD_DRAW_TO_WINDOW;
+ } else {
+ pfdFlags |= WGL.PFD_DRAW_TO_BITMAP;
+ }
+ if (caps.getStereo()) {
+ pfdFlags |= WGL.PFD_STEREO;
+ }
+ pfd.dwFlags(pfdFlags);
+ pfd.iPixelType((byte) WGL.PFD_TYPE_RGBA);
+ pfd.cColorBits((byte) colorDepth);
+ pfd.cRedBits ((byte) caps.getRedBits());
+ pfd.cGreenBits((byte) caps.getGreenBits());
+ pfd.cBlueBits ((byte) caps.getBlueBits());
+ pfd.cAlphaBits((byte) caps.getAlphaBits());
+ int accumDepth = (caps.getAccumRedBits() +
+ caps.getAccumGreenBits() +
+ caps.getAccumBlueBits());
+ pfd.cAccumBits ((byte) accumDepth);
+ pfd.cAccumRedBits ((byte) caps.getAccumRedBits());
+ pfd.cAccumGreenBits((byte) caps.getAccumGreenBits());
+ pfd.cAccumBlueBits ((byte) caps.getAccumBlueBits());
+ pfd.cAccumAlphaBits((byte) caps.getAccumAlphaBits());
+ pfd.cDepthBits((byte) caps.getDepthBits());
+ pfd.cStencilBits((byte) caps.getStencilBits());
+ pfd.iLayerType((byte) WGL.PFD_MAIN_PLANE);
+ return pfd;
+ }
+
+ protected static PIXELFORMATDESCRIPTOR newPixelFormatDescriptor() {
+ PIXELFORMATDESCRIPTOR pfd = PIXELFORMATDESCRIPTOR.create();
+ pfd.nSize((short) pfd.size());
+ pfd.nVersion((short) 1);
+ return pfd;
+ }
+
+ protected static GLCapabilities pfd2GLCapabilities(PIXELFORMATDESCRIPTOR pfd) {
+ if ((pfd.dwFlags() & WGL.PFD_SUPPORT_OPENGL) == 0) {
+ return null;
+ }
+ GLCapabilities res = new GLCapabilities();
+ res.setRedBits (pfd.cRedBits());
+ res.setGreenBits (pfd.cGreenBits());
+ res.setBlueBits (pfd.cBlueBits());
+ res.setAlphaBits (pfd.cAlphaBits());
+ res.setAccumRedBits (pfd.cAccumRedBits());
+ res.setAccumGreenBits(pfd.cAccumGreenBits());
+ res.setAccumBlueBits (pfd.cAccumBlueBits());
+ res.setAccumAlphaBits(pfd.cAccumAlphaBits());
+ res.setDepthBits (pfd.cDepthBits());
+ res.setStencilBits (pfd.cStencilBits());
+ res.setDoubleBuffered((pfd.dwFlags() & WGL.PFD_DOUBLEBUFFER) != 0);
+ res.setStereo ((pfd.dwFlags() & WGL.PFD_STEREO) != 0);
+ res.setHardwareAccelerated(((pfd.dwFlags() & WGL.PFD_GENERIC_FORMAT) == 0) ||
+ ((pfd.dwFlags() & WGL.PFD_GENERIC_ACCELERATED) != 0));
+ return res;
+ }
+
+ protected static boolean glCapabilities2iattributes(GLCapabilities capabilities,
+ int[] iattributes,
+ WGLExt wglExt,
+ boolean pbuffer,
+ int[] floatMode) throws GLException {
+ if (!wglExt.isExtensionAvailable("WGL_ARB_pixel_format")) {
+ return false;
+ }
+
+ int niattribs = 0;
+
+ iattributes[niattribs++] = WGLExt.WGL_SUPPORT_OPENGL_ARB;
+ iattributes[niattribs++] = GL.GL_TRUE;
+ if (pbuffer) {
+ iattributes[niattribs++] = WGLExt.WGL_DRAW_TO_PBUFFER_ARB;
+ iattributes[niattribs++] = GL.GL_TRUE;
+ } else {
+ iattributes[niattribs++] = WGLExt.WGL_DRAW_TO_WINDOW_ARB;
+ iattributes[niattribs++] = GL.GL_TRUE;
+ }
+
+ iattributes[niattribs++] = WGLExt.WGL_DOUBLE_BUFFER_ARB;
+ if (capabilities.getDoubleBuffered()) {
+ iattributes[niattribs++] = GL.GL_TRUE;
+ } else {
+ iattributes[niattribs++] = GL.GL_FALSE;
+ }
+
+ iattributes[niattribs++] = WGLExt.WGL_STEREO_ARB;
+ if (capabilities.getStereo()) {
+ iattributes[niattribs++] = GL.GL_TRUE;
+ } else {
+ iattributes[niattribs++] = GL.GL_FALSE;
+ }
+
+ iattributes[niattribs++] = WGLExt.WGL_DEPTH_BITS_ARB;
+ iattributes[niattribs++] = capabilities.getDepthBits();
+ iattributes[niattribs++] = WGLExt.WGL_RED_BITS_ARB;
+ iattributes[niattribs++] = capabilities.getRedBits();
+ iattributes[niattribs++] = WGLExt.WGL_GREEN_BITS_ARB;
+ iattributes[niattribs++] = capabilities.getGreenBits();
+ iattributes[niattribs++] = WGLExt.WGL_BLUE_BITS_ARB;
+ iattributes[niattribs++] = capabilities.getBlueBits();
+ iattributes[niattribs++] = WGLExt.WGL_ALPHA_BITS_ARB;
+ iattributes[niattribs++] = capabilities.getAlphaBits();
+ iattributes[niattribs++] = WGLExt.WGL_STENCIL_BITS_ARB;
+ iattributes[niattribs++] = capabilities.getStencilBits();
+ if (capabilities.getAccumRedBits() > 0 ||
+ capabilities.getAccumGreenBits() > 0 ||
+ capabilities.getAccumBlueBits() > 0 ||
+ capabilities.getAccumAlphaBits() > 0) {
+ iattributes[niattribs++] = WGLExt.WGL_ACCUM_BITS_ARB;
+ iattributes[niattribs++] = (capabilities.getAccumRedBits() +
+ capabilities.getAccumGreenBits() +
+ capabilities.getAccumBlueBits() +
+ capabilities.getAccumAlphaBits());
+ iattributes[niattribs++] = WGLExt.WGL_ACCUM_RED_BITS_ARB;
+ iattributes[niattribs++] = capabilities.getAccumRedBits();
+ iattributes[niattribs++] = WGLExt.WGL_ACCUM_GREEN_BITS_ARB;
+ iattributes[niattribs++] = capabilities.getAccumGreenBits();
+ iattributes[niattribs++] = WGLExt.WGL_ACCUM_BLUE_BITS_ARB;
+ iattributes[niattribs++] = capabilities.getAccumBlueBits();
+ iattributes[niattribs++] = WGLExt.WGL_ACCUM_ALPHA_BITS_ARB;
+ iattributes[niattribs++] = capabilities.getAccumAlphaBits();
+ }
+
+ if (wglExt.isExtensionAvailable("WGL_ARB_multisample")) {
+ if (capabilities.getSampleBuffers()) {
+ iattributes[niattribs++] = WGLExt.WGL_SAMPLE_BUFFERS_ARB;
+ iattributes[niattribs++] = GL.GL_TRUE;
+ iattributes[niattribs++] = WGLExt.WGL_SAMPLES_ARB;
+ iattributes[niattribs++] = capabilities.getNumSamples();
+ }
+ }
+
+ boolean rtt = capabilities.getPbufferRenderToTexture();
+ boolean rect = capabilities.getPbufferRenderToTextureRectangle();
+ boolean useFloat = capabilities.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 (!wglExt.isExtensionAvailable("GL_NV_texture_rectangle")) {
+ throw new GLException("Render-to-texture-rectangle requires GL_NV_texture_rectangle extension");
+ }
+ }
+
+ if (useFloat) {
+ if (!wglExt.isExtensionAvailable("WGL_ATI_pixel_format_float") &&
+ !wglExt.isExtensionAvailable("WGL_NV_float_buffer")) {
+ throw new GLException("Floating-point pbuffers not supported by this hardware");
+ }
+
+ // Prefer NVidia extension over ATI
+ if (wglExt.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_ATI;
+ }
+ } else {
+ if (!rtt) {
+ // Currently we don't support non-truecolor visuals in the
+ // GLCapabilities, so we don't offer the option of making
+ // color-index pbuffers.
+ iattributes[niattribs++] = 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;
+ }
+
+ return true;
+ }
+
+ protected static GLCapabilities iattributes2GLCapabilities(int[] iattribs,
+ int niattribs,
+ int[] iresults,
+ boolean requireRenderToWindow) {
+ GLCapabilities res = new GLCapabilities();
+ for (int i = 0; i < niattribs; i++) {
+ int attr = iattribs[i];
+ switch (attr) {
+ case WGLExt.WGL_DRAW_TO_WINDOW_ARB:
+ if (requireRenderToWindow && iresults[i] != GL.GL_TRUE)
+ return null;
+ break;
+
+ case WGLExt.WGL_DRAW_TO_PBUFFER_ARB:
+ break;
+
+ case WGLExt.WGL_ACCELERATION_ARB:
+ res.setHardwareAccelerated(iresults[i] == WGLExt.WGL_FULL_ACCELERATION_ARB);
+ break;
+
+ case WGLExt.WGL_SUPPORT_OPENGL_ARB:
+ if (iresults[i] != GL.GL_TRUE)
+ return null;
+ break;
+
+ case WGLExt.WGL_DEPTH_BITS_ARB:
+ res.setDepthBits(iresults[i]);
+ break;
+
+ case WGLExt.WGL_STENCIL_BITS_ARB:
+ res.setStencilBits(iresults[i]);
+ break;
+
+ case WGLExt.WGL_DOUBLE_BUFFER_ARB:
+ res.setDoubleBuffered(iresults[i] == GL.GL_TRUE);
+ break;
+
+ case WGLExt.WGL_STEREO_ARB:
+ res.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_ATI) {
+ res.setPbufferFloatingPointBuffers(true);
+ }
+ break;
+
+ case WGLExt.WGL_FLOAT_COMPONENTS_NV:
+ if (iresults[i] != 0) {
+ res.setPbufferFloatingPointBuffers(true);
+ }
+ break;
+
+ case WGLExt.WGL_RED_BITS_ARB:
+ res.setRedBits(iresults[i]);
+ break;
+
+ case WGLExt.WGL_GREEN_BITS_ARB:
+ res.setGreenBits(iresults[i]);
+ break;
+
+ case WGLExt.WGL_BLUE_BITS_ARB:
+ res.setBlueBits(iresults[i]);
+ break;
+
+ case WGLExt.WGL_ALPHA_BITS_ARB:
+ res.setAlphaBits(iresults[i]);
+ break;
+
+ case WGLExt.WGL_ACCUM_RED_BITS_ARB:
+ res.setAccumRedBits(iresults[i]);
+ break;
+
+ case WGLExt.WGL_ACCUM_GREEN_BITS_ARB:
+ res.setAccumGreenBits(iresults[i]);
+ break;
+
+ case WGLExt.WGL_ACCUM_BLUE_BITS_ARB:
+ res.setAccumBlueBits(iresults[i]);
+ break;
+
+ case WGLExt.WGL_ACCUM_ALPHA_BITS_ARB:
+ res.setAccumAlphaBits(iresults[i]);
+ break;
+
+ case WGLExt.WGL_SAMPLE_BUFFERS_ARB:
+ res.setSampleBuffers(iresults[i] != 0);
+ break;
+
+ case WGLExt.WGL_SAMPLES_ARB:
+ res.setNumSamples(iresults[i]);
+ break;
+
+ default:
+ throw new GLException("Unknown pixel format attribute " + iattribs[i]);
+ }
+ }
+ return res;
+ }
+
+ protected static String getThreadName() {
+ return Thread.currentThread().getName();
+ }
+}
diff --git a/src/classes/com/sun/opengl/impl/windows/wgl/WindowsWGLDrawableFactory.java b/src/classes/com/sun/opengl/impl/windows/wgl/WindowsWGLDrawableFactory.java
new file mode 100644
index 000000000..fd4e5620c
--- /dev/null
+++ b/src/classes/com/sun/opengl/impl/windows/wgl/WindowsWGLDrawableFactory.java
@@ -0,0 +1,276 @@
+/*
+ * 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.sun.opengl.impl.windows.wgl;
+
+import java.nio.*;
+import java.util.*;
+import javax.media.opengl.*;
+import com.sun.opengl.impl.*;
+import javax.media.opengl.util.BufferUtil;
+
+public class WindowsWGLDrawableFactory extends GLDrawableFactoryImpl {
+ private static final boolean DEBUG = Debug.debug("WindowsWGLDrawableFactory");
+ private static final boolean VERBOSE = Debug.verbose();
+
+ // Handle to GLU32.dll
+ // FIXME: this should go away once we delete support for the C GLU library
+ private long hglu32;
+
+ static {
+ NativeLibLoader.loadCore();
+ }
+
+ public WindowsWGLDrawableFactory() {
+ super();
+ }
+
+ public AbstractGraphicsConfiguration chooseGraphicsConfiguration(GLCapabilities capabilities,
+ GLCapabilitiesChooser chooser,
+ AbstractGraphicsDevice device) {
+ return null;
+ }
+
+ public GLDrawable createGLDrawable(NativeWindow target,
+ GLCapabilities capabilities,
+ GLCapabilitiesChooser chooser) {
+ if (target == null) {
+ throw new IllegalArgumentException("Null target");
+ }
+ if (capabilities == null) {
+ capabilities = new GLCapabilities();
+ }
+ if (chooser == null) {
+ chooser = new DefaultGLCapabilitiesChooser();
+ }
+ return new WindowsOnscreenWGLDrawable(this, target, capabilities, chooser);
+ }
+
+ public GLDrawableImpl createOffscreenDrawable(GLCapabilities capabilities,
+ GLCapabilitiesChooser chooser) {
+ return new WindowsOffscreenWGLDrawable(this, capabilities, chooser);
+ }
+
+ private boolean pbufferSupportInitialized = false;
+ private boolean canCreateGLPbuffer = false;
+ public boolean canCreateGLPbuffer() {
+ if (!pbufferSupportInitialized) {
+ final GLDrawableFactory factory = this;
+ Runnable r = new Runnable() {
+ public void run() {
+ WindowsDummyWGLDrawable dummyDrawable = new WindowsDummyWGLDrawable(factory);
+ GLContext dummyContext = dummyDrawable.createContext(null);
+ if (dummyContext != null) {
+ GLContext lastContext = GLContext.getCurrent();
+ if (lastContext != null) {
+ lastContext.release();
+ }
+ dummyContext.makeCurrent();
+ GL dummyGL = dummyContext.getGL();
+ canCreateGLPbuffer = dummyGL.isExtensionAvailable("GL_ARB_pbuffer");
+ pbufferSupportInitialized = true;
+ dummyContext.release();
+ dummyContext.destroy();
+ dummyDrawable.destroy();
+ if (lastContext != null) {
+ lastContext.makeCurrent();
+ }
+ }
+ }
+ };
+ maybeDoSingleThreadedWorkaround(r);
+ }
+ if (DEBUG) {
+ System.err.println("WindowsWGLDrawableFactory.canCreateGLPbuffer() = " + canCreateGLPbuffer);
+ }
+ return canCreateGLPbuffer;
+ }
+
+ public GLPbuffer createGLPbuffer(final GLCapabilities capabilities,
+ final GLCapabilitiesChooser chooser,
+ final int initialWidth,
+ final int initialHeight,
+ final GLContext shareWith) {
+ if (!canCreateGLPbuffer()) {
+ throw new GLException("Pbuffer support not available with current graphics card");
+ }
+ final List returnList = new ArrayList();
+ final GLDrawableFactory factory = this;
+ Runnable r = new Runnable() {
+ public void run() {
+ WindowsDummyWGLDrawable dummyDrawable = new WindowsDummyWGLDrawable(factory);
+ WindowsWGLContext dummyContext = (WindowsWGLContext) dummyDrawable.createContext(null);
+ GLContext lastContext = GLContext.getCurrent();
+ if (lastContext != null) {
+ lastContext.release();
+ }
+ dummyContext.makeCurrent();
+ WGLExt dummyWGLExt = dummyContext.getWGLExt();
+ try {
+ WindowsPbufferWGLDrawable pbufferDrawable = new WindowsPbufferWGLDrawable(factory, capabilities,
+ initialWidth,
+ initialHeight,
+ dummyDrawable,
+ dummyWGLExt);
+ GLPbufferImpl pbuffer = new GLPbufferImpl(pbufferDrawable, shareWith);
+ returnList.add(pbuffer);
+ dummyContext.release();
+ dummyContext.destroy();
+ dummyDrawable.destroy();
+ } finally {
+ if (lastContext != null) {
+ lastContext.makeCurrent();
+ }
+ }
+ }
+ };
+ maybeDoSingleThreadedWorkaround(r);
+ return (GLPbuffer) returnList.get(0);
+ }
+
+ public GLContext createExternalGLContext() {
+ return new WindowsExternalWGLContext();
+ }
+
+ public boolean canCreateExternalGLDrawable() {
+ return true;
+ }
+
+ public GLDrawable createExternalGLDrawable() {
+ return WindowsExternalWGLDrawable.create(this);
+ }
+
+ public void loadGLULibrary() {
+ if (hglu32 == 0) {
+ hglu32 = WGL.LoadLibraryA("GLU32");
+ if (hglu32 == 0) {
+ throw new GLException("Error loading GLU32.DLL");
+ }
+ }
+ }
+
+ public long dynamicLookupFunction(String glFuncName) {
+ long res = WGL.wglGetProcAddress(glFuncName);
+ if (res == 0) {
+ // GLU routines aren't known to the OpenGL function lookup
+ if (hglu32 != 0) {
+ res = WGL.GetProcAddress(hglu32, glFuncName);
+ }
+ }
+ return res;
+ }
+
+ static String wglGetLastError() {
+ long err = WGL.GetLastError();
+ String detail = null;
+ switch ((int) err) {
+ case WGL.ERROR_INVALID_PIXEL_FORMAT: detail = "ERROR_INVALID_PIXEL_FORMAT"; break;
+ case WGL.ERROR_NO_SYSTEM_RESOURCES: detail = "ERROR_NO_SYSTEM_RESOURCES"; break;
+ case WGL.ERROR_INVALID_DATA: detail = "ERROR_INVALID_DATA"; break;
+ case WGL.ERROR_PROC_NOT_FOUND: detail = "ERROR_PROC_NOT_FOUND"; break;
+ case WGL.ERROR_INVALID_WINDOW_HANDLE:detail = "ERROR_INVALID_WINDOW_HANDLE"; break;
+ default: detail = "(Unknown error code " + err + ")"; break;
+ }
+ return detail;
+ }
+
+ private void maybeDoSingleThreadedWorkaround(Runnable action) {
+ if (Threading.isSingleThreaded() &&
+ !Threading.isOpenGLThread()) {
+ Threading.invokeOnOpenGLThread(action);
+ } else {
+ action.run();
+ }
+ }
+
+ public boolean canCreateContextOnJava2DSurface() {
+ return false;
+ }
+
+ public 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 int getGammaRampLength() {
+ return GAMMA_RAMP_LENGTH;
+ }
+
+ protected 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 = WGL.GetDC(0);
+ boolean res = WGL.SetDeviceGammaRamp(screenDC, ShortBuffer.wrap(rampData));
+ WGL.ReleaseDC(0, screenDC);
+ return res;
+ }
+
+ protected Buffer getGammaRamp() {
+ ShortBuffer rampData = ShortBuffer.allocate(3 * GAMMA_RAMP_LENGTH);
+ long screenDC = WGL.GetDC(0);
+ boolean res = WGL.GetDeviceGammaRamp(screenDC, rampData);
+ WGL.ReleaseDC(0, screenDC);
+ if (!res) {
+ return null;
+ }
+ return rampData;
+ }
+
+ protected void resetGammaRamp(Buffer originalGammaRamp) {
+ if (originalGammaRamp == null) {
+ // getGammaRamp failed earlier
+ return;
+ }
+ long screenDC = WGL.GetDC(0);
+ WGL.SetDeviceGammaRamp(screenDC, originalGammaRamp);
+ WGL.ReleaseDC(0, screenDC);
+ }
+}