/******************************************************************************* * Copyright (c) 2000, 2004 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 *******************************************************************************/ package org.eclipse.swt.opengl; import org.eclipse.swt.*; import org.eclipse.swt.graphics.*; import org.eclipse.swt.internal.motif.*; import org.eclipse.swt.opengl.internal.motif.*; /** * Instances of <code>GLContext</code> are used to draw on swt <code>Drawable</code>s * through invocations of provided OpenGL functions. * <p> * Application code must explicitly invoke the <code>GLContext.dispose ()</code> * method to release the operating system resources managed by each instance * when those instances are no longer required. This is <em>particularly</em> * important on Windows95 and Windows98 where the operating system has a limited * number of device contexts available. * </p> */ public class GLContext { int handle; int gc; GCData data; Drawable drawable; int selectBufferPtr = 0; static final int MSB_FIRST = 1; static final int LSB_FIRST = 2; /** * Constructs a new instance of this class which has been * configured to draw on the specified drawable. * <p> * You must dispose the <code>GLContext</code> when it is no longer required. * </p> * * @param drawable the drawable to draw on * @exception IllegalArgumentException <ul> * <li>ERROR_NULL_ARGUMENT - if the drawable is null</li> * </ul> * @exception SWTError <ul> * <li>ERROR_NO_HANDLES if a handle could not be obtained for gc creation</li> * <li>ERROR_UNSUPPORTED_DEPTH - if the current display depth is not supported</li> * </ul> */ public GLContext (Drawable drawable) { if (drawable == null) SWT.error (SWT.ERROR_NULL_ARGUMENT); this.drawable = drawable; this.data = new GCData (); gc = drawable.internal_new_GC (data); if (gc == 0) SWT.error (SWT.ERROR_NO_HANDLES); int xDisplay = data.display; int screen = OS.XDefaultScreen (xDisplay); int depth = OS.XDefaultDepthOfScreen (OS.XDefaultScreenOfDisplay (xDisplay)); int attrib [] = { XGL.GLX_LEVEL, 0, XGL.GLX_RGBA, XGL.GLX_DOUBLEBUFFER, // XGL.GLX_DEPTH_SIZE, // depth, 0 }; int infoPtr = XGL.glXChooseVisual (xDisplay, screen, attrib); if (infoPtr == 0) SWT.error (SWT.ERROR_UNSUPPORTED_DEPTH); XVisualInfo info = new XVisualInfo (); XGL.memmove (info, infoPtr, XVisualInfo.sizeof); OS.XFree (infoPtr); handle = XGL.glXCreateContext (xDisplay, info, 0, false); if (handle == 0) SWT.error (SWT.ERROR_NO_HANDLES); } public ImageData convertImageData (ImageData source) { PaletteData palette = new PaletteData (0xff0000, 0xff00, 0xff); ImageData newSource = new ImageData (source.width, source.height, 24, palette); ImageDataUtil.blit ( 1, source.data, source.depth, source.bytesPerLine, (source.depth != 16) ? MSB_FIRST : LSB_FIRST, 0, 0, source.width, source.height, source.palette.redMask, source.palette.greenMask, source.palette.blueMask, 255, null, 0, 0, 0, newSource.data, newSource.depth, newSource.bytesPerLine, (newSource.depth != 16) ? MSB_FIRST : LSB_FIRST, 0, 0, newSource.width, newSource.height, newSource.palette.redMask, newSource.palette.greenMask, newSource.palette.blueMask, false, true); return newSource; } /** * Disposes of the operating system resources associated with * the receiver. Applications must dispose of all <code>GLContext</code>s * that they allocate. */ public void dispose () { if (handle == 0) return; int xDisplay = data.display; if (XGL.glXGetCurrentContext () == handle) { XGL.glXMakeCurrent (xDisplay, 0, 0); } if (selectBufferPtr != 0) OS.XtFree (selectBufferPtr); XGL.glXDestroyContext (xDisplay, handle); handle = 0; // drawable may be disposed try { drawable.internal_dispose_GC (gc, data); } catch (SWTException e) { } gc = 0; data.display = data.drawable = data.colormap = 0; /*data.fontList =*/ data.clipRgn = data.renderTable = 0; drawable = null; data.device = null; data.image = null; //data.codePage = null; data = null; } public int[] getSelectBuffer (int selectBufferPtr, int[] selectBuffer) { OS.memmove (selectBuffer, selectBufferPtr, selectBuffer.length * 4); return selectBuffer; } public int getSelectBufferPtr (int[] selectBuffer) { if (selectBufferPtr == 0) { selectBufferPtr = OS.XtMalloc (selectBuffer.length * 4); } OS.memmove (selectBufferPtr, selectBuffer, selectBuffer.length * 4); return selectBufferPtr; } /** * Returns a boolean indicating whether the receiver is the current * <code>GLContext</code>. * * @return true if the receiver is the current <code>GLContext</code>, * false otherwise * @exception SWTError <ul> * <li>ERROR_GRAPHIC_DISPOSED if the receiver is disposed</li> * </ul> */ public boolean isCurrent () { if (isDisposed ()) SWT.error (SWT.ERROR_GRAPHIC_DISPOSED); return XGL.glXGetCurrentContext () == handle; } /** * Returns a boolean indicating whether the <code>GLContext</code> has been * disposed. * <p> * This method gets the dispose state for the <code>GLContext</code>. * When a <code>GLContext</code> has been disposed, it is an error to * invoke any other method using the <code>GLContext</code>. * * @return true if the <code>GLContext</code> is disposed, false otherwise */ public boolean isDisposed () { return handle == 0; } /** * Loads the specified bitmap font. * * @param fdata * @param device * @param base * @param first * @param count */ public void loadBitmapFont (FontData fdata, Device device, int base, int startIndex, int length) { /* Temporary code, due some problems when running on UTF-8 loadBitmapFont () * is restrict to works only for ascii. * Note: en_US.ISO8859-1 also code be used. */ fdata.setLocale ("C"); Font font = new Font (device, fdata); int fontList = font.handle; int[] buffer = new int [1]; if (!OS.XmFontListInitFontContext (buffer, fontList)) return; int context = buffer [0]; XFontStruct fontStruct = new XFontStruct (); int fontListEntry; int[] fontStructPtr = new int [1]; int[] fontNamePtr = new int [1]; int xfont = 0; // go through each entry in the font list while ((fontListEntry = OS.XmFontListNextEntry (context)) != 0) { int fontPtr = OS.XmFontListEntryGetFont (fontListEntry, buffer); if (buffer [0] == OS.XmFONT_IS_FONT) { // FontList contains a single font OS.memmove (fontStruct, fontPtr, 20 * 4); xfont = fontStruct.fid; } else { // FontList contains a fontSet int nFonts = OS.XFontsOfFontSet (fontPtr, fontStructPtr, fontNamePtr); int[] fontStructs = new int [nFonts]; OS.memmove (fontStructs, fontStructPtr [0], nFonts * 4); // Go through each fontStruct in the font set. for (int i = 0; i < nFonts; i++) { OS.memmove (fontStruct, fontStructs [i], XFontStruct.sizeof); xfont = fontStruct.fid; } } } if (xfont != 0) { XGL.glXUseXFont (xfont, startIndex, length, base); } font.dispose (); OS.XmFontListFreeFontContext (context); } /** * Loads the specified outline font. * * @param fdata * @param device * @param base * @param first * @param count * @param deviation * @param extrusion * @param format * @param lpgmf */ public void loadOutlineFont (FontData fdata, Device device, int base, int first, int count, float deviation, float extrusion, int format, GLYPHMETRICSFLOAT[] lpgmf) { // stub } /** * Resizes the receiver. * * @param x * @param y * @param width * @param height */ public void resize (int x, int y, int width, int height) { if (height == 0) height = 1; GL.glViewport (x, y, width, height); GL.glMatrixMode (GL.GL_PROJECTION); GL.glLoadIdentity (); GLU.gluPerspective (45.0f, (float) width / (float) height, 0.1f, 100.0f); GL.glMatrixMode (GL.GL_MODELVIEW); GL.glLoadIdentity (); } /** * Sets the receiver to be the current <code>GLContext</code>. * * @exception SWTError <ul> * <li>ERROR_GRAPHIC_DISPOSED if the receiver is disposed</li> * </ul> */ public void setCurrent () { if (isDisposed ()) SWT.error (SWT.ERROR_GRAPHIC_DISPOSED); if (XGL.glXGetCurrentContext () == handle) return; XGL.glXMakeCurrent (data.display, data.drawable, handle); } /** * Swaps the receiver's buffers. * * @exception SWTError <ul> * <li>ERROR_GRAPHIC_DISPOSED if the receiver is disposed</li> * </ul> */ public void swapBuffers () { if (isDisposed ()) SWT.error (SWT.ERROR_GRAPHIC_DISPOSED); XGL.glXSwapBuffers (data.display, data.drawable); } }