Image
defines a data format for a graphical image. The image
- * is defined by a format, a height and width, and the image data. The width and
- * height must be greater than 0. The data is contained in a byte buffer, and
- * should be packed before creation of the image object.
- *
- * @author Mark Powell
- * @author Joshua Slack
- * @version $Id: Image.java 4131 2009-03-19 20:15:28Z blaine.dev $
- */
-public class Image extends NativeObject implements Savable /*, Cloneable*/ {
-
- public enum Format {
- /**
- * 8-bit alpha
- */
- Alpha8(8),
-
- /**
- * 16-bit alpha
- */
- Alpha16(16),
-
- /**
- * 8-bit grayscale/luminance.
- */
- Luminance8(8),
-
- /**
- * 16-bit grayscale/luminance.
- */
- Luminance16(16),
-
- /**
- * half-precision floating-point grayscale/luminance.
- */
- Luminance16F(16,true),
-
- /**
- * single-precision floating-point grayscale/luminance.
- */
- Luminance32F(32,true),
-
- /**
- * 8-bit luminance/grayscale and 8-bit alpha.
- */
- Luminance8Alpha8(16),
-
- /**
- * 16-bit luminance/grayscale and 16-bit alpha.
- */
- Luminance16Alpha16(32),
-
- /**
- * half-precision floating-point grayscale/luminance and alpha.
- */
- Luminance16FAlpha16F(32,true),
-
- @Deprecated
- Intensity8(8),
-
- @Deprecated
- Intensity16(16),
-
- /**
- * 8-bit blue, green, and red.
- */
- BGR8(24), // BGR and ABGR formats are often used on windows systems
-
- /**
- * 8-bit red, green, and blue.
- */
- RGB8(24),
-
- @Deprecated
- RGB10(30),
-
- /**
- * 16-bit red, green, and blue.
- */
- RGB16(48),
-
- /**
- * 5-bit red, 6-bit green, and 5-bit blue.
- */
- RGB565(16),
-
- /**
- * 4-bit alpha, red, green, and blue. Used on Android only.
- */
- ARGB4444(16),
-
- /**
- * 5-bit red, green, and blue with 1-bit alpha.
- */
- RGB5A1(16),
-
- /**
- * 8-bit red, green, blue, and alpha.
- */
- RGBA8(32),
-
- /**
- * 8-bit alpha, blue, green, and red.
- */
- ABGR8(32),
-
- /**
- * 16-bit red, green, blue and alpha
- */
- RGBA16(64),
-
- /**
- * S3TC compression DXT1.
- * Called BC1 in DirectX10.
- */
- DXT1(4,false,true, false),
-
- /**
- * S3TC compression DXT1 with 1-bit alpha.
- */
- DXT1A(4,false,true, false),
-
- /**
- * S3TC compression DXT3 with 4-bit alpha.
- * Called BC2 in DirectX10.
- */
- DXT3(8,false,true, false),
-
- /**
- * S3TC compression DXT5 with interpolated 8-bit alpha.
- * Called BC3 in DirectX10.
- */
- DXT5(8,false,true, false),
-
- /**
- * Luminance-Alpha Texture Compression.
- * Called BC5 in DirectX10.
- */
- LATC(8, false, true, false),
-
- /**
- * Arbitrary depth format. The precision is chosen by the video
- * hardware.
- */
- Depth(0,true,false,false),
-
- /**
- * 16-bit depth.
- */
- Depth16(16,true,false,false),
-
- /**
- * 24-bit depth.
- */
- Depth24(24,true,false,false),
-
- /**
- * 32-bit depth.
- */
- Depth32(32,true,false,false),
-
- /**
- * single-precision floating point depth.
- */
- Depth32F(32,true,false,true),
-
- /**
- * Texture data is stored as {@link Format#RGB16F} in system memory,
- * but will be converted to {@link Format#RGB111110F} when sent
- * to the video hardware.
- */
- RGB16F_to_RGB111110F(48,true),
-
- /**
- * unsigned floating-point red, green and blue that uses 32 bits.
- */
- RGB111110F(32,true),
-
- /**
- * Texture data is stored as {@link Format#RGB16F} in system memory,
- * but will be converted to {@link Format#RGB9E5} when sent
- * to the video hardware.
- */
- RGB16F_to_RGB9E5(48,true),
-
- /**
- * 9-bit red, green and blue with 5-bit exponent.
- */
- RGB9E5(32,true),
-
- /**
- * half-precision floating point red, green, and blue.
- */
- RGB16F(48,true),
-
- /**
- * half-precision floating point red, green, blue, and alpha.
- */
- RGBA16F(64,true),
-
- /**
- * single-precision floating point red, green, and blue.
- */
- RGB32F(96,true),
-
- /**
- * single-precision floating point red, green, blue and alpha.
- */
- RGBA32F(128,true),
-
- /**
- * Luminance/grayscale texture compression.
- * Called BC4 in DirectX10.
- */
- LTC(4, false, true, false),
-
- /**
- * 24-bit depth with 8-bit stencil.
- * Check the cap {@link Caps#PackedDepthStencilBuffer}.
- */
- Depth24Stencil8(32, true, false, false);
-
- private int bpp;
- private boolean isDepth;
- private boolean isCompressed;
- private boolean isFloatingPoint;
-
- private Format(int bpp){
- this.bpp = bpp;
- }
-
- private Format(int bpp, boolean isFP){
- this(bpp);
- this.isFloatingPoint = isFP;
- }
-
- private Format(int bpp, boolean isDepth, boolean isCompressed, boolean isFP){
- this(bpp, isFP);
- this.isDepth = isDepth;
- this.isCompressed = isCompressed;
- }
-
- /**
- * @return bits per pixel.
- */
- public int getBitsPerPixel(){
- return bpp;
- }
-
- /**
- * @return True if this format is a depth format, false otherwise.
- */
- public boolean isDepthFormat(){
- return isDepth;
- }
-
- /**
- * @return True if this is a compressed image format, false if
- * uncompressed.
- */
- public boolean isCompressed() {
- return isCompressed;
- }
-
- /**
- * @return True if this image format is in floating point,
- * false if it is an integer format.
- */
- public boolean isFloatingPont(){
- return isFloatingPoint;
- }
-
- }
-
- // image attributes
- protected Format format;
- protected int width, height, depth;
- protected int[] mipMapSizes;
- protected ArrayListImage
object. All values
- * are undefined.
- */
- public Image() {
- super(Image.class);
- data = new ArrayListImage
object. The
- * attributes of the image are defined during construction.
- *
- * @param format
- * the data format of the image.
- * @param width
- * the width of the image.
- * @param height
- * the height of the image.
- * @param data
- * the image data.
- * @param mipMapSizes
- * the array of mipmap sizes, or null for no mipmaps.
- */
- public Image(Format format, int width, int height, int depth, ArrayListImage
object. The
- * attributes of the image are defined during construction.
- *
- * @param format
- * the data format of the image.
- * @param width
- * the width of the image.
- * @param height
- * the height of the image.
- * @param data
- * the image data.
- * @param mipMapSizes
- * the array of mipmap sizes, or null for no mipmaps.
- */
- public Image(Format format, int width, int height, ByteBuffer data,
- int[] mipMapSizes) {
-
- this();
-
- if (mipMapSizes != null && mipMapSizes.length <= 1) {
- mipMapSizes = null;
- }
-
- setFormat(format);
- this.width = width;
- this.height = height;
- if (data != null){
- this.data = new ArrayListImage
object. The
- * attributes of the image are defined during construction.
- *
- * @param format
- * the data format of the image.
- * @param width
- * the width of the image.
- * @param height
- * the height of the image.
- * @param data
- * the image data.
- */
- public Image(Format format, int width, int height, int depth, ArrayListImage
object. The
- * attributes of the image are defined during construction.
- *
- * @param format
- * the data format of the image.
- * @param width
- * the width of the image.
- * @param height
- * the height of the image.
- * @param data
- * the image data.
- */
- public Image(Format format, int width, int height, ByteBuffer data) {
- this(format, width, height, data, null);
- }
-
- /**
- * @return The number of samples (for multisampled textures).
- * @see Image#setMultiSamples(int)
- */
- public int getMultiSamples() {
- return multiSamples;
- }
-
- /**
- * @param multiSamples Set the number of samples to use for this image,
- * setting this to a value higher than 1 turns this image/texture
- * into a multisample texture (on OpenGL3.1 and higher).
- */
- public void setMultiSamples(int multiSamples) {
- if (multiSamples <= 0)
- throw new IllegalArgumentException("multiSamples must be > 0");
-
- if (getData(0) != null)
- throw new IllegalArgumentException("Cannot upload data as multisample texture");
-
- if (hasMipmaps())
- throw new IllegalArgumentException("Multisample textures do not support mipmaps");
-
- this.multiSamples = multiSamples;
- }
-
- /**
- * setData
sets the data that makes up the image. This data
- * is packed into an array of ByteBuffer
objects.
- *
- * @param data
- * the data that contains the image information.
- */
- public void setData(ArrayListsetData
sets the data that makes up the image. This data
- * is packed into a single ByteBuffer
.
- *
- * @param data
- * the data that contains the image information.
- */
- public void setData(ByteBuffer data) {
- this.data = new ArrayList
- * Some system implementations are more efficient at operating
- * on data other than ByteBuffers, in that case, this method can be used.
- *
- * @param efficientData
- */
- public void setEfficentData(Object efficientData){
- this.efficientData = efficientData;
- setUpdateNeeded();
- }
-
- /**
- * @return The efficient data representation of this image.
- * @see Image#setEfficentData(java.lang.Object)
- */
- public Object getEfficentData(){
- return efficientData;
- }
-
- /**
- * Sets the mipmap sizes stored in this image's data buffer. Mipmaps are
- * stored sequentially, and the first mipmap is the main image data. To
- * specify no mipmaps, pass null and this will automatically be expanded
- * into a single mipmap of the full
- *
- * @param mipMapSizes
- * the mipmap sizes array, or null for a single image map.
- */
- public void setMipMapSizes(int[] mipMapSizes) {
- if (mipMapSizes != null && mipMapSizes.length <= 1)
- mipMapSizes = null;
-
- this.mipMapSizes = mipMapSizes;
- setUpdateNeeded();
- }
-
- /**
- *
+ * Some system implementations are more efficient at operating
+ * on data other than ByteBuffers, in that case, this method can be used.
+ *
+ * @param efficientData
+ */
+ public void setEfficentData(Object efficientData){
+ this.efficientData = efficientData;
+ setUpdateNeeded();
+ }
+
+ /**
+ * @return The efficient data representation of this image.
+ * @see Image#setEfficentData(java.lang.Object)
+ */
+ public Object getEfficentData(){
+ return efficientData;
+ }
+
+ /**
+ * Sets the mipmap sizes stored in this image's data buffer. Mipmaps are
+ * stored sequentially, and the first mipmap is the main image data. To
+ * specify no mipmaps, pass null and this will automatically be expanded
+ * into a single mipmap of the full
+ *
+ * @param mipMapSizes
+ * the mipmap sizes array, or null for a single image map.
+ */
+ public void setMipMapSizes(int[] mipMapSizes) {
+ if (mipMapSizes != null && mipMapSizes.length <= 1)
+ mipMapSizes = null;
+
+ this.mipMapSizes = mipMapSizes;
+
+ if (mipMapSizes != null) {
+ needGeneratedMips = false;
+ mipsWereGenerated = false;
+ } else {
+ needGeneratedMips = false;
+ mipsWereGenerated = true;
+ }
+
+ setUpdateNeeded();
+ }
+
+ /**
+ * setHeight
sets the height value of the image. It is
- * typically a good idea to try to keep this as a multiple of 2.
- *
- * @param height
- * the height of the image.
- */
- public void setHeight(int height) {
- this.height = height;
- setUpdateNeeded();
- }
-
- /**
- * setDepth
sets the depth value of the image. It is
- * typically a good idea to try to keep this as a multiple of 2. This is
- * used for 3d images.
- *
- * @param depth
- * the depth of the image.
- */
- public void setDepth(int depth) {
- this.depth = depth;
- setUpdateNeeded();
- }
-
- /**
- * setWidth
sets the width value of the image. It is
- * typically a good idea to try to keep this as a multiple of 2.
- *
- * @param width
- * the width of the image.
- */
- public void setWidth(int width) {
- this.width = width;
- setUpdateNeeded();
- }
-
- /**
- * setFormat
sets the image format for this image.
- *
- * @param format
- * the image format.
- * @throws NullPointerException
- * if format is null
- * @see Format
- */
- public void setFormat(Format format) {
- if (format == null) {
- throw new NullPointerException("format may not be null.");
- }
-
- this.format = format;
- setUpdateNeeded();
- }
-
- /**
- * getFormat
returns the image format for this image.
- *
- * @return the image format.
- * @see Format
- */
- public Format getFormat() {
- return format;
- }
-
- /**
- * getWidth
returns the width of this image.
- *
- * @return the width of this image.
- */
- public int getWidth() {
- return width;
- }
-
- /**
- * getHeight
returns the height of this image.
- *
- * @return the height of this image.
- */
- public int getHeight() {
- return height;
- }
-
- /**
- * getDepth
returns the depth of this image (for 3d images).
- *
- * @return the depth of this image.
- */
- public int getDepth() {
- return depth;
- }
-
- /**
- * getData
returns the data for this image. If the data is
- * undefined, null will be returned.
- *
- * @return the data for this image.
- */
- public ListgetData
returns the data for this image. If the data is
- * undefined, null will be returned.
- *
- * @return the data for this image.
- */
- public ByteBuffer getData(int index) {
- if (data.size() > index)
- return data.get(index);
- else
- return null;
- }
-
- /**
- * Returns whether the image data contains mipmaps.
- *
- * @return true if the image data contains mipmaps, false if not.
- */
- public boolean hasMipmaps() {
- return mipMapSizes != null;
- }
-
- /**
- * Returns the mipmap sizes for this image.
- *
- * @return the mipmap sizes for this image.
- */
- public int[] getMipMapSizes() {
- return mipMapSizes;
- }
-
- @Override
- public String toString(){
- StringBuilder sb = new StringBuilder();
- sb.append(getClass().getSimpleName());
- sb.append("[size=").append(width).append("x").append(height);
-
- if (depth > 1)
- sb.append("x").append(depth);
-
- sb.append(", format=").append(format.name());
-
- if (hasMipmaps())
- sb.append(", mips");
-
- if (getId() >= 0)
- sb.append(", id=").append(id);
-
- sb.append("]");
-
- return sb.toString();
- }
-
- @Override
- public boolean equals(Object other) {
- if (other == this) {
- return true;
- }
- if (!(other instanceof Image)) {
- return false;
- }
- Image that = (Image) other;
- if (this.getFormat() != that.getFormat())
- return false;
- if (this.getWidth() != that.getWidth())
- return false;
- if (this.getHeight() != that.getHeight())
- return false;
- if (this.getData() != null && !this.getData().equals(that.getData()))
- return false;
- if (this.getData() == null && that.getData() != null)
- return false;
- if (this.getMipMapSizes() != null
- && !Arrays.equals(this.getMipMapSizes(), that.getMipMapSizes()))
- return false;
- if (this.getMipMapSizes() == null && that.getMipMapSizes() != null)
- return false;
- if (this.getMultiSamples() != that.getMultiSamples())
- return false;
-
- return true;
- }
-
- @Override
- public int hashCode() {
- int hash = 7;
- hash = 97 * hash + (this.format != null ? this.format.hashCode() : 0);
- hash = 97 * hash + this.width;
- hash = 97 * hash + this.height;
- hash = 97 * hash + this.depth;
- hash = 97 * hash + Arrays.hashCode(this.mipMapSizes);
- hash = 97 * hash + (this.data != null ? this.data.hashCode() : 0);
- hash = 97 * hash + this.multiSamples;
- return hash;
- }
-
- public void write(JmeExporter e) throws IOException {
- OutputCapsule capsule = e.getCapsule(this);
- capsule.write(format, "format", Format.RGBA8);
- capsule.write(width, "width", 0);
- capsule.write(height, "height", 0);
- capsule.write(depth, "depth", 0);
- capsule.write(mipMapSizes, "mipMapSizes", null);
- capsule.write(multiSamples, "multiSamples", 1);
- capsule.writeByteBufferArrayList(data, "data", null);
- }
-
- public void read(JmeImporter e) throws IOException {
- InputCapsule capsule = e.getCapsule(this);
- format = capsule.readEnum("format", Format.class, Format.RGBA8);
- width = capsule.readInt("width", 0);
- height = capsule.readInt("height", 0);
- depth = capsule.readInt("depth", 0);
- mipMapSizes = capsule.readIntArray("mipMapSizes", null);
- multiSamples = capsule.readInt("multiSamples", 1);
- data = (ArrayListImage
defines a data format for a graphical image. The image
+ * is defined by a format, a height and width, and the image data. The width and
+ * height must be greater than 0. The data is contained in a byte buffer, and
+ * should be packed before creation of the image object.
+ *
+ * @author Mark Powell
+ * @author Joshua Slack
+ * @version $Id: Image.java 4131 2009-03-19 20:15:28Z blaine.dev $
+ */
+public class Image extends NativeObject implements Savable /*, Cloneable*/ {
+
+ public enum Format {
+ /**
+ * 8-bit alpha
+ */
+ Alpha8(8),
+
+ /**
+ * 16-bit alpha
+ */
+ Alpha16(16),
+
+ /**
+ * 8-bit grayscale/luminance.
+ */
+ Luminance8(8),
+
+ /**
+ * 16-bit grayscale/luminance.
+ */
+ Luminance16(16),
+
+ /**
+ * half-precision floating-point grayscale/luminance.
+ */
+ Luminance16F(16,true),
+
+ /**
+ * single-precision floating-point grayscale/luminance.
+ */
+ Luminance32F(32,true),
+
+ /**
+ * 8-bit luminance/grayscale and 8-bit alpha.
+ */
+ Luminance8Alpha8(16),
+
+ /**
+ * 16-bit luminance/grayscale and 16-bit alpha.
+ */
+ Luminance16Alpha16(32),
+
+ /**
+ * half-precision floating-point grayscale/luminance and alpha.
+ */
+ Luminance16FAlpha16F(32,true),
+
+ @Deprecated
+ Intensity8(8),
+
+ @Deprecated
+ Intensity16(16),
+
+ /**
+ * 8-bit blue, green, and red.
+ */
+ BGR8(24), // BGR and ABGR formats are often used on windows systems
+
+ /**
+ * 8-bit red, green, and blue.
+ */
+ RGB8(24),
+
+ @Deprecated
+ RGB10(30),
+
+ /**
+ * 16-bit red, green, and blue.
+ */
+ RGB16(48),
+
+ /**
+ * 5-bit red, 6-bit green, and 5-bit blue.
+ */
+ RGB565(16),
+
+ /**
+ * 4-bit alpha, red, green, and blue. Used on Android only.
+ */
+ ARGB4444(16),
+
+ /**
+ * 5-bit red, green, and blue with 1-bit alpha.
+ */
+ RGB5A1(16),
+
+ /**
+ * 8-bit red, green, blue, and alpha.
+ */
+ RGBA8(32),
+
+ /**
+ * 8-bit alpha, blue, green, and red.
+ */
+ ABGR8(32),
+
+ /**
+ * 16-bit red, green, blue and alpha
+ */
+ RGBA16(64),
+
+ /**
+ * S3TC compression DXT1.
+ * Called BC1 in DirectX10.
+ */
+ DXT1(4,false,true, false),
+
+ /**
+ * S3TC compression DXT1 with 1-bit alpha.
+ */
+ DXT1A(4,false,true, false),
+
+ /**
+ * S3TC compression DXT3 with 4-bit alpha.
+ * Called BC2 in DirectX10.
+ */
+ DXT3(8,false,true, false),
+
+ /**
+ * S3TC compression DXT5 with interpolated 8-bit alpha.
+ * Called BC3 in DirectX10.
+ */
+ DXT5(8,false,true, false),
+
+ /**
+ * Luminance-Alpha Texture Compression.
+ * Called BC5 in DirectX10.
+ */
+ LATC(8, false, true, false),
+
+ /**
+ * Arbitrary depth format. The precision is chosen by the video
+ * hardware.
+ */
+ Depth(0,true,false,false),
+
+ /**
+ * 16-bit depth.
+ */
+ Depth16(16,true,false,false),
+
+ /**
+ * 24-bit depth.
+ */
+ Depth24(24,true,false,false),
+
+ /**
+ * 32-bit depth.
+ */
+ Depth32(32,true,false,false),
+
+ /**
+ * single-precision floating point depth.
+ */
+ Depth32F(32,true,false,true),
+
+ /**
+ * Texture data is stored as {@link Format#RGB16F} in system memory,
+ * but will be converted to {@link Format#RGB111110F} when sent
+ * to the video hardware.
+ */
+ RGB16F_to_RGB111110F(48,true),
+
+ /**
+ * unsigned floating-point red, green and blue that uses 32 bits.
+ */
+ RGB111110F(32,true),
+
+ /**
+ * Texture data is stored as {@link Format#RGB16F} in system memory,
+ * but will be converted to {@link Format#RGB9E5} when sent
+ * to the video hardware.
+ */
+ RGB16F_to_RGB9E5(48,true),
+
+ /**
+ * 9-bit red, green and blue with 5-bit exponent.
+ */
+ RGB9E5(32,true),
+
+ /**
+ * half-precision floating point red, green, and blue.
+ */
+ RGB16F(48,true),
+
+ /**
+ * half-precision floating point red, green, blue, and alpha.
+ */
+ RGBA16F(64,true),
+
+ /**
+ * single-precision floating point red, green, and blue.
+ */
+ RGB32F(96,true),
+
+ /**
+ * single-precision floating point red, green, blue and alpha.
+ */
+ RGBA32F(128,true),
+
+ /**
+ * Luminance/grayscale texture compression.
+ * Called BC4 in DirectX10.
+ */
+ LTC(4, false, true, false),
+
+ /**
+ * 24-bit depth with 8-bit stencil.
+ * Check the cap {@link Caps#PackedDepthStencilBuffer}.
+ */
+ Depth24Stencil8(32, true, false, false);
+
+ private int bpp;
+ private boolean isDepth;
+ private boolean isCompressed;
+ private boolean isFloatingPoint;
+
+ private Format(int bpp){
+ this.bpp = bpp;
+ }
+
+ private Format(int bpp, boolean isFP){
+ this(bpp);
+ this.isFloatingPoint = isFP;
+ }
+
+ private Format(int bpp, boolean isDepth, boolean isCompressed, boolean isFP){
+ this(bpp, isFP);
+ this.isDepth = isDepth;
+ this.isCompressed = isCompressed;
+ }
+
+ /**
+ * @return bits per pixel.
+ */
+ public int getBitsPerPixel(){
+ return bpp;
+ }
+
+ /**
+ * @return True if this format is a depth format, false otherwise.
+ */
+ public boolean isDepthFormat(){
+ return isDepth;
+ }
+
+ /**
+ * @return True if this is a compressed image format, false if
+ * uncompressed.
+ */
+ public boolean isCompressed() {
+ return isCompressed;
+ }
+
+ /**
+ * @return True if this image format is in floating point,
+ * false if it is an integer format.
+ */
+ public boolean isFloatingPont(){
+ return isFloatingPoint;
+ }
+
+ }
+
+ // image attributes
+ protected Format format;
+ protected int width, height, depth;
+ protected int[] mipMapSizes;
+ protected ArrayListImage
object. All values
+ * are undefined.
+ */
+ public Image() {
+ super(Image.class);
+ data = new ArrayListImage
object. The
+ * attributes of the image are defined during construction.
+ *
+ * @param format
+ * the data format of the image.
+ * @param width
+ * the width of the image.
+ * @param height
+ * the height of the image.
+ * @param data
+ * the image data.
+ * @param mipMapSizes
+ * the array of mipmap sizes, or null for no mipmaps.
+ */
+ public Image(Format format, int width, int height, int depth, ArrayListImage
object. The
+ * attributes of the image are defined during construction.
+ *
+ * @param format
+ * the data format of the image.
+ * @param width
+ * the width of the image.
+ * @param height
+ * the height of the image.
+ * @param data
+ * the image data.
+ * @param mipMapSizes
+ * the array of mipmap sizes, or null for no mipmaps.
+ */
+ public Image(Format format, int width, int height, ByteBuffer data,
+ int[] mipMapSizes) {
+
+ this();
+
+ if (mipMapSizes != null && mipMapSizes.length <= 1) {
+ mipMapSizes = null;
+ } else {
+ needGeneratedMips = false;
+ mipsWereGenerated = true;
+ }
+
+ setFormat(format);
+ this.width = width;
+ this.height = height;
+ if (data != null){
+ this.data = new ArrayListImage
object. The
+ * attributes of the image are defined during construction.
+ *
+ * @param format
+ * the data format of the image.
+ * @param width
+ * the width of the image.
+ * @param height
+ * the height of the image.
+ * @param data
+ * the image data.
+ */
+ public Image(Format format, int width, int height, int depth, ArrayListImage
object. The
+ * attributes of the image are defined during construction.
+ *
+ * @param format
+ * the data format of the image.
+ * @param width
+ * the width of the image.
+ * @param height
+ * the height of the image.
+ * @param data
+ * the image data.
+ */
+ public Image(Format format, int width, int height, ByteBuffer data) {
+ this(format, width, height, data, null);
+ }
+
+ /**
+ * @return The number of samples (for multisampled textures).
+ * @see Image#setMultiSamples(int)
+ */
+ public int getMultiSamples() {
+ return multiSamples;
+ }
+
+ /**
+ * @param multiSamples Set the number of samples to use for this image,
+ * setting this to a value higher than 1 turns this image/texture
+ * into a multisample texture (on OpenGL3.1 and higher).
+ */
+ public void setMultiSamples(int multiSamples) {
+ if (multiSamples <= 0)
+ throw new IllegalArgumentException("multiSamples must be > 0");
+
+ if (getData(0) != null)
+ throw new IllegalArgumentException("Cannot upload data as multisample texture");
+
+ if (hasMipmaps())
+ throw new IllegalArgumentException("Multisample textures do not support mipmaps");
+
+ this.multiSamples = multiSamples;
+ }
+
+ /**
+ * setData
sets the data that makes up the image. This data
+ * is packed into an array of ByteBuffer
objects.
+ *
+ * @param data
+ * the data that contains the image information.
+ */
+ public void setData(ArrayListsetData
sets the data that makes up the image. This data
+ * is packed into a single ByteBuffer
.
+ *
+ * @param data
+ * the data that contains the image information.
+ */
+ public void setData(ByteBuffer data) {
+ this.data = new ArrayListsetHeight
sets the height value of the image. It is
+ * typically a good idea to try to keep this as a multiple of 2.
+ *
+ * @param height
+ * the height of the image.
+ */
+ public void setHeight(int height) {
+ this.height = height;
+ setUpdateNeeded();
+ }
+
+ /**
+ * setDepth
sets the depth value of the image. It is
+ * typically a good idea to try to keep this as a multiple of 2. This is
+ * used for 3d images.
+ *
+ * @param depth
+ * the depth of the image.
+ */
+ public void setDepth(int depth) {
+ this.depth = depth;
+ setUpdateNeeded();
+ }
+
+ /**
+ * setWidth
sets the width value of the image. It is
+ * typically a good idea to try to keep this as a multiple of 2.
+ *
+ * @param width
+ * the width of the image.
+ */
+ public void setWidth(int width) {
+ this.width = width;
+ setUpdateNeeded();
+ }
+
+ /**
+ * setFormat
sets the image format for this image.
+ *
+ * @param format
+ * the image format.
+ * @throws NullPointerException
+ * if format is null
+ * @see Format
+ */
+ public void setFormat(Format format) {
+ if (format == null) {
+ throw new NullPointerException("format may not be null.");
+ }
+
+ this.format = format;
+ setUpdateNeeded();
+ }
+
+ /**
+ * getFormat
returns the image format for this image.
+ *
+ * @return the image format.
+ * @see Format
+ */
+ public Format getFormat() {
+ return format;
+ }
+
+ /**
+ * getWidth
returns the width of this image.
+ *
+ * @return the width of this image.
+ */
+ public int getWidth() {
+ return width;
+ }
+
+ /**
+ * getHeight
returns the height of this image.
+ *
+ * @return the height of this image.
+ */
+ public int getHeight() {
+ return height;
+ }
+
+ /**
+ * getDepth
returns the depth of this image (for 3d images).
+ *
+ * @return the depth of this image.
+ */
+ public int getDepth() {
+ return depth;
+ }
+
+ /**
+ * getData
returns the data for this image. If the data is
+ * undefined, null will be returned.
+ *
+ * @return the data for this image.
+ */
+ public ListgetData
returns the data for this image. If the data is
+ * undefined, null will be returned.
+ *
+ * @return the data for this image.
+ */
+ public ByteBuffer getData(int index) {
+ if (data.size() > index)
+ return data.get(index);
+ else
+ return null;
+ }
+
+ /**
+ * Returns whether the image data contains mipmaps.
+ *
+ * @return true if the image data contains mipmaps, false if not.
+ */
+ public boolean hasMipmaps() {
+ return mipMapSizes != null;
+ }
+
+ /**
+ * Returns the mipmap sizes for this image.
+ *
+ * @return the mipmap sizes for this image.
+ */
+ public int[] getMipMapSizes() {
+ return mipMapSizes;
+ }
+
+ @Override
+ public String toString(){
+ StringBuilder sb = new StringBuilder();
+ sb.append(getClass().getSimpleName());
+ sb.append("[size=").append(width).append("x").append(height);
+
+ if (depth > 1)
+ sb.append("x").append(depth);
+
+ sb.append(", format=").append(format.name());
+
+ if (hasMipmaps())
+ sb.append(", mips");
+
+ if (getId() >= 0)
+ sb.append(", id=").append(id);
+
+ sb.append("]");
+
+ return sb.toString();
+ }
+
+ @Override
+ public boolean equals(Object other) {
+ if (other == this) {
+ return true;
+ }
+ if (!(other instanceof Image)) {
+ return false;
+ }
+ Image that = (Image) other;
+ if (this.getFormat() != that.getFormat())
+ return false;
+ if (this.getWidth() != that.getWidth())
+ return false;
+ if (this.getHeight() != that.getHeight())
+ return false;
+ if (this.getData() != null && !this.getData().equals(that.getData()))
+ return false;
+ if (this.getData() == null && that.getData() != null)
+ return false;
+ if (this.getMipMapSizes() != null
+ && !Arrays.equals(this.getMipMapSizes(), that.getMipMapSizes()))
+ return false;
+ if (this.getMipMapSizes() == null && that.getMipMapSizes() != null)
+ return false;
+ if (this.getMultiSamples() != that.getMultiSamples())
+ return false;
+
+ return true;
+ }
+
+ @Override
+ public int hashCode() {
+ int hash = 7;
+ hash = 97 * hash + (this.format != null ? this.format.hashCode() : 0);
+ hash = 97 * hash + this.width;
+ hash = 97 * hash + this.height;
+ hash = 97 * hash + this.depth;
+ hash = 97 * hash + Arrays.hashCode(this.mipMapSizes);
+ hash = 97 * hash + (this.data != null ? this.data.hashCode() : 0);
+ hash = 97 * hash + this.multiSamples;
+ return hash;
+ }
+
+ public void write(JmeExporter e) throws IOException {
+ OutputCapsule capsule = e.getCapsule(this);
+ capsule.write(format, "format", Format.RGBA8);
+ capsule.write(width, "width", 0);
+ capsule.write(height, "height", 0);
+ capsule.write(depth, "depth", 0);
+ capsule.write(mipMapSizes, "mipMapSizes", null);
+ capsule.write(multiSamples, "multiSamples", 1);
+ capsule.writeByteBufferArrayList(data, "data", null);
+ }
+
+ public void read(JmeImporter e) throws IOException {
+ InputCapsule capsule = e.getCapsule(this);
+ format = capsule.readEnum("format", Format.class, Format.RGBA8);
+ width = capsule.readInt("width", 0);
+ height = capsule.readInt("height", 0);
+ depth = capsule.readInt("depth", 0);
+ mipMapSizes = capsule.readIntArray("mipMapSizes", null);
+ multiSamples = capsule.readInt("multiSamples", 1);
+ data = (ArrayList