2

I have been playing around with trying to draw a 320 by 240 full screen resolution image in opengl using java and lwjgl. I set the resolution to 640 by 480 and doubled the size of the pixels to fill in the space. After a lot of google searching I found some information about using the glDrawPixels function to speed up drawing to the screen. I wanted to test it by assigning random colors to all the pixels on the screen, but it wouldn't fill the screen. I divided the width into 4 sections of 80 pixels each and colored them red, green, blue, and white. I saw that I was interleaving the colors but I can't figure out how.

Here is an image of the output:

img

Here is where I run the openGL code:

// init OpenGL
GL11.glMatrixMode(GL11.GL_PROJECTION);
GL11.glLoadIdentity();
GL11.glOrtho(0, 640, 0, 480, 1, -1);
GL11.glMatrixMode(GL11.GL_MODELVIEW);

while (!Display.isCloseRequested()) {
    pollInput();

    // Clear the screen and depth buffer
    GL11.glClear(GL11.GL_COLOR_BUFFER_BIT | GL11.GL_DEPTH_BUFFER_BIT);  



    randomizePixels();
    GL11.glRasterPos2i(0, 0);

    GL11.glDrawPixels(320, 240,GL11.GL_RGBA, GL11.GL_UNSIGNED_BYTE,buff);

    GL11.glPixelZoom(2, 2);


    Display.update();   
}
Display.destroy();
}

and here is where I create the pixel color data:

public void randomizePixels(){
    for(int y = 0; y < 240; y++){
        for(int x = 0; x < 320; x+=4){
            /*
            pixels[x * 320 + y] = (byte)(-128 + ran.nextInt(256));
            pixels[x * 320 + y + 1] = (byte)(-128 + ran.nextInt(256));
            pixels[x * 320 + y + 2] = (byte)(-128 + ran.nextInt(256));
            pixels[x * 320 + y + 3] = (byte)(-128 + ran.nextInt(256));
            */

            if(x >= 0 && x < 80){
                pixels[y * 240 + x] = (byte)128;
                pixels[y * 240 + x + 1] = (byte)0;
                pixels[y * 240 + x + 2] = (byte)0;
                pixels[y * 240 + x + 3] = (byte)128;
            }else if(x >= 80 && x < 160){
                pixels[y * 240 + x] = (byte)0;
                pixels[y * 240 + x + 1] = (byte)128;
                pixels[y * 240 + x + 2] = (byte)0;
                pixels[y * 240 + x + 3] = (byte)128;
            }else if(x >= 160 && x < 240){
                pixels[y * 240 + x] = (byte)0;
                pixels[y * 240 + x + 1] = (byte)0;
                pixels[y * 240 + x + 2] = (byte)128;
                pixels[y * 240 + x + 3] = (byte)128;
            }else if(x >= 240 && x < 320){
                pixels[y * 240 + x] = (byte)128;
                pixels[y * 240 + x + 1] = (byte)128;
                pixels[y * 240 + x + 2] = (byte)128;
                pixels[y * 240 + x + 3] = (byte)128;
            }

        }
    }
    buff.put(pixels).flip();
}

If you can figure out why I can't get the pixels to line up to the x and y coordinates I want them to go to that would be great. I have read that glDrawPixels probably isn't the best or fastest way to draw pixels to the screen, but I want to understand why I'm having this particular issue before I have to move on to some other method.

genpfault
  • 51,148
  • 11
  • 85
  • 139
user137
  • 282
  • 2
  • 14

3 Answers3

4

Just load your image (unscaled) into a texture and draw a textured quad.

Don't use glDrawPixels. This function was never properly optimized in most drivers and has was deprecated since OpenGL-2 and got removed from OpenGL-3 core and later.

datenwolf
  • 159,371
  • 13
  • 185
  • 298
  • I got a textured quad version working and sorted out how to make it look pixelated on magnification ( was originally blurry on scale up ). But both the glDrawPixel and Textured Quads programs run at 60fps. I think, but I'm not sure, not an expert, that either openGL or jlwgl is throttling them to 60fps. How do I make them run at full speed to determine which runs faster? I intend to throttle it back to 30fps in the end, but I figure faster pixel draw times leaves more time for other calculations. – user137 Jul 06 '12 at 01:52
2

I spot 2 issues in your randomizePixels().

1. Indexing Pixel Buffer

The total size of pixel buffer is 320x240x4 bytes because the pixel type is GL_RGBA. So, indexing each pixel with subscript operator, [], it would be;

for(int y = 0; y < 240; y++)
{
    for(int x = 0; x < 320; x++)
    {
        pixels[y * 320 * 4 + x * 4 + 0] = ... // R
        pixels[y * 320 * 4 + x * 4 + 1] = ... // G
        pixels[y * 320 * 4 + x * 4 + 2] = ... // B
        pixels[y * 320 * 4 + x * 4 + 3] = ... // A
    }
}

2. Colour Value

The max intensity of 8bit colour is 255, for example, an opaque red pixel would be (255, 0, 0, 255).

song
  • 154
  • 4
  • Thanks, I was concerned I was getting the buffer wrong and converting to a texture quad wouldn't solve that. I've been using 128 because I thought I couldn't get an unsigned byte in java and had to work in the range of -128 to 127, I thought openGL would translate that to a normal 0 to 255 range, am I wrong? – user137 Jul 05 '12 at 23:46
  • EDIT: I checked and 255 works fine, my whites are whiter and all the colors line up exactly as expected. I'll try to convert it over to a textured quad now. – user137 Jul 06 '12 at 00:28
0

your operating on the texture. better do it on quadrature. it would yield good results