Need for speed
I beleive this program implements the fastest drawing "algorithm" possible in Java. Is it possible to speed it up? Can volatile images be used. Anyone?
import java.awt.*;
import java.awt.image.*;
publicclass Test3
{
publicstaticvoid main(String [] args)
{
try
{
Frame frame =new Frame();
frame.setSize(700,700);
frame.setVisible(true);
int [] pixels =newint[600 * 600];
DirectColorModel colorModel =new DirectColorModel(24, 0x00FF0000, 0x0000FF00, 0x000000FF);
MemoryImageSource source =new MemoryImageSource(600, 600, colorModel, pixels, 0, 600);
source.setAnimated(true);
Image image = frame.createImage(source);
Graphics graphics = frame.getGraphics();
for (int j=0;;)
{
long t = System.currentTimeMillis();
for (int c=0;c<100;c++,j++)
{
for (int n=pixels.length; --n>=0;) pixels[n] = n+j;
source.newPixels();
graphics.drawImage(image, 50, 50,null);
}
System.out.println((System.currentTimeMillis()-t)/100f);
}
}
catch (Exception e)
{
e.printStackTrace();
}
}
}
Sorry, should have tested Volatile images with the new version of java. Apparently performance has improved considerably since I last tested it.
This code uses a Volatile image, can this code be improved? Is int buffer the best way to access a raster buffer?
import java.awt.*;
import java.awt.image.*;
public class Test3
{
public static void main(String [] args)
{
try
{
Frame frame = new Frame();
frame.setSize(700,700);
frame.setVisible(true);
int [] pixels = new int[600 * 600];
DirectColorModel colorModel = new DirectColorModel(24, 0x00FF0000, 0x0000FF00, 0x000000FF);
MemoryImageSource source = new MemoryImageSource(600, 600, colorModel, pixels, 0, 600);
source.setAnimated(true);
Image image = frame.createImage(source);
Graphics graphics = frame.getGraphics();
VolatileImage volatileImage = frame.createVolatileImage(600, 600);
for (int j=0;;)
{
long t = System.currentTimeMillis();
for (int c=0;c<100;c++,j++)
{
for (int n=pixels.length; --n>=0;) pixels[n] = n+j;
source.newPixels();
do
{
if (volatileImage.validate(frame.getGraphicsConfiguration()) == VolatileImage.IMAGE_INCOMPATIBLE)
{
volatileImage = frame.createVolatileImage(600, 600);
}
Graphics2D g = volatileImage.createGraphics();
g.drawImage(image, 0, 0, null);
g.dispose();
}
while (volatileImage.contentsLost());
graphics.drawImage(volatileImage, 50, 50, null);
}
System.out.println((System.currentTimeMillis()-t)/100f);
}
}
catch (Exception e)
{
e.printStackTrace();
}
}
}
Use a BufferStrategy. This will pipe you directly into the hardware and allow you to accelerate your app to its maximum speed. Here's my example of using BufferStrategy:
http://java.dnsalias.com/duke
With page-flipping (which is locked into the monitor's refresh rate) it runs at 60 fps. Without, it runs at somewhere between 200-400 FPS.
Thanks jbanes!
The buffer strategy made a tiny improvement. My code now performs a massive 40 fps (P3 500 mHz Riva TNT 2).
import java.awt.*;
import java.awt.image.*;
public class Test3
{
public static void main(String [] args)
{
try
{
Frame frame = new Frame();
frame.setSize(700,700);
frame.setVisible(true);
int [] pixels = new int[600 * 600];
DirectColorModel colorModel = new DirectColorModel(24, 0x00FF0000, 0x0000FF00, 0x000000FF);
MemoryImageSource source = new MemoryImageSource(600, 600, colorModel, pixels, 0, 600);
source.setAnimated(true);
Image image = frame.createImage(source);
frame.createBufferStrategy(2);
BufferStrategy strategy = frame.getBufferStrategy();
for (int j=0;;)
{
long t = System.currentTimeMillis();
for (int c=0;c<100;c++,j++)
{
for (int n=pixels.length; --n>=0;) pixels[n] = n+j;
source.newPixels();
Graphics g = strategy.getDrawGraphics();
g.drawImage(image, 50, 50, null);
strategy.show();
}
System.out.println((System.currentTimeMillis()-t)/100f);
}
}
catch (Exception e)
{
e.printStackTrace();
}
}
}
Cool game!It runs at 80 fps on my PC. Main differences is that you only draw the blocks and Duke whilst I paint an entire frame buffer and then draws that as a single image.
BTW, what are you trying to accomplish? Most actual games will blit cached images to the screen, which is MUCH faster than the pixel by pixel stuff you're doing here. The reason is, that images can be cached and internally scaled, sheared, rotated, and blitted inside the hardware. All you're accomplishing here is to see how fast your CPU can generate an image and dump it through the AGP bus.
I'm doing lots of things, building a 3D engine, similar to Java3D but in software. And my latest project is a "dungeon game". I could probably use some of the 2D graphics offered by Java but it would make things complicated.
Just a thought, but your performance could be improved by using Affine texturing in your engine. Affine is where you rotate and scale an image so that it "looks" 3D when applied, but actually takes advantage of 2D rendering hardware. The type you want in particular is Perspective Affine. Otherwise, the textures wouldn't look correct to a keen eye. Doing "perfect" point-by-point rendering is too slow, that's why 3D cards are popular.
Oh, and if you liked Duke Nukes Stuff, try doing a search on the 'net for "Meat Fighter". You'll be pleasently surprised. :-)