浏览代码

GLRenderer: Fix modifyTexture(). Clarify documentation.

shadowislord 10 年之前
父节点
当前提交
fb7708af24

+ 4 - 1
jme3-core/src/main/java/com/jme3/renderer/Renderer.java

@@ -235,7 +235,10 @@ public interface Renderer {
     public void setTexture(int unit, Texture tex);
 
     /**
-     * Modify the given Texture tex with the given Image. The image will be put at x and y into the texture.
+     * Modify the given Texture with the given Image. 
+     * The image will be put at x and y into the texture.
+     * 
+     * NOTE: this is only supported for uncompressed 2D images without mipmaps.
      *
      * @param tex the Texture that will be modified
      * @param pixels the source Image data to copy data from

+ 3 - 2
jme3-core/src/main/java/com/jme3/renderer/opengl/GLRenderer.java

@@ -2111,8 +2111,9 @@ public class GLRenderer implements Renderer {
     }
 
     public void modifyTexture(Texture tex, Image pixels, int x, int y) {
-//        setTexture(0, tex);
-//        texUtil.uploadSubTexture(caps, pixels, convertTextureType(tex.getType(), pixels.getMultiSamples(), -1), 0, x, y, linearizeSrgbImages);
+        setTexture(0, tex);
+        int target = convertTextureType(tex.getType(), pixels.getMultiSamples(), -1);
+        texUtil.uploadSubTexture(pixels, target, 0, x, y, linearizeSrgbImages);
     }
 
     public void deleteImage(Image image) {

+ 39 - 103
jme3-core/src/main/java/com/jme3/renderer/opengl/TextureUtil.java

@@ -259,108 +259,44 @@ final class TextureUtil {
         }
     }
 
-    /**
-     * Update the texture currently bound to target at with data from the given
-     * Image at position x and y. The parameter index is used as the zoffset in
-     * case a 3d texture or texture 2d array is being updated.
-     *
-     * @param image Image with the source data (this data will be put into the
-     * texture)
-     * @param target the target texture
-     * @param index the mipmap level to update
-     * @param x the x position where to put the image in the texture
-     * @param y the y position where to put the image in the texture
-     */
-    /*
-     public void uploadSubTexture(
-     EnumSet<Caps> caps,
-     Image image,
-     int target,
-     int index,
-     int x,
-     int y,
-     boolean linearizeSrgb) {
-     Image.Format fmt = image.getFormat();
-     GLImageFormat glFmt = getImageFormatWithError(caps, fmt, image.getColorSpace() == ColorSpace.sRGB  && linearizeSrgb);
-
-     ByteBuffer data = null;
-     if (index >= 0 && image.getData() != null && image.getData().size() > 0) {
-     data = image.getData(index);
-     }
-
-     int width = image.getWidth();
-     int height = image.getHeight();
-     int depth = image.getDepth();
-
-     if (data != null) {
-     gl.glPixelStorei(GL.GL_UNPACK_ALIGNMENT, 1);
-     }
-
-     int[] mipSizes = image.getMipMapSizes();
-     int pos = 0;
-
-     // TODO: Remove unneccessary allocation
-     if (mipSizes == null){
-     if (data != null) {
-     mipSizes = new int[]{ data.capacity() };
-     } else {
-     mipSizes = new int[]{ width * height * fmt.getBitsPerPixel() / 8 };
-     }
-     }
-
-     int samples = image.getMultiSamples();
-
-     for (int i = 0; i < mipSizes.length; i++){
-     int mipWidth =  Math.max(1, width  >> i);
-     int mipHeight = Math.max(1, height >> i);
-     int mipDepth =  Math.max(1, depth  >> i);
-
-     if (data != null){
-     data.position(pos);
-     data.limit(pos + mipSizes[i]);
-     }
-
-     // to remove the cumbersome if/then/else stuff below we'll update the pos right here and use continue after each
-     // gl*Image call in an attempt to unclutter things a bit
-     pos += mipSizes[i];
-
-     int glFmtInternal = glFmt.internalFormat;
-     int glFmtFormat = glFmt.format;
-     int glFmtDataType = glFmt.dataType;
-
-     if (glFmt.compressed && data != null){
-     if (target == GL.GL_TEXTURE_3D){
-     gl.glCompressedTexSubImage3D(target, i, x, y, index, mipWidth, mipHeight, mipDepth, glFmtInternal, data);
-     continue;
-     }
-
-     // all other targets use 2D: array, cubemap, 2d
-     gl.glCompressedTexSubImage2D(target, i, x, y, mipWidth, mipHeight, glFmtInternal, data);
-     continue;
-     }
-
-     if (target == GL.GL_TEXTURE_3D){
-     gl.glTexSubImage3D(target, i, x, y, index, mipWidth, mipHeight, mipDepth, glFmtFormat, glFmtDataType, data);
-     continue;
-     }
-
-     if (target == GLExt.GL_TEXTURE_2D_ARRAY_EXT){
-     // prepare data for 2D array or upload slice
-     if (index == -1){
-     gl.glTexSubImage3D(target, i, x, y, index, mipWidth, mipHeight, mipDepth, glFmtFormat, glFmtDataType, data);
-     continue;
-     }
-
-     gl.glTexSubImage3D(target, i, x, y, index, width, height, 1, glFmtFormat, glFmtDataType, data);
-     continue;
-     }
-
-     if (samples > 1){
-     throw new IllegalStateException("Cannot update multisample textures");
-     }
+    public void uploadSubTexture(Image image, int target, int index, int x, int y, boolean linearizeSrgb) {
+        if (target != GL.GL_TEXTURE_2D || image.getDepth() > 1) {
+            throw new UnsupportedOperationException("Updating non-2D texture is not supported");
+        }
+        
+        if (image.getMipMapSizes() != null) {
+            throw new UnsupportedOperationException("Updating mip-mappped images is not supported");
+        }
+        
+        if (image.getMultiSamples() > 1) {
+            throw new UnsupportedOperationException("Updating multisampled images is not supported");
+        }
+        
+        Image.Format jmeFormat = image.getFormat();
+        
+        if (jmeFormat.isCompressed()) {
+            throw new UnsupportedOperationException("Updating compressed images is not supported");
+        } else if (jmeFormat.isDepthFormat()) {
+            throw new UnsupportedOperationException("Updating depth images is not supported");
+        }
+        
+        boolean getSrgbFormat = image.getColorSpace() == ColorSpace.sRGB && linearizeSrgb;
+        GLImageFormat oglFormat = getImageFormatWithError(jmeFormat, getSrgbFormat);
+        
+        ByteBuffer data = null;
+        
+        if (index >= 0) {
+            data = image.getData(index);
+        }
+        
+        if (data == null) {
+            throw new IndexOutOfBoundsException("The image index " + index + " is not valid for the given image");
+        }
 
-     gl.glTexSubImage2D(target, i, x, y, mipWidth, mipHeight, glFmtFormat, glFmtDataType, data);
-     }
-     }
-     */
+        data.position(0);
+        data.limit(data.capacity());
+        
+        gl.glTexSubImage2D(target, 0, x, y, image.getWidth(), image.getHeight(), 
+                           oglFormat.format, oglFormat.dataType, data);
+    }
 }