Speeding up graphics which changes minimal per frame

Hi there,

I’d like to program a game in which music plays an important role. Thus I need to write kind of a spectrum analyser. Just some bars changing their height in time. I want it to run in its own window. What I’ve done by now was to define a JPanel and to calculate the height of the bars. Then I draw them as rectangles into an image and afterwards I use drawImage to make the image visible.
My problem: this routine uses so many resources that I can hardly stop the program, because the window doesn’t react (or at least very slowly). I think this can be done much better, especially because I change at most the height of two bars per frame. Therefore it should be sufficient to redraw at most eight pixels (every unit of a bar is 2x2 pixels big) plus a small string in the corner, maybe.
Now I don’t know how to realize this idea. I think I have to go on painting the whole image into the imagebuffer, because a refresh of the whole window could be necessary (after being in background and so on). But with drawImage I cannot paint single pixels onto the screen. And even if, is it the best way to do it? And is it sufficient to write the graphical data straight to the image-object? I’ve found a lot of solutions to make this operation faster (and more difficult), but after all the time killing procedure isn’t the writing to the buffer but making the buffer visible, right?

I’m looking forward to your commands and suggestions :).

Reilly

If you just use drawImage(…) once per frame, this shouldn’t be critical to performance. Your problem might be excessive updating (what framerate do you want?) and the fact that the paint events that manage the drawing are executed from the Event Dispatch Thread, thus consuming time which could be used listening for user input.

Of course I don’t know how you do this, so you’ll have to elaborate if you want more detailed help.

Are you using an accelerated canvas at all?

Kev

Thanks for your answers so far… to give you an idea of the program, I paste the important parts into this text:


public class BarPanel extends JPanel implements Runnable{

    public void run(){
		while(runs <= simulationSteps){
	    	for(int i=0; i < 100 && runs <= simulationSteps; i++){
				update();
	    	}
	    	render();
	    	paintScreen();
	    }
	}

    private void traderRender(){
		if(dbImage == null){
		    dbImage = createImage(pWidth, pHeight);
	    	if(dbImage == null){
			System.out.println("dbImage is null");
			return;
	    }
	    else dbg = dbImage.getGraphics();
	
		// calculate values to draw and draw on dbg
		//...
    }

    private void paintScreen(){
		Graphics g;
		try{
	    	g = this.getGraphics();
	    	if ((g != null && dbImage != null))
			g.drawImage(dbImage, 0, 0, null);
	    	g.dispose();
		}
		catch(Exception e){
	    	System.out.println("Graphics context error: " +e);
		}
    }
}

I think there’s no need for big explanations. The update routine calculates the values to display. I’ve experimented a little bit with doing more than one update for every frame, but I had no success. Furthermore I’ve tried to implement a more complicated version, which measures the drawing-time for every frame and matches the number of updates per frame to these values. This idea was inspired by “Killer Game Programming in Java”, accessible under http://fivedots.coe.psu.ac.th/~ad/jg/
Anyway, the code was more complex but not neccessarily more efficient :(.
@Hjorth Larsen: The window shows just some bars, thus the refresh rate doesn’t have to be too high. As long as it doesn"t look jerky, I’m happy.

Greetings,
Reilly

Either the paste breaks indentation, or you should check the coding conventions and realign accordingly.

I assume that you declare a Thread somewhere outside that class then?

Why would you update() a hundred times before calling render() and paintScreen() ?

Since you use Swing, it should be okay to let paintComponent do the redrawing as it sees fit. No serious need for active rendering unless you really want to draw hardcore graphics.

Sorry for the bad representation of the code. It’s the result of editing an Emacs-written code with a windows-editor.
Anyway, the thread is declared inside the class. There’s a method initializing and starting the thread. This method is called from the
main class.
I let the update-method runs more than once because the changes of every update are so small that it doesn’t disturb the visiual presentation. And it’s surely faster to draw something just once instead of 100 times.
So I will change back to paintComponent. The idea of active rendering was again taken from the “Game Programming in Java” book.

I’m a little bit suprised that there’s no need to reduce the amount of data which must be drawn. I thought this was the bottle neck, but after all your suggestions I seem to be wrong. On the other hand the only change I’ve made until now was switching from active to passive rendering and this hasn’t solved the problem. Still, the program runs fine but everything else (the window wherein it runs included) is almost frozen.
Oh, maybe I should mention one thing: To figure out how the bars behave on a long time scale I did 100,000 updates before refreshing the screen. Of course, you couldn’t speak of animation anymore. But at least the system reacted to my mouse clicks. Thus, the reason for the waste of ressources must be somwhere inside the render-routines.

Try adding a Thread.yield() or Thread.sleep(5) in the run() while loop. This will prevent the thread from hogging the cpu.

I’ve already tried to send the thread into sleep (even longer than you suggest), but without much success.