Hi guys !
For those who have been on this list for some time, or on JavaLobby
list, you probably know that I am concentrating on the same things for a lot
of time now.. I want to thank you all for all the help you gave me about
graphic optimisation in JDK 1.1. This morning, I sent this mail to Sun,
which recaps my current situation. Hopefully, the guys at Sun will help me
out with this !!! Anyways, I include the mail I sent them with this one so
if you are interested in following the thread, I can forward the answers
from Sun to this list... It would be a great opportunity to create a good
and efficient animation model that we could all use. That would be a great
help for Java... Video games and animations pushed the PC forward in the
last years, why not do the same with Java ?
If any of you are interested in that subject, I would propose that
we create a thread or a subgroup that would be specific to that subject, to
create our own model that would be as optimized as possible...
Anyways, just wanted to let you know !
Maxime.
Here is the mail I sent to Sun (awt and java2d specific mail addresses).
Hello Java People,
My name is Maxime Poulin, and I am working for UbiSoft Entertainment
as manager of the Java Research And Development Team. As you might know,
UbiSoft Entertainment is a video game company which is targeting the "High
Animation and Image quality" segment of video games. About 18 months ago,
the company hired me and the other members of the team with the goeal to
study the possibility of building games in Java.
For the last 12 months, our main concern have been graphic
processing. I<ve been going through most of the major mailing lists,
searching for the bets way to build java animations for our games. We made
great progress in that field but didn't progress much for the last 3 months,
and I think that we reached the point where only you can help us getting
more performance. So this is of great importance to me, and I would greatly
appreciate your help and comments about the way we use Java for that
purpose.
If you allow me, I will describe the technique we presently use for
the 2d action game we are presently building.
- Game Presentation :
Roughly, the game is a 2d raceing game. The screen is 500*400
pixels. The track is bigger than that se we intrudiced a scrolling algo. The
view is from above. The game will be offered as an applet, as an application
and as a native win32 application. We decided to create a native win32
application because we want to use the game as part of the UbiSoft
GameService, which allows user to play different games in multi-player. We
use Symantec Visual Caf� 3.0 as dev tool.
We develop this game in JDK 1.1, because we didn't have time to
study Java 2 enough.
- Graphic technique :
The graphic technique we are using is the following. The algos we
are using for the special effects are working on arrays of pixels. So we
created a Sprite class which contains all the information on the sprite, as
well as the array of pixels representing the sprite. We also create a class
which contains only static methods. These methods are processing on the
arrays. For example, you would have the method
public static void drawImage(int[] srcImage, int[] dstImage, int
srcWidth, int srcHeight, int dstWidth, int dstHeight, int x, int y)
Which would simply draw the source image on the destination image...
So we have a binch of static method like this one in a class called
ArrayManip.
Then we have the GameManager class which contains roughly the
following game loop :
updateSpritesPosition()
prepareImage()
paint()
wait()
In this class, we have an image which we call offscreenImage, and an
array of pixels which we call offscreenPixels. The offscreen image is
created using a MemoryImageSource instance. The color model we use is ARGB
or Direct.
The prepareImage method is the most important here. It has two
parts. The first part erases the sprite from the offscreenPixels array. So
we go through all the sprites and use the drawImage method from our
ArrayManip to restore offscreenPixels with a copy of the original
offscreenPixels. For example, if a sprite occupies the rectangle
(10,10,50,50), then we copy the pixels from offscreenPixelsSource to
offscreenPixels for the rectangle 10,10,50,50. (this restores the
background). Then, we call
newPixels(10,10,50,50,false) from the memoryImageSource.
This is done for all the sprites that moved.
The second part is to redraw the sprites at their new position. So
if the same sprite is now at 30,30, we copy the pixels from the array of
picels contained in the sprite instance to the offscreenPixels array using
again ArrayManip. Then, we call again
newPixels(30,30,50,50, false).
So at the end of the prepareImage method, the offscreenPixels and
the offscreenImage are updated and ready to be painted as the next frame.
So after the prepareImage() call in the GameLoop, we just call the
paint() method which just do a g.drawImage(offscreenImage, 0, 0, this).
So roughly, this is the technique we've been using... There are some
more or less important optimizations we do but that's about it.
Now, the problem here are :
- The drawImage() call uses 60% of precess time. We used OptimizeIt and
JavaProbe to track it. That time is spent in the
ImageRepresentation.drawImage() method. We decompiled ImageRepresentation
with mocha to find out that ImageRepresentation.drawImage was playing around
with observers and image format before calling a native method.
- The sprites we use in our game are small : about 64 * 64 pixels images. If
we use big sprites, then the time spent in the newPixels() call gets to long
to keep 24 frames per second. The newPixels call is really really time
consuming.
- We do not use much sprites, for the same reasons as previous point.
-You may be wondering why we keep on working with arrays of pixels. Well
mostly because we need to use algos that work on arrays of pixels...
So, sadly, we've been optimizing all our code as much as we could,
especially the ArrayManip methods, and also optimized (minimized) the calls
to the time consuming newPixels and drawImage(), but now we reached the
point where these are the most important things to optimize in our program.
And for this we need your help and advice.
We had some time to study the BufferedImage class in JDK 1.2 and
make some tests with it. Unfortunately, we were unable to obtain better
performance from it. Actually, the performance was worst, but as I said, we
are still concentrating on JDK 1.1.
The advice I need are concerning the whole idea. What ColorModel
would be the most efficient to use (so ImageRepresentation does not have to
do conversions), how can I do a better use of the MemoryImageSource, or how
can I modify MemoryImageSource to make it more efficient. How can I prevent
the ImageRepresentation.drawImage() to be so long. Or what is the best
architecture for an animation using arrays of pixels in Java.
You know, we've been playing around with a lot of different
solutions, and tried so much approaches ! If you can provide me with
implementation details, maybe we will see that we missed something that
seemed irrelevant to us. Hopefully we will, because after a year an a half
of R&D, time will soon come when we will have to decide wether we keep on
building Games in Java, we switch to building turn based strategy games in
Java without much image processing, or forget about games in Java and
dissolve the team. That last solution would be really sad, and I am doing my
bets to avoid it... I've been programming with Java for 3 years now, so I
would prefer to keep on with it than getting back to C++.....
Thanks a lot for your time guys, I know that my mail is quite long
but as I told you, I submitted this problem to a lot of mailing lists, and a
lot of really advanced developpers helped me out on this, but sometime you
have to get to the source !
NB. Sorry for my english mistakes, but it is not my first language.
Maxime Poulin,
UbiSoft Entertainment,
JavaTeam Manager.
�����������������������
To subscribe/unsubscribe, send mail to [EMAIL PROTECTED]
Java 2D Home Page: http://java.sun.com/products/java-media/2D/