Hi, I noticed you’re using createCompatibleImage(), you should use createCompatibleVolatileImage(), only then can you be relatively assured the image is accelerated.
Here’s a side scrolling thingy I wrote. Compare the speeds. In my tests there were definite performance improvements.
Some comments on this code. The display mode is hardcoded. It’s not checking for available display modes before doing the switch, so you should know beforehand what’s supported by your system. you can change it in the constructor, reference name ‘fullScreenMode’. alt-enter to switch into full screen.
Don’t take this code as the correct way to run a rendering loop though. I hacked it up today. The correct way should turn off paint events.
Well, hope it helps,
Seb
import java.awt.*;
import java.awt.image.*;
import java.awt.event.*;
public class GraphicsTest2 extends Frame implements KeyListener {
final static int WIDTH = 640, HEIGHT = 480;
Map map;
int offset;
String sync = "SEMAFORO";
GraphicsEnvironment ge;
GraphicsDevice gd;
DisplayMode normalMode, fullScreenMode;
boolean fullScreen;
public GraphicsTest2() {
ge = GraphicsEnvironment.getLocalGraphicsEnvironment();
gd = ge.getDefaultScreenDevice();
normalMode = gd.getDisplayMode();
fullScreenMode = new DisplayMode( WIDTH, HEIGHT, 32, DisplayMode.REFRESH_RATE_UNKNOWN );
fullScreen = false;
setUndecorated( true );
map = new GraphicsTest2.Map();
// map.setGraphicsConfiguration( gd.getDefaultConfiguration() );
offset = 0;
setBounds( 0, 0, WIDTH, HEIGHT );
addKeyListener( this );
setVisible( true );
}
public void paint( Graphics g ) {
synchronized ( sync ) {
GraphicsConfiguration gc = ( (Graphics2D) g ).getDeviceConfiguration();
for ( int y = 0; y < (HEIGHT >> 4); y++ ) {
for (int x = 0; x < (WIDTH >> 4); x++ ) {
g.drawImage( map.getTile( gc, x, y ), ( (x<<4)+offset)%WIDTH, y<<4, null );
// g.drawImage( map.tiles[ map.bitmap[x][y] ], ( (x<<4)+offset)%640, y<<4, null );
}
}
}
}
public void update( Graphics g ) {
paint(g);
}
public void setFullScreen( boolean yes ) {
if ( yes && ! fullScreen ) {
gd.setFullScreenWindow( this );
gd.setDisplayMode( fullScreenMode );
fullScreen = true;
} else if ( !yes && fullScreen ) {
gd.setDisplayMode( normalMode );
gd.setFullScreenWindow( null );
fullScreen = false;
}
}
public boolean getFullScreen() {
return fullScreen;
}
public void keyTyped( KeyEvent ke ) {
}
public void keyPressed( KeyEvent ke ) {
if ( ke.getKeyCode() == KeyEvent.VK_ENTER && ke.isAltDown() ) {
setFullScreen( !getFullScreen() );
}
if ( ke.getKeyCode() == KeyEvent.VK_ESCAPE ) {
setFullScreen( false );
System.exit( 0 );
}
}
public void keyReleased( KeyEvent ke ) {
}
public void setOffset( int i ) {
synchronized ( sync ) {
offset = i;
}
}
public Object getSync() {
return sync;
}
public static void main( String[] args ) {
GraphicsTest2 window = new GraphicsTest2();
while( true ) {
for ( int j = 0; j< 640; j++ ) {
synchronized ( window.getSync() ) {
window.setOffset( j );
}
window.repaint();
}
}
}
class Map {
static final int MAX_TILES = 128;
byte[][] bitmap;
Image[] tiles;
VolatileImage[] volatiles;
public Map() {
createTiles();
volatiles = new VolatileImage[MAX_TILES];
System.out.println( "Map constructor done." );
createMap();
}
public final Image getTile( GraphicsConfiguration gc, int x, int y ) {
int tileId = bitmap[x][y];
VolatileImage img = volatiles[ tileId ];
if ( img == null ) {
volatiles[ tileId ] = img = gc.createCompatibleVolatileImage( 16, 16 );
renderVolatile( img, tiles[ tileId ] );
} else {
int returnCode = img.validate( gc );
if ( returnCode == VolatileImage.IMAGE_INCOMPATIBLE ) {
img.flush();
volatiles[ tileId ] = img = gc.createCompatibleVolatileImage( 16, 16 );
renderVolatile( img, tiles[ tileId ] );
} else if ( returnCode == VolatileImage.IMAGE_RESTORED ) {
renderVolatile( img, tiles[ tileId ] );
}
}
return img;
}
private final void renderVolatile( VolatileImage vImg, Image img ) {
Graphics2D g = vImg.createGraphics();
g.drawImage( img, 0, 0, null );
}
private void createMap() {
System.out.println( "Creating map bytemap..." );
bitmap = new byte[64][48];
for ( int y = 0; y < 48; y++ ) {
for (int x = 0; x < 64; x++ ) {
bitmap[x][y] = (byte) ( (x*y) % 128 );
}
}
}
private void createTiles() {
System.out.println( "Creating tiles..." );
tiles = new Image[MAX_TILES];
Font f = new Font( "SansSerif", Font.PLAIN, 16 );
for ( int i = 0; i < 128; i++ ) {
BufferedImage img = new BufferedImage( 16, 16, BufferedImage.TYPE_INT_RGB );
Graphics2D g = img.createGraphics();
g.drawString( Integer.toString( i, 16 ), 0, 14 );
tiles[i] = img;
}
}
}
}