/** * @(#) GLContext.java */ package gl4java; import gl4java.jau.awt.WinHandleAccess; import java.awt.*; import java.applet.Applet; import java.awt.event.*; import java.io.*; import java.lang.reflect.*; import java.security.*; import java.util.*; /** * The base manager class for the OpenGL language mapping for Java ! * *

* If you are interessting in further Documentation and/or * the history of GL4Java follow the following link. * *

        The GL4Java Documentation
 * 
*

* * All native libraries and GLFunc* and GLUFunc* implementations * can/should be loaded right here ! * *

 	doLoadNativeLibraries
 	createGLFunc
 	createGLUFunc
        

To check the library versions, you can start the main function with java gl4java.GLContext *

* *

* * This class creates a GLContext in the constructor which fits to the native Window * of the given Component ! * *

   	glc2glj - A simple c to java converter for C- and GL-types
 * 
*

* * The native libraries are plattform depended. * *

	  The default native library's are:
	  

GL4JavaJauGljJNI (jdk ==1.1), GL4JavaJauGljJNI12 (jdk ==1.2), GL4JavaJauGljJNI13 (jdk ==1.3) GL4JavaJauGljJNI14 (jdk >=1.4)

To check wich version and vendors are currently used, just call while a GLContext is created :

gljShowVersions

Or just run at the command line:

java gl4java.GLContext -info

*

* * Make sure that this library is installed in your library path. * The library path is for Unices one path of the environment * variable ´LD_LIBRARY_PATH´ and for Windows 32 * ´c:/winnt/system32´ (WinNT) or 'c:/windows/system' (Windows 95) . * Or it should be installed in the 'jre/bin' or * 'Netscape/communicator/Program/java/bin' path ! * *

* * To have a convinient usage, e.g. automatic resizing, GLContext * and painting/gl-rendering, some classes in the package gl4java.awt * may help you. * *

          E.g.: gl4java.awt.GLCanvas 
	  

init to create the java-stuff and GL-inits display to render one frame, called by paint reshape to reshape (window resize)

Or look for animation at gl4java.awt.GLAnimCanvas ! *

* *

* * IF you remove/release a The component which is binded to this GLContext, * you have to release the GLContext also - while calling: * *

 	gljDestroy
 * 
* * before releasing/dispose it´s Window ! * *

* * We also define our own OpenGL extension. This extension functions * start with the prefix glj like you can see here: * *

        THIS FUNCTIONS ARE FOR USERS PURPOSES:
	======================================

 	doLoadNativeLibraries
 	createGLFunc
 	createGLUFunc
 	gljIsInit
 	gljMakeCurrent
 	gljSwap
 	gljFree
 	gljDestroy
 	gljGetNativeLibVersion
 	gljGetClassVersion
	gljShowVersions
 	gljCheckGL
 	gljCheckGLTypes
 	gljResize

 * 
*

* * You can see our example demo sources: *

	olympicCvs.java as java source
	glLogoCvs.java as java source
	glDemosCvs.java as java source
 * 
*

* * If you are interessting in further Documentation, downloading the latest * version, and/or the history of GL4Java click on the following link. * *

	The GL4Java Homepage
 * 
*

* * @version 2.00, 21. April 1999 * @author Sven Goethel * */ public class GLContext extends Object implements Runnable { protected boolean isInitialized = false; /** * Flag is the native library is loaded. * The native library is loaded at startup. * If we failed loading the lib., * gljMakeCurrent and gljIsInit will return false. * * @see gl4java.GLContext#gljIsInit */ protected static boolean libsLoaded = false; /** * The default extra native library for Windows 95/NT && MS-JVM * */ public final static String defGljMSWinLib = "GL4JavaGljMSJDirect" ; /** * The default GLContext/GLFunc/GLUFunc native library for all * */ public final static String defGljLib = "GL4JavaJauGljJNI" ; /** * The default GLFunc implementation * */ public static final String defGLFuncClass = "GLFuncJauJNI" ; public static final String defGLFunc14Class = "GLFunc14JauJNI" ; /** * The default GLUFunc implementation * */ public static final String defGLUFuncClass = "GLUFuncJauJNI" ; public static final String defGLUFunc14Class = "GLUFunc14JauJNI" ; /** * The default native GL library ... for X11 */ public final static String defNativeGLLibX11 = "libGL.so"; /** * The default native GL library ... for MacOS9 */ public final static String defNativeGLLibMacOS9 = "\\pOpenGLLibrary"; /** * The default native GL library ... for MacOSX */ public final static String defNativeGLLibMacOSX = "libGL.so"; /** * The default native GL library ... for Win32 */ public final static String defNativeGLLibWin32 = "OPENGL32.DLL"; /** * The default native GLU library ... for X11 */ public final static String defNativeGLULibX11 = "libGLU.so"; /** * The default native GLU library ... for MacOS9 */ public final static String defNativeGLULibMacOS9 = "\\pOpenGLULibrary"; /** * The default native GLU library ... for MacOSX */ public final static String defNativeGLULibMacOSX = "libGLU.so"; /** * The default native GLU library ... for Win32 */ public final static String defNativeGLULibWin32 = "GLU32.DLL"; /** * the version of this java-class * * ... * * Each is dezimal ! */ public final static String version = __SED_CLASS_VERSION__ ; /** * Flag's to enable/disable verbose Information. * Usually for debugging. */ public static boolean gljClassDebug = false; public static boolean gljThreadDebug = false; public static boolean gljNativeDebug = false; /** * We will store the GL Context right here. * * @see gl4java.GLContext#createGLContext * @see gl4java.GLContext#gljInit */ protected long glContext=0; protected static int glContextNumber=0; /** * The context with witch display lists and textures will be shared. * * @see gl4java.GLContext#createGLContext * @see gl4java.GLContext#gljInit */ protected GLContext sharedGLContext; protected long sharedGLContextNative= 0; // No sharing by default. /** * Xwindow data AND Windows data for the widget * * @see gl4java.GLContext#createGLContext * @see gl4java.GLContext#gljInit */ protected long pixmapHandle=0; // unique handle for the Pixmap protected long windowHandle=0; // unique handle for this widget's window protected long displayHandle=0; // unqiue handle to the display private int createwinw; private int createwinh; /** * MS-JDirect-Window data for the MS-JVM interface * * @see gl4java.GLContext#createGLContext * @see gl4java.GLContext#gljInit */ private int createwinx; private int createwiny; private boolean threadRunning = false; private boolean destroyWindow = false; protected Container containerWindow = null; /** * The custom set offscreen Size * * If this is set to != null, * the offscreen pixmap is used in this size, * not in the components-size (-> faster if smaller) * * Must be set via createOffScreenCtx * * @see gl4java.swing.GLJPanel#paint * @see gl4java.GLContext#createOffScreenCtx */ protected Dimension offScrnSize = null; /** * Windows data AND flag is Window-Handel is read (for X11 also) ! * * @see gl4java.GLContext#createGLContext * @see gl4java.GLContext#gljInit */ long pData = 0; // stores the pointer structure that holds windows info /** * Flag to check, if the OpenGL-Context is active ! * * @see gl4java.GLContext#isEnabled * @see gl4java.GLContext#setEnabled */ protected boolean glEnabled = true; /** * Do we use offscreen rendering * X11: pixmap eq window-ressources, * window eq. GLXPixmap a GLXDrawable * glContext eq. GLXContext * * This is set via the constructor ! * * @see gl4java.GLContext#GLContext */ protected boolean offScreenRenderer = false; /** * We normally do not have to create an own Window ! * This is the default visual property ... ! * But some machines, like SGI's Irix, * must use an own created overlapped window ! * For these machines, a compiler flag is set, * so that this value is alsways set to true ! * * This is set via the constructor ! * * @see gl4java.GLContext#isOwnWindowCreated * @see gl4java.GLContext#GLContext */ protected boolean createOwnWindow = false; /** * The GLCapabilities .. * * This is set via the constructor ! * * @see gl4java.GLContext#GLContext */ protected GLCapabilities glCaps = null; /** * The resize flag, which indicates a resize for the next paint function ! * This flag will bes set in 'componentResized' * and will be cleared after resize (glViewport) in sDisplay !! * * @see gl4java.awt.GLCanvas#sDisplay */ protected boolean mustResize = false; protected Dimension size = null; /** * the light- or heavy component * where GL commands should be drawn */ protected Component _comp = null; /** * the heavy component * where GL commands should be drawn * * if the _comp component is a swing (light) * component, this component contains its heavy parent ! */ protected Component _compHeavy = null; /** * Variable to tell is where windows or not (X11) * Usally X11 ;-)) * * Ok - lets give one to the Max :-) */ public final static int OsWindoof = -1, OsUnknown = 0, OsX11 = 1, OsMac9 = 2, // for Gerard Ziemski's port OsMacX = 3; // for Gerard Ziemski's port private static int osType=OsUnknown; private static boolean isNetscapeJvm = false; private static boolean isMicrosoftJvm = false; private static boolean isIBMJvm = false; private static boolean useMSJDirect = false; private static String jvmVendor = null; private static String jvmVersion = null; private static int jvmVersionMajor = 1; // min. defaults private static int jvmVersionMinor = 1; // min. defaults private static String osName = null; private static String jniEXTsuff = null; /** * Get the native GL Context ! * * @see gl4java.GLContext#glContext */ public final long getNativeGLContext() { return glContext; } public final static int getNativeGLContextNumber() { return glContextNumber; } /** * Get the native Window Handle ! * * @see gl4java.GLContext#windowHandle * * @deprecated The native window handle is no more accessible * through this method since JDK >= 1.3 ! */ public final long getNativeWindoHandle() { return windowHandle; } /** * Get the optional shared GL Context ! * * @see gl4java.GLContext#sharedGLContext */ public final GLContext getSharedGLContext() { return sharedGLContext; } /** * Get the native OS-Type ! * * @see gl4java.GLContext#OsWindoof * @see gl4java.GLContext#OsUnknown * @see gl4java.GLContext#OsX11 * @see gl4java.GLContext#OsMac9 * @see gl4java.GLContext#OsMacX */ public static int getNativeOSType() { return osType; } public static String getNativeOSName() { return osName; } /** * Query the visual property ... ! * * After a GLContext is created, this property can be queried ! * * @see gl4java.GLContext#glCaps * @see gl4java.GLContext#GLContext */ public final GLCapabilities getGLCapabilities() { return glCaps; } /** * Query the visual property ... ! * * After a GLContext is created, this property can be queried ! * * @see gl4java.GLContext#glCaps * @see gl4java.GLContext#GLContext */ public final boolean isDoubleBuffer() { return glCaps.getDoubleBuffered(); } /** * Query the visual property ... ! * * After a GLContext is created, this property can be queried ! * * @see gl4java.GLContext#glCaps * @see gl4java.GLContext#GLContext */ public final int getStencilBitNumber() { return glCaps.getStencilBits(); } /** * Query the visual property ... ! * * After a GLContext is created, this property can be queried ! * * @see gl4java.GLContext#glCaps * @see gl4java.GLContext#GLContext */ public final int getAccumSize() { return glCaps.getAccumRedBits()+ glCaps.getAccumGreenBits()+ glCaps.getAccumBlueBits()+ glCaps.getAccumAlphaBits(); } /** * Query the visual property ... ! * * After a GLContext is created, this property can be queried ! * * @see gl4java.GLContext#glCaps * @see gl4java.GLContext#GLContext */ public final boolean isStereoView() { return glCaps.getStereo(); } /** * Query the visual property ... ! * * After a GLContext is created, this property can be queried ! * * @see gl4java.GLContext#glCaps * @see gl4java.GLContext#GLContext */ public final boolean isRGBA() { return glCaps.getTrueColor(); } /** * Query the visual property ... ! * * After a GLContext is created, this property can be queried ! * * @see gl4java.GLContext#createOwnWindow * @see gl4java.GLContext#GLContext */ public final boolean isOwnWindowCreated() { return createOwnWindow; } /** * Support of loading the native library seperatly. * * Link with the default native OpenGL library. * If we cannot link, an exception is thrown. * * The name of the library is named e.g.: "GL4JavaJauGljJNI" at the * Java level, or "libGL4JavaJauGljJNI.so" at the solaris level, * or "GL4JavaJauGljJNI.dll" at the win32 level :-). * *

* * The user must call loadNativeLibrary ! * E.g. he can add the default loader like this: *

	    static {
		if(GLContext.loadNativeLibraries(null, null, null)==false)
		  System.out.println("could not load def. native libs.");
	    }
     * 
* * @param gljLibName The name of the GLContex/GLFunc/GLUFunc * native library. * If gljLibName==null, the default library will be used ! * * @param glLibName deprecated * * @param gluLibName deprecated * * @return boolean, true if succesfull ! * * @see gl4java.GLContext#defGljLib * * @deprecated The arguments glLibName and gluLibName are obsolete, * because all glj/gl/glu stuff resides within * the gljLib ! * Now you can use doLoadNativeLibraries ! */ public final static boolean loadNativeLibraries ( String gljLibName, String glLibName, String gluLibName ) { return doLoadNativeLibraries(gljLibName, null, null); } /** * Support of loading the native library seperatly. * * Link with the given OpenGL library. * If we cannot link, an exception is thrown. * * You can also specify the OpenGL and GLU library by * the environment variables: *
     		GLTOOL_USE_GLLIB	- OpenGL library name
     		GLTOOL_USE_GLULIB	- GLU    library name
     * 
* these environment variables does _always_ overrides * any given ones at this point !! * * The name of the library is named e.g.: "GL4JavaJauGljJNI" at the * Java level, or "libGL4JavaJauGljJNI.so" at the solaris level, * or "GL4JavaJauGljJNI.dll" at the win32 level :-). * *

