|
|
@ -54,6 +54,7 @@ final class TextureUtil { |
|
|
|
private final GL2 gl2; |
|
|
|
private final GL2 gl2; |
|
|
|
private final GLExt glext; |
|
|
|
private final GLExt glext; |
|
|
|
private GLImageFormat[][] formats; |
|
|
|
private GLImageFormat[][] formats; |
|
|
|
|
|
|
|
private boolean supportUnpackRowLength; |
|
|
|
|
|
|
|
|
|
|
|
public TextureUtil(GL gl, GL2 gl2, GLExt glext) { |
|
|
|
public TextureUtil(GL gl, GL2 gl2, GLExt glext) { |
|
|
|
this.gl = gl; |
|
|
|
this.gl = gl; |
|
|
@ -62,6 +63,7 @@ final class TextureUtil { |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
public void initialize(EnumSet<Caps> caps) { |
|
|
|
public void initialize(EnumSet<Caps> caps) { |
|
|
|
|
|
|
|
supportUnpackRowLength = caps.contains(Caps.UnpackRowLength); |
|
|
|
this.formats = GLImageFormats.getFormatsForCaps(caps); |
|
|
|
this.formats = GLImageFormats.getFormatsForCaps(caps); |
|
|
|
if (logger.isLoggable(Level.FINE)) { |
|
|
|
if (logger.isLoggable(Level.FINE)) { |
|
|
|
StringBuilder sb = new StringBuilder(); |
|
|
|
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) { |
|
|
|
public void uploadSubTexture(Image image, int target, int index, int x, int y, boolean linearizeSrgb) { |
|
|
|
if (target != GL.GL_TEXTURE_2D || image.getDepth() > 1) { |
|
|
|
if (target != GL.GL_TEXTURE_2D || image.getDepth() > 1) { |
|
|
|
throw new UnsupportedOperationException("Updating non-2D texture is not supported"); |
|
|
|
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(), |
|
|
|
gl.glTexSubImage2D(target, 0, x, y, image.getWidth(), image.getHeight(), |
|
|
|
oglFormat.format, oglFormat.dataType, data); |
|
|
|
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); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
} |
|
|
|
} |
|
|
|