accelerated images

Hi all!

I have two questions concerning accelerated images:

1.) Currently Im doing my all gfx stuff in int arrays. I made a wrapper
around this which will use MemoryImageSource to create images
out of the arrays when BufferedImages are not available. If BufferedImages
are available I create a bufferedimage with graphicsconfiguration.createCompatibleImage(w, h, Transparency.OPAQUE)

I get the image data with (DataBufferInt)image.getRaster().getDataBuffer();
and get its int[] contents with getData();

Will this still be accelerated? I remember reading somewhere that using getRaster
and such would prevent the bufferedimage from being accelerated?

2.) For my backbuffer I thought using volatile images would be great (if available)
But im getting very bad fps when using a volatile image to draw to the screen (compared
to writing bufferedimages or plain images directly to screen, about half the fps).

A bufferedimage is created from a int[] (see situation in q1), this bufferedimage is then
drawn onto the volatileimage (by getting the volatileimage’s graphics context). Last the
volatile image is drawn to the applet’s screen graphics. Is it performance wise good
to draw the bufferdimage to the volatileimages graphics? or would it be just as fast or
maybe faster to draw this bufferedimage directly to the screen (lets assume the bufferedimage
is not accelerated, see question nr1).

Here’s how I draw the volatileimage to the screen (assume the surface in toFront is a
non accelerated bufferedimage):

public class VolatileBackBuffer extends BackBuffer
{
protected VolatileImage buffer;
protected static Component base;
protected GraphicsConfiguration gc;
protected Graphics volatileGraphics;

public VolatileBackBuffer(Component base)
{
	this.base = base;
	gc = base.getGraphicsConfiguration();
}

public void toFront(Surface s, Graphics g)
{
	if (buffer == null) createBackBuffer(s.width,s.height);

	do
	{
		int valCode = buffer.validate(gc);
			if (valCode == VolatileImage.IMAGE_INCOMPATIBLE)
			createBackBuffer(s.width,s.height);

		volatileGraphics.drawImage(s.getImage(), 0, 0, null);
		g.drawImage(buffer, 0, 0, null);
	} while (buffer.contentsLost());
}

public void createBackBuffer(int width, int height)
{
	gc = base.getGraphicsConfiguration();
	buffer = gc.createCompatibleVolatileImage(width, height);
	volatileGraphics = buffer.getGraphics();
}

}

Any help is greatly appreciated!

  1. No, it will not be accelerated.
  2. Faster to draw BufferedImage directly to the screen.

Hmmm short and clear answer =)

But this raises new ones ::slight_smile:

1.) What are the conditions so a bufferedimage might be accelerated?

2.) And what use have volatile images then? I thought they where mainly used as backbuffers?

Thanks!

When an Image is accelerated, it is kept in video memory. BufferedImages may get accelerated when you use create compatible image. However I’m pretty certain that requesting the underlying byte structure will get it unaccelerated again, because that array must be in processor memory, not video memory.

Image acceleration (volatileImage) is for the case where you create the image once (e.g. a sprite) and then regularly draw it to the screen. Provided you don’t start drawing on the sprite it can remain in video memory and stay accelerated.

So if you create an ImageBuffer to draw on, perhaps directly using its underlying byte array, then it won’t get accelerated. When you draw it on the screen, the current version in processor memory must be transferred to video memory. This is the slow non-accelerated operation. However you need it and just have to live with the slowness.

Ok, last question about this topic… really :wink:

I asked about accelerated images because I have a game that performs poorly.
It’s an applet game with an resolution of 640*550, I use int arrays to put all the pixel
data in and calculate with. I hook a surface (the memoryimagesource or bufferedimage to
it to render it to a image which I then draw to the screen.)

I did some tests, I don’t sleep or wait my main thread, I only yield to give other threads
a little air to breathe, this should draw as much fps as possible.

When I disable the draw to screen and measure how much the paint is excecuted I should be
able to measure how long the gamelogic takes for each frame drawn.

With the surfaces defined as bufferedimage: 120fps = ~8.3ms per frame
With the surfaces defined as memoryimagesource: 120fps = ~8.3ms per frame

no surprise here. I don’t blit the surface to the screen so they should be about equal.

when I enable the draw surface to screen I can measure the time nescesary to draw the image:

With the surfaces defined as bufferedimage: 50fps = 20ms per frame
With the surfaces defined as memoryimagesource: 46fps = ~21.7ms per frame

The bufferedimage is a tad faster than memoryimagesource, this isn’t surprising either.

What I do find surprising is that the paint cost about 12ms to perform. Thats over twice the
time needed to do all the gamelogic, which involves the same int buffers (even more) as the
paint should blit to the screen. :-\

