38package com.jogamp.opengl.util.texture.awt;
40import java.awt.AlphaComposite;
41import java.awt.Graphics2D;
42import java.awt.Transparency;
43import java.awt.image.BufferedImage;
44import java.awt.image.ComponentColorModel;
45import java.awt.image.ComponentSampleModel;
46import java.awt.image.DataBuffer;
47import java.awt.image.DataBufferByte;
48import java.awt.image.DataBufferDouble;
49import java.awt.image.DataBufferFloat;
50import java.awt.image.DataBufferInt;
51import java.awt.image.DataBufferShort;
52import java.awt.image.DataBufferUShort;
53import java.awt.image.MultiPixelPackedSampleModel;
54import java.awt.image.SampleModel;
55import java.awt.image.SinglePixelPackedSampleModel;
56import java.awt.image.WritableRaster;
57import java.nio.Buffer;
58import java.nio.ByteBuffer;
59import java.nio.FloatBuffer;
60import java.nio.IntBuffer;
61import java.nio.ShortBuffer;
63import com.jogamp.opengl.GL;
64import com.jogamp.opengl.GL2;
65import com.jogamp.opengl.GL2GL3;
66import com.jogamp.opengl.GLException;
67import com.jogamp.opengl.GLProfile;
69import com.jogamp.opengl.util.GLPixelBuffer.GLPixelAttributes;
70import com.jogamp.opengl.util.texture.TextureData;
77 private BufferedImage imageForLazyCustomConversion;
78 private boolean expectingEXTABGR;
79 private boolean expectingGL12;
81 private static final java.awt.image.ColorModel rgbaColorModel =
82 new ComponentColorModel(java.awt.color.ColorSpace.getInstance(java.awt.color.ColorSpace.CS_sRGB),
83 new int[] {8, 8, 8, 8},
true,
true,
84 Transparency.TRANSLUCENT,
85 DataBuffer.TYPE_BYTE);
86 private static final java.awt.image.ColorModel rgbColorModel =
87 new ComponentColorModel(java.awt.color.ColorSpace.getInstance(java.awt.color.ColorSpace.CS_sRGB),
88 new int[] {8, 8, 8, 0},
false,
false,
90 DataBuffer.TYPE_BYTE);
118 final int pixelFormat,
120 final BufferedImage image) {
123 this.internalFormat = image.getColorModel().hasAlpha() ? GL.GL_RGBA :
GL.
GL_RGB;
127 createFromImage(glp, image);
133 if (imageForLazyCustomConversion !=
null) {
139 private void validatePixelAttributes() {
140 if (imageForLazyCustomConversion !=
null) {
143 revertPixelAttributes();
150 validatePixelAttributes();
151 return super.getPixelAttributes();
156 validatePixelAttributes();
157 return super.getPixelFormat();
161 validatePixelAttributes();
162 return super.getPixelType();
167 if (imageForLazyCustomConversion !=
null) {
170 revertPixelAttributes();
173 createFromCustom(imageForLazyCustomConversion);
179 private void createFromImage(
final GLProfile glp,
final BufferedImage image) {
183 width = image.getWidth();
184 height = image.getHeight();
188 final SampleModel sm = image.getRaster().getSampleModel();
189 if (sm instanceof SinglePixelPackedSampleModel) {
191 ((SinglePixelPackedSampleModel)sm).getScanlineStride();
192 }
else if (sm instanceof MultiPixelPackedSampleModel) {
194 ((MultiPixelPackedSampleModel)sm).getScanlineStride();
195 }
else if (sm instanceof ComponentSampleModel) {
197 ((ComponentSampleModel)sm).getScanlineStride();
200 setupLazyCustomConversion(image);
204 width = image.getWidth();
205 height = image.getHeight();
208 switch (image.getType()) {
209 case BufferedImage.TYPE_INT_RGB:
210 pixelAttributes =
new GLPixelAttributes(GL.GL_BGRA, GL2GL3.GL_UNSIGNED_INT_8_8_8_8_REV);
213 expectingGL12 =
true;
214 setupLazyCustomConversion(image);
216 case BufferedImage.TYPE_INT_ARGB_PRE:
217 pixelAttributes =
new GLPixelAttributes(GL.GL_BGRA, GL2GL3.GL_UNSIGNED_INT_8_8_8_8_REV);
220 expectingGL12 =
true;
221 setupLazyCustomConversion(image);
223 case BufferedImage.TYPE_INT_BGR:
224 pixelAttributes =
new GLPixelAttributes(GL.GL_RGBA, GL2GL3.GL_UNSIGNED_INT_8_8_8_8_REV);
227 expectingGL12 =
true;
228 setupLazyCustomConversion(image);
230 case BufferedImage.TYPE_3BYTE_BGR:
234 if ((scanlineStride % 3) == 0) {
235 pixelAttributes =
new GLPixelAttributes(GL.GL_BGR, GL.GL_UNSIGNED_BYTE);
239 setupLazyCustomConversion(image);
244 case BufferedImage.TYPE_4BYTE_ABGR_PRE:
254 if ((scanlineStride % 4) == 0 && glp.
isGL2() &&
false) {
255 pixelAttributes =
new GLPixelAttributes(GL2.GL_ABGR_EXT, GL.GL_UNSIGNED_BYTE);
262 setupLazyCustomConversion(image);
263 expectingEXTABGR =
true;
266 setupLazyCustomConversion(image);
270 case BufferedImage.TYPE_USHORT_565_RGB:
271 pixelAttributes =
new GLPixelAttributes(GL.GL_RGB, GL.GL_UNSIGNED_SHORT_5_6_5);
274 expectingGL12 =
true;
275 setupLazyCustomConversion(image);
277 case BufferedImage.TYPE_USHORT_555_RGB:
278 pixelAttributes =
new GLPixelAttributes(GL.GL_BGRA, GL2GL3.GL_UNSIGNED_SHORT_1_5_5_5_REV);
281 expectingGL12 =
true;
282 setupLazyCustomConversion(image);
284 case BufferedImage.TYPE_BYTE_GRAY:
285 pixelAttributes =
new GLPixelAttributes(GL.GL_LUMINANCE, GL.GL_UNSIGNED_BYTE);
289 case BufferedImage.TYPE_USHORT_GRAY:
290 pixelAttributes =
new GLPixelAttributes(GL.GL_LUMINANCE, GL.GL_UNSIGNED_SHORT);
297 case BufferedImage.TYPE_INT_ARGB:
298 case BufferedImage.TYPE_4BYTE_ABGR:
299 case BufferedImage.TYPE_BYTE_BINARY:
300 case BufferedImage.TYPE_BYTE_INDEXED:
301 case BufferedImage.TYPE_CUSTOM:
303 final java.awt.image.ColorModel cm = image.getColorModel();
304 if (cm.equals(rgbColorModel)) {
305 pixelAttributes =
new GLPixelAttributes(GL.GL_RGB, GL.GL_UNSIGNED_BYTE);
308 }
else if (cm.equals(rgbaColorModel)) {
309 pixelAttributes =
new GLPixelAttributes(GL.GL_RGBA, GL.GL_UNSIGNED_BYTE);
313 setupLazyCustomConversion(image);
319 switch (image.getType()) {
320 case BufferedImage.TYPE_INT_RGB:
321 pixelAttributes =
new GLPixelAttributes(GL.GL_RGB, GL.GL_UNSIGNED_BYTE);
324 expectingGL12 =
true;
325 setupLazyCustomConversion(image);
327 case BufferedImage.TYPE_INT_ARGB_PRE:
328 throw new GLException(
"INT_ARGB_PRE n.a.");
329 case BufferedImage.TYPE_INT_BGR:
330 throw new GLException(
"INT_BGR n.a.");
331 case BufferedImage.TYPE_3BYTE_BGR:
332 throw new GLException(
"INT_BGR n.a.");
333 case BufferedImage.TYPE_4BYTE_ABGR_PRE:
334 throw new GLException(
"INT_BGR n.a.");
335 case BufferedImage.TYPE_USHORT_565_RGB:
336 pixelAttributes =
new GLPixelAttributes(GL.GL_RGB, GL.GL_UNSIGNED_SHORT_5_6_5);
339 expectingGL12 =
true;
340 setupLazyCustomConversion(image);
342 case BufferedImage.TYPE_USHORT_555_RGB:
343 pixelAttributes =
new GLPixelAttributes(GL.GL_RGBA, GL.GL_UNSIGNED_SHORT_5_5_5_1);
346 expectingGL12 =
true;
347 setupLazyCustomConversion(image);
349 case BufferedImage.TYPE_BYTE_GRAY:
350 pixelAttributes =
new GLPixelAttributes(GL.GL_LUMINANCE, GL.GL_UNSIGNED_BYTE);
354 case BufferedImage.TYPE_USHORT_GRAY:
355 throw new GLException(
"USHORT_GRAY n.a.");
359 case BufferedImage.TYPE_INT_ARGB:
360 case BufferedImage.TYPE_4BYTE_ABGR:
361 case BufferedImage.TYPE_BYTE_BINARY:
362 case BufferedImage.TYPE_BYTE_INDEXED:
363 case BufferedImage.TYPE_CUSTOM:
365 final java.awt.image.ColorModel cm = image.getColorModel();
366 if (cm.equals(rgbColorModel)) {
367 pixelAttributes =
new GLPixelAttributes(GL.GL_RGB, GL.GL_UNSIGNED_BYTE);
370 }
else if (cm.equals(rgbaColorModel)) {
371 pixelAttributes =
new GLPixelAttributes(GL.GL_RGBA, GL.GL_UNSIGNED_BYTE);
375 setupLazyCustomConversion(image);
382 createNIOBufferFromImage(image);
385 private void setupLazyCustomConversion(
final BufferedImage image) {
386 imageForLazyCustomConversion = image;
387 final boolean hasAlpha = image.getColorModel().hasAlpha();
390 if (pixelFormat == 0) {
391 pixelFormat = hasAlpha ? GL.GL_RGBA : GL.GL_RGB;
398 final DataBuffer data = image.getRaster().getDataBuffer();
399 if (data instanceof DataBufferByte || isPackedInt(image)) {
401 if (pixelType == 0) pixelType = GL.GL_UNSIGNED_BYTE;
402 }
else if (data instanceof DataBufferDouble) {
403 throw new RuntimeException(
"DataBufferDouble rasters not supported by OpenGL");
404 }
else if (data instanceof DataBufferFloat) {
405 if (pixelType == 0) pixelType = GL.GL_FLOAT;
406 }
else if (data instanceof DataBufferInt) {
408 if (pixelType == 0) pixelType = GL.GL_UNSIGNED_INT;
409 }
else if (data instanceof DataBufferShort) {
410 if (pixelType == 0) pixelType = GL.GL_SHORT;
411 }
else if (data instanceof DataBufferUShort) {
412 if (pixelType == 0) pixelType = GL.GL_UNSIGNED_SHORT;
414 throw new RuntimeException(
"Unexpected DataBuffer type?");
419 private void createFromCustom(
final BufferedImage image) {
420 final int width = image.getWidth();
421 final int height = image.getHeight();
424 final boolean hasAlpha = image.getColorModel().hasAlpha();
425 java.awt.image.ColorModel cm =
null;
426 int dataBufferType = image.getRaster().getDataBuffer().getDataType();
428 if (isPackedInt(image)) {
429 dataBufferType = DataBuffer.TYPE_BYTE;
431 if (dataBufferType == DataBuffer.TYPE_BYTE) {
432 cm = hasAlpha ? rgbaColorModel : rgbColorModel;
435 cm =
new ComponentColorModel(java.awt.color.ColorSpace.getInstance(java.awt.color.ColorSpace.CS_sRGB),
437 Transparency.TRANSLUCENT,
440 cm =
new ComponentColorModel(java.awt.color.ColorSpace.getInstance(java.awt.color.ColorSpace.CS_sRGB),
447 final boolean premult = cm.isAlphaPremultiplied();
448 final WritableRaster raster =
450 final BufferedImage texImage =
new BufferedImage(cm, raster, premult,
null);
453 final Graphics2D g = texImage.createGraphics();
454 g.setComposite(AlphaComposite.Src);
455 g.drawImage(image, 0, 0,
null);
459 createNIOBufferFromImage(texImage);
462 private boolean isPackedInt(
final BufferedImage image) {
463 final int imgType = image.getType();
464 return (imgType == BufferedImage.TYPE_INT_RGB ||
465 imgType == BufferedImage.TYPE_INT_BGR ||
466 imgType == BufferedImage.TYPE_INT_ARGB ||
467 imgType == BufferedImage.TYPE_INT_ARGB_PRE);
470 private void revertPixelAttributes() {
476 setupLazyCustomConversion(imageForLazyCustomConversion);
479 private void createNIOBufferFromImage(
final BufferedImage image) {
480 buffer = wrapImageDataBuffer(image);
483 private Buffer wrapImageDataBuffer(
final BufferedImage image) {
493 final DataBuffer data = image.getRaster().getDataBuffer();
494 if (data instanceof DataBufferByte) {
495 return ByteBuffer.wrap(((DataBufferByte) data).getData());
496 }
else if (data instanceof DataBufferDouble) {
497 throw new RuntimeException(
"DataBufferDouble rasters not supported by OpenGL");
498 }
else if (data instanceof DataBufferFloat) {
499 return FloatBuffer.wrap(((DataBufferFloat) data).getData());
500 }
else if (data instanceof DataBufferInt) {
501 return IntBuffer.wrap(((DataBufferInt) data).getData());
502 }
else if (data instanceof DataBufferShort) {
503 return ShortBuffer.wrap(((DataBufferShort) data).getData());
504 }
else if (data instanceof DataBufferUShort) {
505 return ShortBuffer.wrap(((DataBufferUShort) data).getData());
507 throw new RuntimeException(
"Unexpected DataBuffer type?");
Specifies the the OpenGL profile.
final boolean isGL2GL3()
Indicates whether this profile is capable of GL2GL3.
final boolean isGL2()
Indicates whether this profile is capable of GL2 .
final int type
The OpenGL pixel data type
final int format
The OpenGL pixel data format.
static final GLPixelAttributes UNDEF
Undefined instance of GLPixelAttributes, having componentCount:=0, format:=0 and type:= 0.
Represents the data for an OpenGL texture.
boolean mustFlipVertically
GLPixelAttributes pixelAttributes
AWTTextureData(final GLProfile glp, final int internalFormat, final int pixelFormat, final boolean mipmap, final BufferedImage image)
Constructs a new TextureData object with the specified parameters and data contained in the given Buf...
int getPixelType()
Returns the intended OpenGL pixel type of the texture data using getPixelAttributes().
int getPixelFormat()
Returns the intended OpenGL pixel format of the texture data using getPixelAttributes().
GLPixelAttributes getPixelAttributes()
Returns the intended OpenGL GLPixelAttributes of the texture data, i.e.
Buffer getBuffer()
Returns the texture data, or null if it is specified as a set of mipmaps.
static final int GL_RGB
GL_ES_VERSION_2_0, GL_VERSION_1_1, GL_VERSION_1_0, GL_VERSION_ES_1_0 Define "GL_RGB" with expression ...