// ActiveRenderingTestApplet.java Copyright (c) Kari Laitinen // http://www.naturalprogramming.com // 2007-11-21 File created. // 2007-11-22 Latest modification. /* This program demonstrates so-called active rendering. Active rendering means that a program actively decides when it wants to draw its drawings to its window. Active rendering is thus a kind of opposite to using the repaint() and paint() methods, the use of which can be described as "passive rendering". By using active rendering drawing operations are faster, which is necessary, for example, when game programs are written. This program shows a moving "worm" on the screen. It thus resembles WormApplet.java that can be found among my programs. The worm of this program may be drawn almost hundred times per second to the screen. The number of drawings (frames) per second depends on the used computer. The picture of the worm on the screen is "beautiful" regardless of the high drawing speed. This is the result of the use of active rendering. This program is based on a prorgram presented by Tim Wright (See: http://www.gamedev.net/reference/articles/article2418.asp) java.sun.com also provides articles related to active rendering. */ import java.awt.* ; import javax.swing.* ; import javax.swing.event.* ; import java.awt.image.BufferStrategy; import java.awt.image.BufferedImage; import java.util.Random; public class ActiveRenderingTestApplet extends JApplet implements Runnable { int applet_width, applet_height ; Thread animation_thread = null ; boolean thread_must_be_executed = false ; BufferedImage offscreen_drawing_surface ; BufferStrategy buffer_strategy ; // Objects needed for rendering... Graphics graphics = null; Graphics2D graphics2D = null; Color background_color = Color.BLACK; // Variables for counting frames per seconds int frames_per_second = 0; int frames_during_last_second = 0; long total_time = 0; long current_time = System.currentTimeMillis(); long previous_time = current_time; public void init() { applet_width = getSize().width ; applet_height = getSize().height ; setIgnoreRepaint( true ) ; // Create canvas for painting... Canvas canvas_for_drawing = new Canvas(); canvas_for_drawing.setIgnoreRepaint( true ); canvas_for_drawing.setSize( applet_width, applet_height ); // Add canvas_for_drawing to this applet add( canvas_for_drawing ); // Create BackBuffer... canvas_for_drawing.createBufferStrategy( 2 ); buffer_strategy = canvas_for_drawing.getBufferStrategy(); // Get graphics configuration... GraphicsEnvironment graphics_environment = GraphicsEnvironment.getLocalGraphicsEnvironment() ; GraphicsDevice graphics_device = graphics_environment.getDefaultScreenDevice() ; GraphicsConfiguration graphics_configuration = graphics_device.getDefaultConfiguration() ; // Create off-screen drawing surface offscreen_drawing_surface = graphics_configuration.createCompatibleImage( applet_width, applet_height ) ; } public void start() { if ( animation_thread == null ) { animation_thread = new Thread( this ) ; thread_must_be_executed = true ; animation_thread.start() ; } System.out.print( "\n Method start() executed. " ) ; } public void stop() { if ( animation_thread != null ) { animation_thread.interrupt() ; thread_must_be_executed = false ; animation_thread = null ; } System.out.print( "\n Method stop() executed. " ) ; } public void run() { System.out.print( "\n Method run() started." ) ; final int INITIAL_WORM_LENGTH = 100 ; final int WORM_HEIGHT = 30 ; final int MAXIMUM_WORM_STRETCHING = 35 ; int current_worm_length = INITIAL_WORM_LENGTH ; int worm_position_x = - INITIAL_WORM_LENGTH ; boolean worm_is_stretching = true ; Color worm_color = Color.YELLOW ; while ( thread_must_be_executed == true ) { try { // count Frames per second... previous_time = current_time ; current_time = System.currentTimeMillis() ; total_time += current_time - previous_time ; if( total_time > 1000 ) { total_time -= 1000; frames_per_second = frames_during_last_second ; frames_during_last_second = 0 ; } frames_during_last_second ++ ; // clear back buffer... graphics2D = offscreen_drawing_surface.createGraphics(); graphics2D.setColor( background_color ); graphics2D.fillRect( 0, 0, applet_width, applet_height ); // draw a "worm" to the screen graphics2D.setColor( worm_color ) ; graphics2D.fillRoundRect( worm_position_x, ( applet_height - WORM_HEIGHT ) / 2, current_worm_length, WORM_HEIGHT, 20, 20); // We'll adjust current_worm_length and worm_position_x // for the next drawing operation. if ( worm_is_stretching == true ) { current_worm_length ++ ; if ( current_worm_length - INITIAL_WORM_LENGTH >= MAXIMUM_WORM_STRETCHING ) { worm_is_stretching = false ; } } else { current_worm_length -- ; worm_position_x ++ ; if ( current_worm_length <= INITIAL_WORM_LENGTH ) { worm_is_stretching = true ; } } if ( worm_position_x >= applet_width ) { // Next time the worm will be back in its initial position worm_position_x = - INITIAL_WORM_LENGTH ; current_worm_length = INITIAL_WORM_LENGTH ; } // display frames per second... graphics2D.setFont( new Font( "Courier New", Font.PLAIN, 12 ) ); graphics2D.setColor( Color.GREEN ); graphics2D.drawString( "FRAMES PER SECOND: " + frames_per_second, 20, 20 ); // Blit image and flip... graphics = buffer_strategy.getDrawGraphics(); graphics.drawImage( offscreen_drawing_surface, 0, 0, null ) ; if( ! buffer_strategy.contentsLost() ) { buffer_strategy.show(); } //Thread.yield(); // give processor time to other threads } finally { // release resources if( graphics != null ) { graphics.dispose() ; } if( graphics2D != null ) { graphics2D.dispose() ; } } try { Thread.sleep( 10 ) ; } catch ( InterruptedException caught_exception ) { thread_must_be_executed = false ; } } System.out.print( "\n Method run() stopped. " ) ; } } /**** The following is the first version of the run() method. It draws 20 random rectangles onto each frame. public void run() { System.out.print( "\n Method run() started." ) ; Random random_number_generator = new Random(); while ( thread_must_be_executed == true ) { try { // count Frames per second... previous_time = current_time ; current_time = System.currentTimeMillis() ; total_time += current_time - previous_time ; if( total_time > 1000 ) { total_time -= 1000; frames_per_second = frames_during_last_second ; frames_during_last_second = 0 ; } frames_during_last_second ++ ; // clear back buffer... graphics2D = offscreen_drawing_surface.createGraphics(); graphics2D.setColor( background_color ); graphics2D.fillRect( 0, 0, applet_width, applet_height ); // draw some rectangles... for( int rectangle_count = 0 ; rectangle_count < 20 ; rectangle_count ++ ) { int r = random_number_generator.nextInt(256); int g = random_number_generator.nextInt(256); int b = random_number_generator.nextInt(256); graphics2D.setColor( new Color(r,g,b) ); int x = random_number_generator.nextInt( applet_width/2 ); int y = random_number_generator.nextInt( applet_height/2 ); int w = random_number_generator.nextInt( applet_width/2 ); int h = random_number_generator.nextInt( applet_height/2 ); graphics2D.fillRect( x, y, w, h ); } // display frames per second... graphics2D.setFont( new Font( "Courier New", Font.PLAIN, 12 ) ); graphics2D.setColor( Color.GREEN ); graphics2D.drawString( String.format( "FPS: %s", frames_per_second ), 20, 20 ); // Blit image and flip... graphics = buffer_strategy.getDrawGraphics(); graphics.drawImage( offscreen_drawing_surface, 0, 0, null ) ; if( ! buffer_strategy.contentsLost() ) { buffer_strategy.show(); } Thread.yield(); // give processor time to other threads } finally { // release resources if( graphics != null ) { graphics.dispose() ; } if( graphics2D != null ) { graphics2D.dispose() ; } } } System.out.print( "\n Method run() stopped. " ) ; } *****/