dime
Senior Newbie 
|
 |
«
Posted
2010-09-28 09: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?
|
|
|
|
gouessej
|
 |
«
Reply #1 - Posted
2010-09-28 10:55:54 » |
|
Hi!
Slick2D already uses LWJGL. I'm not sure using OpenGL yourself would give better performance.
|
|
|
|
moogie
|
 |
«
Reply #2 - Posted
2010-09-28 12: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();
...
while (true) {
for (int y=0;y<height;y++) { for (int x=0;x<width;x++) {
imagePixelData[y*width+x] = red<<16 | green <<8 | blue; } }
g.drawImage(image,0,0,null);
} |
|
Java4k RIP 2014
|
|
|
Games published by our own members! Check 'em out!
|
|
ShannonSmith
|
 |
«
Reply #3 - Posted
2010-09-28 15: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.
|
|
|
|
moogie
|
 |
«
Reply #4 - Posted
2010-09-28 23:11:18 » |
|
true for a single color, however I was under the impression he wanted to manipulate the colour of individual pixels...
|
Java4k RIP 2014
|
|
|
ShannonSmith
|
 |
«
Reply #5 - Posted
2010-09-29 00: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.
|
|
|
|
Momoko_Fan
|
 |
«
Reply #6 - Posted
2010-09-29 01: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.
|
|
|
|
dime
Senior Newbie 
|
 |
«
Reply #7 - Posted
2010-09-29 08: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?
|
|
|
|
moogie
|
 |
«
Reply #8 - Posted
2010-09-29 11: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; private static final int SCREEN_HEIGHT = 768; 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);
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();
do { time=System.currentTimeMillis(); 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; } g = (Graphics2D) strategy.getDrawGraphics(); g.drawImage(image,0,0,null); strategy.show(); Thread.yield(); } while (true); } } |
|
Java4k RIP 2014
|
|
|
dime
Senior Newbie 
|
 |
«
Reply #9 - Posted
2010-09-29 19: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; private static final int SCREEN_HEIGHT = 768; 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);
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();
do { time=System.currentTimeMillis(); 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; } g = (Graphics2D) strategy.getDrawGraphics(); g.drawImage(image,0,0,null); strategy.show(); 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! Check 'em out!
|
|
moogie
|
 |
«
Reply #10 - Posted
2010-09-30 00: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;
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
} |
|
Java4k RIP 2014
|
|
|
|