changeset 126:8d7572b6f3f6

Add OpenGL Support
author John Reimer <terminal.node@gmail.com
date Mon, 11 Feb 2008 22:26:05 -0800
parents 8b6d038b7f79
children fdc7e71c7331
files dwt/DWT.d dwt/internal/opengl/win32/WGL.d dwt/internal/opengl/win32/native.d dwt/layout/FormData.d dwt/opengl/GLCanvas.d dwt/opengl/GLData.d
diffstat 6 files changed, 487 insertions(+), 1 deletions(-) [+]
line wrap: on
line diff
--- a/dwt/DWT.d	Tue Feb 12 02:23:29 2008 +0100
+++ b/dwt/DWT.d	Mon Feb 11 22:26:05 2008 -0800
@@ -32,6 +32,7 @@
     pragma(link, "user32");
     pragma(link, "usp10");
     pragma(link, "msimg32");
+    pragma(link, "opengl32");
     //pragma(link, "gdiplus"); // load dynamic
     //pragma(link, "uxtheme"); // load dynamic
 }
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/dwt/internal/opengl/win32/WGL.d	Mon Feb 11 22:26:05 2008 -0800
@@ -0,0 +1,127 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2007 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ * Port to the D Programming Language:
+ *     John Reimer <terminal.node@gmail.com>
+ *******************************************************************************/
+module dwt.internal.opengl.win32.WGL;
+
+import dwt.internal.Library;
+import dwt.internal.Platform;
+
+private import dwt.internal.win32.WINAPI;
+private import dwt.internal.opengl.win32.native;
+    
+public class WGL : Platform { 
+
+public:
+    enum : int {
+        WGL_FONT_LINES      = 0,
+        WGL_FONT_POLYGONS   = 1,
+    
+    /* LAYERPLANEDESCRIPTOR flags */
+        LPD_DOUBLEBUFFER        = 0x00000001,
+        LPD_STEREO              = 0x00000002,
+        LPD_SUPPORT_GDI         = 0x00000010,
+        LPD_SUPPORT_OPENGL      = 0x00000020,
+        LPD_SHARE_DEPTH         = 0x00000040,
+        LPD_SHARE_STENCIL       = 0x00000080,
+        LPD_SHARE_ACCUM         = 0x00000100,
+        LPD_SWAP_EXCHANGE       = 0x00000200,
+        LPD_SWAP_COPY           = 0x00000400,
+        LPD_TRANSPARENT         = 0x00001000,
+    
+        LPD_TYPE_RGBA        = 0,
+        LPD_TYPE_COLORINDEX  = 1,
+    
+    /* wglSwapLayerBuffers flags */
+        WGL_SWAP_MAIN_PLANE     = 0x00000001,
+        WGL_SWAP_OVERLAY1       = 0x00000002,
+        WGL_SWAP_OVERLAY2       = 0x00000004,
+        WGL_SWAP_OVERLAY3       = 0x00000008,
+        WGL_SWAP_OVERLAY4       = 0x00000010,
+        WGL_SWAP_OVERLAY5       = 0x00000020,
+        WGL_SWAP_OVERLAY6       = 0x00000040,
+        WGL_SWAP_OVERLAY7       = 0x00000080,
+        WGL_SWAP_OVERLAY8       = 0x00000100,
+        WGL_SWAP_OVERLAY9       = 0x00000200,
+        WGL_SWAP_OVERLAY10      = 0x00000400,
+        WGL_SWAP_OVERLAY11      = 0x00000800,
+        WGL_SWAP_OVERLAY12      = 0x00001000,
+        WGL_SWAP_OVERLAY13      = 0x00002000,
+        WGL_SWAP_OVERLAY14      = 0x00004000,
+        WGL_SWAP_OVERLAY15      = 0x00008000,
+        WGL_SWAP_UNDERLAY1      = 0x00010000,
+        WGL_SWAP_UNDERLAY2      = 0x00020000,
+        WGL_SWAP_UNDERLAY3      = 0x00040000,
+        WGL_SWAP_UNDERLAY4      = 0x00080000,
+        WGL_SWAP_UNDERLAY5      = 0x00100000,
+        WGL_SWAP_UNDERLAY6      = 0x00200000,
+        WGL_SWAP_UNDERLAY7      = 0x00400000,
+        WGL_SWAP_UNDERLAY8      = 0x00800000,
+        WGL_SWAP_UNDERLAY9      = 0x01000000,
+        WGL_SWAP_UNDERLAY10     = 0x02000000,
+        WGL_SWAP_UNDERLAY11     = 0x04000000,
+        WGL_SWAP_UNDERLAY12     = 0x08000000,
+        WGL_SWAP_UNDERLAY13     = 0x10000000,
+        WGL_SWAP_UNDERLAY14     = 0x20000000,
+        WGL_SWAP_UNDERLAY15     = 0x40000000,
+    
+    /* pixel types */
+        PFD_TYPE_RGBA        = 0,
+        PFD_TYPE_COLORINDEX  = 1,
+    
+    /* layer types */
+        PFD_MAIN_PLANE       = 0,
+        PFD_OVERLAY_PLANE    = 1,
+        PFD_UNDERLAY_PLANE   = -1,
+    
+    /* PIXELFORMATDESCRIPTOR flags */
+        PFD_DOUBLEBUFFER            = 0x00000001,
+        PFD_STEREO                  = 0x00000002,
+        PFD_DRAW_TO_WINDOW          = 0x00000004,
+        PFD_DRAW_TO_BITMAP          = 0x00000008,
+        PFD_SUPPORT_GDI             = 0x00000010,
+        PFD_SUPPORT_OPENGL          = 0x00000020,
+        PFD_GENERIC_FORMAT          = 0x00000040,
+        PFD_NEED_PALETTE            = 0x00000080,
+        PFD_NEED_SYSTEM_PALETTE     = 0x00000100,
+        PFD_SWAP_EXCHANGE           = 0x00000200,
+        PFD_SWAP_COPY               = 0x00000400,
+        PFD_SWAP_LAYER_BUFFERS      = 0x00000800,
+        PFD_GENERIC_ACCELERATED     = 0x00001000,
+        PFD_SUPPORT_DIRECTDRAW      = 0x00002000,
+    
+    /* PIXELFORMATDESCRIPTOR flags for use in ChoosePixelFormat only */
+        PFD_DEPTH_DONTCARE          = 0x20000000,
+        PFD_DOUBLEBUFFER_DONTCARE   = 0x40000000,
+        PFD_STEREO_DONTCARE         = 0x80000000
+    }
+
+    alias .ChoosePixelFormat            ChoosePixelFormat;
+    alias .DescribePixelFormat          DescribePixelFormat;
+    alias .GetPixelFormat               GetPixelFormat;
+    alias .SetPixelFormat               SetPixelFormat;
+    alias .SwapBuffers                  SwapBuffers;
+    
+    alias .wglCopyContext               wglCopyContext;
+    alias .wglCreateContext             wglCreateContext;
+    alias .wglCreateLayerContext        wglCreateLayerContext;
+    alias .wglDeleteContext             wglDeleteContext;
+    alias .wglGetCurrentContext         wglGetCurrentContext;
+    alias .wglGetCurrentDC              wglGetCurrentDC;
+    alias .wglGetProcAddress            wglGetProcAddress;
+    alias .wglMakeCurrent               wglMakeCurrent;
+    alias .wglShareLists                wglShareLists;
+    alias .wglDescribeLayerPlane        wglDescribeLayerPlane;
+    alias .wglSetLayerPaletteEntries    wglSetLayerPaletteEntries;
+    alias .wglGetLayerPaletteEntries    wglGetLayerPaletteEntries;
+    alias .wglRealizeLayerPalette       wglRealizeLayerPalette;
+    alias .wglSwapLayerBuffers          wglSwapLayerBuffers;
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/dwt/internal/opengl/win32/native.d	Mon Feb 11 22:26:05 2008 -0800
@@ -0,0 +1,26 @@
+module dwt.internal.opengl.win32.native;
+
+private import dwt.internal.win32.WINTYPES;
+
+extern (Windows):
+
+int     ChoosePixelFormat( HDC, PIXELFORMATDESCRIPTOR* );
+int     DescribePixelFormat( HDC, int, UINT, PIXELFORMATDESCRIPTOR* );
+int     GetPixelFormat( HDC );
+BOOL    SetPixelFormat( HDC, int, PIXELFORMATDESCRIPTOR* );
+BOOL    SwapBuffers( HDC );
+
+BOOL    wglCopyContext(HGLRC, HGLRC, UINT);
+HGLRC   wglCreateContext(HDC);
+HGLRC   wglCreateLayerContext(HDC, int);
+BOOL    wglDeleteContext(HGLRC);
+BOOL    wglDescribeLayerPlane(HDC, int, int, UINT, LPLAYERPLANEDESCRIPTOR);
+HGLRC   wglGetCurrentContext();
+HDC     wglGetCurrentDC();
+int     wglGetLayerPaletteEntries(HDC, int, int, int, COLORREF*);
+FARPROC wglGetProcAddress(LPCSTR);
+BOOL    wglMakeCurrent(HDC, HGLRC);
+BOOL    wglRealizeLayerPalette(HDC, int, BOOL);
+int     wglSetLayerPaletteEntries(HDC, int, int, int, COLORREF*);
+BOOL    wglShareLists(HGLRC, HGLRC);
+BOOL    wglSwapLayerBuffers(HDC, UINT);
\ No newline at end of file
--- a/dwt/layout/FormData.d	Tue Feb 12 02:23:29 2008 +0100
+++ b/dwt/layout/FormData.d	Mon Feb 11 22:26:05 2008 -0800
@@ -17,7 +17,6 @@
 import dwt.graphics.Point;
 import dwt.widgets.Control;
 import dwt.layout.FormAttachment;
-import tango.text.Util;
 
 import tango.text.Util;
 import tango.util.Convert;
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/dwt/opengl/GLCanvas.d	Mon Feb 11 22:26:05 2008 -0800
@@ -0,0 +1,188 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2007 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ * Port to the D Programming Languae:
+ *      John Reimer <terminal.node@gmail.com
+ *******************************************************************************/
+module dwt.opengl.GLCanvas;
+
+import dwt.DWT;
+import dwt.DWTException;
+import dwt.internal.opengl.win32.WGL;
+import dwt.internal.win32.OS;
+import dwt.widgets.Canvas;
+import dwt.widgets.Composite;
+import dwt.widgets.Event;
+import dwt.widgets.Listener;
+import dwt.opengl.GLData;
+
+/**
+ * GLCanvas is a widget capable of displaying OpenGL content.
+ * 
+ * @since 3.2
+ */
+
+public class GLCanvas : Canvas {
+    HGLRC context;
+    int pixelFormat;
+
+/**
+ * Create a GLCanvas widget using the attributes described in the GLData
+ * object provided.
+ *
+ * @param parent a composite widget
+ * @param style the bitwise OR'ing of widget styles
+ * @param data the requested attributes of the GLCanvas
+ *
+ * @exception IllegalArgumentException
+ * <ul><li>ERROR_NULL_ARGUMENT when the data is null
+ *     <li>ERROR_UNSUPPORTED_DEPTH when the requested attributes cannot be provided</ul> 
+ * </ul>
+ */
+public this (Composite parent, int style, GLData data) {
+    super (parent, style);
+    if (data is null) DWT.error (DWT.ERROR_NULL_ARGUMENT);
+    PIXELFORMATDESCRIPTOR pfd;
+    pfd.nSize = cast(short) PIXELFORMATDESCRIPTOR.sizeof;
+    pfd.nVersion = 1;
+    pfd.dwFlags = WGL.PFD_DRAW_TO_WINDOW | WGL.PFD_SUPPORT_OPENGL;
+    pfd.dwLayerMask = WGL.PFD_MAIN_PLANE;
+    pfd.iPixelType = cast(byte) WGL.PFD_TYPE_RGBA;
+    if (data.doubleBuffer) pfd.dwFlags |= WGL.PFD_DOUBLEBUFFER;
+    if (data.stereo) pfd.dwFlags |= WGL.PFD_STEREO;
+    pfd.cRedBits = cast(byte) data.redSize;
+    pfd.cGreenBits = cast(byte) data.greenSize;
+    pfd.cBlueBits = cast(byte) data.blueSize;
+    pfd.cAlphaBits = cast(byte) data.alphaSize;
+    pfd.cDepthBits = cast(byte) data.depthSize;
+    pfd.cStencilBits = cast(byte) data.stencilSize;
+    pfd.cAccumRedBits = cast(byte) data.accumRedSize;
+    pfd.cAccumGreenBits = cast(byte) data.accumGreenSize;
+    pfd.cAccumBlueBits = cast(byte) data.accumBlueSize;
+    pfd.cAccumAlphaBits = cast(byte) data.accumAlphaSize;
+    pfd.cAccumBits = cast(byte) (pfd.cAccumRedBits + pfd.cAccumGreenBits + pfd.cAccumBlueBits + pfd.cAccumAlphaBits);
+    
+    //FIXME - use wglChoosePixelFormatARB
+//  if (data.sampleBuffers > 0) {
+//      wglAttrib [pos++] = WGL.WGL_SAMPLE_BUFFERS_ARB;
+//      wglAttrib [pos++] = data.sampleBuffers;
+//  }
+//  if (data.samples > 0) {
+//      wglAttrib [pos++] = WGL.WGL_SAMPLES_ARB;
+//      wglAttrib [pos++] = data.samples;
+//  }
+
+    auto hDC = OS.GetDC (handle);
+    pixelFormat = WGL.ChoosePixelFormat (hDC, &pfd);
+    if (pixelFormat is 0 || !WGL.SetPixelFormat (hDC, pixelFormat, &pfd)) {
+        OS.ReleaseDC (handle, hDC);
+        dispose ();
+        DWT.error (DWT.ERROR_UNSUPPORTED_DEPTH);
+    }
+    context = WGL.wglCreateContext (hDC);
+    if (context is null) {
+        OS.ReleaseDC (handle, hDC);
+        DWT.error (DWT.ERROR_NO_HANDLES);
+    }
+    OS.ReleaseDC (handle, hDC);
+    //FIXME- share lists
+    //if (share !is null) WGL.wglShareLists (context, share.context);
+    
+    Listener listener = new class() Listener {
+        public void handleEvent (Event event) {
+            switch (event.type) {
+                case DWT.Dispose:
+                    WGL.wglDeleteContext (context);
+                    break;
+            }
+        }
+    };
+    addListener (DWT.Dispose, listener);
+}
+
+/**
+ * Returns a GLData object describing the created context.
+ *  
+ * @return GLData description of the OpenGL context attributes
+ * @exception DWTException <ul>
+ *    <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
+ *    <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
+ * </ul>
+ */
+public GLData getGLData () {
+    checkWidget ();
+    GLData data = new GLData ();
+    PIXELFORMATDESCRIPTOR pfd;
+    pfd.nSize = cast(short) PIXELFORMATDESCRIPTOR.sizeof;
+    auto hDC = OS.GetDC (handle);
+    WGL.DescribePixelFormat (hDC, pixelFormat, PIXELFORMATDESCRIPTOR.sizeof, &pfd);
+    OS.ReleaseDC (handle, hDC);
+    data.doubleBuffer = (pfd.dwFlags & WGL.PFD_DOUBLEBUFFER) !is 0;
+    data.stereo = (pfd.dwFlags & WGL.PFD_STEREO) !is 0;
+    data.redSize = pfd.cRedBits;
+    data.greenSize = pfd.cGreenBits;
+    data.blueSize = pfd.cBlueBits;
+    data.alphaSize = pfd.cAlphaBits;
+    data.depthSize = pfd.cDepthBits;
+    data.stencilSize = pfd.cStencilBits;
+    data.accumRedSize = pfd.cAccumRedBits;
+    data.accumGreenSize = pfd.cAccumGreenBits;
+    data.accumBlueSize = pfd.cAccumBlueBits;
+    data.accumAlphaSize = pfd.cAccumAlphaBits;
+    return data;
+}
+
+/**
+ * Returns a bool indicating whether the receiver's OpenGL context
+ * is the current context.
+ *  
+ * @return true if the receiver holds the current OpenGL context,
+ * false otherwise
+ * @exception DWTException <ul>
+ *    <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
+ *    <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
+ * </ul>
+ */
+public bool isCurrent () {
+    checkWidget ();
+    return (WGL.wglGetCurrentContext is context);
+}
+
+/**
+ * Sets the OpenGL context associated with this GLCanvas to be the
+ * current GL context.
+ * 
+ * @exception DWTException <ul>
+ *    <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
+ *    <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
+ * </ul>
+ */
+public void setCurrent () {
+    checkWidget ();
+    if (WGL.wglGetCurrentContext is context) return;
+    auto hDC = OS.GetDC (handle);
+    WGL.wglMakeCurrent (hDC, context);
+    OS.ReleaseDC (handle, hDC);
+}
+
+/**
+ * Swaps the front and back color buffers.
+ * 
+ * @exception DWTException <ul>
+ *    <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
+ *    <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
+ * </ul>
+ */
+public void swapBuffers () {
+    checkWidget ();
+    auto hDC = OS.GetDC (handle);
+    WGL.SwapBuffers (hDC);
+    OS.ReleaseDC (handle, hDC);
+}
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/dwt/opengl/GLData.d	Mon Feb 11 22:26:05 2008 -0800
@@ -0,0 +1,145 @@
+/*******************************************************************************
+ * Copyright (c) 2005, 2006 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ * Port to the D Programming Language:
+ *     John Reimer <terminal.node@gmail.com>
+ *******************************************************************************/
+module dwt.opengl.GLData;
+
+import tango.text.Util;
+import tango.util.Convert;
+
+/**
+ * The GLData class is a device-independent description
+ * of the pixel format attributes of a GL drawable.
+ *
+ * @see GLCanvas
+ * 
+ * @since 3.2
+ */
+
+public class GLData {
+    /**
+     * Specifies a double-buffered surface.  During context
+     * creation, only double-buffered formats are considered
+     * when set to true. 
+     */
+    public bool doubleBuffer;
+
+    /**
+     * Specifies a stereo surface.  During context creation,
+     * only stereo formats are considered when set to true. 
+     */
+    public bool stereo;
+
+    /**
+     * The size in bits of the color buffer's red channel.
+     * During context creation, this specifies the minimum
+     * required red bits.
+     */
+    public int redSize;
+
+    /**
+     * The size in bits of the color buffer's green channel.
+     * During context creation, this specifies the minimum
+     * required green bits.
+     */
+    public int greenSize;
+
+    /**
+     * The size in bits of the color buffer's blue channel.
+     * During context creation, this specifies the minimum
+     * required blue bits.
+     */
+    public int blueSize;
+
+    /**
+     * The size in bits of the color buffer's alpha channel.
+     * During context creation, this specifies the minimum
+     * required alpha bits.
+     */
+    public int alphaSize;
+
+    /**
+     * The size in bits of the depth buffer.  During context
+     * creation, the smallest depth buffer of at least the
+     * specified value is preferred, or zero for no depth
+     * buffer.
+     */
+    public int depthSize;
+
+    /**
+     * The desired number of stencil bitplanes.  During
+     * context creation, the smallest stencil buffer of at
+     * least the specified value is preferred, or zero for
+     * no stencil buffer.
+     */
+    public int stencilSize;
+
+    /**
+     * The size in bits of the accumulation buffer's red
+     * channel. During context creation, this specifies the
+     * minimum required red bits.
+     */
+    public int accumRedSize;
+
+    /**
+     * The size in bits of the accumulation buffer's green
+     * channel. During context creation, this specifies the
+     * minimum required green bits.
+     */
+    public int accumGreenSize;
+
+    /**
+     * The size in bits of the accumulation buffer's blue
+     * channel. During context creation, this specifies the
+     * minimum required blue bits.
+     */
+    public int accumBlueSize;
+
+    /**
+     * The size in bits of the accumulation buffer's alpha
+     * channel. During context creation, this specifies the
+     * minimum required alpha bits.
+     */
+    public int accumAlphaSize;
+
+    /**
+     * The number of multisample buffers used by this context.
+     * During context creation, this specifies the minimum
+     * number of multisample buffers requested.
+     */
+    public int sampleBuffers;
+
+    /**
+     * The number of samples accepted in the multisample buffer.
+     * During creation, pixel formats with the smallest number of
+     * samples that meets or exceeds the specified minimum number
+     * are preferred.
+     */
+    public int samples;
+    
+/**
+ * Returns a string containing a concise, human-readable
+ * description of the receiver.
+ *
+ * @return a string representation of the data
+ */
+override public char[] toString() {
+    char[] string = doubleBuffer ? "doubleBuffer," : "";
+    string ~= stereo ? "stereo," : "";
+    string ~= "r:" ~     to!(char[])(redSize)  ~ " g:" ~ to!(char[])(greenSize) ~ 
+              " b:" ~    to!(char[])(blueSize) ~ " a:" ~ to!(char[])(alphaSize) ~ "," ~
+              "depth:" ~ to!(char[])(depthSize) ~ ",stencil:" ~ to!(char[])(stencilSize) ~
+              ",accum r:" ~ to!(char[])(accumRedSize) ~ "g:" ~ to!(char[])(accumGreenSize) ~ 
+              "b:" ~ to!(char[])(accumBlueSize) ~ "a:" ~ to!(char[])(accumAlphaSize) ~
+              ",sampleBuffers:" ~ to!(char[])(sampleBuffers) ~ ",samples:" ~ to!(char[])(samples);
+    return string;
+}
+}