When writing a 4d visualization app in Java, I save the state of the window using readPixel so I can write out an image. I am using JOGL, but it’s a very thin wrapper on OpenGL. I am hoping there is a problem with the way calls are happening as opposed to some horrible bug in the parameter passing of the API itself.
First, to get the size of the current window (which has not been manually resized since the beginning of the run:)
gl.glGetIntegerv(GL.GL_VIEWPORT, view);
int w = view[2]+1, h = view[3]+1;
I added one because doing so made the code work, because setting w = view[2] results in a very bad looking picture (see http://davidson.dl.stevens-tech.edu/personal/dkruger/bad1.png))
The following code works well, for the particular size we are generating right now, but when I change the size, it has the same sort of byte alignment problems
I am pretty sure that the image saving code works, because a test pattern invariably comes out the correct size.
BufferedImage image = new BufferedImage( w-1, h-1, BufferedImage.TYPE_BYTE_INDEXED );
// BufferedImage image = new BufferedImage( w, h, BufferedImage.TYPE_BYTE_INDEXED );
DataBufferByte dbRaster = (DataBufferByte)image.getRaster().getDataBuffer();
byte[] buf = new byte[wh3];
byte[] b = dbRaster.getData();
gl.glFlush();
gl.glReadBuffer( GL.GL_FRONT );
gl.glReadPixels( 0, 0, w, h, GL.GL_RGB, GL.GL_UNSIGNED_BYTE, buf);
gl.glFlush();
This should have just put all the rgb bytes into array buf, which is upside-down from png perspective. But whether I comment out the flipVert or not, it is not only upside-down, it is shifted by one pixel (causing a 45 degree slant in the drawing) and even more disturbing, the colors go crazy, indicating that the rgb bytes are not even aligned properly. If it was my processing, then commenting and uncommenting flipVert should solve/recreate the problem. It does not. It also swaps halves of the image left and right. So I “fixed” the code with these awful -1 that I do not really understand, but then, when I change the size of the window and run again, my horrible “fix” no longer works. I don’t think it’s the rgbToIndexed routine (though I include it below anyway) because the same problem appears if I write an RGB png file without the conversion to indexed.
Somehow, it seems as though the buffer is not getting copied in correctly aligned, certainly is not the size that I am asking for. Is there anything obvious I am doing wrong with the readPixel call??
flipVert(buf, w, h);
//System.out.println("buflen="+b.length + " w=" + w + " h=" + h);
rgbToIndexed(buf, b,w);
shiftHoriz(b, w-1, h,(w-1)/2);
public static void shiftHoriz(byte[] buf, int w, int h, int w2) {
byte temp;
for (int y = 0, row = 0; y < h-1; y++, row += w) {
for (int x = 0; x< w2; x++) {
temp = buf[row + x];
buf[row + x] = buf[row + w2+x];
buf[row+w2+x] = temp;
}
}
}
public static void flipVert(byte[] buf, int maxX, int maxY) {
byte r, g, b;
for (int y = 0, top = 0, bottom = 3*maxX * (maxY-1); y<(maxY/2); y++, bottom-=maxX*3, top+=3*maxX) {
for (int x = 0; x<3*maxX; x+=3) {
r = buf[bottom+x ];
g = buf[bottom+x+1];
b = buf[bottom+x+2];
buf[bottom+x ] = buf[top+x ];
buf[bottom+x+1] = buf[top+x+1];
buf[bottom+x+2] = buf[top+x+2];
buf[top+x ] = r;
buf[top+x+1] = g;
buf[top+x+2] = b;
}
}
}
public static void rgbToIndexed(byte[] rgb, byte[] ind, int w) {
byte clr = 0;
for (int i = 0, j = 0; i < ind.length; i++, j+=3){
ind[i] = lookupColor(rgb[j], rgb[j+1], rgb[j+2]);
}
}