How to generate simple 2D graphics in real time? - java

For my internship on Brain-Computer Interfacing I need to generate some very fast flickering squares on a CRT monitor (flickering = alternating between two colors). The monitor's refresh rate is 85Hz and we would like this to be the bottleneck, which means that repainting all squares can take at most 1000/85 = 11ms.
My language of preference for GUI/graphics programming is Java, so I tried making a prototype with AWT, because it's synchronous (unlike Swing). I now seem to have two problems: the first is that time measurements show that the repainting of even 9 squares simply takes too long. My algorithm takes the desired frequency and calculates the times at which the system should repaint in advance and then uses a loop (with no sleep/wait delay) that checks everytime if the next 'time' was reached and if so, loops through all the squares to repaint them. The way I implemented it now is that the squares are Panels with background color A and are contained in another Panel with background color B and the flickering happens because the Panels' visibility is changed. I figured that this would be faster than one Panel that has to draw Rectangles all the time.
I don't have a decent profiling tool (can't get Eclipse TPTP or NetBeans profiler to work) so I can't be sure, but I have the feeling that the bottleneck is actually not in the repainting, but in the looping (with conditional checking etc.). Can you recommend anything about what I should do?
The second problem is that it seems like the squares are rendered top-to-bottom. It's like they unroll really fast, but still visibly. This is unacceptable. What I'm wondering though, is what causes this. Is it Java/AWT, or Windows, or just me writing a slow algorithm?
Can you recommend some things for me to try? I prefer to use Java, but I will use C (or something) if I must.

I would avoid any kind of high-level "components", like JPanels and the like. Try getting a Graphics2D representing the window's contents, and use its fillRect() method.
Failing that, you could probably do this easy enough in C and OpenGL. rasonly.c is a standard template program that sets up OpenGL to work as a "rasterizer" only, i.e. 2D mode. Using this as a starting point, you should be able to get something running that draws your desired "squares" without too much trouble.
You don't describe your desired scene very well, it sounds from that equation as if you want to draw 100 squares, each having a different color. For maximum performance in OpenGL, you should draw all squares of the same color together, to minimize the "state changes" between drawing calls. This is probably a purely theoretical point though, as drawing 100 2D squares at 85 Hz really shouldn't tax OpenGL.
UPDATE: Oh, so it's been a bunch of years, and nowadays you probably need to take the above with a grain of salt and read some modern tutorial. Things have changed. Look up the Vulkan API.

(I remember a demonstration of this using the BBC micro and palette switching, though that would be 50fps rather than 85, as it was a British domestic TV)
I'd switch to jogl and use display lists. They get very high fps rates in Java.

Related

What would be the best solution to making this animation

