diff options
Diffstat (limited to 'demos/SwingDemos/test')
-rw-r--r-- | demos/SwingDemos/test/GLJPanel/GLJPanel.java | 694 | ||||
-rw-r--r-- | demos/SwingDemos/test/GLJPanel/test1.java | 158 | ||||
-rw-r--r-- | demos/SwingDemos/test/GLJPanel/test2.java | 115 | ||||
-rw-r--r-- | demos/SwingDemos/test/GLPanel-AWTGraphics/GLPanel.java | 676 | ||||
-rw-r--r-- | demos/SwingDemos/test/GLPanel-AWTGraphics/test1.java | 137 | ||||
-rw-r--r-- | demos/SwingDemos/test/GLPanel-GLGraphics/GLGraphics.java | 513 | ||||
-rw-r--r-- | demos/SwingDemos/test/GLPanel-GLGraphics/GLPanel.java | 692 | ||||
-rw-r--r-- | demos/SwingDemos/test/GLPanel-GLGraphics/test1.java | 129 |
8 files changed, 3114 insertions, 0 deletions
diff --git a/demos/SwingDemos/test/GLJPanel/GLJPanel.java b/demos/SwingDemos/test/GLJPanel/GLJPanel.java new file mode 100644 index 0000000..166437b --- /dev/null +++ b/demos/SwingDemos/test/GLJPanel/GLJPanel.java @@ -0,0 +1,694 @@ +//package gl4java.swing; + +import gl4java.*; + +import java.awt.*; +import java.awt.event.*; +import javax.swing.*; + +public class GLJPanel extends JPanel + implements GLEnum, GLUEnum, + ComponentListener, WindowListener, MouseListener +{ + protected GLContext glj = null; + public GLFunc gl = null; + public GLUFunc glu = null; + + protected boolean mustResize = false; + + protected boolean cvsInitialized=false; + + protected boolean needCvsDispose = false; + + /** + * Visual pre-set for doubleBuffer, default: true + * This value is updated after a GLContext is created with the + * original updated value of GLContext ! + * + * @see GLJPanel#preInit + * @see GLJPanel#paint + */ + protected boolean doubleBuffer = true; + + /** + * Visual pre-set for stencil-bit number, default: 0 + * This value is updated after a GLContext is created with the + * original updated value of GLContext ! + * + * @see GLJPanel#preInit + * @see GLJPanel#paint + */ + protected int stencilBits = 0; + + /** + * Visual pre-set for stereoView, default: false + * This value is updated after a GLContext is created with the + * original updated value of GLContext ! + * + * @see GLJPanel#preInit + * @see GLJPanel#paint + */ + protected boolean stereoView = false; + + /** + * Visual pre-set for RGBA usage, default: true - of course ;-) + * This value is updated after a GLContext is created with the + * original updated value of GLContext ! + * + * @see GLJPanel#preInit + * @see GLJPanel#paint + */ + protected boolean rgba = true; + + /** + * Visual pre-set for RGBA usage, default: true - of course ;-) + * This value is updated after a GLContext is created with the + * original updated value of GLContext ! + * + * @see GLJPanel#preInit + * @see GLJPanel#paint + */ + protected boolean createOwnWindow = false; + + /** + * The context with witch display lists and textures will be shared. + * + * @see GLJPanel#preInit + * @see GLJPanel#paint + */ + protected GLContext sharedGLContext; + + static { + if(GLContext.loadNativeLibraries(null, null, null)==false) + System.out.println("GLJPanel could not load def. native libs."); + } + + /** + * + * Constructor + * + * @param gl_Name The name of the GLFunc implementation + * If gl_Name==null, the default class will be used ! + * + * @param glu_Name The name of the GLUFunc implementation + * If gl_LibName==null, the default class will be used ! + * + * @param layout the layout manager + * @param isDoubleBuffered the flag indicates, + * if double buffer should be used + * + */ + public GLJPanel( String gl_Name, + String glu_Name, + LayoutManager layout, boolean isDoubleBuffered + ) + { + super( layout, isDoubleBuffered ); + + if( (gl=GLContext.createGLFunc(gl_Name)) ==null) + { + System.out.println("GLFunc implementation "+gl_Name+" not created"); + } + if( (glu=GLContext.createGLUFunc(glu_Name)) ==null) + { + System.out.println("GLUFunc implementation "+glu_Name+" not created"); + } + + /* to be able for RESIZE event's */ + addComponentListener(this); + + setOpaque(false); + } + + /** + * + * Constructor + * + * @param layout the layout manager + * @param isDoubleBuffered the flag indicates, + * if double buffer should be used + * + */ + public GLJPanel( LayoutManager layout, boolean isDoubleBuffered ) + { + this(null, null, layout, isDoubleBuffered); + } + + /** + * + * Constructor + * + * Uses the default GLFunc and GLUFunc implementation ! + * + * @param isDoubleBuffered the flag indicates, + * if double buffer should be used + */ + public GLJPanel( boolean isDoubleBuffered ) + { + this(null, null, new FlowLayout(), isDoubleBuffered); + } + + /** + * + * Constructor + * + * Uses the default GLFunc and GLUFunc implementation ! + * + * @param layout the layout manager + */ + public GLJPanel(LayoutManager layout) + { + this(null, null, layout, true); + } + + /** + * + * Constructor + * + * Uses the default GLFunc and GLUFunc implementation ! + * + */ + public GLJPanel( ) + { + this(null, null, new FlowLayout(), true); + } + + /** + * Used to return the created GLContext + */ + public final GLContext getGLContext() { return glj; } + + /** + * Safe the toplevel window + */ + protected Window topLevelWindow = null; + + /** + * + * This function returns the found TopLevelWindow, + * which contains this Canvas .. + * + * @return void + * + * @see GLJPanel#paint + */ + public final Window getTopLevelWindow() + { return topLevelWindow; } + + /** + * this function overrides the Canvas paint method ! + * + * For the first paint, + * the user function preInit is called, a GLContext is created + * and the user function init is called ! + * + * Also, if a GL Context exist, GLJPanel's sDisplay-method will be called + * to do OpenGL-rendering. + * + * The sDisplay method itself calls the display-method ! + * sDisplay is needed to be thread-safe, to manage + * the resize functionality and to safe the time per frame. + * + * To define your rendering, you should overwrite the display-method + * in your derivation. + * + * @see gl4java.GLContext#GLContext + * @see GLJPanel#cvsIsInit + * @see GLJPanel#sDisplay + * @see GLJPanel#display + * @see GLJPanel#preInit + * @see GLJPanel#init + */ + public synchronized final void paintComponent(Graphics g) + { + //JAU + if(GLContext.gljClassDebug) + System.out.println("GPanel::paintComponent()"); + //super.paintComponent(g); + setOpaque(false); + if(glj == null ) + { + preInit(); + glj = new GLContext ( this, gl, glu, + createOwnWindow, + doubleBuffer, stereoView, + rgba, stencilBits, + sharedGLContext ); + + if(glj!=null) + { + createOwnWindow = glj.isOwnWindowCreated(); + doubleBuffer = glj.isDoubleBuffer(); + stencilBits = glj.getStencilBitNumber(); + stereoView = glj.isStereoView(); + rgba = glj.isRGBA(); + } + + init(); + + // fetch the top-level window , + // to add us as the windowListener + // + Container _c = getParent(); + Container c = null; + + while(_c!=null) + { + c = _c; + _c = _c.getParent(); + } + + if(c instanceof Window) { + topLevelWindow = (Window)c; + topLevelWindow.addComponentListener(this); + topLevelWindow.addMouseListener(this); + } else { + topLevelWindow = null; + System.out.println("toplevel is not a Window: "+c); + } + + if(topLevelWindow!=null) + { + topLevelWindow.addWindowListener(this); + } else { + System.out.println("no parent found for "+getName()); + System.out.flush(); + } + if(glj!=null && glj.gljIsInit()) + cvsInitialized=true; + } + /* + if( mustResize ) size = getSize(); + g.setClip(0, 0, size.width, size.height ); + */ + sPaint(g); + } + + /** + * + * This is the thread save rendering-method called by paint. + * The actual thread will be set to highes priority befor calling + * 'display'. After 'display' the priority will be reset ! + * + * 'gljFree' will be NOT called after 'display'. + * + * We tested the above to use multi-threading and + * for the demonstration 'glDemos' it works ;-)) ! + * + * BE SURE, if you want to call 'display' by yourself + * (e.g. in the run method for animation) + * YOU HAVE TO CALL sDisplay -- OR YOU MUST KNOW WHAT YOU ARE DOING THEN ! + * + * @return void + * + * @see GLJPanel#paint + * @see GLJPanel#display + */ + public synchronized final void sPaint( Graphics g ) + { + boolean ok = true; + + long _s = System.currentTimeMillis(); + + if(!cvsIsInit()) + return; + + /* + if( glj.gljMakeCurrent() == false ) { + System.out.println("GLJPanel: problem in use() method"); + return; + } + */ + + if( mustResize ) + { + if( (ok = glj.gljMakeCurrent()) == true ) + { + Dimension size = getSize(); + glj.gljResize( size.width, size.height ) ; + reshape(size.width, size.height); + mustResize = false; + } + } + if(ok) + { + display(); + g.setClip(getBounds()); + if(GLContext.gljClassDebug) + glj.gljCheckGL(); + _f_dur_self = System.currentTimeMillis()-_s; + + /* + GLGraphics glg1 = (GLGraphics)glg.create(); + try { + super.paint(glg1); + } finally { + glg1.dispose(); + } + */ + //super.paint(g); + if(GLContext.gljClassDebug) + glj.gljCheckGL(); + _f_dur_total = System.currentTimeMillis()-_s; + } + + } + + /** + * + * This is the rendering-method called by sDisplay + * (and sDisplay is called by paint !). + * The derived-class (Your Subclass) will redefine this, to draw it's own... + * + * BE SURE, if you want to call 'display' by yourself + * (e.g. in the run method for animation) + * YOU HAVE TO CALL sDisplay ! + * + * 'sDisplay' manages a semaphore to avoid reentrance of + * the display function !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! + * + * @return void + * + * @see GLJPanel#sDisplay + * @see GLJPanel#paint + */ + public void display() + { + } + + /** + * + * This is your pre-init method. + * preInit is called just BEFORE the GL-Context is created. + * You should override preInit, to initialize your visual-stuff, + * like the protected vars: doubleBuffer and stereoView + * + * @return void + * + * @see GLJPanel#paint + * @see GLJPanel#doubleBuffer + * @see GLJPanel#stereoView + * @see GLJPanel#rgba + * @see GLJPanel#stencilBits + */ + public void preInit() + { + } + + /** + * + * This is your init method. + * init is called right after the GL-Context is initialized. + * You should override init, to initialize your stuff needed + * by OpenGL an Java ! + * + * @return void + * + * @see GLJPanel#paint + */ + public void init() + { + } + + /** + * This method is used to clean up any OpenGL stuff (delete textures + * or whatever) prior to actually deleting the OpenGL context. + * You should override this with your own version, if you need to do + * any cleanup work at this phase. + * This functions is called within cvsDispose + * + * @return void + * + * @see GLJPanel#cvsDispose + */ + public void doCleanup() + { + } + + /** + * This function returns, if everything is init: the GLContext, + * the and the users init function + * This value is set in the paint method! + * + * @return boolean + * + * @see GLJPanel#paint + * @see GLJPanel#init + */ + public boolean cvsIsInit() + { + return cvsInitialized; + } + + protected long _f_dur_self = 0; + protected long _f_dur_total = 0; + + /** + * + * This is the reshape-method called by paint. + * The derived-class (Your Subclass) will redefine this, + * to manage your individual reshape ... + * + * This �reshape� method will be invoked after the first paint command + * after GLJPanel.componentResize is called AND only if �gljUse� was + * succesfull (so a call of gljUse is redundant). + * �reshape� is not an overloading of java.awt.Component.reshape, + * �reshape� is more like �glut�-reshape. + * + * GLJPanel.reshape allready has a simple default implementation, + * which calls �gljResize� and �glViewport� - so you may be can + * left this one as it is (no need to overload). + * The needed call to �gljResize� is done by hte invoker paint ! + * + * @param width the new width + * @param height the new height + * @return void + * + * @see GLJPanel#paint + * @see GLJPanel#sDisplay + */ + public void reshape( int width, int height ) + { + if(GLContext.gljClassDebug) + System.out.println("GLJPanel::reshape bounds("+getBounds()+")"); + gl.glViewport(0,0, width, height); + } + + /* JAU */ + /* + public final void setBounds(int x, int y, int width, int height) { + reshape(x, y, width, height); + } + public final void setBounds(Rectangle r) { + reshape(r.x, r.y, r.width, r.height); + } + + public void reshape(int x, int y, int width, int height) { + super.reshape(x, y, width, height); + if(glj==null || !glj.gljIsInit() || !glj.gljMakeCurrent()) + { + System.out.println("GLJPanel::setBounds(): problem in use() method"); + return; + } + reshape(width-x, height-y); + glj.gljCheckGL(); + glj.gljFree(); + size = new Dimension(width-x, height-y); + } + */ + + + /** + * + * �componentResized� is the componentListeners event handler. + * + * This method sets the variable �mustResize� to true, + * so the upcoming �paint� method-call will invoke �reshape� ! + * + * This little look-alike complicating thing is done, + * to avoid an Exception by using the glContext from more than + * one concurrent thread�s ! + * + * You cannot override this implementation, it is final + * - override �reshape' instead ! + * + * @param e the element, which is resized + * @return void + * + * @see GLJPanel#paint + * @see GLJPanel#reshape + */ + public void componentResized(ComponentEvent e) + { + if(GLContext.gljClassDebug) + System.out.println("GLJPanel::componentResized("+e.getComponent()+")"); + if(glj!=null && glj.gljIsInit() && e.getComponent()==this ) + { + mustResize = true; + //repaint(); + } + } + + public void componentMoved(ComponentEvent e) + { + /* + if(GLContext.gljClassDebug) + System.out.print("GLJPanel::componentMoved("+e.getComponent()+")"); + if(e.getComponent().equals(topLevelWindow)) + { + repaint(); + } + */ + } + + public void componentShown(ComponentEvent e) + { + if(GLContext.gljClassDebug) + System.out.print("GLJPanel::componentShown("+e.getComponent()+")"); + } + + public void componentHidden(ComponentEvent e) + { + if(GLContext.gljClassDebug) + System.out.print("GLJPanel::componentHidden("+e.getComponent()+")"); + } + + public void mouseClicked(MouseEvent e) + { + if(GLContext.gljClassDebug) + System.out.print("."); + } + public void mouseEntered(MouseEvent e) + { + /* + if(GLContext.gljClassDebug) + System.out.print("GLJPanel::mouseEntered("+e.getComponent()+")"); + if(e.getComponent().equals(topLevelWindow)) + { + repaint(); + } + */ + } + public void mouseExited(MouseEvent e) + {} + public void mousePressed(MouseEvent e) + { + if(GLContext.gljClassDebug) + System.out.print("<"); + } + public void mouseReleased(MouseEvent e) + { + if(GLContext.gljClassDebug) + System.out.print(">"); + } + + public void windowOpened(WindowEvent e) + { + } + + /** + * + * �windowClosing� is the windowListeners event handler + * for the topLevelWindow of this Canvas ! + * + * This methods free�s AND destroy�s + * the GL Context with �glj.gljDestroy� ! + * + * @return void + * + */ + public void windowClosing(WindowEvent e) + { + if(e.getComponent().equals(topLevelWindow)) + { + cvsDispose(); + } + } + + /** + * + * �windowClosed� is the windowListeners event handler. + * + * @return void + * + */ + public void windowClosed(WindowEvent e) + { + if (needCvsDispose) cvsDispose(); + } + + public void windowIconified(WindowEvent e) + { + } + + public void windowDeiconified(WindowEvent e) + { + } + + public void windowActivated(WindowEvent e) + { + } + + public void windowDeactivated(WindowEvent e) + { + } + + /** + * You should call this before releasing/dispose this Window ! + * Also you can overwrite this class, + * to dispose your own elements, e.g. a Frame etc. - + * but be shure that you call + * cvsDispose implementation call this one ! + * + * This function calls gljDestroy of GLContext ! + * + * @see gl4java.GLContext#gljDestroy + * @see GLJPanel#doCleanup + */ + public void cvsDispose() + { + cvsInitialized = false; + if (glj != null) + { + if (glj.gljIsInit()) + { + /* Sometimes the Microsoft VM calls the + Applet.stop() method but doesn't have + permissions to do J/Direct calls, so + this whole block of code will throw a + security exception. If this happens, + however, windowClosing() will still + call us again later and we will have + another opportunity to shut down the + context, so it all works out fine. */ + try + { + glj.gljFree(); + doCleanup(); + //locks and free's GLContext + glj.setEnabled(false); + glj.gljDestroy(); + needCvsDispose = false; + } + catch (Exception ex) + { + needCvsDispose = true; + } + } + } + + // Setting glj to null will simply cause paint() to re-initialize. + // We don't want that to happen, so we will leave glj non-null. + } + + /** + * get methods + */ + public final int cvsGetWidth() { + return getSize().width; + } + public final int cvsGetHeight() { + return getSize().height; + } +} + diff --git a/demos/SwingDemos/test/GLJPanel/test1.java b/demos/SwingDemos/test/GLJPanel/test1.java new file mode 100644 index 0000000..3dcb96a --- /dev/null +++ b/demos/SwingDemos/test/GLJPanel/test1.java @@ -0,0 +1,158 @@ +import java.applet.*; +import java.awt.*; +import java.awt.event.*; +import java.awt.Dimension; +import javax.swing.*; +import gl4java.*; +import gl4java.awt.*; +import gl4java.utils.glut.*; +import gl4java.utils.glut.fonts.*; + +public class test1 extends JApplet + implements GLEnum, GLUEnum, ActionListener, ItemListener +{ + static { + if(GLContext.loadNativeLibraries(null, null, null)==false) + System.out.println("GLCanvas could not load def. native libs."); + } + + protected class test1Panel extends GLJPanel + implements ActionListener, ItemListener + { + public test1Panel( LayoutManager layout, boolean isDoubleBuffered) + { + super(layout, isDoubleBuffered); + GLContext.gljNativeDebug = true; + GLContext.gljClassDebug = true; + doubleBuffer = false; + } + + + public void init() { + System.out.println("<i>"); + //glg = new GLGraphics(gl, glu); + reshape(getSize().width, getSize().height); + } + + public void display() + { + if( glj.gljMakeCurrent() == false ) { + System.out.println("problem in use() method"); + return; + } + + System.out.println("<p>"); + + int i; + + gl.glPushMatrix(); + gl.glClear(GL_COLOR_BUFFER_BIT); + + gl.glColor4f(0f, 0f, 1f, 1f); + + int width=getSize().width; + int height=getSize().height; + + gl.glBegin(GLEnum.GL_LINES); + gl.glVertex3i( 0, 0, 0); + gl.glVertex3i( 10, 10, 0); + gl.glVertex3i( 0, 10, 0); + gl.glVertex3i( 10, 0, 0); + gl.glEnd(); + + gl.glPopMatrix(); + + glj.gljSwap(); + glj.gljCheckGL(); + glj.gljFree(); + } + + public void reshape( int width, int height ) + { + Rectangle bounds = getBounds(); + System.out.println("reshape("+width+", "+height+")"); + System.out.println("reshape bounds("+bounds+")"); + //gl.glViewport(0,0, width, height); + gl.glViewport(bounds.x, bounds.y, + bounds.width, bounds.height); + gl.glMatrixMode(GL_PROJECTION); + gl.glLoadIdentity(); + gl.glOrtho(0, 10, 0, 10, -50.0,50.0); + gl.glMatrixMode(GL_MODELVIEW); + } + + public void actionPerformed(ActionEvent e) { + if (e.getActionCommand().equals("east")) { + System.out.println("East pressed"); + } else if (e.getActionCommand().equals("west")) { + System.out.println("West pressed"); + } + } + + public void itemStateChanged(ItemEvent e) { + Object source = e.getItemSelectable(); + System.out.println("item changed: "+source); + } + + } + + test1Panel tst1cvs1; + + public void init() + { + JPanel jp1 = new JPanel (new BorderLayout(), false); + setContentPane(jp1); + tst1cvs1 = new test1Panel(new BorderLayout(), false); + jp1.add("Center", tst1cvs1); + + String[] data = {"one", "two", "three", "four"}; + JList dataList = new JList(data); + jp1.add("North", dataList); + + JButton b1, b2; + jp1.add("East", (b1 = new JButton("E"))); + b1.setActionCommand("east"); + b1.addActionListener(this); + jp1.add("West", (b2 = new JButton("W"))); + b2.setActionCommand("west"); + b2.addActionListener(this); + + JCheckBox c1; + jp1.add("South", (c1 = new JCheckBox("SouthButton", true))); + c1.addItemListener(this); + } + + public static void main(java.lang.String[] args) { + try { + Frame mainFrame = new Frame("test1"); + + test1 applet=new test1(); + + applet.setSize(400, 400); + applet.init(); + applet.start(); + + mainFrame.add(applet); + + mainFrame.pack(); + mainFrame.setVisible(true); + } catch (Throwable exception) { + System.err.println("Exception occurred in main()"); + exception.printStackTrace(System.out); + } + } + + public void actionPerformed(ActionEvent e) { + if (e.getActionCommand().equals("east")) { + System.out.println("East pressed"); + } else if (e.getActionCommand().equals("west")) { + System.out.println("West pressed"); + } + } + + public void itemStateChanged(ItemEvent e) { + Object source = e.getItemSelectable(); + System.out.println("item changed: "+source); + } + +} diff --git a/demos/SwingDemos/test/GLJPanel/test2.java b/demos/SwingDemos/test/GLJPanel/test2.java new file mode 100644 index 0000000..c479133 --- /dev/null +++ b/demos/SwingDemos/test/GLJPanel/test2.java @@ -0,0 +1,115 @@ +import java.applet.*; +import java.awt.*; +import java.awt.event.*; +import java.awt.Dimension; +import javax.swing.*; + +public class test2 extends JApplet + implements ActionListener, ItemListener +{ + protected class test2Panel extends JPanel + implements ActionListener, ItemListener + { + public test2Panel( LayoutManager layout, boolean isDoubleBuffered) + { + super(layout, isDoubleBuffered); + } + + + public void paintComponent(Graphics g) + { + System.out.println("<p>"); + + super.paintComponent(g); + + g.setColor(Color.blue); + + int width=getSize().width; + int height=getSize().height; + + g.drawLine ( 0, height/2, width, height/2 ); + g.drawLine ( width/2, 0, width/2, height ); + + g.setColor(Color.yellow); + + g.drawLine ( 0, 0, width, height); + g.drawString("Left-top", 0, 10); + g.drawString("GLGraphics - CENTER", width/2, height/2); + g.drawString("Right - Bottom (nearly)", width*2/3, height*2/3); + } + + public void actionPerformed(ActionEvent e) { + if (e.getActionCommand().equals("east")) { + System.out.println("East pressed"); + } else if (e.getActionCommand().equals("west")) { + System.out.println("West pressed"); + } + } + + public void itemStateChanged(ItemEvent e) { + Object source = e.getItemSelectable(); + System.out.println("item changed: "+source); + } + + } + + test2Panel tst1cvs1; + + public void init() + { + JPanel jp1 = new JPanel (new BorderLayout(), false); + setContentPane(jp1); + tst1cvs1 = new test2Panel(new BorderLayout(), false); + jp1.add("Center", tst1cvs1); + + String[] data = {"one", "two", "three", "four"}; + JList dataList = new JList(data); + jp1.add("North", dataList); + + JButton b1, b2; + jp1.add("East", (b1 = new JButton("E"))); + b1.setActionCommand("east"); + b1.addActionListener(this); + jp1.add("West", (b2 = new JButton("W"))); + b2.setActionCommand("west"); + b2.addActionListener(this); + + JCheckBox c1; + jp1.add("South", (c1 = new JCheckBox("SouthButton", true))); + c1.addItemListener(this); + } + + public static void main(java.lang.String[] args) { + try { + Frame mainFrame = new Frame("test2"); + + test2 applet=new test2(); + + applet.setSize(400, 400); + applet.init(); + applet.start(); + + mainFrame.add(applet); + + mainFrame.pack(); + mainFrame.setVisible(true); + } catch (Throwable exception) { + System.err.println("Exception occurred in main()"); + exception.printStackTrace(System.out); + } + } + + public void actionPerformed(ActionEvent e) { + if (e.getActionCommand().equals("east")) { + System.out.println("East pressed"); + } else if (e.getActionCommand().equals("west")) { + System.out.println("West pressed"); + } + } + + public void itemStateChanged(ItemEvent e) { + Object source = e.getItemSelectable(); + System.out.println("item changed: "+source); + } + +} diff --git a/demos/SwingDemos/test/GLPanel-AWTGraphics/GLPanel.java b/demos/SwingDemos/test/GLPanel-AWTGraphics/GLPanel.java new file mode 100644 index 0000000..4c7989d --- /dev/null +++ b/demos/SwingDemos/test/GLPanel-AWTGraphics/GLPanel.java @@ -0,0 +1,676 @@ +//package gl4java.awt; + +import gl4java.*; + +import java.awt.*; +import java.awt.event.*; + +public class GLPanel extends Panel + implements GLEnum, GLUEnum, + ComponentListener, WindowListener, MouseListener +{ + protected GLContext glj = null; + public GLFunc gl = null; + public GLUFunc glu = null; + + protected boolean mustResize = false; + + protected boolean cvsInitialized=false; + + protected boolean needCvsDispose = false; + + /** + * Visual pre-set for doubleBuffer, default: true + * This value is updated after a GLContext is created with the + * original updated value of GLContext ! + * + * @see GLPanel#preInit + * @see GLPanel#paint + */ + protected boolean doubleBuffer = true; + + /** + * Visual pre-set for stencil-bit number, default: 0 + * This value is updated after a GLContext is created with the + * original updated value of GLContext ! + * + * @see GLPanel#preInit + * @see GLPanel#paint + */ + protected int stencilBits = 0; + + /** + * Visual pre-set for stereoView, default: false + * This value is updated after a GLContext is created with the + * original updated value of GLContext ! + * + * @see GLPanel#preInit + * @see GLPanel#paint + */ + protected boolean stereoView = false; + + /** + * Visual pre-set for RGBA usage, default: true - of course ;-) + * This value is updated after a GLContext is created with the + * original updated value of GLContext ! + * + * @see GLPanel#preInit + * @see GLPanel#paint + */ + protected boolean rgba = true; + + /** + * Visual pre-set for RGBA usage, default: true - of course ;-) + * This value is updated after a GLContext is created with the + * original updated value of GLContext ! + * + * @see GLPanel#preInit + * @see GLPanel#paint + */ + protected boolean createOwnWindow = false; + + /** + * The context with witch display lists and textures will be shared. + * + * @see GLPanel#preInit + * @see GLPanel#paint + */ + protected GLContext sharedGLContext; + + static { + if(GLContext.loadNativeLibraries(null, null, null)==false) + System.out.println("GLPanel could not load def. native libs."); + } + + /** + * + * Constructor + * + * @param width the canvas initial-prefered width + * @param height the canvas initial-prefered height + * + * @param gl_Name The name of the GLFunc implementation + * If gl_Name==null, the default class will be used ! + * + * @param glu_Name The name of the GLUFunc implementation + * If gl_LibName==null, the default class will be used ! + * + */ + public GLPanel( String gl_Name, + String glu_Name + ) + { + super( new BorderLayout() ); + + if( (gl=GLContext.createGLFunc(gl_Name)) ==null) + { + System.out.println("GLFunc implementation "+gl_Name+" not created"); + } + if( (glu=GLContext.createGLUFunc(glu_Name)) ==null) + { + System.out.println("GLUFunc implementation "+glu_Name+" not created"); + } + + /* to be able for RESIZE event's */ + addComponentListener(this); + } + + /** + * + * Constructor + * + * Uses the default GLFunc and GLUFunc implementation ! + * + * @param width the canvas initial-prefered width + * @param height the canvas initial-prefered height + * + */ + public GLPanel( ) + { + this(null, null); + } + + /** + * Used to return the created GLContext + */ + public final GLContext getGLContext() { return glj; } + + /** + * + * Overridden update + * This one only call's the paint method, without clearing + * the background - thats hopefully done by OpenGL ;-) + * + * @param g the Graphics Context + * @return void + * + * @see GLPanel#paint + */ + public void update(Graphics g) + { + //JAU + if(GLContext.gljClassDebug) + System.out.println("GPanel::update(): isShowing()="+isShowing()); + if(isShowing()) + { + /* let's let OpenGL clear the background ... */ + paint(g); + } + } + + + /** + * Safe the toplevel window + */ + protected Window topLevelWindow = null; + + /** + * + * This function returns the found TopLevelWindow, + * which contains this Canvas .. + * + * @return void + * + * @see GLPanel#paint + */ + public final Window getTopLevelWindow() + { return topLevelWindow; } + + /** + * this function overrides the Canvas paint method ! + * + * For the first paint, + * the user function preInit is called, a GLContext is created + * and the user function init is called ! + * + * Also, if a GL Context exist, GLPanel's sDisplay-method will be called + * to do OpenGL-rendering. + * + * The sDisplay method itself calls the display-method ! + * sDisplay is needed to be thread-safe, to manage + * the resize functionality and to safe the time per frame. + * + * To define your rendering, you should overwrite the display-method + * in your derivation. + * + * @see gl4java.GLContext#GLContext + * @see GLPanel#cvsIsInit + * @see GLPanel#sDisplay + * @see GLPanel#display + * @see GLPanel#preInit + * @see GLPanel#init + */ + public synchronized final void paint( Graphics g ) + { + //JAU + if(GLContext.gljClassDebug) + System.out.println("GPanel::paint()"); + if(glj == null ) + { + preInit(); + glj = new GLContext ( this, gl, glu, + createOwnWindow, + doubleBuffer, stereoView, + rgba, stencilBits, + sharedGLContext ); + + if(glj!=null) + { + createOwnWindow = glj.isOwnWindowCreated(); + doubleBuffer = glj.isDoubleBuffer(); + stencilBits = glj.getStencilBitNumber(); + stereoView = glj.isStereoView(); + rgba = glj.isRGBA(); + } + + init(); + + // fetch the top-level window , + // to add us as the windowListener + // + Container _c = getParent(); + Container c = null; + + while(_c!=null) + { + c = _c; + _c = _c.getParent(); + } + + if(c instanceof Window) { + topLevelWindow = (Window)c; + topLevelWindow.addComponentListener(this); + topLevelWindow.addMouseListener(this); + } else { + topLevelWindow = null; + System.out.println("toplevel is not a Window: "+c); + } + + if(topLevelWindow!=null) + { + topLevelWindow.addWindowListener(this); + } else { + System.out.println("no parent found for "+getName()); + System.out.flush(); + } + if(glj!=null && glj.gljIsInit()) + cvsInitialized=true; + } + /* + if( mustResize ) size = getSize(); + g.setClip(0, 0, size.width, size.height ); + */ + sPaint(g); + } + + /** + * + * This is the thread save rendering-method called by paint. + * The actual thread will be set to highes priority befor calling + * 'display'. After 'display' the priority will be reset ! + * + * 'gljFree' will be NOT called after 'display'. + * + * We tested the above to use multi-threading and + * for the demonstration 'glDemos' it works ;-)) ! + * + * BE SURE, if you want to call 'display' by yourself + * (e.g. in the run method for animation) + * YOU HAVE TO CALL sDisplay -- OR YOU MUST KNOW WHAT YOU ARE DOING THEN ! + * + * @return void + * + * @see GLPanel#paint + * @see GLPanel#display + */ + public synchronized final void sPaint( Graphics g ) + { + boolean ok = true; + + long _s = System.currentTimeMillis(); + + if(!cvsIsInit()) + return; + + /* + if( glj.gljMakeCurrent() == false ) { + System.out.println("GLPanel: problem in use() method"); + return; + } + */ + + if( mustResize ) + { + Dimension size = getSize(); + glj.gljResize( size.width, size.height ) ; + reshape(size.width, size.height); + mustResize = false; + } + if(ok) + { + display(); + if(GLContext.gljClassDebug) + glj.gljCheckGL(); + _f_dur_self = System.currentTimeMillis()-_s; + + /* + GLGraphics glg1 = (GLGraphics)glg.create(); + try { + super.paint(glg1); + } finally { + glg1.dispose(); + } + */ + super.paint(g); + if(GLContext.gljClassDebug) + glj.gljCheckGL(); + _f_dur_total = System.currentTimeMillis()-_s; + + glj.gljSwap(); + glj.gljFree(); + } + + } + + /** + * + * This is the rendering-method called by sDisplay + * (and sDisplay is called by paint !). + * The derived-class (Your Subclass) will redefine this, to draw it's own... + * + * BE SURE, if you want to call 'display' by yourself + * (e.g. in the run method for animation) + * YOU HAVE TO CALL sDisplay ! + * + * 'sDisplay' manages a semaphore to avoid reentrance of + * the display function !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! + * + * @return void + * + * @see GLPanel#sDisplay + * @see GLPanel#paint + */ + public void display() + { + } + + /** + * + * This is your pre-init method. + * preInit is called just BEFORE the GL-Context is created. + * You should override preInit, to initialize your visual-stuff, + * like the protected vars: doubleBuffer and stereoView + * + * @return void + * + * @see GLPanel#paint + * @see GLPanel#doubleBuffer + * @see GLPanel#stereoView + * @see GLPanel#rgba + * @see GLPanel#stencilBits + */ + public void preInit() + { + } + + /** + * + * This is your init method. + * init is called right after the GL-Context is initialized. + * You should override init, to initialize your stuff needed + * by OpenGL an Java ! + * + * @return void + * + * @see GLPanel#paint + */ + public void init() + { + } + + /** + * This method is used to clean up any OpenGL stuff (delete textures + * or whatever) prior to actually deleting the OpenGL context. + * You should override this with your own version, if you need to do + * any cleanup work at this phase. + * This functions is called within cvsDispose + * + * @return void + * + * @see GLPanel#cvsDispose + */ + public void doCleanup() + { + } + + /** + * This function returns, if everything is init: the GLContext, + * the and the users init function + * This value is set in the paint method! + * + * @return boolean + * + * @see GLPanel#paint + * @see GLPanel#init + */ + public boolean cvsIsInit() + { + return cvsInitialized; + } + + protected long _f_dur_self = 0; + protected long _f_dur_total = 0; + + /** + * + * This is the reshape-method called by paint. + * The derived-class (Your Subclass) will redefine this, + * to manage your individual reshape ... + * + * This �reshape� method will be invoked after the first paint command + * after GLPanel.componentResize is called AND only if �gljUse� was + * succesfull (so a call of gljUse is redundant). + * �reshape� is not an overloading of java.awt.Component.reshape, + * �reshape� is more like �glut�-reshape. + * + * GLPanel.reshape allready has a simple default implementation, + * which calls �gljResize� and �glViewport� - so you may be can + * left this one as it is (no need to overload). + * The needed call to �gljResize� is done by hte invoker paint ! + * + * @param width the new width + * @param height the new height + * @return void + * + * @see GLPanel#paint + * @see GLPanel#sDisplay + */ + public void reshape( int width, int height ) + { + if(GLContext.gljClassDebug) + System.out.println("GLPanel::reshape bounds("+getBounds()+")"); + gl.glViewport(0,0, width, height); + gl.glMatrixMode(GL_PROJECTION); + gl.glLoadIdentity(); + gl.glOrtho(0, width, height, 0, -50.0,50.0); + gl.glMatrixMode(GL_MODELVIEW); + } + + /* JAU */ + /* + public final void setBounds(int x, int y, int width, int height) { + reshape(x, y, width, height); + } + public final void setBounds(Rectangle r) { + reshape(r.x, r.y, r.width, r.height); + } + + public void reshape(int x, int y, int width, int height) { + super.reshape(x, y, width, height); + if(glj==null || !glj.gljIsInit() || !glj.gljMakeCurrent()) + { + System.out.println("GLPanel::setBounds(): problem in use() method"); + return; + } + reshape(width-x, height-y); + glj.gljCheckGL(); + glj.gljFree(); + size = new Dimension(width-x, height-y); + } + */ + + + /** + * + * �componentResized� is the componentListeners event handler. + * + * This method sets the variable �mustResize� to true, + * so the upcoming �paint� method-call will invoke �reshape� ! + * + * This little look-alike complicating thing is done, + * to avoid an Exception by using the glContext from more than + * one concurrent thread�s ! + * + * You cannot override this implementation, it is final + * - override �reshape' instead ! + * + * @param e the element, which is resized + * @return void + * + * @see GLPanel#paint + * @see GLPanel#reshape + */ + public void componentResized(ComponentEvent e) + { + if(GLContext.gljClassDebug) + System.out.println("GLPanel::componentResized("+e.getComponent()+")"); + if(glj!=null && glj.gljIsInit() && e.getComponent()==this ) + { + mustResize = true; + //repaint(); + } + } + + public void componentMoved(ComponentEvent e) + { + if(GLContext.gljClassDebug) + System.out.print("GLPanel::componentMoved("+e.getComponent()+")"); + /* + if(e.getComponent().equals(topLevelWindow)) + { + repaint(); + } + */ + } + + public void componentShown(ComponentEvent e) + { + if(GLContext.gljClassDebug) + System.out.print("GLPanel::componentShown("+e.getComponent()+")"); + } + + public void componentHidden(ComponentEvent e) + { + if(GLContext.gljClassDebug) + System.out.print("GLPanel::componentHidden("+e.getComponent()+")"); + } + + public void mouseClicked(MouseEvent e) + { + if(GLContext.gljClassDebug) + System.out.print("."); + } + public void mouseEntered(MouseEvent e) + { + if(GLContext.gljClassDebug) + System.out.print("GLPanel::mouseEntered("+e.getComponent()+")"); + /* + if(e.getComponent().equals(topLevelWindow)) + { + repaint(); + } + */ + } + public void mouseExited(MouseEvent e) + {} + public void mousePressed(MouseEvent e) + { + if(GLContext.gljClassDebug) + System.out.print("<"); + } + public void mouseReleased(MouseEvent e) + { + if(GLContext.gljClassDebug) + System.out.print(">"); + } + + public void windowOpened(WindowEvent e) + { + } + + /** + * + * �windowClosing� is the windowListeners event handler + * for the topLevelWindow of this Canvas ! + * + * This methods free�s AND destroy�s + * the GL Context with �glj.gljDestroy� ! + * + * @return void + * + */ + public void windowClosing(WindowEvent e) + { + if(e.getComponent().equals(topLevelWindow)) + { + cvsDispose(); + } + } + + /** + * + * �windowClosed� is the windowListeners event handler. + * + * @return void + * + */ + public void windowClosed(WindowEvent e) + { + if (needCvsDispose) cvsDispose(); + } + + public void windowIconified(WindowEvent e) + { + } + + public void windowDeiconified(WindowEvent e) + { + } + + public void windowActivated(WindowEvent e) + { + } + + public void windowDeactivated(WindowEvent e) + { + } + + /** + * You should call this before releasing/dispose this Window ! + * Also you can overwrite this class, + * to dispose your own elements, e.g. a Frame etc. - + * but be shure that you call + * cvsDispose implementation call this one ! + * + * This function calls gljDestroy of GLContext ! + * + * @see gl4java.GLContext#gljDestroy + * @see GLPanel#doCleanup + */ + public void cvsDispose() + { + cvsInitialized = false; + if (glj != null) + { + if (glj.gljIsInit()) + { + /* Sometimes the Microsoft VM calls the + Applet.stop() method but doesn't have + permissions to do J/Direct calls, so + this whole block of code will throw a + security exception. If this happens, + however, windowClosing() will still + call us again later and we will have + another opportunity to shut down the + context, so it all works out fine. */ + try + { + glj.gljFree(); + doCleanup(); + //locks and free's GLContext + glj.setEnabled(false); + glj.gljDestroy(); + needCvsDispose = false; + } + catch (Exception ex) + { + needCvsDispose = true; + } + } + } + + // Setting glj to null will simply cause paint() to re-initialize. + // We don't want that to happen, so we will leave glj non-null. + } + + /** + * get methods + */ + public final int cvsGetWidth() { + return getSize().width; + } + public final int cvsGetHeight() { + return getSize().height; + } +} + diff --git a/demos/SwingDemos/test/GLPanel-AWTGraphics/test1.java b/demos/SwingDemos/test/GLPanel-AWTGraphics/test1.java new file mode 100644 index 0000000..b9786a0 --- /dev/null +++ b/demos/SwingDemos/test/GLPanel-AWTGraphics/test1.java @@ -0,0 +1,137 @@ +import java.applet.*; +import java.awt.*; +import java.awt.event.*; +import java.awt.Dimension; +import javax.swing.*; +import gl4java.*; +import gl4java.awt.*; +import gl4java.swing.*; +import gl4java.utils.glut.*; +import gl4java.utils.glut.fonts.*; + +public class test1 extends JApplet + implements GLEnum, GLUEnum +{ + static { + if(GLContext.loadNativeLibraries(null, null, null)==false) + System.out.println("GLCanvas could not load def. native libs."); + } + + protected class test1Panel extends GLPanel + implements ActionListener, ItemListener + { + public test1Panel() { + super(); + GLContext.gljNativeDebug = true; + GLContext.gljClassDebug = true; + //String[] data = {"one", "two", "three", "four"}; + //JList dataList = new JList(data); + //add("North", dataList); + JButton b1, b2; + add("East", (b1 = new JButton("E"))); + b1.setActionCommand("east"); + b1.addActionListener(this); + add("West", (b2 = new JButton("W"))); + b2.setActionCommand("west"); + b2.addActionListener(this); + + JCheckBox c1; + add("South", (c1 = new JCheckBox("SouthButton", true))); + c1.addItemListener(this); + } + + + public void init() { + System.out.println("<i>"); + //glg = new GLGraphics(gl, glu); + reshape(getSize().width, getSize().height); + } + + public void display() + { + if( glj.gljMakeCurrent() == false ) { + System.out.println("problem in use() method"); + return; + } + + System.out.println("<p>"); + + int i; + + gl.glPushMatrix(); + gl.glClear(GL_COLOR_BUFFER_BIT); + + gl.glColor4f(0f, 0f, 1f, 1f); + + int width=getSize().width; + int height=getSize().height; + + gl.glBegin(GLEnum.GL_LINES); + gl.glVertex3i( 0, 0, 0); + gl.glVertex3i( 10, 10, 0); + gl.glVertex3i( 0, 10, 0); + gl.glVertex3i( 10, 0, 0); + gl.glEnd(); + + gl.glPopMatrix(); + + glj.gljSwap(); + glj.gljCheckGL(); + glj.gljFree(); + } + + public void reshape( int width, int height ) + { + System.out.println("reshape("+width+", "+height+")"); + System.out.println("reshape bounds("+getBounds()+")"); + gl.glViewport(0,0, width, height); + gl.glMatrixMode(GL_PROJECTION); + gl.glLoadIdentity(); + gl.glOrtho(0, 10, 0, 10, -50.0,50.0); + gl.glMatrixMode(GL_MODELVIEW); + } + + public void actionPerformed(ActionEvent e) { + if (e.getActionCommand().equals("east")) { + System.out.println("East pressed"); + } else if (e.getActionCommand().equals("west")) { + System.out.println("West pressed"); + } + } + + public void itemStateChanged(ItemEvent e) { + Object source = e.getItemSelectable(); + System.out.println("item changed: "+source); + } + + } + + test1Panel tst1cvs1; + + public void init() + { + tst1cvs1 = new test1Panel(); + tst1cvs1.setSize(400,400); + setContentPane(tst1cvs1); + } + + public static void main(java.lang.String[] args) { + try { + Frame mainFrame = new Frame("test1"); + + test1 applet=new test1(); + + applet.setSize(400, 400); + applet.init(); + applet.start(); + + mainFrame.add(applet); + + mainFrame.pack(); + mainFrame.setVisible(true); + } catch (Throwable exception) { + System.err.println("Exception occurred in main()"); + exception.printStackTrace(System.out); + } + } +} diff --git a/demos/SwingDemos/test/GLPanel-GLGraphics/GLGraphics.java b/demos/SwingDemos/test/GLPanel-GLGraphics/GLGraphics.java new file mode 100644 index 0000000..835febf --- /dev/null +++ b/demos/SwingDemos/test/GLPanel-GLGraphics/GLGraphics.java @@ -0,0 +1,513 @@ +/** + * @(#) GLGraphics.java + */ + +//package gl4java.awt; + +import gl4java.*; +import gl4java.utils.glut.*; +import gl4java.utils.glut.fonts.*; + +import java.awt.*; +import java.awt.image.*; +import java.awt.event.*; +import java.awt.image.ImageObserver; +import java.text.*; + +public class GLGraphics + extends java.awt.Graphics + implements Cloneable +{ + +protected final boolean debug = false; + +/** + * this is the original Graphics context + */ +protected Graphics g = null; + +protected GLContext glj = null; +protected GLFunc gl = null; +protected GLUFunc glu = null; +protected GLUTFunc glut = null; +protected int currentGlutFont = GLUTEnum.GLUT_BITMAP_TIMES_ROMAN_10; +protected int x_orig = 0; +protected int y_orig = 0; +protected int z_orig = 0; + +//protected Color clr = Color.black; +//protected Shape clip = null; +//protected Font fnt = null; + +public GLGraphics (Graphics g, GLContext glj, GLFunc gl, GLUFunc glu) { + this.g=g; + this.glj=glj; + this.gl=gl; + this.glu=glu; + glut = new GLUTFuncLightImplWithFonts(gl, glu); +} + +public GLGraphics (Graphics g, GLContext glj, GLFunc gl, GLUFunc glu, GLUTFunc glut) { + this.g=g; + this.glj=glj; + this.gl=gl; + this.glu=glu; + this.glut=glut; +} + +protected GLGraphics (GLContext glj, GLFunc gl, GLUFunc glu, GLUTFunc glut) { + this.glj=glj; + this.gl=gl; + this.glu=glu; + this.glut=glut; +} + +protected Object clone() + throws CloneNotSupportedException +{ + GLGraphics glg = new GLGraphics(g, glj, gl, glu, glut); + //glg.g=g.create(); + glg.x_orig=x_orig; + glg.y_orig=y_orig; + glg.z_orig=z_orig; + glg.currentGlutFont=currentGlutFont; + + //glg.clr = clr; + //glg.clip=clip; + //glg.fnt = fnt; + + return glg; +} + +public Graphics create () { + try { + return ((Graphics)clone()); + } + catch (CloneNotSupportedException _) { + return (null); + } +} + +public Graphics create ( int x, int y, int width, int height ) { + if(debug) + System.out.println("Graphics::create("+x+","+y+","+width+","+height+")"); + // slow, generic version + Graphics g = create(); + + // modify cloned state acording to request + g.translate( x, y); + g.clipRect( 0, 0, width, height); // spec says this should be the intersection + + return g; +} + +public void clearRect ( int x, int y, int width, int height ) +{ + if(debug) + System.out.println("Graphics::clearRect("+x+","+y+","+width+","+height+")"); +} + +public void clipRect ( int x, int y, int width, int height ) +{ g.clipRect(x, y, width, height); +} + +public void copyArea ( int x, int y, int width, int height, int dx, int dy ) +{ + if(debug) + System.out.println("Graphics::copyArea("+x+","+y+","+width+","+height+","+dx+","+dy+")"); +} + +public void dispose () +{ + //g.dispose(); +} + +public void drawArc ( int x, int y, int width, int height, + int startAngle, int arcAngle ) +{ + if(debug) + System.out.println("Graphics::drawArc("+x+","+y+","+width+","+height+","+startAngle+","+arcAngle+")"); +} + +public boolean drawImage (Image img, int x, int y, Color bgcolor, + ImageObserver observer) +{ + if(debug) + System.out.println("Graphics::drawImage("+x+","+y+","+bgcolor+")"); + if( glj.gljMakeCurrent() == false ) { + System.out.println("GLGraphics: problem in use() method"); + return false; + } + return false; +} + +public boolean drawImage ( Image img, int x, int y, ImageObserver observer) +{ + if(debug) + System.out.println("Graphics::drawImage("+x+","+y+")"); + if( glj.gljMakeCurrent() == false ) { + System.out.println("GLGraphics: problem in use() method"); + return false; + } + + glDrawImage(observer, img, x_orig+x, y_orig+y, z_orig); + return false; +} + +public boolean drawImage ( Image img, int x, int y, int width, int height, + Color background, ImageObserver observer ) +{ + if(debug) + System.out.println("Graphics::drawImage("+x+","+y+","+width+","+height+","+background+")"); + if( glj.gljMakeCurrent() == false ) { + System.out.println("GLGraphics: problem in use() method"); + return false; + } + return false; +} + +public boolean drawImage ( Image img, int x, int y, int width, int height, + ImageObserver observer) +{ + if(debug) + System.out.println("Graphics::drawImage("+x+","+y+","+width+","+height+")"); + if( glj.gljMakeCurrent() == false ) { + System.out.println("GLGraphics: problem in use() method"); + return false; + } + return false; +} + +public boolean drawImage ( Image img, + int dx0, int dy0, int dx1, int dy1, + int sx0, int sy0, int sx1, int sy1, + Color bgColor, ImageObserver observer) +{ + if(debug) + System.out.println("Graphics::drawImage(..)"); + if( glj.gljMakeCurrent() == false ) { + System.out.println("GLGraphics: problem in use() method"); + return false; + } + return false; +} + +public boolean drawImage ( Image img, + int dx1, int dy1, int dx2, int dy2, + int sx1, int sy1, int sx2, int sy2, + ImageObserver observer) +{ + if(debug) + System.out.println("Graphics::drawImage(..)"); + return false; +} + +public void drawLine ( int x1, int y1, int x2, int y2 ) +{ + if(debug) + System.out.println("Graphics("+x_orig+","+y_orig+")::drawLine("+x1+","+y1+","+x2+","+y2+")"); + if( glj.gljMakeCurrent() == false ) { + System.out.println("GLGraphics: problem in use() method"); + return; + } + gl.glBegin(GLEnum.GL_LINES); + gl.glVertex3i( x_orig+x1, y_orig+y1, z_orig); + gl.glVertex3i( x_orig+x2, y_orig+y2, z_orig); + gl.glEnd(); +} + +public void drawOval ( int x, int y, int width, int height ) +{ + if(debug) + System.out.println("Graphics::drawOval("+x+","+y+","+width+","+height+")"); +} + +public void drawPolygon ( int xPoints[], int yPoints[], int nPoints ) +{ + if(debug) + System.out.println("Graphics("+x_orig+","+y_orig+")::drawPolygon(...)"); + if( glj.gljMakeCurrent() == false ) { + System.out.println("GLGraphics: problem in use() method"); + return; + } + gl.glPolygonMode(GLEnum.GL_FRONT_AND_BACK, GLEnum.GL_LINE); + gl.glBegin(GLEnum.GL_POLYGON); + for(int i=0; i<nPoints; i++) + gl.glVertex3i( x_orig+xPoints[i], y_orig+yPoints[i], z_orig); + gl.glEnd(); +} + +public void drawPolyline ( int xPoints[], int yPoints[], int nPoints ) +{ + if(debug) + System.out.println("Graphics("+x_orig+","+y_orig+")::drawPolyline(...)"); + if( glj.gljMakeCurrent() == false ) { + System.out.println("GLGraphics: problem in use() method"); + return; + } + gl.glPolygonMode(GLEnum.GL_FRONT_AND_BACK, GLEnum.GL_LINE); + gl.glBegin(GLEnum.GL_POLYGON); + for(int i=0; i<nPoints; i++) + gl.glVertex3i( x_orig+xPoints[i], y_orig+yPoints[i], z_orig); + gl.glEnd(); +} + +public void drawRoundRect ( int x, int y, int width, int height, + int arcWidth, int arcHeight) +{ + if(debug) + System.out.println("Graphics::drawRoundRect("+x+","+y+","+width+","+height+","+arcWidth+","+arcHeight+")"); +} + +public void drawString ( String str, int x, int y ) +{ + if(debug) + System.out.println("Graphics("+x_orig+","+y_orig+")::drawString("+x+","+y+","+str+")"); + if( glj.gljMakeCurrent() == false ) { + System.out.println("GLGraphics: problem in use() method"); + return; + } + gl.glRasterPos3d(x_orig+x, y_orig+y, z_orig); + glut.glutBitmapString(currentGlutFont,str); +} + +public void drawString(java.text.AttributedCharacterIterator aci, int x, int y) +{ + if(debug) + System.out.println("Graphics("+x_orig+","+y_orig+")::drawStringACI("+x+","+y+")"); + StringBuffer sb = new StringBuffer(); + for(char c = aci.first(); c != CharacterIterator.DONE; c = aci.next()) + sb.append(c); + drawString(sb.toString(), x, y); +} + +public void fillArc ( int x, int y, int width, int height, + int startAngle, int arcAngle ) +{ + if(debug) + System.out.println("Graphics::fillArc("+x+","+y+","+width+","+height+","+startAngle+","+arcAngle+")"); +} + +public void fillOval ( int x, int y, int width, int height ) +{ + if(debug) + System.out.println("Graphics::fillOval("+x+","+y+","+width+","+height+")"); +} + +public void fillPolygon ( int xPoints[], int yPoints[], int nPoints ) +{ + if(debug) + System.out.println("Graphics::fillPolygon(..)"); +} + +public void fillRect ( int x, int y, int width, int height ) +{ + if(debug) + System.out.println("Graphics::fillRect("+x+","+y+","+width+","+height+")"); + if( glj.gljMakeCurrent() == false ) { + System.out.println("GLGraphics: problem in use() method"); + return; + } + gl.glPolygonMode(GLEnum.GL_FRONT_AND_BACK, GLEnum.GL_FILL); + gl.glBegin(GLEnum.GL_POLYGON); + gl.glVertex3i( x_orig+x, y_orig+y, z_orig); + gl.glVertex3i( x_orig+x+width, y_orig+y, z_orig); + gl.glVertex3i( x_orig+x+width, y_orig+y+height, z_orig); + gl.glVertex3i( x_orig+x, y_orig+y+height, z_orig); + gl.glVertex3i( x_orig+x, y_orig+y, z_orig); + gl.glEnd(); +} + +public void fillRoundRect ( int x, int y, int width, int height, + int arcWidth, int arcHeight ) +{ + if(debug) + System.out.println("Graphics::fillRoundRect("+x+","+y+","+width+","+height+","+arcWidth+","+arcHeight+")"); +} + +public Shape getClip () +{ return g.getClip(); } + +public Rectangle getClipBounds() +{ return null; } + +public Color getColor() +{ return g.getColor(); } + +public Font getFont() +{ return g.getFont(); } + +public FontMetrics getFontMetrics ( Font fnt ) +{ return g.getFontMetrics(fnt); } + +public void setClip ( Shape clip ) +{ g.setClip(clip); } + +public void setClip ( int x, int y, int width, int height ) +{ g.setClip(x, y, width, height); } + +public void setColor ( Color clr ) +{ + if(debug) + System.out.println("Graphics("+x_orig+","+y_orig+")::setColor("+clr+")"); + g.setColor(clr); + if( glj.gljMakeCurrent() == false ) { + System.out.println("GLGraphics: problem in use() method"); + return; + } + gl.glColor4d(clr.getRed()/255.0, clr.getGreen()/255.0, + clr.getBlue()/255.0, clr.getAlpha()/255.0); +} + +public void setFont ( Font newFnt ) +{ g.setFont(newFnt); + if(debug) + System.out.println("Graphics("+(x_orig)+","+(y_orig)+")::setFont("+newFnt.getName()+" / "+ newFnt.getFamily()+" / "+ newFnt.getSize()+")"); + switch(newFnt.getSize()) + { + case 8: + currentGlutFont = GLUTEnum.GLUT_BITMAP_8_BY_13; + break; + case 9: + currentGlutFont = GLUTEnum.GLUT_BITMAP_9_BY_15; + break; + case 10: + currentGlutFont = GLUTEnum.GLUT_BITMAP_TIMES_ROMAN_10; + break; + case 24: + currentGlutFont = GLUTEnum.GLUT_BITMAP_TIMES_ROMAN_24; + break; + /* + case 10: + currentGlutFont = GLUTEnum.GLUT_BITMAP_HELVETICA_10; + break; + */ + case 12: + currentGlutFont = GLUTEnum.GLUT_BITMAP_HELVETICA_12; + break; + case 18: + currentGlutFont = GLUTEnum.GLUT_BITMAP_HELVETICA_18; + break; + default: + currentGlutFont = GLUTEnum.GLUT_BITMAP_TIMES_ROMAN_10; + } +} + +public void setPaintMode() +{} + +public void setXORMode ( Color newXorClr ) +{} + +public void translate ( int x, int y ) +{ + x_orig+=x; + y_orig+=y; + if(debug) + System.out.println("Graphics("+(x_orig-x)+","+(y_orig-y)+")::translate("+x+","+y+") -> ("+x_orig+","+y_orig+")"); + g.translate(x, y); +} + +protected void glDrawImage(ImageObserver observer, Image image, + int xpos, int ypos, int zpos) +{ + int imageWidth = image.getWidth(observer); + int imageHeight = image.getHeight(observer); + int glFormat=GLEnum.GL_RGB; //def. RGB type + int comps=3; //def. RGB type + + if(debug) + System.out.println("Graphics("+(x_orig)+","+(y_orig)+")::glDrawImage("+xpos+","+ypos+") ("+imageWidth+","+imageHeight+")"); + + /* This is Java2 only code :-( + BufferedImage image = + new BufferedImage(imageWidth, imageHeight, + BufferedImage.TYPE_INT_RGB); + + Graphics g = image.createGraphics(); + g.drawImage(img,0,0,comp); + + imageWidth = image.getWidth(); + imageHeight = image.getHeight(); + */ + + // Read entire PNG image (doesn't throw exceptions) + int[] iPixels = new int[imageWidth * imageHeight]; + + PixelGrabber pp=new PixelGrabber(image, + 0,0, + imageWidth, imageHeight, + iPixels, + 0, + imageWidth); + try + { + pp.grabPixels(); + } + catch (InterruptedException e) + { + System.err.println("interrupted waiting for pixel!"); + return; + } + if ((pp.getStatus() & ImageObserver.ABORT) != 0) + { + System.err.println("image fetch aborted or errored"); + return; + } + + /* This is Java2 only code :-( + int imagetype = image.getType(); + switch(imagetype) + { + case BufferedImage.TYPE_INT_RGB: + glFormat=GLEnum.GL_RGB; + comps=3; + break; + case BufferedImage.TYPE_INT_ARGB: + case BufferedImage.TYPE_INT_ARGB_PRE: + glFormat=GLEnum.GL_RGBA; + comps=4; + break; + default: + System.err.println("unsupported format: "+imagetype); + return; + }; + */ + + byte[] pixel=new byte[imageWidth * imageHeight * comps]; + + byte alpha=0; + byte red=0; + byte green=0; + byte blue=0; + int offset=0; + int aPixel; + int y_desc, y_asc; + for(y_desc=imageHeight-1, y_asc=0; y_desc>=0; y_desc--, y_asc++) + { + for(int x=0;x<imageWidth;x++) + { + aPixel = iPixels[y_desc*imageWidth + x]; + + if(glFormat==GLEnum.GL_RGBA) + alpha =new Integer( (aPixel >> 24) & 0xff ).byteValue(); + red =new Integer( (aPixel >> 16) & 0xff ).byteValue(); + green =new Integer( (aPixel >> 8) & 0xff ).byteValue(); + blue =new Integer( (aPixel ) & 0xff ).byteValue(); + + pixel[offset++]=red; + pixel[offset++]=green; + pixel[offset++]=blue; + if(glFormat==GLEnum.GL_RGBA) + pixel[offset++]=alpha; + } + } + gl.glPixelStorei(GLEnum.GL_UNPACK_ALIGNMENT, 1); + gl.glDrawBuffer(GLEnum.GL_FRONT); + gl.glRasterPos3i(xpos, ypos+imageHeight, zpos); + gl.glDrawPixels(imageWidth, imageHeight, + glFormat, GLEnum.GL_UNSIGNED_BYTE, + pixel); + gl.glDrawBuffer(GLEnum.GL_BACK); +} +} diff --git a/demos/SwingDemos/test/GLPanel-GLGraphics/GLPanel.java b/demos/SwingDemos/test/GLPanel-GLGraphics/GLPanel.java new file mode 100644 index 0000000..266595e --- /dev/null +++ b/demos/SwingDemos/test/GLPanel-GLGraphics/GLPanel.java @@ -0,0 +1,692 @@ +//package gl4java.awt; + +import gl4java.*; + +import java.awt.*; +import java.awt.event.*; + +public class GLPanel extends Panel + implements GLEnum, GLUEnum, + ComponentListener, WindowListener, MouseListener +{ + protected GLContext glj = null; + public GLFunc gl = null; + public GLUFunc glu = null; + public GLGraphics glg = null; + + protected boolean mustResize = false; + + protected boolean cvsInitialized=false; + + protected boolean needCvsDispose = false; + + /** + * Visual pre-set for doubleBuffer, default: true + * This value is updated after a GLContext is created with the + * original updated value of GLContext ! + * + * @see GLPanel#preInit + * @see GLPanel#paint + */ + protected boolean doubleBuffer = true; + + /** + * Visual pre-set for stencil-bit number, default: 0 + * This value is updated after a GLContext is created with the + * original updated value of GLContext ! + * + * @see GLPanel#preInit + * @see GLPanel#paint + */ + protected int stencilBits = 0; + + /** + * Visual pre-set for stereoView, default: false + * This value is updated after a GLContext is created with the + * original updated value of GLContext ! + * + * @see GLPanel#preInit + * @see GLPanel#paint + */ + protected boolean stereoView = false; + + /** + * Visual pre-set for RGBA usage, default: true - of course ;-) + * This value is updated after a GLContext is created with the + * original updated value of GLContext ! + * + * @see GLPanel#preInit + * @see GLPanel#paint + */ + protected boolean rgba = true; + + /** + * Visual pre-set for RGBA usage, default: true - of course ;-) + * This value is updated after a GLContext is created with the + * original updated value of GLContext ! + * + * @see GLPanel#preInit + * @see GLPanel#paint + */ + protected boolean createOwnWindow = false; + + /** + * The context with witch display lists and textures will be shared. + * + * @see GLPanel#preInit + * @see GLPanel#paint + */ + protected GLContext sharedGLContext; + + static { + if(GLContext.loadNativeLibraries(null, null, null)==false) + System.out.println("GLPanel could not load def. native libs."); + } + + /** + * + * Constructor + * + * @param width the canvas initial-prefered width + * @param height the canvas initial-prefered height + * + * @param gl_Name The name of the GLFunc implementation + * If gl_Name==null, the default class will be used ! + * + * @param glu_Name The name of the GLUFunc implementation + * If gl_LibName==null, the default class will be used ! + * + */ + public GLPanel( String gl_Name, + String glu_Name + ) + { + super( new BorderLayout() ); + + if( (gl=GLContext.createGLFunc(gl_Name)) ==null) + { + System.out.println("GLFunc implementation "+gl_Name+" not created"); + } + if( (glu=GLContext.createGLUFunc(glu_Name)) ==null) + { + System.out.println("GLUFunc implementation "+glu_Name+" not created"); + } + + /* to be able for RESIZE event's */ + addComponentListener(this); + } + + /** + * + * Constructor + * + * Uses the default GLFunc and GLUFunc implementation ! + * + * @param width the canvas initial-prefered width + * @param height the canvas initial-prefered height + * + */ + public GLPanel( ) + { + this(null, null); + } + + /** + * Used to return the created GLContext + */ + public final GLContext getGLContext() { return glj; } + + /** + * + * Overridden update + * This one only call's the paint method, without clearing + * the background - thats hopefully done by OpenGL ;-) + * + * @param g the Graphics Context + * @return void + * + * @see GLPanel#paint + */ + public void update(Graphics g) + { + //JAU + if(GLContext.gljClassDebug) + System.out.println("GPanel::update(): isShowing()="+isShowing()); + if(isShowing()) + { + /* let's let OpenGL clear the background ... */ + paint(g); + } + } + + + /** + * Safe the toplevel window + */ + protected Window topLevelWindow = null; + + /** + * + * This function returns the found TopLevelWindow, + * which contains this Canvas .. + * + * @return void + * + * @see GLPanel#paint + */ + public final Window getTopLevelWindow() + { return topLevelWindow; } + + /** + * this function overrides the Canvas paint method ! + * + * For the first paint, + * the user function preInit is called, a GLContext is created + * and the user function init is called ! + * + * Also, if a GL Context exist, GLPanel's sDisplay-method will be called + * to do OpenGL-rendering. + * + * The sDisplay method itself calls the display-method ! + * sDisplay is needed to be thread-safe, to manage + * the resize functionality and to safe the time per frame. + * + * To define your rendering, you should overwrite the display-method + * in your derivation. + * + * @see gl4java.GLContext#GLContext + * @see GLPanel#cvsIsInit + * @see GLPanel#sDisplay + * @see GLPanel#display + * @see GLPanel#preInit + * @see GLPanel#init + */ + public synchronized final void paint( Graphics g ) + { + //JAU + if(GLContext.gljClassDebug) + System.out.println("GPanel::paint()"); + if(glj == null ) + { + preInit(); + glj = new GLContext ( this, gl, glu, + createOwnWindow, + doubleBuffer, stereoView, + rgba, stencilBits, + sharedGLContext ); + + if(glj!=null) + { + createOwnWindow = glj.isOwnWindowCreated(); + doubleBuffer = glj.isDoubleBuffer(); + stencilBits = glj.getStencilBitNumber(); + stereoView = glj.isStereoView(); + rgba = glj.isRGBA(); + } + + init(); + + // fetch the top-level window , + // to add us as the windowListener + // + Container _c = getParent(); + Container c = null; + + while(_c!=null) + { + c = _c; + _c = _c.getParent(); + } + + if(c instanceof Window) { + topLevelWindow = (Window)c; + topLevelWindow.addComponentListener(this); + topLevelWindow.addMouseListener(this); + } else { + topLevelWindow = null; + System.out.println("toplevel is not a Window: "+c); + } + + if(topLevelWindow!=null) + { + topLevelWindow.addWindowListener(this); + } else { + System.out.println("no parent found for "+getName()); + System.out.flush(); + } + if(glj!=null && glj.gljIsInit()) + cvsInitialized=true; + } + if(glg!=null) + glg.dispose(); + glg = new GLGraphics(g, glj, gl, glu); + /* + if( mustResize ) size = getSize(); + g.setClip(0, 0, size.width, size.height ); + */ + sPaint(g); + } + + /** + * + * This is the thread save rendering-method called by paint. + * The actual thread will be set to highes priority befor calling + * 'display'. After 'display' the priority will be reset ! + * + * 'gljFree' will be NOT called after 'display'. + * + * We tested the above to use multi-threading and + * for the demonstration 'glDemos' it works ;-)) ! + * + * BE SURE, if you want to call 'display' by yourself + * (e.g. in the run method for animation) + * YOU HAVE TO CALL sDisplay -- OR YOU MUST KNOW WHAT YOU ARE DOING THEN ! + * + * @return void + * + * @see GLPanel#paint + * @see GLPanel#display + */ + public synchronized final void sPaint( Graphics g ) + { + boolean ok = true; + + long _s = System.currentTimeMillis(); + + if(!cvsIsInit()) + return; + + /* + if( glj.gljMakeCurrent() == false ) { + System.out.println("GLPanel: problem in use() method"); + return; + } + */ + + if( mustResize ) + { + Dimension size = getSize(); + glj.gljResize( size.width, size.height ) ; + reshape(size.width, size.height); + mustResize = false; + } + if(ok) + { + display(); + if(GLContext.gljClassDebug) + glj.gljCheckGL(); + _f_dur_self = System.currentTimeMillis()-_s; + + /* + GLGraphics glg1 = (GLGraphics)glg.create(); + try { + super.paint(glg1); + } finally { + glg1.dispose(); + } + */ + super.paint(glg); + if(GLContext.gljClassDebug) + glj.gljCheckGL(); + _f_dur_total = System.currentTimeMillis()-_s; + + glj.gljSwap(); + glj.gljFree(); + } + + } + + public Graphics getGraphics() + { + if(glg==null) + return super.getGraphics(); + return glg.create(); + } + + public Graphics getNativeGraphics() + { + return super.getGraphics(); + } + + /** + * + * This is the rendering-method called by sDisplay + * (and sDisplay is called by paint !). + * The derived-class (Your Subclass) will redefine this, to draw it's own... + * + * BE SURE, if you want to call 'display' by yourself + * (e.g. in the run method for animation) + * YOU HAVE TO CALL sDisplay ! + * + * 'sDisplay' manages a semaphore to avoid reentrance of + * the display function !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! + * + * @return void + * + * @see GLPanel#sDisplay + * @see GLPanel#paint + */ + public void display() + { + } + + /** + * + * This is your pre-init method. + * preInit is called just BEFORE the GL-Context is created. + * You should override preInit, to initialize your visual-stuff, + * like the protected vars: doubleBuffer and stereoView + * + * @return void + * + * @see GLPanel#paint + * @see GLPanel#doubleBuffer + * @see GLPanel#stereoView + * @see GLPanel#rgba + * @see GLPanel#stencilBits + */ + public void preInit() + { + } + + /** + * + * This is your init method. + * init is called right after the GL-Context is initialized. + * You should override init, to initialize your stuff needed + * by OpenGL an Java ! + * + * @return void + * + * @see GLPanel#paint + */ + public void init() + { + } + + /** + * This method is used to clean up any OpenGL stuff (delete textures + * or whatever) prior to actually deleting the OpenGL context. + * You should override this with your own version, if you need to do + * any cleanup work at this phase. + * This functions is called within cvsDispose + * + * @return void + * + * @see GLPanel#cvsDispose + */ + public void doCleanup() + { + } + + /** + * This function returns, if everything is init: the GLContext, + * the and the users init function + * This value is set in the paint method! + * + * @return boolean + * + * @see GLPanel#paint + * @see GLPanel#init + */ + public boolean cvsIsInit() + { + return cvsInitialized; + } + + protected long _f_dur_self = 0; + protected long _f_dur_total = 0; + + /** + * + * This is the reshape-method called by paint. + * The derived-class (Your Subclass) will redefine this, + * to manage your individual reshape ... + * + * This �reshape� method will be invoked after the first paint command + * after GLPanel.componentResize is called AND only if �gljUse� was + * succesfull (so a call of gljUse is redundant). + * �reshape� is not an overloading of java.awt.Component.reshape, + * �reshape� is more like �glut�-reshape. + * + * GLPanel.reshape allready has a simple default implementation, + * which calls �gljResize� and �glViewport� - so you may be can + * left this one as it is (no need to overload). + * The needed call to �gljResize� is done by hte invoker paint ! + * + * @param width the new width + * @param height the new height + * @return void + * + * @see GLPanel#paint + * @see GLPanel#sDisplay + */ + public void reshape( int width, int height ) + { + if(GLContext.gljClassDebug) + System.out.println("GLPanel::reshape bounds("+getBounds()+")"); + gl.glViewport(0,0, width, height); + gl.glMatrixMode(GL_PROJECTION); + gl.glLoadIdentity(); + gl.glOrtho(0, width, height, 0, -50.0,50.0); + gl.glMatrixMode(GL_MODELVIEW); + } + + /* JAU */ + /* + public final void setBounds(int x, int y, int width, int height) { + reshape(x, y, width, height); + } + public final void setBounds(Rectangle r) { + reshape(r.x, r.y, r.width, r.height); + } + + public void reshape(int x, int y, int width, int height) { + super.reshape(x, y, width, height); + if(glj==null || !glj.gljIsInit() || !glj.gljMakeCurrent()) + { + System.out.println("GLPanel::setBounds(): problem in use() method"); + return; + } + reshape(width-x, height-y); + glj.gljCheckGL(); + glj.gljFree(); + size = new Dimension(width-x, height-y); + } + */ + + + /** + * + * �componentResized� is the componentListeners event handler. + * + * This method sets the variable �mustResize� to true, + * so the upcoming �paint� method-call will invoke �reshape� ! + * + * This little look-alike complicating thing is done, + * to avoid an Exception by using the glContext from more than + * one concurrent thread�s ! + * + * You cannot override this implementation, it is final + * - override �reshape' instead ! + * + * @param e the element, which is resized + * @return void + * + * @see GLPanel#paint + * @see GLPanel#reshape + */ + public void componentResized(ComponentEvent e) + { + if(GLContext.gljClassDebug) + System.out.println("GLPanel::componentResized("+e.getComponent()+")"); + if(glj!=null && glj.gljIsInit() && e.getComponent()==this ) + { + mustResize = true; + //repaint(); + } + } + + public void componentMoved(ComponentEvent e) + { + if(GLContext.gljClassDebug) + System.out.print("GLPanel::componentMoved("+e.getComponent()+")"); + /* + if(e.getComponent().equals(topLevelWindow)) + { + repaint(); + } + */ + } + + public void componentShown(ComponentEvent e) + { + if(GLContext.gljClassDebug) + System.out.print("GLPanel::componentShown("+e.getComponent()+")"); + } + + public void componentHidden(ComponentEvent e) + { + if(GLContext.gljClassDebug) + System.out.print("GLPanel::componentHidden("+e.getComponent()+")"); + } + + public void mouseClicked(MouseEvent e) + { + if(GLContext.gljClassDebug) + System.out.print("."); + } + public void mouseEntered(MouseEvent e) + { + if(GLContext.gljClassDebug) + System.out.print("GLPanel::mouseEntered("+e.getComponent()+")"); + /* + if(e.getComponent().equals(topLevelWindow)) + { + repaint(); + } + */ + } + public void mouseExited(MouseEvent e) + {} + public void mousePressed(MouseEvent e) + { + if(GLContext.gljClassDebug) + System.out.print("<"); + } + public void mouseReleased(MouseEvent e) + { + if(GLContext.gljClassDebug) + System.out.print(">"); + } + + public void windowOpened(WindowEvent e) + { + } + + /** + * + * �windowClosing� is the windowListeners event handler + * for the topLevelWindow of this Canvas ! + * + * This methods free�s AND destroy�s + * the GL Context with �glj.gljDestroy� ! + * + * @return void + * + */ + public void windowClosing(WindowEvent e) + { + if(e.getComponent().equals(topLevelWindow)) + { + cvsDispose(); + } + } + + /** + * + * �windowClosed� is the windowListeners event handler. + * + * @return void + * + */ + public void windowClosed(WindowEvent e) + { + if (needCvsDispose) cvsDispose(); + } + + public void windowIconified(WindowEvent e) + { + } + + public void windowDeiconified(WindowEvent e) + { + } + + public void windowActivated(WindowEvent e) + { + } + + public void windowDeactivated(WindowEvent e) + { + } + + /** + * You should call this before releasing/dispose this Window ! + * Also you can overwrite this class, + * to dispose your own elements, e.g. a Frame etc. - + * but be shure that you call + * cvsDispose implementation call this one ! + * + * This function calls gljDestroy of GLContext ! + * + * @see gl4java.GLContext#gljDestroy + * @see GLPanel#doCleanup + */ + public void cvsDispose() + { + cvsInitialized = false; + if (glj != null) + { + if (glj.gljIsInit()) + { + /* Sometimes the Microsoft VM calls the + Applet.stop() method but doesn't have + permissions to do J/Direct calls, so + this whole block of code will throw a + security exception. If this happens, + however, windowClosing() will still + call us again later and we will have + another opportunity to shut down the + context, so it all works out fine. */ + try + { + glj.gljFree(); + doCleanup(); + //locks and free's GLContext + glj.setEnabled(false); + glj.gljDestroy(); + needCvsDispose = false; + } + catch (Exception ex) + { + needCvsDispose = true; + } + } + } + + // Setting glj to null will simply cause paint() to re-initialize. + // We don't want that to happen, so we will leave glj non-null. + } + + /** + * get methods + */ + public final int cvsGetWidth() { + return getSize().width; + } + public final int cvsGetHeight() { + return getSize().height; + } +} + diff --git a/demos/SwingDemos/test/GLPanel-GLGraphics/test1.java b/demos/SwingDemos/test/GLPanel-GLGraphics/test1.java new file mode 100644 index 0000000..1b8bf4b --- /dev/null +++ b/demos/SwingDemos/test/GLPanel-GLGraphics/test1.java @@ -0,0 +1,129 @@ +import java.applet.*; +import java.awt.*; +import java.awt.event.*; +import java.awt.Dimension; +import javax.swing.*; +import gl4java.*; +import gl4java.swing.*; +import gl4java.utils.glut.*; +import gl4java.utils.glut.fonts.*; + +public class test1 extends JApplet + implements GLEnum, GLUEnum +{ + static { + if(GLContext.loadNativeLibraries(null, null, null)==false) + System.out.println("GLCanvas could not load def. native libs."); + } + + protected class test1Panel extends GLPanel + implements ActionListener, ItemListener + { + public test1Panel() { + super(); + GLContext.gljNativeDebug = true; + GLContext.gljClassDebug = true; + //String[] data = {"one", "two", "three", "four"}; + //JList dataList = new JList(data); + //add("North", dataList); + JButton b1, b2; + add("East", (b1 = new JButton("E"))); + b1.setActionCommand("east"); + b1.addActionListener(this); + add("West", (b2 = new JButton("W"))); + b2.setActionCommand("west"); + b2.addActionListener(this); + + JCheckBox c1; + add("South", (c1 = new JCheckBox("SouthButton", true))); + c1.addItemListener(this); + } + + GLGraphics glg = null; + + public void init() { + System.out.println("<i>"); + //glg = new GLGraphics(gl, glu); + reshape(getSize().width, getSize().height); + } + + public void display() + { + System.out.println("<p>"); + + int i; + + glg = (GLGraphics)getGraphics(); + + gl.glPushMatrix(); + gl.glClear(GL_COLOR_BUFFER_BIT); + + glg.setColor(Color.blue); + + int width=getSize().width; + int height=getSize().height; + + glg.drawLine ( 0, height/2, width, height/2 ); + glg.drawLine ( width/2, 0, width/2, height ); + + glg.setColor(Color.yellow); + + glg.drawLine ( 0, 0, width, height); + glg.drawString("Left-top", 0, 10); + glg.drawString("GLGraphics - CENTER", width/2, height/2); + glg.drawString("Right - Bottom (nearly)", width*2/3, height*2/3); + gl.glPopMatrix(); + + glj.gljCheckGL(); + } + + public void reshape(int width, int height) + { + System.out.println("reshape("+width+", "+height+")"); + super.reshape(width, height); + } + + public void actionPerformed(ActionEvent e) { + if (e.getActionCommand().equals("east")) { + System.out.println("East pressed"); + } else if (e.getActionCommand().equals("west")) { + System.out.println("West pressed"); + } + } + + public void itemStateChanged(ItemEvent e) { + Object source = e.getItemSelectable(); + System.out.println("item changed: "+source); + } + + } + + test1Panel tst1cvs1; + + public void init() + { + tst1cvs1 = new test1Panel(); + tst1cvs1.setSize(400,400); + setContentPane(tst1cvs1); + } + + public static void main(java.lang.String[] args) { + try { + Frame mainFrame = new Frame("test1"); + + test1 applet=new test1(); + + applet.setSize(400, 400); + applet.init(); + applet.start(); + + mainFrame.add(applet); + + mainFrame.pack(); + mainFrame.setVisible(true); + } catch (Throwable exception) { + System.err.println("Exception occurred in main()"); + exception.printStackTrace(System.out); + } + } +} |