Fastest way to set every pixel?

I have a game board, let’s say 1024x768. Kind of like the game of life, but every cell will be it’s own color.

What’s the fastest way to do this? I tried it though Slick 2d, but assuming there is probably some over head there.
I don’t know OpenGL, so hopefully someone can guide me?

I’ve tried drawing fillRect and using an image (byte) buffer (ImageData.getImage() - involves lots of creating/destroying of an Image object)
I did it on different workstations, one has a way better CPU and the other has way better GPU.
It seems filling quads is heavy on the GPU and creating an image/byte buffer kills the cpu/memory.

Doing in direct in lwjgl will give better performance? What would be a good approach and can someone point me in the right direction?

Hi!

Slick2D already uses LWJGL. I’m not sure using OpenGL yourself would give better performance.

not sure why you would need to be constantly creating/destroying image objects when using a byte array to “blit” pixels.

I have used this in the past an achived reasonable frame rate:



BufferedImage image = new BufferedImage(width,height,BufferedImage.INT_RGB);

Int[] imagePixelData = ((DataBufferInt)image.getRaster().getDataBuffer()).getData();

...

// main loop start
while (true)
{


/// do stuff...


for (int y=0;y<height;y++)
{
for (int x=0;x<width;x++)
{

// get red, green, blue components however you like

imagePixelData[y*width+x] = red<<16 | green <<8 | blue;
}
}


// get graphic object of swing component to draw on and draw the image
g.drawImage(image,0,0,null);

// go back to start of main loop
}

Using any of the BufferedImage INT_ types:

Arrays.fill(((DataBufferInt)image.getData().getDataBuffer()).getData(),color);

Arrays.fill is much faster than a for loop.

true for a single color, however I was under the impression he wanted to manipulate the colour of individual pixels…

Oh… I think your right, I read the title and thought he was talking about filling the whole image with a single colour.

Probably just getting the pixels from the BufferedImage, modifying it, then drawing the image should be fastest.
Or you can go overboard and write a GPU shader that does this with OpenGL/OpenCL, it would be extremely fast but also hard to write.

I think that is what I want. I’ved tried images and rects already, but pretty slow.
Any newbie articles to get started on shaders?

well, i knocked up a simple program which fills pixels of a 1024x768 image using a buffered image and on my atom net book it achieves 68 fps so on higher spec machines it should do better. what is your target frame rate?



import java.awt.Graphics2D;
import java.awt.image.BufferStrategy;
import java.awt.image.BufferedImage;
import java.awt.image.DataBufferInt;

import javax.swing.JFrame;

final public class a extends JFrame
{
	private static final int SCREEN_WIDTH = 1024;							// Screen Width
	private static final int SCREEN_HEIGHT = 768;							// Screen Height
	private static final int WIDTH_MUL_HEIGHT_MINUS_ONE=SCREEN_WIDTH*SCREEN_HEIGHT-1;
	
    final public static  void main( String[] a) throws Exception
    {
   		new a();
    }
        
    a() throws Exception
    {

   		Graphics2D g; 
		final BufferedImage image= new BufferedImage(SCREEN_WIDTH,SCREEN_HEIGHT,BufferedImage.TYPE_INT_RGB);
		
/****************************************************************************************************************
 * Initalize Screen
 */
		// the buffer strategey used for the video double buffer
		BufferStrategy strategy;
       
		setSize(SCREEN_WIDTH, SCREEN_HEIGHT); 
		show();
		
		setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
		
		createBufferStrategy(2);
		strategy = getBufferStrategy();
		
    	int frameCount=0;
		long threashold=System.currentTimeMillis();
		long time;
		int i;
		
		int[] pixelData=((DataBufferInt)image.getRaster().getDataBuffer()).getData();

		/****************************************************************************************************************
		 * Game Loop
		 */
		do
		{		
			time=System.currentTimeMillis();	// the current timestamp
			frameCount++;
		    if(time>threashold)
		    {
		    	setTitle(""+frameCount);
		    	frameCount=0;
		    	threashold=time+1000-(time-threashold);
		    }
		    
		    for (i=WIDTH_MUL_HEIGHT_MINUS_ONE;i>=0;i--)
		    {
		    	pixelData[i]=(i)&0xFFFFFF;
		    }
		    
		    
		    
	        // Get hold of a graphics context for the accelerated surface
	        g = (Graphics2D) strategy.getDrawGraphics();
			g.drawImage(image,0,0,null);
			
		    strategy.show();
		
		//    // give some cpu time to other processes
		    Thread.yield();
		} while (true);
			
    }
    
}
	

Thanks, but I’m using Slick 2d; so would need to convert from AWT BufferedImage to Image:http://slick.cokeandcode.com/javadoc/org/newdawn/slick/Image.html

I’m assuming that would take a performance hit converting it every frame.

well, i have never used slick2d before, however I would assume that you can do similar… i.e.


ImageBuffer buffer = new ImageBuffer(1024,768);
byte[] pixelData = buffer.getRGBA() ;
Image image = buffer.getImage();

...

int index;

// main loop
while(true)
{

for (int y=0;y<height;y++)
{

for (int x=0;x<width;x++)
{
   index=(y*width+x)*4;
   pixelData[index++]=red_component
   pixelData[index++]=green_component
   pixelData[index++]=blue_component
   pixelData[index]=alpha_component
}
}

...

draw image to canvas

}