I am trying to make a game where you have multiple levels where you have to figure out a way to where a certain color should go through pipes that are displayed on the screen. The pipes look like (it all should be better, but just as a reference). So basically there should be an animation of color going down these pipes (different color for different pipe). Now, I can make a gif and use that as my animation, but it's just too large (aprox. 5MB, which isn't a lot, but if you put dozens of levels, it tends to add up).What would be a solution that would be the most efficient?
Well I would first recommend you to go with Unity for Game Development.
If not then check out cocos2d or any other frameworks.
Secondly, if you want to animate things using the native code, then play around with draw() functions (as suggested by #Wakeman) of the Canvas.
Now coming to your question, if your game does not involve continuous user interaction and you are thinking of GIFs as a solution then I would recommend using Lottie library.
You can create beautiful animations in Adobe After Effects and import those (json files) in Android without hurting much memory, plus would get high resolution output.
Have you tried using the drawRect() or drawCircle()? You only need coordinations of the starting point, the turning points, and the ending point. Draw it with a recursive function with delay, and it should look good.
It would be better to construct your levels as tilemap. Every segment of pipe can be coded by number and drawn as bitmap (Sprite) that depends on its state (empty, 1/4, 1/3, 1/2 or full). Similar principles works for engines like Unity/Cocos 2D or your own renderer. This way of building your levels would be hundred times lighter in size than full screen animation and used multiple times for different levels.

Is it good practice to cache parts of a 2D drawing?

I'm making a 2D game in Java and one of the main issues causing low FPS (on my slow laptop) is having to re-draw complex structures to a Graphics instance, such as dials with markings.
The dial and its markings will never change unless the window is resized, so I thought it would be a good idea to draw to a BufferedImage and just re-draw the image rather than re-drawing the details. The position of the needle obviously changes, so this can just be drawn on top.
I've never heard about this being done to improve the FPS of 2D games so I'm wondering if it's actually good practice to store a cache of images or if there's a better way to solve this sort of problem? Are there any issues associated with this that I haven't considered?
Caching images isn't a bad idea: you can rely on raster rendering to be pretty well optimised on most any platform. In my experience (which is admittedly mostly on mobile devices where 2D graphics are concerned) the Graphics.drawXXX() methods are often considerably slower than Graphics.drawImage().
In my experience the vast majority of 2D games out there make use of sprites (i.e. images) for rendering just about everything. Often that's true even when the graphics look like they are rendered using primitives!
Another useful technique to think about is not redrawing regions at all unless you really need to!
EDIT:
As others have mentioned, the major tradeoff is that you're going to be using more memory. You're also going to have to make sure you free up those images once you no longer need them.
Is it good practice to cache parts of a 2D drawing?
You're making a trade-off between drawing speed and storage space. Only you can determine which is more important.
You might consider rendering your dials in advance and saving the images as GIF, JPG, or PNG files. You would have to scale these images to your window size before you draw them.
Are you using double buffering for your Graphics panel?
Yes, that is a good practice, and it's done all the time. Drawing to an image first before displaying it on the screen is called double buffering, and that method can be used in different ways according to the needs of the program.
The downside of double buffering is memory, since it takes more memory to store the second image, but that sounds like a trade-off you'll need to make.

More Efficient Method of Drawing Thousands of Particles (Java/Android)

So I'm writing a sort of particle simulator, like a "falling sand game" if you know what that is, and I've kind of hit a roadblock now. The way I'm doing this is I have a particle object that basically as of now has an position (int x, int y) and that's it. The way I'm drawing/moving them, is with a thread and the onDraw event for an android panel. Each time onDraw is called I loop through all the particles, move them down one pixel unless they hit the bottom and then draw them, this is pretty smooth until I get to about 200 particles, then the fps drops significantly. I know this is computation heavy the way I'm doing it, there's no debate about it, but is there any way I could do this to allow a lot more particles to be drawn and with less lag?
Thanks in advance.
I take it you're using an individual-pixel drawing function for this? That would indeed be slow.
I see a couple ways to improve it. First is to put the pixels into an in-memory bitmap then draw the whole bitmap at the same time. Second, since particles are always just going down one pixel, you can scroll part of the bitmap instead of replotting everything. If Android doesn't have a scroll then just draw the bitmap one pixel down and start a new bitmap for the particles above the scroll. You'll have to fix up the particles on the bottom, but there are fewer of those.
I've never done things like this before, but I have done some complex cellular automata. Sorry if this is too vague.
The basic idea here is to mark all particles that should "keep falling" or "not move" and exclude them from complex processing (with a special short/fast processor for the "falling" list - all you need to do is drop each one by a pixel).
The acceleration for non-moving particles - static particles (I'll call them S particles), is that they don't move. Mark it for all non-moving regions (like a gravity-immune "wall" or "bowl" that a user might make. Mark particles above it S if they are stable, so for example for liquid, if it has S particles under, and to both sides of itself, it will not move. For something like sand that forms piles, if it has an S in each of the three spots under it, it makes a pile, you'll get nice 45-degree piles like this, I'm sure you can change it to make some things form steeper, or less-steep piles. Do S mapping bottom-up.
The acceleration for particles with no particle under them is falling - F particles. Particles with an F particle under them are also F particles. Mark these bottom-up as well.
Particles unmarked F or S are complex, they may start falling, stop falling, or roll, use the slow processor, which you already have, to deal with them, there shouldn't be many.
In the end what you will have is many many fast particles. Those in a pile/lake and those raining down. The leftover particles are those on the edge of slopes, on the top of lakes, or in other complex positions. There shouldn't be nearly as many as there will be fast particles.
Visually mark each kind of particle with some colour, complex particles being bright red. Find cases where it is still slow, and see what other kinds of fast processors you should make. For example you may find that making lots of piles of sand creates lots of red areas along slopes, you may want to invest in speeding up "rolling zones" along the slopes of piles.
Hope it makes sense. Don't forget to come back and edit once you've figured something out!
You may want to look into OpenGL ES hardware acceleration and renderscript. It doesn't give you a more efficient solution code wise (see the other answers for that). It does open up a lot more processing power for you to use however. You can even run the entire simulation on the GPU (possibly, don't know your implementation details).
Edit
Also, if you still decide to do the processing in java, you should look at Method Profiling in DDMS. This will help you visualize where your performance bottlenecks are.
If you blur your image a bit, then you could just move half particule at a time, maybe one fourth only and print them all.. that would cut computation and the user wouldn't see it, getting the feeling all particules move.
But what ever you choose, I think you should be put a strong limit, not all users have powerfull android devices.
Regards,
stéphane
I think if particles are close each other, you can create objects that represent 3 or more particles.
When displaying several particles on screen, sets of grains maybe gets unnoticed.

What should I use to display game graphics?

I have a system in place for a game yet I don't know what I should use to display it. I am making a vertical shooter game and I have written the methods for all the classes controlling enemies and players, but I have not idea how to efficiently display the game. I was thinking a Canvas, that would repaint every frame, but is that really the most efficient method?
Important details:
ideal framerate: 25fps
It is a 2d game
There are anywhere between 25-100 objects on the screen at any one time, all of which are moving
All objects being displayed are images, all in PNG format
The window is 640px by 480px
Right now all the images are loaded as BufferedImage, although I could easily change this
7. I need a coordinate plane. This is the only fundamental part that cannot be changed without completely restructuring my code.
Most importantly the way I have everything set up, every frame all of the objects move and interact in a coordinate plane I devised (deals with collision detection and movement, no graphical component), then everything should get painted to the screen, simply by going through the ArrayLists which keep track of all moving objects and painting them one by one.
If Swing is acceptable, JPanel is double-buffered by default, and a javax.swing.Timer with a period of 40 ms will give you ~25 Hz updates. This example shows the basic approach, while this example shows a number of images in motion.
I need a coordinate plane.
It's not unusual to have the the model and view use different coordinates; all that's needed are functions to map one system to the other. In this game, the view relies on four methods that map tiles to pixels and vice-versa. The same approach is outlined here for map tiles.
You have a number of options available to you:
Firstly, you could use one of the existing Java game frameworks:
JMonkeyEngine (http://jmonkeyengine.com/)
Slick (http://slick.cokeandcode.com/index.php)
(Slick is aimed at 2D graphics, while JMonkey is aimed at 3D and uses OpenGL - While I have looked into their use, I've not actually used them myself)
Alternatively you can code everything yourself. From the sounds of things this is your first (graphical) game, so you may want to read up on a technique known as double buffering, whereby you write each frame off-screen and the just paint the whole thing to screen, as this can lead to smoother animation.
To get you into games development a bit more, I would highly recommend reading this site, Killer Game Programming in Java by Dr Andrew Davison, as he gives some good pointers, and also provides a good progressive learning path for new game developers, and moving them into 2D and then 3D development.
HTH
The answer really depends on whether this game is 2D or 3D.
If your game is 2D, an easy way to do what you want is to use Java's own 2D Graphics API. A good tutorial to start you off (at least in my opinion) can be found at The Java Tutorials. In my experience I have found that Java's graphics API is easy to learn, and is more efficient than one might expect. The basic technique is to have your game code keep track of the positions of all your objects, then translate those coordinates into screen coordinates and display appropriate images at those locations. I made a (very, very simple) game in Java once, and this is the method I used.
If your game is in 3D, OpenGL is definetly the way to go. I have only limited experience with OpenGL, so I'm not sure how easy the Java bindings are to work with. In general, 3D programming is a massive topic, so if this is a first-time project or you aren't prepared for a major time investment, I would attempt to find a good game framework to use or make the game 2D. If you are interested in OpenGL, or 3D programming in general, a quick Google turned up the JOGL project. I would recommend investigating JOGL as a way to access the OpenGL API from within Java code, but for actually learning OpenGL I recommend The OpenGL SuperBible(5th edition), commonly known as "The Blue Book".
The code examples are all in C++, but for the OpenGL functions it could possibly be just a matter of using a wrapper library. For example:
glDrawElements(...);
May become:
JavaGLWrapperObject.glDrawElements(...);
Unfortunately I can't give concrete examples because I haven't used OpenGL with a Java program, but the above example very coarsely approximates how OpenGL ES is used on the Android platform.
As far as performance... Java's API comes with a non-trivial ammount of overhead, but I could see it doing alright for your purposes. You may have to put a little more effort into making your algorithms efficient, and your game may not run as well on less-capable hardware. If you do decide to go the OpenGL route, it will almost certainly be much faster (again, depending on how efficient your algorithms are), but is correspondingly much harder to learn and get started with. Certainly doable, but it will be a challenge.
Canvas will quickly be too slow for 25+ fps targeted.
the number of object is irrelevant, what is is how complex they are.
if it is 100 images will take nothing compared to 1 3D model of Avatar for example.
in Java you can use either Opengl or Java3D
I would tend to go with Opengl as a personel choise

Java graphics performance

I was programming a simple game and wanted to display it via the Java Graphics + Swing API. It felt a little slow, of course, so I measured how long it took to repaint, which was around 32ms. Then I read about accelerated Java graphics and used the method described here: Space Invaders
However, somehow this is even slower. It now takes around 98ms to redraw. Why is that?
Note that I am aware of libraries like LWGL and JOGL, but I don't want to use a full-blown OpenGL wrapper for such a graphically simple game.
A few hints to improve performance:
Clip and just draw the area that has changed
Don't scale anything when drawing
Use the correct buffer strategy
Use full screen exclusive mode if appropriate.
Swing isn't inherently slow. Most of the confusion about Swing comes from people who don't know or understand about the Event Dispatch Thread (and yes, it's a lot of effort to get it right).
Regarding your times, are you just calling g.drawImage between the time settings? If so, what size are you repainting, and are you doing any scaling on this call?
EDIT: Forgot to mention Pulp Core - a very nice gaming framework for Java.
Read this about timers
Use an always sleeping thread in the background to lower the system interrupt rate to get much more precise timers!
You can take a look at my code in here
A small game I've created can be found here
long renderStart = System.nanoTime()
// render stuff here
long renderTime = (System.nanoTime() - renderStart) / 1000000;
Swing will be slow for a game. Your best bet is probably an SDL wrapper, such as jsdl or sdljava. SDL is quite lightweight and supported on many platforms.
The nice thing is, well-implemented 2d graphics library wrappers implement the Graphics interface, so you should be able to try several and see which one performs best for your app without modifying your code.
I am not an expert, but Java2D supports different rendering pipelines. On my machine, switching to the OpenGL one by setting the system property
sun.java2d.opengl=true
yielded a substantial increase in rendering speed.
You may look at processing.
I agree with Nicolas, for graphics / interactivity processing is great
Try JGame. It's a simple engine for 2D games which uses GL when its available and can produce games that run on anything from a mobile phone to a desktop system.
First of all, you should check and see how much time is spent in your own code vs. how much time is spent actually drawing the frame. You may have some bug or glitch that makes it run more slowly.
You should be able to get much better performance then 98ms to draw your screen. Those game libraries will probably be using the same graphics calls as you would. But which containers you use can have a big impact on how fast things draw. I remember a couple months ago working on some double buffered graphics code, and how the back buffer was created made a huge difference in performance.
In particular, make sure you only create background image once or at least, only when your canvas resizes. In my draw code I do this:
//create a graphics backplane
if(backplane == null || !backplaneSize.equals(this.getSize())){
backplane = this.createImage((int)this.getSize().getWidth(), (int)this.getSize().getHeight());
backplaneSize = this.getSize();
}
So the back plane only gets created if it's new, or if the component is resized. This has a huge impact on speed.
I've been doing graphics programming in java since JDK 1.0. Actually I'd never heard of this BufferStrategy thing. Heh.
I've never had any trouble getting good frame rates with basic java graphics calls. Another thing to look out for is making sure that Swing isn't trying to clear the background of your component for you. That can be another source of slowdown.
Java2D performance is a bit of a dark art. It can vary between platforms, but it possible to get it to perform well.
Sometimes doing seemingly innocuous things can result in much slower performance. You want to make sure that you are using accelerated images as much as possible.
The type of the image can also be significant. I don't know the full details, but I do know that my programs were much faster using type 1 images (INT RGB) than other types such as type 5 (3BYTE BGR) because of conversion issues.
I can't tell exactly what you are doing. Your question is about Swing but you mention a Canvas and Bufferstrategy. Well in Swing you would use a JPanel which is automatically double buffered so you don't have to worry about that.
I tested a simple animation with 1000 moving balls. The Timer was set to fire every 100ms. When the Timer fired, the 1000 ball where randomly moved to a new position and a new BufferedImage was created and the panel displaying the image was repainted. The difference in time between the repainting was 110ms implying it only took 10ms to create an new BufferedImage and do the painting. The painting was done a a full screen so no clipping was done.
This posting show the example code I tested.

Categories