Accelerated Java?

Hi!

I’ve just begun creating a framework for 2D games in Java, and I have read some of the posts here. I have set up some code to test the things I have learned so far, but something seems på be wrong. It’s just a small demo that runs for 5 seconds and then shows you the framerate. It draws 1000 sprites @ 128 x 128 as fast as possible (no sleeps). I just made it to find out how to get the best performance from Java2D.

This is the testcode (I outcommented fullscreen for testing purposes):

package main;

import java.awt.;
import java.awt.image.
;
import javax.swing.JFrame;

public class Main extends JFrame implements Runnable
{
private static final long serialVersionUID = 1L;
private GraphicsConfiguration gc;
private GraphicsDevice gd;
private BufferStrategy buffer;
private BufferedImage bImage;

public Main()
{
	setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
	setUndecorated(true);
	setSize(800, 600);
	setVisible(true);
	setIgnoreRepaint(true);
}

public void start()
{
	gc = getGraphicsConfiguration();
	gd = gc.getDevice();
	//gd.setFullScreenWindow(this);
	//gd.setDisplayMode(new DisplayMode(800, 600, 16, 60));
	createBufferStrategy(2);
	buffer = getBufferStrategy();
	bImage = gc.createCompatibleImage(128, 128);
	new Thread(this).start();
}

public static void main(String args[])
{
	Main main = new Main();
	main.start();
}

public void run()
{
	double fps = 0;
	long frames = 0;
	Graphics2D g;
	long startTime = System.nanoTime() / 1000000L;
	long lastFrame = startTime;
	
	while (lastFrame <= (startTime + 5000))
	{
		g = (Graphics2D)buffer.getDrawGraphics();
		g.clearRect(0, 0, 800, 600);
		g.setColor(Color.BLUE);
		
		for (int i = 0; i < 1000; i++)
			g.drawImage(bImage, 100, 100, null);
		
		g.drawString(String.valueOf(fps), 50, 50);
		g.dispose();
		
		if (!buffer.contentsLost())
			buffer.show();
		
		frames++;
		lastFrame = System.nanoTime() / 1000000L;
		fps = (double)frames / (lastFrame - startTime) * 1000;
	}
	
	System.out.println(fps);
	System.exit(0);
}

}

And this is the trace count:

220 calls to sun.java2d.loops.DrawGlyphList::DrawGlyphList(OpaqueColor, SrcNoEa, AnyInt)
220220 calls to sun.awt.windows.Win32BlitLoops::Blit(“Integer RGB DirectDraw”, SrcNoEa, “Integer RGB DirectDraw”)
1 call to GDIFillRect
2 calls to sun.java2d.loops.Blit::Blit(IntRgb, SrcNoEa, IntRgb)
226 calls to DDFillRect
220669 total calls to 5 different primitives

But from what I’ve read on the forums, I shouldn’t have those Win32BlitLoops, the should be D3DBlitLoops, right? So, what am I doing wrong? I’m not using any -D (other than trace). I’m running Java 1.5 on an XP Pro machine @ Athlon XP 2500+ with 1 GB RAM, with a GeForce FX 5700 Ultra, for those of you who just have to know! :slight_smile:

Please help me, it’s driving me insane! :slight_smile: And by the way, is there anything that can be done better? (Except the fact that I need to do some Thread.sleep() between render cycles)?

I can’t see any problem with your code, though creating the main window should be in a seperate class instead of the main one. It doesn’t make much difference in a demo, but it’s much easier in real programs.

Are the results similar for full-screen mode? I don’t know much about it, but maybe DirectDraw is only for full-screen mode.

Your code doesn’t seem to fundamentally different from the code I wrote for the same thing, so I don’t know what to tell you. If you haven’t already, you should buy a book about Java game programming. It seems likely that you already have.

If you like, I could post my own code, which has some additional code that makes it safe to use with Swing, but I doubt that would effect your problem.

My advice to you is not to worry. It’s fast enough, isn’t it? Does it really matter whether it uses DirectDraw or not?

get the BufferCapabilities of your BufferStrategy and BufferedImage and find out whether they’re accelerated. If they are, then it’s apples, acceleration is being used.

On windows, setting fullscreen and doing bufferStrat.createBufferStrategy(3) may give you page-flipping rather than blitting (for the buffer strat only, not the BufferedImage), which may be faster, and it will lock the frame rate to the vertical retrace of the screen, preventing ‘tearing’ (but then you can’t get FPS > screen refresh).

In 1.5 the Direct3D pipeline is very incomplete, so you won’t get much out of it.

Were you not satisfied with the DirectDraw pipeline results? Win32BlitLoops::Blit
is a DirectDraw blit.

You can try the Direct3D pipeline in 1.6 (with -Dsun.java2d.d3d=true), or you can also
try the OpenGL pipeline in 1.5 or 1.6. Note that there may be driver issues with the OGL
pipeline, so make sure you have the latest drivers (although some problems aren’t fixed
even in those).

Thanks,
Dmitri

Hello,

Just because of interest, the D3D pipeline does basically the same things that the OpenGL pipeline does (except the stuff you mentioned in your article), using more or less the same functionality of the underlayig graphic apis, right?
But why do even many really old boards work fine with the d3d pipeline whereas the OpenGL pipeline only works on some cards and only with latest drivers installed?

Is D3D easier to implement for driver programmers, or is OpenGL more complex.
Or are OpenGL implementations more likely to be broken since they don’t get that much attention from consumers?

Thank you in advance, lg Clemens

Thank you for your replies.

And to the most of you; yes, I do get the performance I need. But I just became a bit confused because of the many threads mentioning the D3DBlitLoops. It’s simply because I prefer to do things “as right as possible” from the start, to prevent a lot of re-coding.

Once again, thank you all! :slight_smile: