glGetTexImage

Hi all

I’m trying to get a texture image from the GPU back into a BufferedImage, but I can’t get it right. This is the code:


            BufferedImage bkgImage = new BufferedImage(256,256, BufferedImage.TYPE_INT_ARGB);

            //load image data...
            
            DataBufferInt buffer = (DataBufferInt) bkgImage.getRaster().getDataBuffer();
            gl.glShadeModel(GL.GL_FLAT);
            gl.glPixelStorei(GL.GL_UNPACK_ALIGNMENT, 1);
            gl.glBindTexture(GL.GL_TEXTURE_2D, backgroundTexturePointerID);
            gl.glTexEnvf(GL.GL_TEXTURE_ENV, GL.GL_TEXTURE_ENV_MODE, GL.GL_DECAL);
            gl.glTexParameterf(GL.GL_TEXTURE_2D, GL.GL_TEXTURE_WRAP_S, GL.GL_CLAMP_TO_EDGE);
            gl.glTexParameterf(GL.GL_TEXTURE_2D, GL.GL_TEXTURE_WRAP_T, GL.GL_CLAMP_TO_EDGE);
            gl.glTexParameterf(GL.GL_TEXTURE_2D, GL.GL_TEXTURE_MAG_FILTER, GL.GL_LINEAR);
            gl.glTexParameterf(GL.GL_TEXTURE_2D, GL.GL_TEXTURE_MIN_FILTER, GL.GL_LINEAR);
            
            gl.glTexImage2D(GL.GL_TEXTURE_2D, 0, 4, bkgImage.getWidth(), bkgImage.getHeight(), 0, 
                            GL.GL_BGRA, GL.GL_UNSIGNED_INT_8_8_8_8_REV, buffer.getData());


            gl.glBindTexture(GL.GL_TEXTURE_2D, backgroundTexturePointerID);
            bkgImage.flush();
            bkgImage = null;

            
            int[] pixels = new int[256*256];
            gl.glGetTexImage(GL.GL_TEXTURE_2D,0,GL.GL_BGRA, GL.GL_UNSIGNED_INT_8_8_8_8_REV,pixels);
            BufferedImage image = new BufferedImage(256,256, BufferedImage.TYPE_INT_ARGB);
            image.getRaster().setSamples(0,0,256,256,0,pixels);
            
            JLabel l = new JLabel(new ImageIcon(image));
            JFrame f = new JFrame();
            f.setLayout(null);
            l.setBounds(0,0,256,256);
            l.setBorder(BorderFactory.createLineBorder(Color.yellow));
            f.add(l);
            
            f.setSize(300,300);
            f.setVisible(true);

The above code should show the same image that was loaded in the first place and was used for the texture. Instead, I get all kinds of strange results, depending on the pixel format and type I use when calling glGetTexImage.

a) Should pixel format and type when calling the glGetTexImage be the same with the ones used when specifying the texture with glTexImage, or there is an auto conversion between different formats?

b) What happens when other pixel formats are used? For example, if the pixel format for the texture is BGR, and type is GL_UNSIGNED BYTE, how can one set the byte[] of pixels to a bufferedImage? setSamples can’t use byte arrays, so does an int array have to be created from the byte array?

c) is it possible to create a texture from other existing texture data, without getting all the texture images back to CPU/memory, combine them and then put them in a new texture?

(Sorry about the too many questions)

TIA
N

I’ve done some testing, and it seems that for some reason the image.getRaster().setSamples() has no result. Instead, when I used the image.setRGB(), everyting works fine.

However, the problem related to “non INT” formats and types in images and textures remains. Also, if anyone has any idea about creating textures from other alteady existing textures, or mosaicking images at the GPU, please let me know.

You can call BufferedImage.getRaster().getDataBuffer() to get a pointer to the actual pixels to feed to glGetTexImage. The DataBuffer will typically be either a DataBufferByte or DataBufferInt from which you can extract the byte[] or int[]. Take a look at the GLJPanel source code which does similar operations.

You were right, but now I get another strange behavior. Here is my code:

           
 //First, read already existing texture data, and put it to an image.
            int id = parent.model.textureRegistry.getFirstAvailableTexture(bounds);
            Texture t = parent.model.textureRegistry.getTexture(id);
            //System.out.println("Will use texture: "+id);
            BufferedImage image = new BufferedImage(t.width,t.height, BufferedImage.TYPE_INT_ARGB);
            DataBufferInt buffer = (DataBufferInt) image.getRaster().getDataBuffer();
            gl.glGetTexImage(GL.GL_TEXTURE_2D,0,GL.GL_BGRA, GL.GL_UNSIGNED_INT_8_8_8_8_REV,buffer.getData());

            
 
            BufferedImage backgroundArea = null;
            if (t.bounds.equals(bounds)){
                System.out.println("Hey, using our own texture!");
            }


            JLabel l = new JLabel(new ImageIcon(image));
            JFrame f = new JFrame("Input");
            f.setLayout(null);
            l.setBounds(0,0,256,256);
            l.setBorder(BorderFactory.createLineBorder(Color.yellow));
            f.add(l);
                     
            f.setSize(300,300);
            f.setVisible(true);
            
            BufferedImage i = Mosaicker.mosaic2(image, new GeographicFeatureArray(), 
                    bounds, 
                    new Dimension(128,128),
                    BufferedImage.TYPE_INT_ARGB,
                    Mosaicker.INTERPOLATION_NEAREST_NEIGHBOUR);
            image.flush();
            image = null;
            imageGeoObjects.clear();
            
            if (i != null){
                DataBufferInt buffer2 = (DataBufferInt) i.getData().getDataBuffer();
                int[] arr = new int[buffer2.getData().length];
                System.arraycopy(arr,0,buffer2.getData(),0,arr.length);
                gl.glShadeModel(GL.GL_FLAT);
                gl.glPixelStorei(GL.GL_UNPACK_ALIGNMENT, 1);
                
                gl.glBindTexture(GL.GL_TEXTURE_2D, textureID);
                /*
                gl.glTexEnvf(GL.GL_TEXTURE_ENV, GL.GL_TEXTURE_ENV_MODE, GL.GL_DECAL);
                gl.glTexParameterf(GL.GL_TEXTURE_2D, GL.GL_TEXTURE_WRAP_S, GL.GL_CLAMP_TO_EDGE);
                gl.glTexParameterf(GL.GL_TEXTURE_2D, GL.GL_TEXTURE_WRAP_T, GL.GL_CLAMP_TO_EDGE);
                gl.glTexParameterf(GL.GL_TEXTURE_2D, GL.GL_TEXTURE_MAG_FILTER, GL.GL_LINEAR);
                gl.glTexParameterf(GL.GL_TEXTURE_2D, GL.GL_TEXTURE_MIN_FILTER, GL.GL_LINEAR);
/*                
                gl.glTexImage2D(GL.GL_TEXTURE_2D, 0, 4, i.getWidth(), i.getHeight(), 0, 
                                GL.GL_BGRA, GL.GL_UNSIGNED_INT_8_8_8_8_REV, arr);
                
                gl.glBindTexture(GL.GL_TEXTURE_2D, textureID);
*/                
//                parent.model.textureRegistry.add(texture = new Texture(textureID, key,
//                        bounds, i.getWidth(), i.getHeight()));    
                
                //i.flush();        
                
            }
            
            dirtyData = false;

Please ignore the previous post, it was sent accidentally to this forum.

Sorry about that! :-\