* * The user must call doLoadNativeLibrary ! * E.g. he can add the default loader like this: *

	    static {
		if(GLContext.doLoadNativeLibraries(null, null, null)==false)
		  System.out.println("could not load def. native libs.");
	    }
     * 
* * @param gljLibName The name of the GLContex/GLFunc/GLUFunc * native library. * If gljLibName==null, the default library will be used ! * * @param nativeGLLibName The name of the native GL library. * If nativeGLLibName==null, the default library will be used ! * * @param nativeGLULibName The name of the native GLU library. * If nativeGLULibName==null, the default library will be used ! * * @return boolean, true if succesfull ! * * @see gl4java.GLContext#defGljLib * @see gl4java.GLContext#defNativeGLLibX11 * @see gl4java.GLContext#defNativeGLLibMacOS9 * @see gl4java.GLContext#defNativeGLLibMacOSX * @see gl4java.GLContext#defNativeGLLibWin32 * @see gl4java.GLContext#defNativeGLULibX11 * @see gl4java.GLContext#defNativeGLULibMacOS9 * @see gl4java.GLContext#defNativeGLULibMacOSX * @see gl4java.GLContext#defNativeGLULibWin32 */ public final static boolean doLoadNativeLibraries ( String gljLibName, String nativeGLLibName, String nativeGLULibName ) { if(libsLoaded) return true; if(gljClassDebug) System.out.println("GLContext.doLoadNativeLibraries will do it !"); jvmVendor = java.lang.System.getProperty("java.vendor"); jvmVersion = java.lang.System.getProperty("java.version"); if(gljClassDebug) { System.out.println("jvm vendor: "+jvmVendor); System.out.println("jvm version: "+jvmVersion); } int i0 = 0; int i1 = jvmVersion.indexOf(".", i0); String strhlp = null; if(i1>0) { strhlp = jvmVersion.substring(i0,i1); try { jvmVersionMajor = Integer.valueOf(strhlp).intValue(); } catch (Exception e) {System.out.println("Not a number: "+strhlp+" ("+jvmVersion+")");} } i0 = i1+1; i1 = jvmVersion.indexOf(".", i0); if( i1 < 0 ) i1 = jvmVersion.length(); // no 2nd dot, no bug version number if( 0=0 ; isMicrosoftJvm = jvmVendor!=null && jvmVendor.indexOf("Microsoft")>=0 ; isIBMJvm = jvmVendor!=null && jvmVendor.indexOf("IBM")>=0 ; // Determine the OS osName = System.getProperty( "os.name" ).toLowerCase(); if( osName.startsWith( "wind" ) ) osType = OsWindoof; else if( osName.startsWith( "darwin" ) ) osType = OsMacX; else if( osName.startsWith( "mac os" ) ) osType = OsMac9; else /* oops - lets guess unix/x11 :-) */ osType = OsX11; if( jvmVersionMajor>=2 || ( jvmVersionMajor==1 && jvmVersionMinor>=4 ) ) { jniEXTsuff="14"; } else if( jvmVersionMajor==1 && jvmVersionMinor>=3 && !isIBMJvm && !isMicrosoftJvm ) { jniEXTsuff="13"; } else if( jvmVersionMajor==1 && jvmVersionMinor>=2 ) { jniEXTsuff="12"; } else { jniEXTsuff=""; } if(nativeGLLibName==null) { if ( osType==OsWindoof ) nativeGLLibName = defNativeGLLibWin32; else if ( osType==OsMac9 ) nativeGLLibName = defNativeGLLibMacOS9; else if ( osType==OsMacX ) nativeGLLibName = defNativeGLLibMacOSX; else nativeGLLibName = defNativeGLLibX11; } if(nativeGLULibName==null) { if ( osType==OsWindoof ) nativeGLULibName = defNativeGLULibWin32; else if ( osType==OsMac9 ) nativeGLULibName = defNativeGLULibMacOS9; else if ( osType==OsMacX ) nativeGLULibName = defNativeGLULibMacOSX; else nativeGLULibName = defNativeGLULibX11; } if(gljLibName==null) gljLibName = defGljLib+jniEXTsuff; String[] libNames = null; if ( (osType==OsWindoof) && (isMicrosoftJvm) ) { // JDirect loads the GL libraries automatically, // so we don't have to. libNames = new String[2]; libNames[0]= gljLibName; libNames[1]= defGljMSWinLib; useMSJDirect = true; } else { /* For MAC, Win32+SunJVM, Unices ... */ libNames = new String[1]; libNames[0]= gljLibName; useMSJDirect = false; } final String f_libNames[] = libNames; if(isNetscapeJvm) { System.out.println("Netscape JVM try to get Privileges"); try { Class privmgr = Class.forName("netscape.security.PrivilegeManager"); Class[] parameterTypes = new Class[1]; parameterTypes[0] = Class.forName("java.lang.String"); Method m = privmgr.getMethod("enablePrivilege",parameterTypes); Object args[] = new Object[1]; args[0] = (Object)(new String("UniversalLinkAccess")); m.invoke(privmgr,args); /* netscape.security.PrivilegeManager.enablePrivilege ("UniversalLinkAccess"); */ System.out.println("Netscape-Privilege: enabled UniversalLinkAccess priv."); } catch (Exception ex) { System.out.println("Not enabled Netscape-Privilege: UniversalLinkAccess priv."); } } boolean ok; if( jvmVersionMajor>=2 || (jvmVersionMajor==1 && jvmVersionMinor>=2) ) { Boolean ook = (Boolean) AccessController.doPrivileged(new PrivilegedAction() { public Object run() { /* load libs */ int libNumber = 0; String _libName = null ; boolean libLoaded[] = new boolean[f_libNames.length]; for(libNumber=0; libNumber * -GLULib * -gljlib gl4java-glj-lib native library * -glclass gl4java-gl-class java GLFunc implementation * -gluclass gl4java-glu-class java GLUFunc implementation * -info creates a GLContext and prints all avaiable information of GL/GLU and GL4Java * -infotxt like -info, but exits straight after -info ! * * without any arguments, a help screen is shown */ public static void main( String args[] ) { String nativeGLLib = null; String nativeGLULib = null; String gljLibName = null; String glName = null; String gluName = null; boolean info=false; boolean exitImmediatly=false; boolean noFactory=false; int i = 0; boolean ok=true; if(args.length==0) { System.out.println("usage: java gl4java.GLContext , where options can be: "); System.out.println(" -GLLib \t choose a custom OpenGL native library (default: libGL, or OPENGL32, ..)"); System.out.println(" -GLULib \t choose a custom GLU native library (default: libGLU, or GLU32, ..)"); System.out.println(" -gljlib \t choose a custom gl4java-glj-lib native library (default: GL4JavaJauGljJNI)"); System.out.println(" -glclass \t choose a custom gl4java-gl-class java GLFunc implementation (default: GLFuncJauJNI)"); System.out.println(" -gluclass \t choose a custom gl4java-glu-class java GLUFunc implementation (default: GLUFuncJauJNI)"); System.out.println(" -info \t creates a GLContext and prints all avaiable information of GL/GLU and GL4Java"); System.out.println(" -infotxt \t like -info, but exits straight after -info !"); System.out.println(" -noFactory \t creates a GLContext without the new GLDrawableFactory API"); System.exit(0); } while(args.length>i) { if(args[i].equals("-GLLib")) { if(args.length>++i) nativeGLLib=args[i]; } else if(args[i].equals("-GLULib")) { if(args.length>++i) nativeGLULib=args[i]; } else if(args[i].equals("-gljlib")) { if(args.length>++i) gljLibName=args[i]; } else if(args[i].equals("-glclass")) { if(args.length>++i) glName=args[i]; } else if(args[i].equals("-gluclass")) { if(args.length>++i) gluName=args[i]; } else if(args[i].equals("-info")) { info=true; } else if(args[i].equals("-infotxt")) { info=true; exitImmediatly=true; } else if(args[i].equals("-noFactory")) { noFactory=true; } else { System.out.println("illegal arg "+i+": "+args[i]); ok=false; } i++; } GLContext.gljNativeDebug = true; GLContext.gljClassDebug = true; GLFunc gl = null; GLUFunc glu = null; if(GLContext.doLoadNativeLibraries(gljLibName, nativeGLLib, nativeGLULib ) ) System.out.println("native Libraries loaded succesfull"); else { System.out.println("native library NOT loaded complete"); ok=false; } if( (gl=GLContext.createGLFunc(glName)) !=null) System.out.println("GLFunc implementation "+gl.getClass().getName()+" created succesfull"); else { System.out.println("GLFunc implementation "+glName+" not created"); ok=false; } if( (glu=GLContext.createGLUFunc(gluName)) !=null) System.out.println("GLUFunc implementation "+glu.getClass().getName()+" created succesfull"); else { System.out.println("GLUFunc implementation "+gluName+" not created"); ok=false; } if( info && ok==true) { Frame f = new Frame("GL4Java Info"); f.setSize(10, 10); Canvas cvs = null; GLCapabilities glCaps = new GLCapabilities(); gl4java.drawable.GLDrawableFactory df = gl4java.drawable.GLDrawableFactory.getFactory(); if(noFactory || !(df instanceof gl4java.drawable.SunJDK13GLDrawableFactory) ) { cvs = new Canvas(); } else { gl4java.drawable.SunJDK13GLDrawableFactory sdf = (gl4java.drawable.SunJDK13GLDrawableFactory)df; cvs = new Canvas(sdf.getGraphicsConfiguration(glCaps)); } cvs.setVisible(true); cvs.setSize(50,50); f.add("Center", cvs); f.setSize(60,60); // f.pack(); f.setVisible(true); GLContext glj = new GLContext( cvs, gl, glu, glCaps, null); Frame fInfo = glj.gljShowVersions(); fInfo.addWindowListener ( new WindowAdapter() { public void windowClosed(WindowEvent e) { // button exit System.exit(0); } } ); glj.gljDestroy(); if(exitImmediatly) System.exit(0); } } public static String getJVMVersion() { return jvmVersion; } public static int getJVMVersionMajor() { return jvmVersionMajor; } public static int getJVMVersionMinor() { return jvmVersionMinor; } public static String getJVMVendor() { return jvmVendor; } public static boolean isNetscapeJVM() { return isNetscapeJvm; } public static boolean isMicrosoftJVM() { return isMicrosoftJvm; } /** * Used to hold the user given GLFunc implementation */ private GLFunc gl = null; /** * Used to hold the user given GLUFunc implementation */ private GLUFunc glu = null; /** * * Constructor * * This privat constructor is for all possible * compinations and is called from the customized * constructors. * * First the GLContext is fetched from the Component itself ! * To do so, the Component is set visible if it is not ! * * If a GLContext is fetched, it is current ! * * @param comp the users component for the gl-context * @param glf the users selected GLFunc implementation * @param glf the users selected GLUFunc implementation * @param _createOwnWindow the flag for the visual property * @param _offScreenRenderer the flag for the visual property * @param _offScrnSize the fixed offscreen pixmap size * @param _glCaps the GLCapabilities * @param _sharedGLContext the shared GLContext * */ protected GLContext( Component comp, GLFunc glf, GLUFunc gluf, boolean _createOwnWindow, boolean _offScreenRenderer, Dimension _offScrnSize, GLCapabilities _glCaps, GLContext _sharedGLContext ) { super( ); _comp = comp ; // the light- or heavy component gl = glf ; glu = gluf ; createOwnWindow = _createOwnWindow; offScreenRenderer = _offScreenRenderer; offScrnSize= _offScrnSize; glCaps = _glCaps; this.sharedGLContext = _sharedGLContext; if(sharedGLContext != null) sharedGLContextNative = (int)sharedGLContext.getNativeGLContext(); // fetch the heavy peer component in temporary var. comp while(comp!=null && (comp.getPeer() instanceof java.awt.peer.LightweightPeer) ) comp=comp.getParent(); _compHeavy = comp ; // the heavy component Graphics _gr = null; if(_compHeavy!=null) { if( ! _comp.isVisible() ) setVisible(true); // use our own ... _gr = _compHeavy.getGraphics(); if(_gr==null) System.out.println("got empty Graphics"); } else if(!offScreenRenderer) System.out.println("got empty Component"); if( (_comp!=null && _gr!=null) || offScreenRenderer ) { int i = 0; do { createGLContext(_gr); // uses _comp if(gljIsInit()==false) { try { Thread.sleep( 100 ); } catch( Exception e ) { } } i++; } while(gljIsInit()==false && i<5) ; } if(gljClassDebug) { if(gljIsInit()) System.out.println("GLContext GLContext() succeded"); else System.out.println("GLContext GLContext() failed"); } } /** * * Constructor * * This privat constructor is for all possible * compinations and is called from the customized * constructors. * * First the GLContext is fetched from the Component itself ! * To do so, the Component is set visible if it is not ! * * If a GLContext is fetched, it is current ! * * @param comp the users component for the gl-context * @param glf the users selected GLFunc implementation * @param glf the users selected GLUFunc implementation * @param _createOwnWindow the flag for the visual property * @param _offScreenRenderer the flag for the visual property * @param _doubleBuffer the flag for the visual property * @param _stereoView the flag for the visual property * @param _rgba the flag for the visual property * @param _stencilBits the flag for the visual property * @param _accumSize the flag for the visual property * @param _sharedGLContext the shared GLContext * @param _offScrnSize the fixed offscreen pixmap size * */ protected GLContext( Component comp, GLFunc glf, GLUFunc gluf, boolean _createOwnWindow, boolean _offScreenRenderer, boolean _doubleBuffer, boolean _stereoView, boolean _rgba, int _stencilBits, int _accumSize, GLContext _sharedGLContext, Dimension _offScrnSize ) { this( comp, glf, gluf, _createOwnWindow, _offScreenRenderer, _offScrnSize, new GLCapabilities(_doubleBuffer, _stereoView, _rgba, _stencilBits, _accumSize, _accumSize, _accumSize, _accumSize), _sharedGLContext); } /** * * Constructor * * First the GLContext is fetched from the Component itself ! * To do so, the Component is set visible if it is not ! * * If a GLContext is fetched, it is current ! * * @param comp the users component for the gl-context * @param glf the users selected GLFunc implementation * @param glf the users selected GLUFunc implementation * @param _glCaps the GLCapabilities * @param _sharedGLContext the shared GLContext * */ public GLContext( Component comp, GLFunc glf, GLUFunc gluf, GLCapabilities _glCaps, GLContext _sharedGLContext ) { this( comp, glf, gluf, false, false, null, _glCaps, _sharedGLContext); } /** * * Constructor * * First the GLContext is fetched from the Component itself ! * To do so, the Component is set visible if it is not ! * * If a GLContext is fetched, it is current ! * * @param comp the users component for the gl-context * @param glf the users selected GLFunc implementation * @param glf the users selected GLUFunc implementation * @param _createOwnWindow the flag for the visual property * @param _doubleBuffer the flag for the visual property * @param _stereoView the flag for the visual property * @param _rgba the flag for the visual property * @param _stencilBits the flag for the visual property * @param _accumSize the flag for the visual property * @param _sharedGLContext the shared GLContext * */ public GLContext( Component comp, GLFunc glf, GLUFunc gluf, boolean _createOwnWindow, boolean _doubleBuffer, boolean _stereoView, boolean _rgba, int _stencilBits, int _accumSize, GLContext _sharedGLContext ) { this(comp, glf, gluf, _createOwnWindow, false /* offscreen renderer */, _doubleBuffer, _stereoView, _rgba, _stencilBits, _accumSize, _sharedGLContext, null /* offscreen size */ ); } /** * * Constructor * * First the GLContext is fetched from the Component itself ! * To do so, the Component is set visible if it is not ! * * If a GLContext is fetched, it is current ! * * @param comp the users component for the gl-context * @param glf the users selected GLFunc implementation * @param glf the users selected GLUFunc implementation * @param _createOwnWindow the flag for the visual property * @param _doubleBuffer the flag for the visual property * @param _stereoView the flag for the visual property * @param _rgba the flag for the visual property * @param _stencilBits the flag for the visual property * @param _accumSize the flag for the visual property * */ public GLContext( Component comp, GLFunc glf, GLUFunc gluf, boolean _createOwnWindow, boolean _doubleBuffer, boolean _stereoView, boolean _rgba, int _stencilBits, int _accumSize ) { this(comp, glf, gluf, _createOwnWindow, false /* offscreen renderer */, _doubleBuffer, _stereoView, _rgba, _stencilBits, _accumSize, null /* sharedGLContext */, null /* offscreen size */ ); } /** * * Constructor * * First the GLContext is fetched from the Component itself ! * To do so, the Component is set visible if it is not ! * * If a GLContext is fetched, it is current ! * * @param comp the users component for the gl-context * @param glf the users selected GLFunc implementation * @param glf the users selected GLUFunc implementation * @param _createOwnWindow the flag for the visual property * @param _doubleBuffer the flag for the visual property * @param _stereoView the flag for the visual property * @param _rgba the flag for the visual property * @param _stencilBits the flag for the visual property * */ public GLContext( Component comp, GLFunc glf, GLUFunc gluf, boolean _createOwnWindow, boolean _doubleBuffer, boolean _stereoView, boolean _rgba, int _stencilBits ) { this(comp, glf, gluf, _createOwnWindow, false /* offscreen renderer */, _doubleBuffer, _stereoView, _rgba, _stencilBits, 0 /* accumSize */, null /* sharedGLContext */, null /* offscreen size */ ); } /** * * Constructor * * First the GLContext is fetched from the Component itself ! * To do so, the Component is set visible if it is not ! * * If a GLContext is fetched, it is current ! * * @param comp the users component for the gl-context * @param glf the users selected GLFunc implementation * @param glf the users selected GLUFunc implementation * @param _doubleBuffer the flag for the visual property * @param _stereoView the flag for the visual property * @param _rgba the flag for the visual property * @param _stencilBits the flag for the visual property * */ public GLContext( Component comp, GLFunc glf, GLUFunc gluf, boolean _doubleBuffer, boolean _stereoView, boolean _rgba, int _stencilBits, int _accumSize ) { this(comp, glf, gluf, false /* ownWindow */, false /* offscreen renderer */, _doubleBuffer, _stereoView, _rgba, _stencilBits, _accumSize, null /* sharedGLContext */, null /* offscreen size */ ); } /** * * Constructor * * First the GLContext is fetched from the Component itself ! * To do so, the Component is set visible if it is not ! * * If a GLContext is fetched, it is current ! * * @param comp the users component for the gl-context * @param glf the users selected GLFunc implementation * @param glf the users selected GLUFunc implementation * @param _doubleBuffer the flag for the visual property * @param _stereoView the flag for the visual property * @param _rgba the flag for the visual property * @param _stencilBits the flag for the visual property * */ public GLContext( Component comp, GLFunc glf, GLUFunc gluf, boolean _doubleBuffer, boolean _stereoView, boolean _rgba, int _stencilBits ) { this(comp, glf, gluf, false /* ownWindow */, false /* offscreen renderer */, _doubleBuffer, _stereoView, _rgba, _stencilBits, 0 /* accumSize */, null /* sharedGLContext */, null /* offscreen size */ ); } /** * * Constructor * * First the GLContext is fetched from the Component itself ! * To do so, the Component is set visible if it is not ! * * If a GLContext is fetched, it is current ! * * @param comp the users component for the gl-context * @param glf the users selected GLFunc implementation * @param glf the users selected GLUFunc implementation * @param _doubleBuffer the flag for the visual property * @param _stereoView the flag for the visual property * @param _rgba the flag for the visual property * @param _stencilBits the flag for the visual property * */ public GLContext( Component comp, GLFunc glf, GLUFunc gluf, boolean _doubleBuffer, boolean _stereoView, boolean _rgba ) { this(comp, glf, gluf, false /* ownWindow */, false /* offscreen renderer */, _doubleBuffer, _stereoView, _rgba, 0, /* _stencilBits */ 0 /* accumSize */, null /* sharedGLContext */, null /* offscreen size */ ); } /** * * Constructor * * First the GLContext is fetched from the Component itself ! * To do so, the Component is set visible if it is not ! * * If a GLContext is fetched, it is current ! * * ! WARNING ! This flag is just for testing purpose !!! * * @param comp the users component for the gl-context * @param glf the users selected GLFunc implementation * @param glf the users selected GLUFunc implementation * @param _doubleBuffer the flag for the visual property * @param _stereoView the flag for the visual property * */ public GLContext( Component comp, GLFunc glf, GLUFunc gluf, boolean _doubleBuffer, boolean _stereoView ) { this(comp, glf, gluf, false /* ownWindow */, false /* offscreen renderer */, _doubleBuffer, _stereoView, true /* _rgba */, 0, /* _stencilBits */ 0 /* accumSize */, null /* sharedGLContext */, null /* offscreen size */ ); } /** * * Constructor * * First the GLContext is fetched from the Component itself ! * To do so, the Component is set visible if it is not ! * * We use a visual with doubleBuffer and NO stereoView ! * Do not force a new native window ! * * If a GLContext is fetched, it is current ! * * @param comp the users component for the gl-context * @param glf the users selected GLFunc implementation * @param glf the users selected GLUFunc implementation */ public GLContext( Component comp, GLFunc glf, GLUFunc gluf ) { this(comp, glf, gluf, false /* ownWindow */, false /* offscreen renderer */, true /* _doubleBuffer */, false /* _stereoView */, true /* _rgba */, 0, /* _stencilBits */ 0 /* accumSize */, null /* sharedGLContext */, null /* offscreen size */ ); } /** * * Constructor Function for offscreen rendering ! * * First the GLContext is fetched from the Component itself ! * To do so, the Component is set visible if it is not ! * * If a GLContext is fetched, it is current ! * * @param glf the users selected GLFunc implementation * @param glf the users selected GLUFunc implementation * @param _stereoView the flag for the visual property * @param _rgba the flag for the visual property * @param _stencilBits the flag for the visual property * @param _sharedGLContext the shared GLContext * * @return the created offscreen context */ public final static GLContext createOffScreenCtx ( GLFunc glf, GLUFunc gluf, boolean _stereoView, boolean _rgba, int _stencilBits, int _accumSize, GLContext _sharedGLContext ) { return new GLContext(null, glf, gluf, false /* _createOwnWindow */, true /* offscreen renderer */, false /* _doubleBuffer */, _stereoView, _rgba, _stencilBits, _accumSize, _sharedGLContext, null ); } /** * * Constructor Function for offscreen rendering ! * * First the GLContext is fetched from the Component itself ! * To do so, the Component is set visible if it is not ! * * If a GLContext is fetched, it is current ! * * @param glf the users selected GLFunc implementation * @param glf the users selected GLUFunc implementation * @param _stereoView the flag for the visual property * @param _rgba the flag for the visual property * @param _stencilBits the flag for the visual property * @param _sharedGLContext the shared GLContext * @param _offScrnSize the fixed offscreen pixmap size * * @return the created offscreen context */ public final static GLContext createOffScreenCtx ( GLFunc glf, GLUFunc gluf, boolean _stereoView, boolean _rgba, int _stencilBits, int _accumSize, GLContext _sharedGLContext, Dimension _offScrnSize ) { return new GLContext(null, glf, gluf, false /* _createOwnWindow */, true /* offscreen renderer */, false /* _doubleBuffer */, _stereoView, _rgba, _stencilBits, _accumSize, _sharedGLContext, _offScrnSize ); } /** * @see gl4java.GLContext#gljDestroy */ protected void finalize() throws Throwable { gljDestroy(); super.finalize(); } /** * Used to set the user given GLFunc implementation */ public final void setGLFunc(GLFunc _gl) { gl = _gl; } /** * Used to set the user given GLUFunc implementation */ public final void setGLUFunc(GLUFunc _glu) { glu = _glu; } /** * Used to return the user given GLFunc implementation */ public final GLFunc getGLFunc() { return gl; } /** * Used to return the user given GLUFunc implementation */ public final GLUFunc getGLUFunc() { return glu; } /** * Support of loading a vendors GLFunc implementation * * Try to load the Class, if succesfull we do return the instance of it. * Else null is returned ! * * The Class-Name is: "GL4Java." + vendorClass + ".class" ! * * @param vendorClass The name of the GLFunc implementation. * If vendorSuffix==null, the default implementation * "GLFuncJauJNI" (-> GL4Java.GLFuncJauJNI.class ) * will be used ! * * @return GLFunc, the implementation's instance if exists * and valid, or null * * @see gl4java.GLContext#defGLFuncClass */ public final static GLFunc createGLFunc(String vendorClass) { String access_name = "gl4java."; GLFunc gl = null; Object clazz = null; if(vendorClass==null) { if (jvmVersionMajor>=2 || (jvmVersionMajor==1 && jvmVersionMinor>=4)) { vendorClass = defGLFunc14Class; } else { vendorClass = defGLFuncClass; } } String clazzName = access_name + vendorClass ; try { clazz = Class.forName(clazzName).newInstance(); } catch (Exception ex) { // thats ok :-) System.out.println("could not create instance of: "+ clazzName); } if(clazz !=null && (clazz instanceof GLFunc)) gl = (GLFunc) clazz; else System.out.println("Not a GLFunc implementation: "+ clazzName); return gl; } /** * Support of loading a vendors GLUFunc implementation * * Try to load the Class, if succesfull we do return the instance of it. * Else null is returned ! * * The Class-Name is: "GL4Java." + vendorClass + ".class" ! * * @param vendorClass The name of the GLUFunc implementation. * If vendorSuffix==null, the default implementation * "GLUFuncJauJNI" (-> GL4Java.GLUFuncJauJNI.class ) * will be used ! * * @return GLUFunc, the implementation's instance if exists * and valid, or null * * @see gl4java.GLContext#defGLUFuncClass */ public final static GLUFunc createGLUFunc(String vendorClass) { String access_name = "gl4java."; GLUFunc glu = null; Object clazz = null; if(vendorClass==null) { if (jvmVersionMajor>=2 || (jvmVersionMajor==1 && jvmVersionMinor>=4)) { vendorClass = defGLUFunc14Class ; } else { vendorClass = defGLUFuncClass ; } } String clazzName = access_name + vendorClass ; try { clazz = Class.forName(clazzName).newInstance(); } catch (Exception ex) { // thats ok :-) System.out.println("could not create instance of: "+ clazzName); } if(clazz!=null && (clazz instanceof GLUFunc)) glu = (GLUFunc) clazz; else System.out.println("Not a GLUFunc implementation: "+ clazzName); return glu; } /** * * Own setVisible * This one set's us visible - and wait's for that result ! * * @param visible boolean: visible==true, hide==false * @return void */ public void setVisible( boolean visible ) { int i= 0; _comp.setVisible( visible ); while( _comp.isVisible() != visible && i<5) { _comp.setVisible( visible ); try { Thread.sleep( 100 ); } catch( Exception e ) { System.out.println( "GLContext:setVisible: Error - " + e ); } i++; } if(i>=5) System.out.println( "GLContext:setVisible: Error, could not set to "+visible); } /** * * createGLContext gets the window handle and calls gljInit, * so the gl-context will be initialised here. * * this method will be invoked by the constructor * * this method is left public - this time, * to allow the user to to it again later - if it was not succesfull ! * * @param g the graphics reference, * where we will get the native window handle from. * * @return void * * @see gl4java.GLContext#GLContext */ public final void createGLContext(Graphics g) { String access_name = "gl4java.jau.awt."; WinHandleAccess win_access = null; try { if(gljClassDebug) System.out.println("GLContext createGLContext"); if(pData == 0) { if(offScreenRenderer) { // nothing todo .. if(gljClassDebug) System.out.println("using OffScreen rendering ..."); } else if ( useMSJDirect && g!=null ) { if(gljClassDebug) System.out.println("using MSJDirect ..."); win_access = (WinHandleAccess) Class.forName( access_name+"windows.MSWin32HandleAccess" ).newInstance(); /* _comp should be a subclass of Canvas, and its parent class should be of type Panel, Frame or Window. If not, this all falls apart. */ /* This part is now rewritten, to respect direkt Windows (Frames and Dialogs) and Applets .. */ Component ob = _comp; while ( (ob instanceof Window)==false && (ob instanceof Applet)==false ) { ob = ob.getParent(); } containerWindow = (Container)ob; /* refetch the Graphics component */ g = ob.getGraphics(); if(g==null) System.out.println("GL4Java-MSJVM: got empty Graphics"); pData = win_access.getWinHandle(ob,g); if (pData != 0) { Point p1; try { p1 = _comp.getLocationOnScreen(); } catch (Exception e) { p1 = _comp.getLocation(); Point p2 = containerWindow.getLocation(); p1.x += p2.x; p1.y += p2.y; Insets is = containerWindow.getInsets(); p1.x += is.left; p1.y += is.top; } Rectangle r = _comp.getBounds(); createwinx = p1.x; createwiny = p1.y; createwinw = r.width; createwinh = r.height; windowHandle = 0; threadRunning = true; destroyWindow = false; Thread th = new Thread(this); th.start(); while ( (windowHandle == 0) && (threadRunning) ) { try { Thread.currentThread().sleep(100); } catch( Exception e ) { } } } } else if(osType==OsWindoof && !useJAWT()) { win_access = (WinHandleAccess) Class.forName( access_name+"windows.Win32HandleAccess" ).newInstance(); pData = win_access.getWinHandle(_compHeavy, g); windowHandle = pData; } else if((osType==OsMac9 || osType==OsMacX) && !useJAWT()) { win_access = (WinHandleAccess) Class.forName( access_name+"macintosh.MacHandleAccess" ).newInstance(); pData = win_access.getWinHandle(_compHeavy, g); windowHandle = pData; } else if(!useJAWT()) { win_access = (WinHandleAccess) Class.forName( access_name+"motif.X11HandleAccess" ).newInstance(); pData = win_access.getWinHandle(_compHeavy, g); windowHandle = pData; } } if(offScrnSize!=null) { createwinw = offScrnSize.width; createwinh = offScrnSize.height; } else { Rectangle r = _comp.getBounds(); createwinw = r.width; createwinh = r.height; } /* try to establish a context to OpenGL */ try { gljInit(); } catch( GL4JavaInitException e ) { System.out.println( "can't create a GL context\n"); } } catch (Exception e) { System.out.println( "An exception is thrown, while creating a GL context\n"); System.out.println(e); e.printStackTrace(); } } /* glj* stuff */ /** * * Initializes the gl-context. * gljInit is called by createGLContext (which is calles by the first paint)! * * Also gljInit will call the init method after GL initialisation, * so the user can override ´init´ to initialize his own stuff ! * * @return void * @exception GL4Java.GL4JavaInitException * this class throws an exception * if the native call to create a OpenGL context failed. * @see gl4java.GLContext#createGLContext * @see gl4java.awt.GLCanvas#paint * @see gl4java.awt.GLCanvas#init */ protected final synchronized void gljInit() throws GL4JavaInitException { if( libsLoaded==false ) return ; if(glCaps==null) { System.out.println("Internal error: glCaps not initialized !!"); throw new GL4JavaInitException (); } if(pData==0 && !offScreenRenderer && !useJAWT()) { System.out.println("could not open a GL widget -- Win CONTEXT"); throw new GL4JavaInitException (); } if(gljClassDebug) System.out.println("GLContext gljInit"); boolean ok; ok = openOpenGLNative(_comp); if( ! ok ) { if ( useMSJDirect && !offScreenRenderer) { destroyWindow = true; while (threadRunning) { try { Thread.currentThread().sleep(100); } catch( Exception e ) { } } pData = 0; windowHandle = 0; } System.out.println("could not open a GL widget -- GL CONTEXT"); throw new GL4JavaInitException (); } else { isInitialized = true; glEnabled=true; glContextNumber++; } } /** * For MSJVM Only ! * * This functions fetches the window-handle within a special thread ! */ public void run() { if ( !useMSJDirect ) { System.err.println("GL4Java-MSJVM-Run: INTERNAL ERROR"); System.exit(0); } /* System.out.println("OGL create win: x="+createwinx+", y="+createwiny+ ", w="+createwinw+", h="+createwinh); System.out.println("OGL create parent: "+pData); */ pData = gl4java.system.GljMSJDirect.createOGLWindowNative( pData, createwinx,createwiny, createwinw,createwinh); if (pData != 0) { windowHandle = pData; while (!destroyWindow) { gl4java.system.GljMSJDirect.OGLWindowMsgPump(); try { Thread.currentThread().sleep(10); } catch( Exception e ) { } } destroyWindow = false; gl4java.system.GljMSJDirect.destroyOGLWindowNative( windowHandle); windowHandle = 0; pData = 0; gl4java.system.GljMSJDirect.OGLWindowMsgPump(); } threadRunning = false; } /** * * Checks if the gl-context is Initializes * If returns true, * gljInit is allready called and a valid gl-context is achieved. * * No glMakeCurrent is done - * like gljMakeCurrent (important for more gl-context) ! * *

