|
@@ -54,6 +54,7 @@ final class TextureUtil {
|
|
|
private final GL2 gl2;
|
|
|
private final GLExt glext;
|
|
|
private GLImageFormat[][] formats;
|
|
|
+ private boolean supportUnpackRowLength;
|
|
|
|
|
|
public TextureUtil(GL gl, GL2 gl2, GLExt glext) {
|
|
|
this.gl = gl;
|
|
@@ -62,6 +63,7 @@ final class TextureUtil {
|
|
|
}
|
|
|
|
|
|
public void initialize(EnumSet<Caps> caps) {
|
|
|
+ supportUnpackRowLength = caps.contains(Caps.UnpackRowLength);
|
|
|
this.formats = GLImageFormats.getFormatsForCaps(caps);
|
|
|
if (logger.isLoggable(Level.FINE)) {
|
|
|
StringBuilder sb = new StringBuilder();
|
|
@@ -298,6 +300,10 @@ final class TextureUtil {
|
|
|
}
|
|
|
}
|
|
|
|
|
|
+ /**
|
|
|
+ * @deprecated Use uploadSubTexture(int target, Image src, int index,int targetX, int targetY,int srcX,int srcY, int areaWidth,int areaHeight, boolean linearizeSrgb)
|
|
|
+ */
|
|
|
+ @Deprecated
|
|
|
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");
|
|
@@ -338,4 +344,63 @@ final class TextureUtil {
|
|
|
gl.glTexSubImage2D(target, 0, x, y, image.getWidth(), image.getHeight(),
|
|
|
oglFormat.format, oglFormat.dataType, data);
|
|
|
}
|
|
|
+
|
|
|
+ public void uploadSubTexture(int target, Image src, int index, int targetX, int targetY, int areaX, int areaY, int areaWidth, int areaHeight, boolean linearizeSrgb) {
|
|
|
+ if (target != GL.GL_TEXTURE_2D || src.getDepth() > 1) {
|
|
|
+ throw new UnsupportedOperationException("Updating non-2D texture is not supported");
|
|
|
+ }
|
|
|
+
|
|
|
+ if (src.getMipMapSizes() != null) {
|
|
|
+ throw new UnsupportedOperationException("Updating mip-mappped images is not supported");
|
|
|
+ }
|
|
|
+
|
|
|
+ if (src.getMultiSamples() > 1) {
|
|
|
+ throw new UnsupportedOperationException("Updating multisampled images is not supported");
|
|
|
+ }
|
|
|
+
|
|
|
+ Image.Format jmeFormat = src.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 = src.getColorSpace() == ColorSpace.sRGB && linearizeSrgb;
|
|
|
+ GLImageFormat oglFormat = getImageFormatWithError(jmeFormat, getSrgbFormat);
|
|
|
+
|
|
|
+ ByteBuffer data = src.getData(index);
|
|
|
+
|
|
|
+ if (data == null) {
|
|
|
+ throw new IndexOutOfBoundsException("The image index " + index + " is not valid for the given image");
|
|
|
+ }
|
|
|
+
|
|
|
+ int Bpp = src.getFormat().getBitsPerPixel() / 8;
|
|
|
+
|
|
|
+ int srcWidth = src.getWidth();
|
|
|
+ int cpos = data.position();
|
|
|
+ int skip = areaX;
|
|
|
+ skip += areaY * srcWidth;
|
|
|
+ skip *= Bpp;
|
|
|
+
|
|
|
+ data.position(skip);
|
|
|
+
|
|
|
+ boolean needsStride = srcWidth != areaWidth;
|
|
|
+
|
|
|
+ if (needsStride && (!supportUnpackRowLength)) { // doesn't support stride, copy row by row (slower).
|
|
|
+ for (int i = 0; i < areaHeight; i++) {
|
|
|
+ data.position(skip + (srcWidth * Bpp * i));
|
|
|
+ gl.glTexSubImage2D(target, 0, targetX, targetY + i, areaWidth, 1, oglFormat.format, oglFormat.dataType, data);
|
|
|
+ }
|
|
|
+ } else {
|
|
|
+ if (needsStride)
|
|
|
+ gl2.glPixelStorei(GL.GL_UNPACK_ROW_LENGTH, srcWidth);
|
|
|
+ gl.glTexSubImage2D(target, 0, targetX, targetY, areaWidth, areaHeight, oglFormat.format, oglFormat.dataType, data);
|
|
|
+ if (needsStride)
|
|
|
+ gl2.glPixelStorei(GL.GL_UNPACK_ROW_LENGTH, 0);
|
|
|
+ }
|
|
|
+ data.position(cpos);
|
|
|
+
|
|
|
+ }
|
|
|
+
|
|
|
}
|