Bug 257

Summary: RFE: Texture.updateSubImage(x,y,w,h)
Product: [JogAmp] Jogl Reporter: Sven Gothel <sgothel>
Component: coreAssignee: Sven Gothel <sgothel>
Status: VERIFIED FIXED    
Severity: normal    
Priority: P3    
Version: 1   
Hardware: All   
OS: all   
Type: FEATURE SCM Refs:
Workaround: ---

Description Sven Gothel 2010-03-24 07:49:45 CET


---- Reported by campbell 2006-12-07 10:10:21 ----

I've seen a couple requests recently for a Texture.updateSubImage(x,y,w,h) method, see the comments 
here:
http://weblogs.java.net/blog/campbell/archive/2006/10/easy_2d3d_mixin.html

One person had a go at it, but it's not a complete solution:
http://ochafik.free.fr/blog/?p=87

This method would be useful for those cases where you're trying to keep a various regions of a 
BufferedImage in sync with a Texture object.  Imagine you have a 500x500 BufferedImage, and you only 
want to update a small portion of the texture each time around.  Today you have two choices: 1) use 
updateImage(), but this will update the entire image each time, or 2) use updateSubImage(), but the x/y 
parameters are only for the destination, so you'd have to use BufferedImage.getSubimage() to position 
the source correctly, which isn't the most performant solution (would require creating a new 
BufferedImage object for each update).

So the new method might look like this:
    public void updateSubImage(TextureData data, int mipmapLevel,
                               int dstx, int dsty, int srcx, int srcy,
                               int width, int height);

But I see now that this might require lots of changes, e.g. we'd probably need something like 
TextureData.getBuffer(int x, int y).  Any thoughts on whether this would be worth pursuing (or whether 
it's possible without tearing the world apart)?



---- Additional Comments From campbell 2006-12-07 10:27:48 ----

Maybe we wouldn't need a TextureData.getBuffer(x,y) method after all.  It could be as simple as:
    glPixelStorei(GL_UNPACK_SKIP_PIXELS, srcx);
    glPixelStorei(GL_UNPACK_SKIP_ROWS, srcy);
    glPixelStorei(GL_UNPACK_ROW_LENGTH, textureData.getWidth());
    glPixelStorei(GL_UNPACK_ALIGNMENT, textureData.getAlignment());

The only question mark is about GL_UNPACK_ROW_LENGTH, since BufferedImages can (in theory, but 
not commonly) have extra padding at the end of scanlines, so you'd need something like this instead (if 
these methods actually existed on TextureData):
    glPixelStorei(GL_UNPACK_ROW_LENGTH,
                  textureData.getScanlineStride() / textureData.getPixelStride());

We may need to restrict this stuff to non-compressed and non-mipmapped textures only.



---- Additional Comments From kbr 2006-12-29 08:53:11 ----

Changed TextureIO's BufferedImage code paths to no longer copy the
data in order to correct for the vertical flip needed between Java
2D's and OpenGL's coordinate systems, but instead to correct for this
using a flip of the texture coordinates. This was needed to change the
semantics for the BufferedImage from "by-copy" to "by-reference". Made
the custom BufferedImage copying code path occur lazily upon a call to
TextureData.getBuffer(). Added support for the GL_EXT_abgr extension
but disabled the code path currently as it appears there may be bugs
in its support on some drivers. Added computation of row width for all
BufferedImage types with help and suggestions from Chris Campbell.
Improved handling of some BufferedImage types like TYPE_INT_ARGB and
TYPE_4BYTE_ABGR. Added Texture.updateSubImage() taking a source
rectangle as well as a destination coordinate. Wrote TestSubImage test
to show use of the new API which exercises all BufferedImage types.




--- Bug imported by sgothel@jausoft.com 2010-03-24 07:49 EDT  ---

This bug was previously known as _bug_ 257 at https://jogl.dev.java.net/bugs/show_bug.cgi?id=257