001: /*******************************************************************************
002: * Copyright (c) 2000, 2003 IBM Corporation and others.
003: * All rights reserved. This program and the accompanying materials
004: * are made available under the terms of the Eclipse Public License v1.0
005: * which accompanies this distribution, and is available at
006: * http://www.eclipse.org/legal/epl-v10.html
007: *
008: * Contributors:
009: * IBM Corporation - initial API and implementation
010: *******************************************************************************/package org.eclipse.swt.opengl;
011:
012: import org.eclipse.swt.*;
013: import org.eclipse.swt.opengl.internal.win32.*;
014: import org.eclipse.swt.internal.win32.*;
015: import org.eclipse.swt.widgets.*;
016:
017: /**
018: * GLCanvas is a widget capable of displaying OpenGL content.
019: */
020:
021: public class GLCanvas extends Canvas {
022: int context;
023: int pixelFormat;
024:
025: /**
026: * Create a GLCanvas widget using the attributes described in the GLData
027: * object provided.
028: *
029: * @param parent a composite widget
030: * @param style the bitwise OR'ing of widget styles
031: * @param data the requested attributes of the GLCanvas
032: *
033: * @exception IllegalArgumentException
034: * <ul><li>ERROR_NULL_ARGUMENT when the data is null
035: * <li>ERROR_UNSUPPORTED_DEPTH when the requested attributes cannot be provided</ul>
036: * @exception SWTException
037: * <ul><li>ERROR_THREAD_INVALID_ACCESS when called from the wrong thread
038: * <li>ERROR_CANNOT_CREATE_OBJECT when failed to create OLE Object
039: * <li>ERROR_CANNOT_OPEN_FILE when failed to open file
040: * <li>ERROR_INTERFACE_NOT_FOUND when unable to create callbacks for OLE Interfaces
041: * <li>ERROR_INVALID_CLASSID
042: * </ul>
043: */
044: public GLCanvas(Composite parent, int style, GLData data) {
045: super (parent, style);
046: if (data == null)
047: SWT.error(SWT.ERROR_NULL_ARGUMENT);
048:
049: PIXELFORMATDESCRIPTOR pfd = new PIXELFORMATDESCRIPTOR();
050: pfd.nSize = (short) PIXELFORMATDESCRIPTOR.sizeof;
051: pfd.nVersion = 1;
052: pfd.dwFlags = WGL.PFD_DRAW_TO_WINDOW | WGL.PFD_SUPPORT_OPENGL;
053: pfd.dwLayerMask = WGL.PFD_MAIN_PLANE;
054: pfd.iPixelType = (byte) WGL.PFD_TYPE_RGBA;
055: if (data.doubleBuffer)
056: pfd.dwFlags |= WGL.PFD_DOUBLEBUFFER;
057: if (data.stereo)
058: pfd.dwFlags |= WGL.PFD_STEREO;
059: pfd.cRedBits = (byte) data.redSize;
060: pfd.cGreenBits = (byte) data.greenSize;
061: pfd.cBlueBits = (byte) data.blueSize;
062: pfd.cAlphaBits = (byte) data.alphaSize;
063: pfd.cDepthBits = (byte) data.depthSize;
064: pfd.cStencilBits = (byte) data.stencilSize;
065: pfd.cAccumRedBits = (byte) data.accumRedSize;
066: pfd.cAccumGreenBits = (byte) data.accumGreenSize;
067: pfd.cAccumBlueBits = (byte) data.accumBlueSize;
068: pfd.cAccumAlphaBits = (byte) data.accumAlphaSize;
069: pfd.cAccumBits = (byte) (pfd.cAccumRedBits
070: + pfd.cAccumGreenBits + pfd.cAccumBlueBits + pfd.cAccumAlphaBits);
071: //FIXME - use wglChoosePixelFormatARB
072: // if (data.sampleBuffers > 0) {
073: // wglAttrib [pos++] = WGL.WGL_SAMPLE_BUFFERS_ARB;
074: // wglAttrib [pos++] = data.sampleBuffers;
075: // }
076: // if (data.samples > 0) {
077: // wglAttrib [pos++] = WGL.WGL_SAMPLES_ARB;
078: // wglAttrib [pos++] = data.samples;
079: // }
080:
081: int hDC = OS.GetDC(handle);
082: pixelFormat = WGL.ChoosePixelFormat(hDC, pfd);
083: if (pixelFormat == 0) {
084: OS.ReleaseDC(handle, hDC);
085: SWT.error(SWT.ERROR_UNSUPPORTED_DEPTH);
086: }
087: if (!WGL.SetPixelFormat(hDC, pixelFormat, pfd)) {
088: OS.ReleaseDC(handle, hDC);
089: SWT.error(SWT.ERROR_UNSUPPORTED_DEPTH);
090: }
091: context = WGL.wglCreateContext(hDC);
092: if (context == 0) {
093: OS.ReleaseDC(handle, hDC);
094: SWT.error(SWT.ERROR_NO_HANDLES);
095: }
096: OS.ReleaseDC(handle, hDC);
097: // if (share != null) {
098: // WGL.wglShareLists (context, share.context);
099: // }
100:
101: Listener listener = new Listener() {
102: public void handleEvent(Event event) {
103: switch (event.type) {
104: case SWT.Dispose:
105: WGL.wglDeleteContext(context);
106: break;
107: }
108: }
109: };
110: addListener(SWT.Dispose, listener);
111: }
112:
113: /**
114: * Returns a GLData object describing the created context.
115: *
116: * @return GLData description of the OpenGL context attributes
117: * @exception SWTException <ul>
118: * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
119: * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
120: * </ul>
121: */
122: public GLData getGLData() {
123: checkWidget();
124: GLData data = new GLData();
125: PIXELFORMATDESCRIPTOR pfd = new PIXELFORMATDESCRIPTOR();
126: pfd.nSize = (short) PIXELFORMATDESCRIPTOR.sizeof;
127: int hDC = OS.GetDC(handle);
128: WGL.DescribePixelFormat(hDC, pixelFormat,
129: PIXELFORMATDESCRIPTOR.sizeof, pfd);
130: OS.ReleaseDC(handle, hDC);
131: data.doubleBuffer = (pfd.dwFlags & WGL.PFD_DOUBLEBUFFER) != 0;
132: data.stereo = (pfd.dwFlags & WGL.PFD_STEREO) != 0;
133: data.redSize = pfd.cRedBits;
134: data.greenSize = pfd.cGreenBits;
135: data.blueSize = pfd.cBlueBits;
136: data.alphaSize = pfd.cAlphaBits;
137: data.depthSize = pfd.cDepthBits;
138: data.stencilSize = pfd.cStencilBits;
139: data.accumRedSize = pfd.cAccumRedBits;
140: data.accumGreenSize = pfd.cAccumGreenBits;
141: data.accumBlueSize = pfd.cAccumBlueBits;
142: data.accumAlphaSize = pfd.cAccumAlphaBits;
143: return data;
144: }
145:
146: /**
147: * Returns a boolean indicating whether the receiver's OpenGL context
148: * is the current context.
149: *
150: * @return true if the receiver holds the current OpenGL context,
151: * false otherwise
152: * @exception SWTException <ul>
153: * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
154: * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
155: * </ul>
156: */
157: public boolean isCurrent() {
158: checkWidget();
159: return WGL.wglGetCurrentContext() == handle;
160: }
161:
162: /**
163: * Sets the OpenGL context associated with this GLCanvas to be the
164: * current GL context.
165: *
166: * @exception SWTException <ul>
167: * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
168: * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
169: * </ul>
170: */
171: public void setCurrent() {
172: checkWidget();
173: if (WGL.wglGetCurrentContext() == handle)
174: return;
175: int hDC = OS.GetDC(handle);
176: WGL.wglMakeCurrent(hDC, context);
177: OS.ReleaseDC(handle, hDC);
178: }
179:
180: /**
181: * Swaps the front and back color buffers.
182: *
183: * @exception SWTException <ul>
184: * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
185: * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
186: * </ul>
187: */
188: public void swapBuffers() {
189: checkWidget();
190: int hDC = OS.GetDC(handle);
191: WGL.SwapBuffers(hDC);
192: OS.ReleaseDC(handle, hDC);
193: }
194: }
|