View Javadoc

1   package com.insanityengine.ghia.libograf;
2   
3   import java.applet.*;
4   
5   import java.awt.*;
6   import java.awt.image.*;
7   import java.awt.event.*;
8   
9   import javax.swing.*;
10  import javax.swing.event.*;
11  
12  import java.util.*;
13  
14  import com.insanityengine.ghia.m3.*;
15  import com.insanityengine.ghia.pixels.*;
16  import com.insanityengine.ghia.pixelops.*;
17  
18  /***
19   *
20   * <P>
21   * Takes care of most of the Applet cruft, implement initImpl 
22   * and drawImpl and viola!
23   * </P>
24   *
25   * @author BrianHammond
26   *
27   * $Header: /usr/local/cvsroot/ghia/src/java/com/insanityengine/ghia/libograf/AppletBase.java,v 1.15 2005/03/29 02:38:33 brian Exp $
28   *
29   */
30  public class AppletBase
31  	extends 
32  		JApplet
33  	implements 
34  		  KeyListener
35  		, MouseListener
36  		, MouseMotionListener
37  		, ActionListener
38  		, Runnable
39  		, DrawingInterface
40  {
41  	
42  	/////////////////////////////////////////////////////////////
43  /*
44  	public final static void main( String argv[] ) {
45  		new AppletBase().frame();
46  	}	
47  */
48  	/////////////////////////////////////////////////////////////
49  
50  	// override these
51  
52  	/*** 
53  	 * 
54  	 * initImpl
55  	 * 
56  	 * @param w
57  	 * @param h
58  	 * 
59  	 */
60  	public void initImpl( int w, int h ) {
61  	}
62  
63  	/*** 
64  	 * 
65  	 * drawImpl
66  	 * 
67  	 */
68  	public void drawImpl() {
69  	}
70  
71  	/////////////////////////////////////////////////////////////
72  	
73  	/*** 
74  	 * 
75  	 * Constructor
76  	 * 
77  	 */
78  	public AppletBase() {
79  		performanceTest = ( null != System.getProperty( "m3_perfHarness" ) );
80  	}
81  
82  	/*** 
83  	 * 
84  	 * Constructor
85  	 * 
86  	 * @param w
87  	 * @param h
88  	 * 
89  	 */
90  	public AppletBase( int w, int h ) {
91  		this();
92  		init( w, h );
93  	}
94  	
95  	/////////////////////////////////////////////////////////////
96  	
97  	/*** 
98  	 * 
99  	 * init
100 	 * 
101 	 */
102 	public void init() {
103 		init( getSize().width, getSize().height );
104 	}
105 
106 	/*** 
107 	 * 
108 	 * paint
109 	 * 
110 	 * @param g
111 	 * 
112 	 */
113 	public void paint( Graphics g ) { 
114 		update( g ); 
115 	}
116 
117 	/*** 
118 	 * 
119 	 * update
120 	 * 
121 	 * @param g
122 	 * 
123 	 */
124 	public void update( Graphics g ) {
125 		gl.render( g );
126 		fcount++;
127 	}
128 
129 	/*** 
130 	 * 
131 	 * start
132 	 * 
133 	 */
134 	public void start() {
135 		badJoke();
136 
137 		if ( null != thread ) return; 
138 		thread = new Thread( this );
139 		thread.start();
140 	}
141 	
142 	/*** 
143 	 * 
144 	 * stop
145 	 * 
146 	 */
147 	public void stop() {
148 		if ( null == thread ) return;
149 		//thread.stop();
150 	}
151 	
152 	/*** 
153 	 * 
154 	 * run
155 	 * 
156 	 */
157 	public void run() {
158 		while ( keepRunning ) {
159 			drawFrame();
160 
161 			if ( null != rname ) {
162 				gl.createRenderer( rname );
163 				rname = null;
164 			}
165 		}
166 	}
167 
168 	/***
169 	 *
170 	 * Draw a frame
171 	 *
172 	 * @param gl to use
173 	 *
174 	 */
175 	public void draw( LiboGrafInterface gl ) {
176 
177 		if ( whenPerf == fcount ) the5k();
178 
179 		if ( null == gl ) {
180 			return;
181 		}
182 		//gl.getRenderer().clearDepthBuffer();
183 		
184 		drawImpl();
185 
186 		// just for fun
187 		if ( !true ) {
188 			if ( gl.getRenderer() instanceof PixelBufferReadInterface ) {
189 				com.insanityengine.ghia.pixelops.TextDitherer.dither( 
190 					( PixelBufferReadInterface ) gl.getRenderer() 
191 				);
192 			} 
193 		}
194 
195 		if ( paused ) return;
196 
197 		rotation.add( 0.1f );
198 	}
199 
200 	/*** 
201 	 * 
202 	 * println
203 	 * 
204 	 * @param o
205 	 * 
206 	 */
207 	public void println( Object o ) {
208 		System.out.println( o );
209 	}
210 
211 	/*** 
212 	 * 
213 	 * frame
214 	 * 
215 	 */
216 	public void frame() {
217 		frame( 500, 350 );
218 	}
219 	
220 	/*** 
221 	 * 
222 	 * frame
223 	 * 
224 	 * @param w
225 	 * @param h
226 	 * 
227 	 */
228 	public void frame( int w, int h ) {
229 		JFrame frame = new JFrame( "AppletBase" );
230 		this.createUI( frame, w, h );
231 		
232 		frame.addWindowListener( new WindowAdapter() {
233 			public void windowClosing( WindowEvent e ) {
234 				System.exit( 0 );
235 			}
236 		} );
237 		
238 		frame.setVisible( true );
239 	}
240 
241 	/*** 
242 	 * 
243 	 * actionPerformed
244 	 * 
245 	 * @param e
246 	 * 
247 	 */
248 	public void actionPerformed( ActionEvent e ) {
249 		printRates();
250 		System.exit( 0 );
251 	}
252 
253 	////////////////////////////////////////////////////////////
254 
255 	/*** 
256 	 * 
257 	 * printRates
258 	 * 
259 	 */
260 	public float printRates() {
261 		long now = System.currentTimeMillis();
262 		long timeDiff = now - startTime;
263 		float secs = ( timeDiff ) / 1000.0f;
264 		float fps = fcount / secs;
265 		System.out.println( fcount + "/" + secs + "=" + fps + " fps" );
266 		if ( secs > 10 ) {
267 			startTime = now;
268 			fcount = 0;
269 		}
270 		return fps;
271 	}
272 
273 	////////////////////////////////////////////////////////////
274 	// KeyListener
275 
276 	/*** 
277 	 * 
278 	 * keyReleased
279 	 * 
280 	 * @param e
281 	 * 
282 	 */
283 	public void keyReleased( KeyEvent e ) {
284 	}
285 	
286 	/*** 
287 	 * 
288 	 * keyTyped
289 	 * 
290 	 * @param e
291 	 * 
292 	 */
293 	public void keyTyped( KeyEvent e ) {
294 	}
295 	
296 	/*** 
297 	 * 
298 	 * keyPressed
299 	 * 
300 	 * @param e
301 	 * 
302 	 */
303 	public void keyPressed( KeyEvent e ) {
304 		switch( e.getKeyCode() ) {
305 			case KeyEvent.VK_SPACE: fx.statiq(); break;
306 			case KeyEvent.VK_S: printRates(); break;
307 			case KeyEvent.VK_P:	paused = !paused; break;
308 			case KeyEvent.VK_Q: System.exit( 0 ); break;
309 			case KeyEvent.VK_R:
310 				fcount = 0;
311 				startTime = System.currentTimeMillis();
312 				break;
313 			default:
314 				//System.out.println( "" + " e = " + e );
315 		}
316 	}
317 
318 	////////////////////////////////////////////////////////////
319 	// MouseListener
320 
321 	/*** 
322 	 * 
323 	 * mousePressed
324 	 * 
325 	 * @param e
326 	 * 
327 	 */
328 	public void mousePressed( MouseEvent e ) {
329 		printRates();
330 		paused = true;
331 		mx = e.getX();
332 		my = e.getY();
333 		requestFocus();
334 	}
335 
336 	/*** 
337 	 * 
338 	 * mouseReleased
339 	 * 
340 	 * @param e
341 	 * 
342 	 */
343 	public void mouseReleased( MouseEvent e ) {
344 		requestFocus();
345 	}
346 
347 	/*** 
348 	 * 
349 	 * mouseClicked
350 	 * 
351 	 * @param e
352 	 * 
353 	 */
354 	public void mouseClicked( MouseEvent e ) {
355 	}
356 	
357 	/*** 
358 	 * 
359 	 * mouseEntered
360 	 * 
361 	 * @param e
362 	 * 
363 	 */
364 	public void mouseEntered( MouseEvent e ) {
365 		requestFocus();
366 	}
367 	
368 	/*** 
369 	 * 
370 	 * mouseExited
371 	 * 
372 	 * @param e
373 	 * 
374 	 */
375 	public void mouseExited( MouseEvent e ) {
376 	}
377     
378 	////////////////////////////////////////////////////////////
379 	// MouseMotionListener
380 	
381 	/*** 
382 	 * 
383 	 * mouseDragged
384 	 * 
385 	 * @param e
386 	 * 
387 	 */
388 	public void mouseDragged( MouseEvent e ) {
389 		requestFocus();
390 		int xd = e.getX() - mx;
391 	  	int yd = e.getY() - my;
392 
393 		float xf = xd / ( float ) ( gl.getRenderer().getWidth() );
394 		float yf = yd / ( float ) ( gl.getRenderer().getHeight() );
395 
396 		float f = 44.0f / 7.0f;
397 		rotation.setY( xf * f );
398 		rotation.setX( yf * f );
399 	}
400 	
401 	/*** 
402 	 * 
403 	 * mouseMoved
404 	 * 
405 	 * @param e
406 	 * 
407 	 */
408 	public void mouseMoved( MouseEvent e ) {
409 	}
410 
411 	/*** 
412 	 * 
413 	 * getGl
414 	 * 
415 	 * @return a LiboGrafInterface
416 	 * 
417 	 */
418 	public LiboGrafInterface getGl() {
419 		if ( null == gl ) {
420 			gl = LiboGraf.createLiboGrafInterface( this );
421 			if ( null != gl ) {
422 				gl.init( this );
423 			}
424 		}
425 		return gl;
426 	}
427 
428 	/*** 
429 	 * 
430 	 * switchRenderer
431 	 * 
432 	 * @param rname
433 	 * 
434 	 */
435 	public void switchRenderer( String rname ) {
436 		this.rname = rname;
437 	}
438 
439 	/*** 
440 	 * 
441 	 * testHarness
442 	 * 
443 	 * @return a float
444 	 * 
445 	 */
446 	public float testHarness() {
447 		restart();
448 
449 		// juice the goose
450 		do { 
451 			drawFrame();
452 		} while ( ( System.currentTimeMillis() - startTime ) / 1000.0 < 10 );
453 
454 		// kick it!
455 		restart();
456 		while ( fcount < 2600 ) {
457 			drawFrame();
458 		}
459 		
460 		// fps it
461 		long now = System.currentTimeMillis();
462 		long timeDiff = now - startTime;
463 		float secs = ( timeDiff ) / 1000.0f;
464 		return fcount / ( ( timeDiff ) / 1000.0f );
465 	}
466 
467 	/*** 
468 	 * 
469 	 * setPerformanceTest
470 	 * 
471 	 * @param newValue
472 	 * 
473 	 */
474 	public void setPerformanceTest( boolean newValue ) {
475 		performanceTest = newValue;
476 	}
477 
478 	//////////////
479 
480 	private final void badJoke() {
481 		
482 		///gl = LiboGraf.createLiboGrafInterface( this );
483 		getGl();
484 		
485 		int[] sk = { 0x0000FF00 };
486 		skin = new ImageSkin( 1, 1, sk );
487 		
488 		fx = new BufferFx( gl.getRenderer() );
489 
490 		gl.getRenderer().addDrawer( this );
491 
492 		initImpl( w, h );
493 	}
494 
495 	private void init( int w, int h ) {
496 		this.w = w;
497 		this.h = h;
498 		
499 		setSize( new Dimension( w, h ) );
500 
501 		addKeyListener( this );
502 		addMouseListener( this );
503 		addMouseMotionListener( this );
504 	}
505 
506 	private void createUI( JFrame frame, int w, int h ) {
507 		Container main = frame.getContentPane();
508 
509 		JMenuBar menuBar = new JMenuBar();
510 		frame.setJMenuBar( menuBar );
511 		
512 		JMenu menu = new JMenu( "File" );
513 		menu.setMnemonic( KeyEvent.VK_F );
514 		menuBar.add( menu );
515 
516 		JMenuItem menuItem = new JMenuItem( "Quit", KeyEvent.VK_Q );
517 		menu.add( menuItem );
518 		menuItem.addActionListener( this ); 
519 		
520 		main.setLayout( new BorderLayout() );
521 
522 		init( w, h );
523 		main.add( this, BorderLayout.CENTER );
524 		this.start();
525 
526 		frame.addKeyListener( this );
527 
528 		main.add( this );
529 		frame.setSize( w, h );	
530 	}
531 
532 	/*** 
533 	 * 
534 	 * the5k
535 	 * 
536 	 */
537 	private final void the5k() {
538 		
539 		long timeDiff = System.currentTimeMillis() - startTime;
540 		float secs = ( timeDiff ) / 1000.0f;
541 
542 		if ( secs < 30 ) {
543 			whenPerf *= 2;
544 		} else {
545 
546 			String aname = getClass().getName();
547 			String rname = gl.getRenderer().getClass().getName();
548 
549 			aname = aname.substring( 1 + aname.lastIndexOf( "." ) );
550 			rname = rname.substring( 1 + rname.lastIndexOf( "." ) );
551 			
552 			System.out.println( 
553 				"Rate\t" +
554 				rname + "@" + aname +
555 				"\t" + 
556 				fcount + "/" + secs + 
557 				"=" + 
558 				fcount / secs 
559 			);
560 
561 			if ( performanceTest ) {
562 				keepRunning = false;
563 			}
564 		}
565 	}
566 
567 	/*** 
568 	 * 
569 	 * restart
570 	 * 
571 	 */
572 	public void restart() {
573 		keepRunning = true;
574 		startTime = System.currentTimeMillis();
575 		fcount = 0;
576 	}
577 		
578 	/*** 
579 	 * 
580 	 * frame
581 	 * 
582 	 * @return a protected
583 	 * 
584 	 */
585 	protected final void drawFrame() {
586 		thread.setPriority( Thread.MAX_PRIORITY );
587 		repaint();
588 		thread.setPriority( Thread.MIN_PRIORITY );
589 		thread.yield();
590 	}
591 	
592 	////////////////////////////////////////////////////////////
593 
594 	private void setShade( int shade_mode ) {
595 		String shadeType[] = { "NONE", "NORM", "DEPTH", "PHONG" };
596 		shade_mode %= 4;
597 		switch( shade_mode ) {
598 			case 0: gl.getRenderer().setShadingMethod( M3_Constants.NONE_SHADE );  break;
599 			case 1: gl.getRenderer().setShadingMethod( M3_Constants.NORM_SHADE );  break;
600 			case 2: gl.getRenderer().setShadingMethod( M3_Constants.DEPTH_SHADE ); break;
601 			case 3: gl.getRenderer().setShadingMethod( M3_Constants.PHONG_SHADE ); break;
602 		}
603 		System.out.println( "shade_mode = " + shade_mode + " : " + shadeType[ shade_mode ] );
604 	}
605 
606 	////////////////////////////////////////////////////////////
607 
608 	protected boolean paused = false;
609 	
610 	protected int mx, my;
611 
612 	private int whenPerf = 5000;
613 	protected int fcount = 0;
614 	protected Thread thread = null;
615 	protected long startTime = System.currentTimeMillis();
616 
617 	protected BufferFx fx;
618 
619 	protected LiboGrafInterface gl = null;
620 	protected Pt3 rotation = new Pt3();
621 
622 	protected ImageSkin skin = null;
623 
624 	protected int shade_mode = 1;
625 	protected int w = 0, h = 0;
626 
627 	private String rname = null;
628 
629 	private boolean performanceTest = false;
630 	private boolean keepRunning = true;
631 };
632 
633 /***
634  *
635  * $Log: AppletBase.java,v $
636  * Revision 1.15  2005/03/29 02:38:33  brian
637  * trying to round out perf testing stuff
638  *
639  * Revision 1.14  2005/03/26 23:42:41  brian
640  * fix links
641  *
642  * Revision 1.13  2005/03/26 03:38:11  brian
643  * don't auto unpause onMouseUp
644  *
645  * Revision 1.12  2005/03/21 05:56:22  brian
646  * reset counter after 10sec if polled...
647  *
648  * Revision 1.11  2005/03/21 05:52:12  brian
649  * add enuff stuff to be able to calc pps (polygons per second)
650  *
651  * Revision 1.10  2005/03/21 00:42:11  brian
652  * reorg, comment public methods, reset fps after print...
653  *
654  * Revision 1.9  2005/03/19 17:50:02  brian
655  * repackaging
656  *
657  * Revision 1.8  2005/03/11 23:35:31  brian
658  * major refactoring to add in com.insanityengine.ghia.libograf.State bitz
659  *
660  * Revision 1.7  2004/09/16 11:07:45  brian
661  * don't clear depth buffer by default each frame and allow size to be passed into frame method
662  *
663  * Revision 1.6  2004/09/11 21:27:10  brian
664  * rework perf test
665  *
666  * Revision 1.5  2004/09/11 20:08:46  brian
667  * added timing testing infrastructure...
668  *
669  * Revision 1.4  2004/09/11 19:32:29  brian
670  * effects of adding LiboGrafInterface
671  *
672  * Revision 1.3  2004/09/11 14:37:21  brian
673  * added RendererConsumer and stuff
674  *
675  * Revision 1.2  2004/09/05 03:41:31  brian
676  * refactored to have the render method of the renderers invoke the drawingIfz
677  *
678  * Revision 1.1  2004/09/02 13:17:16  brian
679  * the big reorg
680  *
681  * Revision 1.7  2004/09/01 01:10:42  brian
682  * fix class level javadoc placement
683  *
684  * Revision 1.6  2004/09/01 00:11:06  brian
685  * author, log and header stuff
686  *
687  *
688  */