Java-Gaming.org Java4K winners: [ by our judges | by the community ]         
Featured games (67)
games approved by the League of Dukes
Games in Showcase (∞)
games submitted by our members



News: Read the Java Gaming Resources, or peek at the official Java tutorials
 
    Home     Help   Search   Login   Register   
Pages: [1]
  Print  
  Fastest way to set every pixel?  (Read 2592 times)
0 Members and 1 Guest are viewing this topic.
Offline dime

JGO n00b
*

Posts: 40



« on: 2010-09-28 05:54:19 »

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?

Offline gouessej

JGO Kernel
*****

Posts: 3558
Medals: 30


TUER


« Reply #1 on: 2010-09-28 06:55:54 »

Hi!

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

Julien Gouesse
Offline moogie

JGO Strike Force
***

Posts: 775
Medals: 5


Java games rock!


« Reply #2 on: 2010-09-28 08:09:20 »

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:

1  
2  
3  
4  
5  
6  
7  
8  
9  
10  
11  
12  
13  
14  
15  
16  
17  
18  
19  
20  
21  
22  
23  
24  
25  
26  
27  
28  
29  
30  
31  
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
}
Games published by our own members! Go get 'em!
Offline ShannonSmith

Sr. Member
**

Posts: 365
Medals: 13



« Reply #3 on: 2010-09-28 11:42:55 »

Using any of the BufferedImage INT_ types:

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

Arrays.fill is much faster than a for loop.

Offline moogie

JGO Strike Force
***

Posts: 775
Medals: 5


Java games rock!


« Reply #4 on: 2010-09-28 19:11:18 »

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

Sr. Member
**

Posts: 365
Medals: 13



« Reply #5 on: 2010-09-28 20:44:26 »

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.
Offline Momoko_Fan

Full Member
**

Posts: 101
Medals: 3



« Reply #6 on: 2010-09-28 21:12:43 »

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.
Offline dime

JGO n00b
*

Posts: 40



« Reply #7 on: 2010-09-29 04:09:49 »

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?


Offline moogie

JGO Strike Force
***

Posts: 775
Medals: 5


Java games rock!


« Reply #8 on: 2010-09-29 07:53:35 »

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?

1  
2  
3  
4  
5  
6  
7  
8  
9  
10  
11  
12  
13  
14  
15  
16  
17  
18  
19  
20  
21  
22  
23  
24  
25  
26  
27  
28  
29  
30  
31  
32  
33  
34  
35  
36  
37  
38  
39  
40  
41  
42  
43  
44  
45  
46  
47  
48  
49  
50  
51  
52  
53  
54  
55  
56  
57  
58  
59  
60  
61  
62  
63  
64  
65  
66  
67  
68  
69  
70  
71  
72  
73  
74  
75  
76  
77  
78  
79  
80  
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);
         
    }
   
}
   
Offline dime

JGO n00b
*

Posts: 40



« Reply #9 on: 2010-09-29 15:58:31 »

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?

1  
2  
3  
4  
5  
6  
7  
8  
9  
10  
11  
12  
13  
14  
15  
16  
17  
18  
19  
20  
21  
22  
23  
24  
25  
26  
27  
28  
29  
30  
31  
32  
33  
34  
35  
36  
37  
38  
39  
40  
41  
42  
43  
44  
45  
46  
47  
48  
49  
50  
51  
52  
53  
54  
55  
56  
57  
58  
59  
60  
61  
62  
63  
64  
65  
66  
67  
68  
69  
70  
71  
72  
73  
74  
75  
76  
77  
78  
79  
80  
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.
Games published by our own members! Go get 'em!
Offline moogie

JGO Strike Force
***

Posts: 775
Medals: 5


Java games rock!


« Reply #10 on: 2010-09-29 20:12:07 »

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

1  
2  
3  
4  
5  
6  
7  
8  
9  
10  
11  
12  
13  
14  
15  
16  
17  
18  
19  
20  
21  
22  
23  
24  
25  
26  
27  
28  
29  
30  
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

}
Pages: [1]
  Print  
 
 
Jump to:  

Powered by MySQL Powered by PHP Powered by SMF 1.1.16 | SMF © 2011, Simple Machines Valid XHTML 1.0! Valid CSS!
Page created in 0.122 seconds with 20 queries.