I think I might be going about this the wrong way.

Some advice would be appreciated.

What I’m trying to do is draw to the screen based on a calculated/stored imagemap in an array. I can do it just fine, but it’s painfully slow: 4FPS on this machine. I’d pre-create my images, but the memory required would be too large for ny tastes.

Maybe I’m just doing something wrong in my code, but it might be that the whole thing might have to be re-thought.

Here’s my test code I whipped up, just in case it is me messing up.

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

class map
{
      public int[] pixels;
      public int width, height;

      public map()
      {
            width=height=100;
            pixels=new int[width*height];
            for(int i=0;i<width*height;i++)
                  pixels[i]=(int)(Math.random()*1073741823);
      }

      public void draw(BufferStrategy bs, int x, int y)
      {
            Graphics g=bs.getDrawGraphics();

            //draw
            BufferedImage bi=new BufferedImage(width,height,BufferedImage.TYPE_INT_RGB);
            WritableRaster wr=bi.getRaster();
            for(int p=0;p<200;p++)
            {
                  for(int row=0;row<height;row++)
                  {
                        for(int col=0;col<width;col++)
                        {
                              wr.setSample(row,col,0,pixels[(row*width)+col]);
                        }
                  }
                  g.drawImage(bi,x,y,null);
            }
            bs.show();
      }
}

class drawtest extends JFrame
{
      private static long ctm, cnt;

      public drawtest()
      {
            super("DrawTest");
      }
      public static void main(String[] args)
      {
      JFrame.setDefaultLookAndFeelDecorated(true);
            drawtest frame = new drawtest();
            frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
            frame.setSize(250,250);
            frame.setVisible(true);

            frame.createBufferStrategy(2);
            BufferStrategy bs=frame.getBufferStrategy();

            ctm=System.currentTimeMillis();
            cnt=0;

            map bm=new map();

            while(true)
            {
                  bm.draw(bs, 100,100);
                  cnt++;
                  if((cnt%100==0) && ((System.currentTimeMillis()-ctm)>2000))
                        System.out.print("Framerate: " + (cnt/((System.currentTimeMillis()-ctm)/1000)) + " Time: " + ((System.currentTimeMillis()-ctm)/1000) + "\n");
            }

      }
}

Thanks in advance.

BufferedImage.setRGB(int startX, int startY, int w, int h, int[] rgbArray, int offset, int scansize), would be faster than setSample().

A couple things I can see (knowing nothing of BufferStrategy, and very little of the Rasters since I just started this back up, but knowing quite a bit about game programming):

  1. First off, you seem to be drawing to the backbuffer 200 times per call to your “draw()” function always in the same position, yet only flipping the page a single time using “bs.show()”. This means that 199 go unseen. If you want to include 200 draw routines in a single function call (which I do NOT recommend), at least make it flip the backbuffer after every draw (unless you’re changing the position of the “sprite” with every call to drawImage(), so draw 200 unique boxes on the screen at one time – in your case, you’re just drawing them on top of each other)

  2. Since you call your draw() function from your main loop, you should really only be drawing once per function call (unless you’re actually trying to draw 200 unique squares, which it doesn’t appear you’re doing – at least not from a user perspective). If you’re trying to simulate drawing a map (such as an isometric one), it’s very rare that you’d be recreating each tile of the map each frame (which you’re doing here).

  3. Even without the “p++” loop, your inner loop has the wr.setSample() function being called 10,000 times. Calling functions is a significant system hog (at least it was in C++ Game Programming – I’m sure most of the same concepts still apply in Java), and doing it not only 10,000 times, but 2,000,000 times in a single function call (with your outer loop included) will bring any system to its knees. Try populating an int[] with your sample data, and then calling wr.setSamples() a single time with your int[] as the last parameter (notice the “s” at the end of the function name).

This code snippet shows how to get a int[] array (buffer) from the writable raster so you can just manipulate the array.


int [] buffer = new int[w*h];

image = new BufferedImage( w, h, BufferedImage.TYPE_INT_RGB ) ;
data = (DataBufferInt)image.getRaster().getDataBuffer() ;
buffer = data.getData() ;


[quote]This code snippet shows how to get a int[] array (buffer) from the writable raster so you can just manipulate the array.
[/quote]
I gave this code a shot, and it does speed things up. I can’t tell if anything is changing, within the for§ loop. I guess I’ll have to code more up for real to see.

On an semi-unrelated note, is 2-3MB in memory too big for a character to take up?

[quote]Calling functions is a significant system hog (at least it was in C++ Game Programming – I’m sure most of the same concepts still apply in Java)
[/quote]
does not. i made a test, a simple image filtering routine. when using a method call in a loop to filter the pixel, it’s faster than inlining the code in the loop… that’s because the JIT does wonders at inlining. I waas amazed at the result, as you might also be, but it’s true.
You’ll find thread about this on the old boards performance tuning section, if still available…

Interesting. I guess you learn something new every day. I always hated expanding functions when writing games in C++ (or forcing them inline). Of course, last verion of Java I used prior to getting back into it (1.1), wasn’t good at much :smiley: Quick question – do you know if this inlines complex functions (say of 100 lines or more?) Probably not a good question for this board.

Thanks!

-Chris

Depends what you mean by ‘character’… Are you talking about just a single sprite? All animation frames? The actual in-game representation including all statistical information?

[quote]Depends what you mean by ‘character’… Are you talking about just a single sprite? All animation frames? The actual in-game representation including all statistical information?
[/quote]
Uh… well, characters are multi-part, so all the sprites for it. There’s a 3D skeleton and animations I haven’t factored in yet, but it’s miniscule compared to the sprites. If you have to know, I’m working on voxelmaps. I’ve got to be nuts.

[quote] Quick question – do you know if this inlines complex functions (say of 100 lines or more?) Probably not a good question for this board.
[/quote]
A great question for the Performance Tuning section actually. The quick answer is No. But there are VM parameters you can tune to adjust the size of what might be inlined… based on #of bytecodes I think. Ask in the Perf Tuning forum if you want better answers.