* * The user can use this method to check if he can start rendering * and to be sure his initialisation (init) is done ! * *

* * If you use gl4java.awt.GLCanvas, you should use the cvsIsInit * method ! *

* * @return boolean * @see gl4java.GLContext#gljInit * @see gl4java.awt.GLCanvas#cvsIsInit */ public final boolean gljIsInit() { return isInitialized; } /** * Resizes the gl-viewport * * Should be called, if the component is resized. * The user should take advantage of this functionality. * * Be sure to resize not within the event-method of the * ComponentHandler, you better resize while normal painting. * This can be done while using a boolean flag ;-) * * Look at GLComponent ! */ public final void gljResize(int width, int height) { if ( ! isInitialized || !glEnabled ) return; if(offScreenRenderer) { /** * nothing to do here * * we just have to recreate the whole bitmap and context */ return; } if ( useMSJDirect && !offScreenRenderer ) { try { Point p = _comp.getLocationOnScreen(); gl4java.system.GljMSJDirect.moveOGLWindowNative( windowHandle,p.x,p.y,width,height); } catch (Exception e) { } } else gljResizeNative( createOwnWindow, displayHandle, windowHandle, width,height); } private final native void gljResizeNative( boolean isOwnWindow, long disp, long thisWin, int width, int height ); /** * native C function of GLJ Library, * which query if it uses the JDK 1.3 JAWT interface * to fetch the native window handle */ protected static final native boolean useJAWT(); private static String makeLibName(String name) { int type = getNativeOSType(); if (type == OsWindoof) { return name + ".dll"; } else if ( type == OsX11 || type == OsMacX ) { return "lib" + name + ".so"; } else { throw new RuntimeException("Please port makeLibName to your platform"); } } private static final native boolean loadJAWT0(String name); private static final String findInPath(String libpath, String libname) { if (libpath == null) return null; String pathsep = System.getProperty("path.separator"); String filesep = System.getProperty("file.separator"); StringTokenizer tok = new StringTokenizer(libpath, pathsep); while (tok.hasMoreTokens()) { String curEntry = tok.nextToken(); String path = curEntry + filesep + libname; if (new File(path).exists()) { return path; } } return null; } /** * Routine which causes jawt.dll/libjawt.so to be loaded if that is * how the window handles are being obtained. */ protected static final boolean loadJAWT() { // Locate jawt.dll/libjawt.so by looking through // java.library.path and sun.boot.library.path String jawtName = makeLibName("jawt"); String libpath = findInPath(System.getProperty("java.library.path"), jawtName); if (libpath == null) { libpath = findInPath(System.getProperty("sun.boot.library.path"), jawtName); } if (libpath == null) { System.err.println("Unable to locate " + jawtName); System.err.println(" java.library.path = " + System.getProperty("java.library.path")); System.err.println(" sun.boot.library.path = " + System.getProperty("sun.boot.library.path")); return false; } return loadJAWT0(libpath); } /** * native C function of GLJ Library, * which query if the JAWT Surface has changed ! * * Use this after gljMakeCurrent -> jawt_lock ! * * If true, we need a new GLContext ! */ protected final native boolean hasJAWTSurfaceChanged(long thisWin); /** * native C function to open the OpenGLwidget */ protected final native boolean openOpenGLNative(Component canvas); /** * native C function to check the gl types. * At this time, all GL* types will be checked if they fit's * in the used java JNI types. * * this checks is allready performed, while the GL context is * fetched with gljInit ! * * BUT we used this function, to perform a check without an * X11-connection to our AIX host ;-)) * So a call to this function is not needed ! */ public final static boolean gljCheckGLTypes() { return gljCheckGLTypesNative(); } private final static native boolean gljCheckGLTypesNative(); public final boolean gljCheckGL() { if ( ! isInitialized || !glEnabled ) return false; int ec = gl.glGetError(); if(ec!=GLFunc.GL_NO_ERROR) { String errStr = glu.gluErrorString(ec); try { throw new Exception(); } catch (Exception e) { System.out.println("GL ERROR : "+errStr); System.out.println("GL ERROR : "+ec+" == 0x"+Integer.toHexString(ec)); e.printStackTrace(); System.out.println(); System.out.flush(); } return false; } return true; } private Thread ctxThread = null; private Thread nextThread = null; /** * * gljIsCurrent checks * if the current Thread holds the GL context of this * GLContext instance ! * * @return boolean * * @see gl4java.GLContext#gljIsRequested * @see gl4java.GLContext#gljMakeCurrent * @see gl4java.GLContext#getNativeGLContext * @see gl4java.GLContext#gljGetCurrentContext */ public synchronized final boolean gljIsCurrent() { if ( ! isInitialized || !glEnabled ) return false; Thread thisThread = Thread.currentThread(); if (ctxThread==thisThread && glContext==gljGetCurrentContext()) return true; return false; } /** * * gljIsRequested checks * if the this GLContext instance's native context * is requested by another thread ! * * @return boolean * * @see gl4java.GLContext#gljIsCurrent * @see gl4java.GLContext#gljMakeCurrent * @see gl4java.GLContext#getNativeGLContext * @see gl4java.GLContext#gljGetCurrentContext */ public synchronized final boolean gljIsRequested() { if ( ! isInitialized || !glEnabled ) return false; Thread thisThread = Thread.currentThread(); if (nextThread!=null && nextThread!=thisThread) return true; return false; } /** * * gljMakeCurrent checks whether GL4Java is initializes * AND makes the GL-Context current for this thread. * *

