summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rwxr-xr-xsrc/classes/com/sun/opengl/util/texture/Texture.java96
-rwxr-xr-xsrc/classes/com/sun/opengl/util/texture/TextureData.java280
2 files changed, 233 insertions, 143 deletions
diff --git a/src/classes/com/sun/opengl/util/texture/Texture.java b/src/classes/com/sun/opengl/util/texture/Texture.java
index d3d9ac224..d22aabc9a 100755
--- a/src/classes/com/sun/opengl/util/texture/Texture.java
+++ b/src/classes/com/sun/opengl/util/texture/Texture.java
@@ -138,6 +138,7 @@ public class Texture {
private int estimatedMemorySize;
private static final boolean DEBUG = Debug.debug("Texture");
+ private static final boolean VERBOSE = Debug.verbose();
// For now make Texture constructor package-private to limit the
// number of public APIs we commit to
@@ -453,7 +454,7 @@ public class Texture {
data.getWidth(), data.getHeight(),
data.getPixelFormat(), data.getPixelType(), data.getBuffer());
} finally {
- gl.glPixelStorei(GL.GL_UNPACK_ALIGNMENT, align[0]); // restore align
+ gl.glPixelStorei(GL.GL_UNPACK_ALIGNMENT, align[0]); // restore alignment
}
} else {
checkCompressedTextureExtensions(data);
@@ -472,7 +473,7 @@ public class Texture {
gl.glTexImage2D(newTarget, i, data.getInternalFormat(),
width, height, data.getBorder(),
data.getPixelFormat(), data.getPixelType(), null);
- updateSubImageImpl(data, newTarget, i, 0, 0);
+ updateSubImageImpl(data, newTarget, i, 0, 0, 0, 0, data.getWidth(), data.getHeight());
}
width /= 2;
@@ -488,7 +489,7 @@ public class Texture {
gl.glTexImage2D(newTarget, 0, data.getInternalFormat(),
texWidth, texHeight, data.getBorder(),
data.getPixelFormat(), data.getPixelType(), null);
- updateSubImageImpl(data, newTarget, 0, 0, 0);
+ updateSubImageImpl(data, newTarget, 0, 0, 0, 0, 0, data.getWidth(), data.getHeight());
}
}
}
@@ -507,9 +508,8 @@ public class Texture {
/**
* Updates a subregion of the content area of this texture using the
- * data in the given image. Only updates the specified mipmap level
- * and does not re-generate mipmaps if they were originally produced
- * or loaded.
+ * given data. Only updates the specified mipmap level and does not
+ * re-generate mipmaps if they were originally produced or loaded.
*
* @param data the image data to be uploaded to this texture
* @param mipmapLevel the mipmap level of the texture to set. If
@@ -524,7 +524,42 @@ public class Texture {
* OpenGL-related errors occurred
*/
public void updateSubImage(TextureData data, int mipmapLevel, int x, int y) throws GLException {
- updateSubImageImpl(data, target, mipmapLevel, x, y);
+ updateSubImageImpl(data, target, mipmapLevel, x, y, 0, 0, data.getWidth(), data.getHeight());
+ }
+
+ /**
+ * Updates a subregion of the content area of this texture using the
+ * specified sub-region of the given data. Only updates the
+ * specified mipmap level and does not re-generate mipmaps if they
+ * were originally produced or loaded. This method is only supported
+ * for uncompressed TextureData sources.
+ *
+ * @param data the image data to be uploaded to this texture
+ * @param mipmapLevel the mipmap level of the texture to set. If
+ * this is non-zero and the TextureData contains mipmap data, the
+ * appropriate mipmap level will be selected.
+ * @param dstx the x offset (in pixels) relative to the lower-left corner
+ * of this texture where the update will be applied
+ * @param dsty the y offset (in pixels) relative to the lower-left corner
+ * of this texture where the update will be applied
+ * @param srcx the x offset (in pixels) relative to the lower-left corner
+ * of the supplied TextureData from which to fetch the update rectangle
+ * @param srcy the y offset (in pixels) relative to the lower-left corner
+ * of the supplied TextureData from which to fetch the update rectangle
+ * @param width the width (in pixels) of the rectangle to be updated
+ * @param height the height (in pixels) of the rectangle to be updated
+ *
+ * @throws GLException if no OpenGL context was current or if any
+ * OpenGL-related errors occurred
+ */
+ public void updateSubImage(TextureData data, int mipmapLevel,
+ int dstx, int dsty,
+ int srcx, int srcy,
+ int width, int height) throws GLException {
+ if (data.isDataCompressed()) {
+ throw new GLException("updateSubImage specifying a sub-rectangle is not supported for compressed TextureData");
+ }
+ updateSubImageImpl(data, target, mipmapLevel, dstx, dsty, srcx, srcy, width, height);
}
/**
@@ -693,23 +728,31 @@ public class Texture {
}
}
- private void updateSubImageImpl(TextureData data, int newTarget, int mipmapLevel, int x, int y) throws GLException {
+ private void updateSubImageImpl(TextureData data, int newTarget, int mipmapLevel,
+ int dstx, int dsty,
+ int srcx, int srcy, int width, int height) throws GLException {
+ GL gl = GLU.getCurrentGL();
+ if (gl.isExtensionAvailable("GL_EXT_abgr")) {
+ data.setHaveEXTABGR(true);
+ }
+
Buffer buffer = data.getBuffer();
if (buffer == null && data.getMipmapData() == null) {
// Assume user just wanted to get the Texture object allocated
return;
}
- GL gl = GLU.getCurrentGL();
gl.glBindTexture(newTarget, texID);
- int width = data.getWidth();
- int height = data.getHeight();
+ int rowlen = data.getRowLength();
if (data.getMipmapData() != null) {
- // Compute the width and height at the specified mipmap level
+ // Compute the width, height and row length at the specified mipmap level
+ // Note we do not support specification of the row length for
+ // mipmapped textures at this point
for (int i = 0; i < mipmapLevel; i++) {
width /= 2;
height /= 2;
}
+ rowlen = 0;
buffer = data.getMipmapData()[mipmapLevel];
}
@@ -717,19 +760,40 @@ public class Texture {
if (data.isDataCompressed()) {
gl.glCompressedTexSubImage2D(newTarget, mipmapLevel,
- x, y, width, height,
+ dstx, dsty, width, height,
data.getInternalFormat(),
buffer.remaining(), buffer);
} else {
int[] align = new int[1];
- gl.glGetIntegerv(GL.GL_UNPACK_ALIGNMENT, align, 0); // save alignment
+ int[] rowLength = new int[1];
+ int[] skipRows = new int[1];
+ int[] skipPixels = new int[1];
+ gl.glGetIntegerv(GL.GL_UNPACK_ALIGNMENT, align, 0); // save alignment
+ gl.glGetIntegerv(GL.GL_UNPACK_ROW_LENGTH, rowLength, 0); // save row length
+ gl.glGetIntegerv(GL.GL_UNPACK_SKIP_ROWS, skipRows, 0); // save skipped rows
+ gl.glGetIntegerv(GL.GL_UNPACK_SKIP_PIXELS, skipPixels, 0); // save skipped pixels
gl.glPixelStorei(GL.GL_UNPACK_ALIGNMENT, data.getAlignment());
+ if (DEBUG && VERBOSE) {
+ System.out.println("Row length = " + rowlen);
+ System.out.println("skip pixels = " + srcx);
+ System.out.println("skip rows = " + srcy);
+ System.out.println("dstx = " + dstx);
+ System.out.println("dsty = " + dsty);
+ System.out.println("width = " + width);
+ System.out.println("height = " + height);
+ }
+ gl.glPixelStorei(GL.GL_UNPACK_ROW_LENGTH, rowlen);
+ gl.glPixelStorei(GL.GL_UNPACK_SKIP_ROWS, srcy);
+ gl.glPixelStorei(GL.GL_UNPACK_SKIP_PIXELS, srcx);
gl.glTexSubImage2D(newTarget, mipmapLevel,
- x, y, width, height,
+ dstx, dsty, width, height,
data.getPixelFormat(), data.getPixelType(),
buffer);
- gl.glPixelStorei(GL.GL_UNPACK_ALIGNMENT, align[0]); // restore align
+ gl.glPixelStorei(GL.GL_UNPACK_ALIGNMENT, align[0]); // restore alignment
+ gl.glPixelStorei(GL.GL_UNPACK_ROW_LENGTH, rowLength[0]); // restore row length
+ gl.glPixelStorei(GL.GL_UNPACK_SKIP_ROWS, skipRows[0]); // restore skipped rows
+ gl.glPixelStorei(GL.GL_UNPACK_SKIP_PIXELS, skipPixels[0]); // restore skipped pixels
}
}
diff --git a/src/classes/com/sun/opengl/util/texture/TextureData.java b/src/classes/com/sun/opengl/util/texture/TextureData.java
index d03faa697..39075e387 100755
--- a/src/classes/com/sun/opengl/util/texture/TextureData.java
+++ b/src/classes/com/sun/opengl/util/texture/TextureData.java
@@ -73,9 +73,18 @@ public class TextureData {
private Buffer buffer; // the actual data...
private Buffer[] mipmapData; // ...or a series of mipmaps
private Flusher flusher;
+ private int rowLength;
private int alignment; // 1, 2, or 4 bytes
private int estimatedMemorySize;
+ // Mechanism for lazily converting input BufferedImages with custom
+ // ColorModels to standard ones for uploading to OpenGL, as well as
+ // backing off from the optimization of hoping that GL_EXT_abgr is
+ // present
+ private BufferedImage imageForLazyCustomConversion;
+ private boolean expectingEXTABGR;
+ private boolean haveEXTABGR;
+
private static final ColorModel rgbaColorModel =
new ComponentColorModel(ColorSpace.getInstance(ColorSpace.CS_sRGB),
new int[] {8, 8, 8, 8}, true, true,
@@ -220,12 +229,12 @@ public class TextureData {
/**
* Constructs a new TextureData object with the specified parameters
- * and data contained in the given BufferedImage. Note that
- * subsequent modifications to the BufferedImage after the
- * construction of the TextureData object are not guaranteed to be
- * visible in any Texture object created from the TextureData (and,
- * in fact, the expectation should be that they will not be visible,
- * although this behavior is explicitly left undefined).
+ * and data contained in the given BufferedImage. The resulting
+ * TextureData "wraps" the contents of the BufferedImage, so if a
+ * modification is made to the BufferedImage between the time the
+ * TextureData is constructed and when a Texture is made from the
+ * TextureData, that modification will be visible in the resulting
+ * Texture.
*
* @param internalFormat the OpenGL internal format for the
* resulting texture; may be 0, in which case
@@ -273,12 +282,26 @@ public class TextureData {
vertically for proper display. */
public boolean getMustFlipVertically() { return mustFlipVertically; }
/** Returns the texture data, or null if it is specified as a set of mipmaps. */
- public Buffer getBuffer() { return buffer; }
+ public Buffer getBuffer() {
+ if (imageForLazyCustomConversion != null) {
+ if (!expectingEXTABGR ||
+ (expectingEXTABGR && !haveEXTABGR)) {
+ // Must present the illusion to the end user that we are simply
+ // wrapping the input BufferedImage
+ createFromCustom(imageForLazyCustomConversion);
+ }
+ }
+ return buffer;
+ }
/** Returns all mipmap levels for the texture data, or null if it is
specified as a single image. */
public Buffer[] getMipmapData() { return mipmapData; }
/** Returns the required byte alignment for the texture data. */
public int getAlignment() { return alignment; }
+ /** Returns the row length needed for correct GL_UNPACK_ROW_LENGTH
+ specification. This is currently only supported for
+ non-mipmapped, non-compressed textures. */
+ public int getRowLength() { return rowLength; }
/** Sets the width in pixels of the texture data. */
public void setWidth(int width) { this.width = width; }
@@ -303,6 +326,16 @@ public class TextureData {
public void setBuffer(Buffer buffer) { this.buffer = buffer; }
/** Sets the required byte alignment for the texture data. */
public void setAlignment(int alignment) { this.alignment = alignment; }
+ /** Sets the row length needed for correct GL_UNPACK_ROW_LENGTH
+ specification. This is currently only supported for
+ non-mipmapped, non-compressed textures. */
+ public void setRowLength(int rowLength) { this.rowLength = rowLength; }
+ /** Indicates to this TextureData whether the GL_EXT_abgr extension
+ is available. Used for optimization along some code paths to
+ avoid data copies. */
+ public void setHaveEXTABGR(boolean haveEXTABGR) {
+ this.haveEXTABGR = haveEXTABGR;
+ }
/** Returns an estimate of the amount of memory in bytes this
TextureData will consume once uploaded to the graphics card. It
@@ -335,176 +368,145 @@ public class TextureData {
// Internals only below this point
//
- private void createNIOBufferFromImage(BufferedImage image, boolean flipVertically) {
- if (flipVertically) {
- ImageUtil.flipImageVertically(image);
- }
-
- try {
- //
- // Note: Grabbing the DataBuffer will defeat Java2D's image
- // management mechanism (as of JDK 5/6, at least). This shouldn't
- // be a problem for most JOGL apps, but those that try to upload
- // the image into an OpenGL texture and then use the same image in
- // Java2D rendering might find the 2D rendering is not as fast as
- // it could be.
- //
-
- // Allow previously-selected pixelType (if any) to override that
- // we can infer from the DataBuffer
- DataBuffer data = image.getRaster().getDataBuffer();
- if (data instanceof DataBufferByte) {
- if (pixelType == 0) pixelType = GL.GL_UNSIGNED_BYTE;
- buffer = ByteBuffer.wrap(copyIfNecessary(((DataBufferByte) data).getData(), flipVertically));
- } else if (data instanceof DataBufferDouble) {
- throw new RuntimeException("DataBufferDouble rasters not supported by OpenGL");
- } else if (data instanceof DataBufferFloat) {
- if (pixelType == 0) pixelType = GL.GL_FLOAT;
- buffer = FloatBuffer.wrap(copyIfNecessary(((DataBufferFloat) data).getData(), flipVertically));
- } else if (data instanceof DataBufferInt) {
- // FIXME: should we support signed ints?
- if (pixelType == 0) pixelType = GL.GL_UNSIGNED_INT;
- buffer = IntBuffer.wrap(copyIfNecessary(((DataBufferInt) data).getData(), flipVertically));
- } else if (data instanceof DataBufferShort) {
- if (pixelType == 0) pixelType = GL.GL_SHORT;
- buffer = ShortBuffer.wrap(copyIfNecessary(((DataBufferShort) data).getData(), flipVertically));
- } else if (data instanceof DataBufferUShort) {
- if (pixelType == 0) pixelType = GL.GL_UNSIGNED_SHORT;
- buffer = ShortBuffer.wrap(copyIfNecessary(((DataBufferShort) data).getData(), flipVertically));
- } else {
- throw new RuntimeException("Unexpected DataBuffer type?");
- }
- } finally {
- // Put image back right-side up if necessary
- if (flipVertically) {
- ImageUtil.flipImageVertically(image);
- }
- }
- }
-
- private byte[] copyIfNecessary(byte[] data, boolean needsCopy) {
- if (needsCopy) {
- return (byte[]) data.clone();
- }
- return data;
- }
-
- private short[] copyIfNecessary(short[] data, boolean needsCopy) {
- if (needsCopy) {
- return (short[]) data.clone();
- }
- return data;
- }
-
- private int[] copyIfNecessary(int[] data, boolean needsCopy) {
- if (needsCopy) {
- return (int[]) data.clone();
- }
- return data;
- }
-
- private float[] copyIfNecessary(float[] data, boolean needsCopy) {
- if (needsCopy) {
- return (float[]) data.clone();
- }
- return data;
- }
-
- private double[] copyIfNecessary(double[] data, boolean needsCopy) {
- if (needsCopy) {
- return (double[]) data.clone();
+ private void createNIOBufferFromImage(BufferedImage image) {
+ //
+ // Note: Grabbing the DataBuffer will defeat Java2D's image
+ // management mechanism (as of JDK 5/6, at least). This shouldn't
+ // be a problem for most JOGL apps, but those that try to upload
+ // the image into an OpenGL texture and then use the same image in
+ // Java2D rendering might find the 2D rendering is not as fast as
+ // it could be.
+ //
+
+ DataBuffer data = image.getRaster().getDataBuffer();
+ if (data instanceof DataBufferByte) {
+ buffer = ByteBuffer.wrap(((DataBufferByte) data).getData());
+ } else if (data instanceof DataBufferDouble) {
+ throw new RuntimeException("DataBufferDouble rasters not supported by OpenGL");
+ } else if (data instanceof DataBufferFloat) {
+ buffer = FloatBuffer.wrap(((DataBufferFloat) data).getData());
+ } else if (data instanceof DataBufferInt) {
+ buffer = IntBuffer.wrap(((DataBufferInt) data).getData());
+ } else if (data instanceof DataBufferShort) {
+ buffer = ShortBuffer.wrap(((DataBufferShort) data).getData());
+ } else if (data instanceof DataBufferUShort) {
+ buffer = ShortBuffer.wrap(((DataBufferUShort) data).getData());
+ } else {
+ throw new RuntimeException("Unexpected DataBuffer type?");
}
- return data;
}
-
private void createFromImage(BufferedImage image) {
pixelType = 0; // Determine from image
+ mustFlipVertically = true;
width = image.getWidth();
height = image.getHeight();
+ int scanlineStride;
+ SampleModel sm = image.getRaster().getSampleModel();
+ if (sm instanceof SinglePixelPackedSampleModel) {
+ scanlineStride =
+ ((SinglePixelPackedSampleModel)sm).getScanlineStride();
+ } else if (sm instanceof MultiPixelPackedSampleModel) {
+ scanlineStride =
+ ((MultiPixelPackedSampleModel)sm).getScanlineStride();
+ } else if (sm instanceof ComponentSampleModel) {
+ scanlineStride =
+ ((ComponentSampleModel)sm).getScanlineStride();
+ } else {
+ // This will only happen for TYPE_CUSTOM anyway
+ setupLazyCustomConversion(image);
+ return;
+ }
+
switch (image.getType()) {
case BufferedImage.TYPE_INT_RGB:
pixelFormat = GL.GL_BGRA;
pixelType = GL.GL_UNSIGNED_INT_8_8_8_8_REV;
+ rowLength = scanlineStride;
alignment = 4;
break;
+ case BufferedImage.TYPE_INT_ARGB:
case BufferedImage.TYPE_INT_ARGB_PRE:
pixelFormat = GL.GL_BGRA;
pixelType = GL.GL_UNSIGNED_INT_8_8_8_8_REV;
+ rowLength = scanlineStride;
alignment = 4;
break;
case BufferedImage.TYPE_INT_BGR:
pixelFormat = GL.GL_RGBA;
pixelType = GL.GL_UNSIGNED_INT_8_8_8_8_REV;
+ rowLength = scanlineStride;
alignment = 4;
break;
case BufferedImage.TYPE_3BYTE_BGR:
{
- Raster raster = image.getRaster();
- ComponentSampleModel csm =
- (ComponentSampleModel)raster.getSampleModel();
// we can pass the image data directly to OpenGL only if
- // the raster is tightly packed (i.e. there is no extra
- // space at the end of each scanline)
- if ((csm.getScanlineStride() / 3) == csm.getWidth()) {
+ // we have an integral number of pixels in each scanline
+ if ((scanlineStride % 3) == 0) {
pixelFormat = GL.GL_BGR;
pixelType = GL.GL_UNSIGNED_BYTE;
+ rowLength = scanlineStride / 3;
alignment = 1;
} else {
- createFromCustom(image);
+ setupLazyCustomConversion(image);
return;
}
}
break;
+ case BufferedImage.TYPE_4BYTE_ABGR:
case BufferedImage.TYPE_4BYTE_ABGR_PRE:
{
- Raster raster = image.getRaster();
- ComponentSampleModel csm =
- (ComponentSampleModel)raster.getSampleModel();
// we can pass the image data directly to OpenGL only if
- // the raster is tightly packed (i.e. there is no extra
- // space at the end of each scanline) and only if the
- // GL_EXT_abgr extension is present
-
- // FIXME: with the way this is currently organized we can't
- // probe for the existence of the GL_EXT_abgr extension
- // here; disable this code path for now
- if (((csm.getScanlineStride() / 4) == csm.getWidth()) &&
- /* gl.isExtensionAvailable("GL_EXT_abgr") */ false)
- {
- pixelFormat = GL.GL_ABGR_EXT;
- pixelType = GL.GL_UNSIGNED_BYTE;
- alignment = 4;
- } else {
- createFromCustom(image);
- return;
- }
+ // we have an integral number of pixels in each scanline
+ // and only if the GL_EXT_abgr extension is present
+
+ // NOTE: disabling this code path for now as it appears it's
+ // buggy at least on some NVidia drivers and doesn't perform
+ // the necessary byte swapping (FIXME: needs more
+ // investigation)
+ if ((scanlineStride % 4) == 0 && false) {
+ pixelFormat = GL.GL_ABGR_EXT;
+ pixelType = GL.GL_UNSIGNED_BYTE;
+ rowLength = scanlineStride / 4;
+ alignment = 4;
+
+ // Store a reference to the original image for later in
+ // case it turns out that we don't have GL_EXT_abgr at the
+ // time we're going to do the texture upload to OpenGL
+ setupLazyCustomConversion(image);
+ expectingEXTABGR = true;
+ break;
+ } else {
+ setupLazyCustomConversion(image);
+ return;
+ }
}
- break;
case BufferedImage.TYPE_USHORT_565_RGB:
pixelFormat = GL.GL_RGB;
pixelType = GL.GL_UNSIGNED_SHORT_5_6_5;
+ rowLength = scanlineStride;
alignment = 2;
break;
case BufferedImage.TYPE_USHORT_555_RGB:
pixelFormat = GL.GL_BGRA;
pixelType = GL.GL_UNSIGNED_SHORT_1_5_5_5_REV;
+ rowLength = scanlineStride;
alignment = 2;
break;
case BufferedImage.TYPE_BYTE_GRAY:
pixelFormat = GL.GL_LUMINANCE;
pixelType = GL.GL_UNSIGNED_BYTE;
+ rowLength = scanlineStride;
alignment = 1;
break;
case BufferedImage.TYPE_USHORT_GRAY:
pixelFormat = GL.GL_LUMINANCE;
pixelType = GL.GL_UNSIGNED_SHORT;
+ rowLength = scanlineStride;
alignment = 2;
break;
- case BufferedImage.TYPE_INT_ARGB:
- case BufferedImage.TYPE_4BYTE_ABGR:
case BufferedImage.TYPE_BYTE_BINARY:
case BufferedImage.TYPE_BYTE_INDEXED:
case BufferedImage.TYPE_CUSTOM:
@@ -513,19 +515,49 @@ public class TextureData {
if (cm.equals(rgbColorModel)) {
pixelFormat = GL.GL_RGB;
pixelType = GL.GL_UNSIGNED_BYTE;
+ rowLength = scanlineStride / 4; // FIXME: correct?
alignment = 1;
} else if (cm.equals(rgbaColorModel)) {
pixelFormat = GL.GL_RGBA;
pixelType = GL.GL_UNSIGNED_BYTE;
+ rowLength = scanlineStride / 4; // FIXME: correct?
alignment = 4;
} else {
- createFromCustom(image);
+ setupLazyCustomConversion(image);
return;
}
break;
}
- createNIOBufferFromImage(image, true);
+ createNIOBufferFromImage(image);
+ }
+
+ private void setupLazyCustomConversion(BufferedImage image) {
+ imageForLazyCustomConversion = image;
+ boolean hasAlpha = image.getColorModel().hasAlpha();
+ pixelFormat = hasAlpha ? GL.GL_RGBA : GL.GL_RGB;
+ alignment = 1; // FIXME: do we need better?
+ rowLength = width; // FIXME: correct in all cases?
+
+ // Allow previously-selected pixelType (if any) to override that
+ // we can infer from the DataBuffer
+ DataBuffer data = image.getRaster().getDataBuffer();
+ if (data instanceof DataBufferByte) {
+ if (pixelType == 0) pixelType = GL.GL_UNSIGNED_BYTE;
+ } else if (data instanceof DataBufferDouble) {
+ throw new RuntimeException("DataBufferDouble rasters not supported by OpenGL");
+ } else if (data instanceof DataBufferFloat) {
+ if (pixelType == 0) pixelType = GL.GL_FLOAT;
+ } else if (data instanceof DataBufferInt) {
+ // FIXME: should we support signed ints?
+ if (pixelType == 0) pixelType = GL.GL_UNSIGNED_INT;
+ } else if (data instanceof DataBufferShort) {
+ if (pixelType == 0) pixelType = GL.GL_SHORT;
+ } else if (data instanceof DataBufferUShort) {
+ if (pixelType == 0) pixelType = GL.GL_UNSIGNED_SHORT;
+ } else {
+ throw new RuntimeException("Unexpected DataBuffer type?");
+ }
}
private void createFromCustom(BufferedImage image) {
@@ -560,17 +592,11 @@ public class TextureData {
// copy the source image into the temporary image
Graphics2D g = texImage.createGraphics();
g.setComposite(AlphaComposite.Src);
- // Flip image vertically as long as we're at it
- g.drawImage(image,
- 0, height, width, 0,
- 0, 0, width, height,
- null);
+ g.drawImage(image, 0, 0, null);
g.dispose();
// Wrap the buffer from the temporary image
- createNIOBufferFromImage(texImage, false);
- pixelFormat = hasAlpha ? GL.GL_RGBA : GL.GL_RGB;
- alignment = 1; // FIXME: do we need better?
+ createNIOBufferFromImage(texImage);
}
private int estimatedMemorySize(Buffer buffer) {