|
|
|
@ -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); |
|
|
|
|
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"); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
int width = image.getWidth(); |
|
|
|
|
int height = image.getHeight(); |
|
|
|
|
int depth = image.getDepth(); |
|
|
|
|
|
|
|
|
|
if (data != null) { |
|
|
|
|
gl.glPixelStorei(GL.GL_UNPACK_ALIGNMENT, 1); |
|
|
|
|
if (image.getMipMapSizes() != null) { |
|
|
|
|
throw new UnsupportedOperationException("Updating mip-mappped images is not supported"); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
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 }; |
|
|
|
|
} |
|
|
|
|
if (image.getMultiSamples() > 1) { |
|
|
|
|
throw new UnsupportedOperationException("Updating multisampled images is not supported"); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
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; |
|
|
|
|
Image.Format jmeFormat = image.getFormat(); |
|
|
|
|
|
|
|
|
|
if (glFmt.compressed && data != null){ |
|
|
|
|
if (target == GL.GL_TEXTURE_3D){ |
|
|
|
|
gl.glCompressedTexSubImage3D(target, i, x, y, index, mipWidth, mipHeight, mipDepth, glFmtInternal, data); |
|
|
|
|
continue; |
|
|
|
|
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"); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
// all other targets use 2D: array, cubemap, 2d
|
|
|
|
|
gl.glCompressedTexSubImage2D(target, i, x, y, mipWidth, mipHeight, glFmtInternal, data); |
|
|
|
|
continue; |
|
|
|
|
} |
|
|
|
|
boolean getSrgbFormat = image.getColorSpace() == ColorSpace.sRGB && linearizeSrgb; |
|
|
|
|
GLImageFormat oglFormat = getImageFormatWithError(jmeFormat, getSrgbFormat); |
|
|
|
|
|
|
|
|
|
if (target == GL.GL_TEXTURE_3D){ |
|
|
|
|
gl.glTexSubImage3D(target, i, x, y, index, mipWidth, mipHeight, mipDepth, glFmtFormat, glFmtDataType, data); |
|
|
|
|
continue; |
|
|
|
|
} |
|
|
|
|
ByteBuffer data = null; |
|
|
|
|
|
|
|
|
|
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; |
|
|
|
|
if (index >= 0) { |
|
|
|
|
data = image.getData(index); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
gl.glTexSubImage3D(target, i, x, y, index, width, height, 1, glFmtFormat, glFmtDataType, data); |
|
|
|
|
continue; |
|
|
|
|
if (data == null) { |
|
|
|
|
throw new IndexOutOfBoundsException("The image index " + index + " is not valid for the given image"); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
if (samples > 1){ |
|
|
|
|
throw new IllegalStateException("Cannot update multisample textures"); |
|
|
|
|
} |
|
|
|
|
data.position(0); |
|
|
|
|
data.limit(data.capacity()); |
|
|
|
|
|
|
|
|
|
gl.glTexSubImage2D(target, i, x, y, mipWidth, mipHeight, glFmtFormat, glFmtDataType, data); |
|
|
|
|
gl.glTexSubImage2D(target, 0, x, y, image.getWidth(), image.getHeight(), |
|
|
|
|
oglFormat.format, oglFormat.dataType, data); |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
*/ |
|
|
|
|
} |
|
|
|
|