* * This functions now optimizes the context-switch ! * * The context is changed, only if : *

    	- another thread has requested this context -> release it
	  this gives the other thread a chance to get it ..

	- this thread does not own the current context
    * 
* *

* * You MUST encapsulate your OpenGL call's within: *

    	- gljMakeCurrent()
		YOUR OpenGL commands here !
    	- gljFree()
    * 
* * @return boolean * * @see gl4java.GLContext#gljSwap * @see gl4java.awt.GLCanvas#display * @see gl4java.awt.GLCanvas#sDisplay */ public synchronized final boolean gljMakeCurrent() { if ( ! isInitialized || !glEnabled ) return false; Thread thisThread = Thread.currentThread(); boolean dbgPrinted = false; /** * force a thread switch to improve responsiveness ! * * if an earmarked thread exist (nextThread) * we have to wait .. */ while (nextThread!=null && nextThread!=thisThread) { if(gljThreadDebug && !dbgPrinted) { System.out.println("wait-switch: "+thisThread); System.out.println("\tctxstate thisThread="+thisThread+", ctxThread="+ctxThread+", nextThread="+nextThread+", thisContext="+glContext+", currentContext="+gljGetCurrentContext()); } if(ctxThread==thisThread) { /** * Force freeing this threads context .. to avoid a deadlock .. * This makes sense, because it is possible, * that the same thread enters this point twice, * before calling gljFree ! */ if(gljThreadDebug && !dbgPrinted) { System.out.println("wait-current: "+thisThread+" for earmarked: "+nextThread); System.out.println("\tfreeing context force .. ctxThread="+ctxThread); } gljFree(true); // force freeing the context } dbgPrinted=true; try { // wait till earmarked nextThread has its chance .. wait(); } catch (InterruptedException e) { } } dbgPrinted=false; /** * put all req. threads to the wait-state, * if another thread owns the GLXContext ! */ while (ctxThread!=null && ctxThread!=thisThread) { /** * remember this thread as earmarked, * to be sure being the next one ... */ nextThread = thisThread; if(gljThreadDebug && !dbgPrinted) { System.out.println("wait-earmarked: "+thisThread); System.out.println("\tctxstate thisThread="+thisThread+", ctxThread="+ctxThread+", nextThread="+nextThread+", thisContext="+glContext+", currentContext="+gljGetCurrentContext()); dbgPrinted=true; } if( _comp instanceof GLRunnable ) { if ( ((GLRunnable)_comp).ownsThread(ctxThread) ) { synchronized (_comp) { ((GLRunnable)_comp).freeGLContext(); ((GLRunnable)_comp).notifyAll(); } notifyAll(); if(gljThreadDebug) System.out.println("\tfreeGLContext -> "+ctxThread); } } try { // wait for gljFree to release the GLXContext wait(); } catch (InterruptedException e) { } } boolean result = false; /* is this thread allready owning the context ? */ if ( gljIsCurrent() ) { result = lockJAWT(_comp, windowHandle, gljThreadDebug); if(gljThreadDebug) System.out.println("MakeCurrent: "+thisThread+" no CTX change, allready own, lockJAWT: "+result); return result; } else if( ctxThread!=null && ctxThread!=thisThread ) { System.out.println("MakeCurrent: ctxThread ain't zero, funny failure"); System.out.println("\tctxstate thisThread="+thisThread+", ctxThread="+ctxThread+", nextThread="+nextThread+", thisContext="+glContext+", currentContext="+gljGetCurrentContext()); return result; } ctxThread = thisThread ; // blocking asap .. if(gljThreadDebug) { if(nextThread==thisThread) { System.out.println("MakeCurrent: "+thisThread+" "); } else { System.out.println("MakeCurrent: "+thisThread+" "); } System.out.println("\tctxstate thisThread="+thisThread+", ctxThread="+ctxThread+", nextThread="+nextThread+", thisContext="+glContext+", currentContext="+gljGetCurrentContext()); } /** * if next thread gotten the context, it is no more earmarked .. */ if(nextThread==thisThread) nextThread = null; result = gljMakeCurrentNative( _comp, displayHandle, windowHandle, glContext); /** * If glXMakeCurrent failed, nobody holds this GLXContext .. */ if(!result) { if(gljThreadDebug) { System.out.println("Native MakeCurrent failed"); System.out.println("\tctxstate thisThread="+thisThread+", ctxThread="+ctxThread+", nextThread="+nextThread+", thisContext="+glContext+", currentContext="+gljGetCurrentContext()); Exception e = new Exception(); e.printStackTrace(); } if(hasJAWTSurfaceChanged(windowHandle)) { /** * This can only happen while using JAWT .. */ System.out.println("GL4Java: JAWT Surface-Change !!!"); System.out.println("\t destroying GLContext ...!!!"); gljDestroy(); System.out.println("GL4Java: JAWT Surface-Change !!!"); System.out.println("\t creating GLContext ...!!!"); /* try to establish a context to OpenGL */ try { System.out.println("GL4Java: JAWT Surface-Change !!!"); gljInit(); System.out.println("GL4Java: JAWT Surface-Change finished !!!"); } catch( GL4JavaInitException e ) { System.out.println( "\tcan't create a GL context\n"); System.out.println("GL4Java: JAWT Surface Change FAILED!!!"); } System.out.println("\t GLContext Recreated ...!!!"); } } notifyAll(); // notify gljFree after action is done .. // Workaround for problem on Windows where extensions do not // become visible until the first time an OpenGL context is // made current (at least with NVidia's drivers). if (firstContextMakeCurrent) { firstContextMakeCurrent = false; gljFetchGLFunctions0(null, null, false, true, gljNativeDebug); } return result; } /** * * gljMakeCurrent checks whether GL4Java is initializes * AND makes the GL-Context current for this thread. * * It's more save to use ´gljMakeCurrent´, instead of * ´gljMakeCurrentNative´, because we do check if GL is initalised ! * * @param freeContextFirst is obsolete ! * * @return boolean * * @deprecated The argument freeContextFirst is obsolete ! */ public final boolean gljMakeCurrent(boolean freeContextFirst) { return gljMakeCurrent(); } /** * if using JAWT, this function handles the JAWT lock also */ private final static native boolean gljMakeCurrentNative( Component canvas, long disp, long thisWin, long glContext); private final static native boolean lockJAWT( Component canvas, long thisWin, boolean verbose); /** * * gljGetCurrentContext fetches the current native * GL-Context, which is attached to this _native_ thread ! * * @return int */ public final static native long gljGetCurrentContext(); /** * * gljDestroy destroy´s the GL Context * * This function should be called when removing * a GLContext !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! * * Call gljFree befor this method, to be sure .. * * @return void * * @see gl4java.GLContext#gljMakeCurrent * @see gl4java.GLContext#gljFree * @see gl4java.GLContext#gljSwap */ public synchronized final boolean gljDestroy() { if ( ! isInitialized ) return false; boolean result = true; if (!gljDestroyNative(_comp)) result = false; windowHandle = 0; glContext = 0; pixmapHandle = 0; if ( useMSJDirect && !offScreenRenderer ) { destroyWindow = false; gl4java.system.GljMSJDirect.destroyOGLWindowNative( pData ); windowHandle = 0; gl4java.system.GljMSJDirect.OGLWindowMsgPump(); } pData = 0; isInitialized = false; glContextNumber--; if(gljClassDebug) System.out.println("GLContext destroyed (remaining ctx="+ glContextNumber+")"); return result; } private final native boolean gljDestroyNative(Component canvas); /** * * gljFree free´s the GL Context * * This MUST be called at last in your display function ! * *