How can it be that the paint takes so much processing time? Is there anything I could do to
speed things up? (and yes, I’d like to stick to crappy(?) applets :’()

Is it maybe even possible to accelerate this through jpct or something alike? (is it even
possible to support opengl through applets?)

Thanks in advance!

The slow part is transfering the data to the graphics card. I know it is sad, but there is nothing you can do about it.

To answer the other question otu there…

A Voaltile image is resident on the graphcis card. This makes it close to the screen and far from the CPU.

Drawing what is IN a VOaltile image to the creen is veryfast (can be as fast as widdling oen pointer if youa re using BufferStratgeies).

HOWEVER drawing anything from anything BUT a volatile image TO a volatile image is very slow because its a long ways for teh CPU to push data to.

To answer your last question, Voaltile images are often used for BLT data that gets drawnr epeatedly btu notmodified, for instacne tiles, and as the desintation OF those draws to build up a screen display.

Its also worth noting, since you asked about acceleration and I assume you mean hardware accelerated drawing, that 2D hardware acceleration can ONLY be done to VolatileImages. Thsi is because the video chip can only draw to video memory. That being said AWT “managed images” will do their best to user Volatile Image memory under the hood to get the best performance they can…

Ok, so if I want better performance I could:

Lower my applet resolution (why the heck does a paint take so long; a 640550 buffer takes ~12ms to paint, a 384384 buffer takes 1.8ms to paint :o)

Take advantage of volatileimages where possible: tiles, static sprites, backgrounds and alike. I suppose Im screwed when the normal/bufferedimages I draw don’t have transparancy? As when they’re drawn over the volatileimages in vram?

Yep, you’ve understood the issues.

Regarding transparency: Volatile images do support 1 bit transparency, so you have have sprites using volatile images and draw them over a background. However if you want a full alpha channel (say for anti-aliasing), then on Java 1.4.2 the images aren’t accelerated. I haven’t checked to see if this is still true with Java 1.5.

It is possible to use opengl in an applet using the LWJGL and signing the applet. However there is no way to automatically install the library using applets, so this isn’t really an option for use on the internet.

How does runescape do is rendering? it is signed, so maybe it uses OGL somehow… :stuck_out_tongue:

runescape uses an int array and it’s own software renderer. But it’s 3d view is only 512*335 pixels in size, wich is not alot compared to hw accel games. Besides, I don’t think the game needs more than 15 fps to run smooth anyway. The signing is probably to alow some networking abilities.

If you want toi use OGL yo ucna use JOGL, (and JInput and JOAL) from a signed webstarted app.

The only issue is that you cannot embed your game in an HTML frame. As logn as you dont mind gameplay happening in a seperate pop-upwindow Id strongly suggest that route…

Sorry for reincarnating this old thread, but some recent developments (http://www.java-gaming.org/forums/index.php?topic=11269.0) made me wonder…

[quote]The slow part is transfering the data to the graphics card. I know it is sad, but there is nothing you can do about it.
[/quote]
Does this also apply when I transfer my int buffers to screen mem through JOGL?
In the tests i’ve done it seemed blitting a 640*550 buffer takes ~12ms to paint, which in fact limits my applet to get 83fps at most. And thats only the blitting, not to mention the gamelogic which also probably takes up to ~10msec for the operations on all int arrays which about halves it to 45fps.

I can’t believe its the physical databus that implies this limitation… I’ve seen software renderers that produced higher framerates at even higher resolutions… It’s probably Java’s Graphics implementation that’s causing this? If so, will blitting (int arrays, for backward compatibility / software rendering) be faster when I do this over opengl with setPixel or something similiar?

Thanks!

Martijn

Does this also apply when I transfer my int buffers to screen mem through JOGL?
[/quote]
Granetd im not a JOGL expert, but I dont follow you here.

In order to put 2D image data to screen with a 3D API it needs tp be in the form of a texture.

How are you getting your data into a texture?

OGL SetPixel is the world’s slowest way to draw.

Forget it exists.

Put your 2D images to textures and map those texture to polys and you will be much happier.

Well I haven’t looked into how I should get my pixel data into a texture… I’d like to know if I’d gain anything using opengl (but stick to using int[] internally because of backward compatibility, ie drawing using a image producer, bufferedimage or opengl where available)

I suppose in OGL I could draw my int[] using a PBuffer or something? (http://www.codesampler.com/oglsrc/oglsrc_7.htm#ogl_offscreen_rendering)

Thanks!

Martijn

If you are updatign the texture every frame then the answer is no.

The problem there is hardware. Getting the bits to the display card.

What software path you use is irrelevent as long as its an efficient one.