Search code examples
opengljoglgldrawpixels

Jogl gldrawpixels() problem


I hope that this ends up being a simple question.

I'm using JOGL in Netbeans to create a checkerboard of pixels where you can specify the number of tiles in each row/col, and also the color of each of these tiles (draw this tile with 0 alpha, draw that tile with full alpha). Speed is not an issue, nor is efficiency.

Here's my problem: When I attempt to use glDrawPixels() my glCanvas is sparsely filled rather then completely filled. As you can see I'm currently trying to get a simple case of the drawing working before moving on to the more involved stuff. I'm filling a 1D byte array with the value of a filled byte. Next I give this to glDrawPixels() to write to the color buffer.

Am I handling the byte array incorrectly? In practice (as opposed to several tutorials I've seen) the method only takes a form of a Buffer for the actual data, so that's why I've wrapped up the byte array.

Also, the method seems to expect twice the data than the dimensions you specify to it. For instance you can see here that although I'm telling it to manage an area of width by height, it throws an exception unless the byte array is actually double the width by double the height.

I'm using glDrawPixels() because I've read that it's the correct way to manage pixels.

        byte[] src = new byte[(width*2)*(height*2)];

        for(int a=0; a<height*2; a++){
            for(int b=0; b<width*2; b++){
                src[a*b+b]= 127;
            }
        }

        gl.glDrawPixels(width, height,
                GL.GL_RED, GL.GL_UNSIGNED_BYTE,
                ByteBuffer.wrap(src));

Note that width and height are the dimensions of my canvas(256x256), so this operation should take up the entire canvas's area.

I'd really appreciate any help you can give me. I'm fine with solutions that involve completely different approaches (as long as they still mean using JOGL). That being said I'd rather not do this in a fragment shader. Thanks for your time.


Solution

  • Your buffer layout is wrong. A image of n×m pixels and k bytes per pixel has n*m*k elements. And to access the buffer you have to advance width*y + x elements. Any buffer overruns despite correct buffer size and parameters passed is due to wrong pixel unpack settings.

    So change it to this:

    byte[] src = new byte[width*height];
    
        for(int a=0; a<height; a++){
            for(int b=0; b<width; b++){
                src[a*width+b]= 127;
            }
        }
    
        gl.glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
        gl.glPixelStorei(GL_UNPACK_SKIP_PIXELS, 0);
        gl.glPixelStorei(GL_UNPACK_SKIP_ROWS, 0);
    
        gl.glDrawPixels(width, height,
                GL.GL_RED, GL.GL_UNSIGNED_BYTE,
                ByteBuffer.wrap(src));