* * This functions now optimizes the context-switch ! * * The context is changed, only if : *

    	- another thread has requested this context -> release it
     * 
* *

* * @return boolean * * @see gl4java.GLContext#gljFree * @see gl4java.GLContext#gljIsCurrent * @see gl4java.GLContext#gljIsRequested * @see gl4java.GLContext#gljMakeCurrent * @see gl4java.GLContext#gljSwap * @see gl4java.awt.GLCanvas#display * @see gl4java.awt.GLCanvas#sDisplay */ public final boolean gljFree() { return gljFree(false); } /** * * gljFree free´s the GL Context * * This MUST be called at last in your display function ! * *

* * This functions now optimizes the context-switch ! * * The context is changed, only if one of the following is true: *

    	- another thread has requested this context
	- the force flag is true
	- this thread is the AWT thread
	- the component of this context does _not_ implement GLRunnable
	- the calling thread is not the thread, this GLRunnable component holds !
     * 
* *

* * @return boolean * * @see gl4java.GLContext#gljIsCurrent * @see gl4java.GLContext#gljIsRequested * @see gl4java.GLContext#gljMakeCurrent * @see gl4java.GLContext#gljSwap * @see gl4java.GLRunnable#run */ public synchronized final boolean gljFree(boolean force) { if ( ! isInitialized ) return false; boolean result = true; Thread thisThread = Thread.currentThread(); if ( ctxThread!=thisThread ) { if(gljThreadDebug) { System.out.println("gljFree: denied, not holding context ! "); System.out.println("\tctxstate thisThread="+thisThread+", ctxThread="+ctxThread+", nextThread="+nextThread+", thisContext="+glContext+", currentContext="+gljGetCurrentContext()); Exception e = new Exception(); e.printStackTrace(); } return true; } if( (_comp instanceof GLRunnable) == false || ((GLRunnable)_comp).ownsThread(thisThread) == false ) force=true; /** * only free the context, if another thread does * request this context ... * or the force-flag is true */ if ( force==true || ( nextThread!=null && nextThread!=thisThread ) ) { result = gljFreeNative ( _comp, displayHandle, windowHandle, glContext); ctxThread = null ; if(gljThreadDebug) { System.out.println("gljFree: gljFreeNative result: "+result); System.out.println("\tctxstate thisThread="+thisThread+", ctxThread="+ctxThread+", nextThread="+nextThread+", thisContext="+glContext+", currentContext="+gljGetCurrentContext()); } } else { result = unlockJAWT(windowHandle, false); if(gljThreadDebug) { System.out.println("gljFree: no CTX change, no requests, unlockJAWT: "+result); System.out.println("\tctxstate thisThread="+thisThread+", ctxThread="+ctxThread+", nextThread="+nextThread+", thisContext="+glContext+", currentContext="+gljGetCurrentContext()); } } notifyAll(); return result; } /** * if using JAWT, this function handles the JAWT unlock also */ private final static native boolean gljFreeNative( Component canvas, long disp, long thisWin, long glContext ); private final static native boolean unlockJAWT(long thisWin, boolean verbose); /** * swap method are for double buffering */ public final boolean gljSwap() { if ( ! isInitialized || !glEnabled ) return false; return gljSwapNative( displayHandle, windowHandle, glContext, glCaps.getDoubleBuffered()); } private final static native boolean gljSwapNative( long disp, long thisWin, long glContext, boolean doubleBuffer ); /** * This function enables, disables the GL-Context ! * If false is given, the openGL renderer/context is * disabled and disconected (gljFree is called, if initialized) ! * * If disabled, all GL Functions are disabled but the * Destroy & Free are not ! * * @return boolean * * @see gl4java.GLContext#gljMakeCurrent * @see gl4java.GLContext#gljDestroy * @see gl4java.GLContext#gljFree */ public void setEnabled(boolean b) { glEnabled = b; if ( b==false && isInitialized ) gljFree(); } /** * This function queries, if the GL-Context is enabled ! * * @return boolean * * @see gl4java.GLContext#setEnabled * @see gl4java.GLContext#gljMakeCurrent */ public boolean isEnabled() { return glEnabled; } /** * This functions fetches/dispatches the GL/GLU functions, * which must be allready loaded via the doLoadNativeLibraries * function ! * * @see gl4java.GLContext#doLoadNativeLibraries */ public final static boolean gljFetchGLFunctions(String gllibname, String glulibname, boolean force) { return gljFetchGLFunctions0(gllibname, glulibname, force, false, gljNativeDebug); } /** * for example Windows it appears * that extensions only become visible once an OpenGL context is * made current for the first time (at least with NVidia's * drivers). To avoid making drastic changes to the code * structure, we reload all of the OpenGL functions the first time * a context is made current. (This could be made more efficient * by only loading extensions' routines at this time.) * * @see gl4java.GLContext#gljFetchGLFunctions */ private volatile static boolean firstContextMakeCurrent = true; private final static native boolean gljFetchGLFunctions0 (String gllibname, String glulibname, boolean force, boolean reload, boolean verbose); /** * This functions checks the existence of * the GL functions ! */ public final static boolean gljTestGLProc ( String name, boolean verbose ) { // Special case any routines which are exposed in a different fashion if (name.equals("glAllocateMemoryNV")) { int os = getNativeOSType(); if (os == OsWindoof) { name = "wglAllocateMemoryNV"; } else if (os == OsX11) { name = "glXAllocateMemoryNV"; } // else will fail anyway; fall through } return gljTestGLProc0(name, verbose); } private static final native boolean gljTestGLProc0(String name, boolean verbose); /** * This functions reads the pixel from the GL frame * and puts it into the pixelDest array, * while converting them correctly to the AWT pixel format, * using GL_BGRA and BufferedImage.TYPE_INT_ARGB ! */ public final static native void gljReadPixelGL2AWT ( int pack_rowlen, int pack_x, int pack_y, int x, int y, int width, int height, int format, int type, int bufferName, int[] pixelDest); /** * This functions reads the pixel from the GL frame * and puts it into the pixelDest array, * while converting them correctly to the AWT pixel format, * using GL_RGB and BufferedImage.TYPE_USHORT_565_RGB ! */ public final static native void gljReadPixelGL2AWT ( int pack_rowlen, int pack_x, int pack_y, int x, int y, int width, int height, int format, int type, int bufferName, short[] pixelDest); /** * This functions reads the pixel from the GL frame * and puts it into the pixelDest array, * while using hardware correct AWT and GL pixel format, * using GL_BGR and BufferedImage.TYPE_3BYTE_BGR ! */ public final static native void gljReadPixelGL2AWT ( int pack_rowlen, int pack_x, int pack_y, int x, int y, int width, int height, int format, int type, int bufferName, byte[] pixelGLDest); /** * native C function to achieve the native lib vendor ! * * now it is possible to check the native-lib at runtime ! */ public final static String gljGetNativeLibVendor() { return gljGetNativeLibVendorNative(); } private final static native String gljGetNativeLibVendorNative(); /** * native C function to achieve the native lib version ! * * now it is possible to check the native-lib at runtime ! */ public final static String gljGetNativeLibVersion() { return gljGetNativeLibVersionNative(); } private final static native String gljGetNativeLibVersionNative(); /** * function to achieve the java-class version ! * * now it is possible to check the java-class at runtime ! */ public final static String gljGetClassVersion() { return version; } /** * function to achieve the java-class vendor ! * * now it is possible to check the java-class at runtime ! */ public final static String gljGetClassVendor() { return "Jausoft - Sven Goethel Software Development"; } /** * function to achieve complete version info * * Be sure that the native library must be loaded ! */ public final String gljGetVersions() { return gljGetVersions(false); } public final String gljGetVersions(boolean verbose) { if(libsLoaded==false || gl==null || glu==null || !gljIsInit()) return null; String jvmstr = "Java Virtual Machine: Version "+ getJVMVersion() + " ("+getJVMVersionMajor()+"."+getJVMVersionMinor()+")"+ ", Vendor: "+ getJVMVendor() + "\n" ; gl4java.utils.glf.GLF glf = new gl4java.utils.glf.GLF(); String info1= "GL4Java - LGPL-Version" + "\n" + "-------------------------------------------------\n" + "-------------------------------------------------\n" + "Java-Class : GL4Java.GLContext \n" + " : Version: "+gljGetClassVersion() + "\n" + " Vendor : "+gljGetClassVendor() + "\n" + "Native-Library : GL4Java.GLContext \n" + " Version: "+gljGetNativeLibVersion()+"\n" + " Vendor : "+gljGetNativeLibVendor() +"\n" + "-------------------------------------------------\n" + "Java-Class : GL4Java.GLFunc impl. \n" + " : Version: "+gl.getClassVersion() + "\n" + " Vendor : "+gl.getClassVendor() + "\n" + "Native-Library : GL4Java.GLFunc impl. \n" + " Version: "+gl.getNativeVersion() + "\n" + " Vendor : "+gl.getNativeVendor() + "\n" + "-------------------------------------------------\n" + "Java-Class : GL4Java.GLUFunc impl. \n" + " : Version: "+glu.getClassVersion() + "\n" + " Vendor : "+glu.getClassVendor() + "\n" + "Native-Library : GL4Java.GLUFunc impl. \n" + " Version: "+glu.getNativeVersion() + "\n" + " Vendor : "+glu.getNativeVendor() + "\n" + "-------------------------------------------------\n" + "Java-Class : GL4Java.utils.glf.GLFFuncJNI \n" + " : Version: "+glf.getClassVersion() + "\n" + " Vendor : "+glf.getClassVendor() + "\n" + "Native-Library : GL4Javautils.glf..GLFFuncJNI \n" + " Version: "+glf.getNativeVersion() + "\n" + " Vendor : "+glf.getNativeVendor() + "\n" + "-------------------------------------------------\n" + "\n"+ jvmstr + "\n" ; String glVen = gl.glGetString(GLFunc.GL_VENDOR); String glRen = gl.glGetString(GLFunc.GL_RENDERER); String glVer = gl.glGetString(GLFunc.GL_VERSION); String glExt = gl.glGetString(GLFunc.GL_EXTENSIONS); String gluVer = glu.gluGetString(GLUFunc.GLU_VERSION); String gluExt = glu.gluGetString(GLUFunc.GLU_EXTENSIONS); String info2= "OpenGL - Versions \n" + "-----------------------------------------------\n" + "GL VENDOR: "+glVen+"\n"+ "GL RENDERER: "+glRen+"\n"+ "GL VERSION: "+glVer+"\n"+ "GL EXTENSIONS: "+glExt+"\n"+ "GLU VERSION: "+gluVer+"\n"+ "GLU EXTENSIONS: "+gluExt+"\n"+"\n" ; String info3= "OpenGL - Function Test ("+ GLFunc.GL_PROC_NAMES.length +" Functions) \n" + "-----------------------------------------------\n"; if(verbose) { System.out.println(info1); System.out.println(info2); System.out.println(info3); } String h; String tmp; int okNum=0; for(int i=0; i