38package com.jogamp.opengl.util.texture;
40import java.nio.Buffer;
41import java.nio.ByteBuffer;
42import java.nio.FloatBuffer;
43import java.nio.IntBuffer;
45import com.jogamp.common.util.Bitfield;
46import com.jogamp.nativewindow.NativeWindowFactory;
47import com.jogamp.opengl.GL;
48import com.jogamp.opengl.GL2;
49import com.jogamp.opengl.GL2ES1;
50import com.jogamp.opengl.GL2ES2;
51import com.jogamp.opengl.GLES2;
52import com.jogamp.opengl.GLException;
53import com.jogamp.opengl.GLExtensions;
54import com.jogamp.opengl.glu.GLU;
55import com.jogamp.opengl.util.texture.spi.DDSImage;
57import jogamp.opengl.Debug;
177 private int imageTarget;
181 private final boolean ownsTextureID;
183 private int texWidth;
185 private int texHeight;
187 private int imgWidth;
189 private int imgHeight;
192 private float aspectRatio;
195 private boolean mustFlipVertically;
198 private boolean usingAutoMipmapGeneration;
205 final String targetS = target == imageTarget ? Integer.toHexString(target) : Integer.toHexString(target) +
" - image "+Integer.toHexString(imageTarget);
206 return "Texture[target "+targetS+
", name "+texID+
", "+
207 imgWidth+
"/"+texWidth+
" x "+imgHeight+
"/"+texHeight+
", y-flip "+mustFlipVertically+
208 ", "+estimatedMemorySize+
" bytes]";
212 private int estimatedMemorySize;
214 private static final boolean DEBUG = Debug.debug(
"Texture");
215 private static final boolean VERBOSE = Debug.verbose();
218 private static final boolean disableNPOT = Debug.isPropertyDefined(
"jogl.texture.nonpot",
true);
219 private static final boolean disableTexRect = Debug.isPropertyDefined(
"jogl.texture.notexrect",
true);
223 this.ownsTextureID =
true;
225 this.imageTarget = 0;
237 this.ownsTextureID =
true;
238 this.target = target;
239 this.imageTarget = target;
268 public Texture(
final int textureID,
final boolean ownsTextureID,
270 final int texWidth,
final int texHeight,
271 final int imgWidth,
final int imgHeight,
272 final boolean mustFlipVertically) {
273 this.texID = textureID;
274 this.ownsTextureID = ownsTextureID;
275 this.target = target;
276 this.imageTarget = target;
277 this.mustFlipVertically = mustFlipVertically;
278 this.texWidth = texWidth;
279 this.texHeight = texHeight;
280 this.aspectRatio = (float) imgWidth / (
float) imgHeight;
281 this.imgWidth = imgWidth;
282 this.imgHeight = imgHeight;
283 this.updateTexCoords();
285 throw new GLException(
"External texture ID invalid: texID "+textureID);
299 public void set(
final int texWidth,
final int texHeight,
300 final int imgWidth,
final int imgHeight) {
301 this.texWidth = texWidth;
302 this.texHeight = texHeight;
303 this.aspectRatio = (float) imgWidth / (
float) imgHeight;
304 this.imgWidth = imgWidth;
305 this.imgHeight = imgHeight;
306 this.updateTexCoords();
359 gl.glDisable(target);
378 validateTexID(gl,
true);
379 gl.glBindTexture(target, texID);
389 if( 0 != texID && ownsTextureID ) {
390 gl.glDeleteTextures(1,
new int[] {texID}, 0);
499 if (mustFlipVertically) {
500 return new TextureCoords(x1, texHeight - y1, x2, texHeight - y2);
505 final float tx1 = (float)x1 / (
float)texWidth;
506 final float ty1 = (float)y1 / (
float)texHeight;
507 final float tx2 = (float)x2 / (
float)texWidth;
508 final float ty2 = (float)y2 / (
float)texHeight;
509 if (mustFlipVertically) {
510 final float yMax = (float) imgHeight / (
float) texHeight;
537 return mustFlipVertically;
548 if( v != mustFlipVertically ) {
549 mustFlipVertically = v;
562 validateTexID(gl,
true);
564 imgWidth = data.getWidth();
565 imgHeight = data.getHeight();
566 aspectRatio = (float) imgWidth / (
float) imgHeight;
567 mustFlipVertically = data.getMustFlipVertically();
570 int texParamTarget = this.target;
573 boolean haveAutoMipmapGeneration =
582 final boolean isPOT = Bitfield.Util.isPowerOf2(imgWidth) && Bitfield.Util.isPowerOf2(imgHeight);
586 if (!isPOT && !haveNPOT(gl)) {
587 haveAutoMipmapGeneration =
false;
590 boolean expandingCompressedTexture =
false;
591 boolean done =
false;
592 if (data.getMipmap() && !haveAutoMipmapGeneration) {
597 imgWidth = Bitfield.Util.roundToPowerOf2(imgWidth);
598 imgHeight = Bitfield.Util.roundToPowerOf2(imgHeight);
600 texHeight = imgHeight;
605 if (!done && preferTexRect(gl) && !isPOT &&
606 haveTexRect(gl) && !data.isDataCompressed() && !gl.isGL3() && !gl.isGLES()) {
609 System.err.println(
"Using GL_ARB_texture_rectangle preferentially on this hardware");
613 texHeight = imgHeight;
618 if (!done && (isPOT || haveNPOT(gl))) {
621 System.err.println(
"Power-of-two texture");
623 System.err.println(
"Using GL_ARB_texture_non_power_of_two");
628 texHeight = imgHeight;
633 if (!done && haveTexRect(gl) && !data.isDataCompressed() && !gl.isGL3() && !gl.isGLES()) {
636 System.err.println(
"Using GL_ARB_texture_rectangle");
640 texHeight = imgHeight;
652 if (data.isDataCompressed()) {
653 if (data.getMipmapData() !=
null) {
659 throw new GLException(
"Mipmapped non-power-of-two compressed textures only supported on OpenGL 2.0 hardware (GL_ARB_texture_non_power_of_two)");
662 expandingCompressedTexture =
true;
666 System.err.println(
"Expanding texture to power-of-two dimensions");
669 if (data.getBorder() != 0) {
670 throw new RuntimeException(
"Scaling up a non-power-of-two texture which has a border won't work");
672 texWidth = Bitfield.Util.roundToPowerOf2(imgWidth);
673 texHeight = Bitfield.Util.roundToPowerOf2(imgHeight);
676 texParamTarget = texTarget;
677 imageTarget = texTarget;
680 if (targetOverride != 0) {
683 if (this.target == 0) {
684 throw new GLException(
"Override of target failed; no target specified yet");
686 texTarget = targetOverride;
687 texParamTarget = this.target;
688 gl.glBindTexture(texParamTarget, texID);
690 gl.glBindTexture(texTarget, texID);
693 if (data.getMipmap() && !haveAutoMipmapGeneration) {
694 final int[] align =
new int[1];
698 if (data.isDataCompressed()) {
699 throw new GLException(
"May not request mipmap generation for compressed textures");
706 data.getWidth(), data.getHeight(),
707 data.getPixelFormat(), data.getPixelType(), data.getBuffer());
712 checkCompressedTextureExtensions(gl, data);
713 final Buffer[] mipmapData = data.getMipmapData();
714 if (mipmapData !=
null) {
715 int width = texWidth;
716 int height = texHeight;
717 for (
int i = 0; i < mipmapData.length; i++) {
718 if (data.isDataCompressed()) {
721 gl.glCompressedTexImage2D(texTarget, i, data.getInternalFormat(),
722 width, height, data.getBorder(),
723 mipmapData[i].remaining(), mipmapData[i]);
726 gl.glTexImage2D(texTarget, i, data.getInternalFormat(),
727 width, height, data.getBorder(),
728 data.getPixelFormat(), data.getPixelType(),
null);
729 updateSubImageImpl(gl, data, texTarget, i, 0, 0, 0, 0, data.getWidth(), data.getHeight());
732 width = Math.max(width / 2, 1);
733 height = Math.max(height / 2, 1);
736 if (data.isDataCompressed()) {
737 if (!expandingCompressedTexture) {
740 gl.glCompressedTexImage2D(texTarget, 0, data.getInternalFormat(),
741 texWidth, texHeight, data.getBorder(),
742 data.getBuffer().capacity(), data.getBuffer());
746 data.getInternalFormat());
747 gl.glCompressedTexImage2D(texTarget, 0, data.getInternalFormat(),
748 texWidth, texHeight, data.getBorder(),
749 buf.capacity(), buf);
750 updateSubImageImpl(gl, data, texTarget, 0, 0, 0, 0, 0, data.getWidth(), data.getHeight());
753 if (data.getMipmap() && haveAutoMipmapGeneration && gl.isGL2ES1()) {
759 usingAutoMipmapGeneration =
true;
762 gl.glTexImage2D(texTarget, 0, data.getInternalFormat(),
763 texWidth, texHeight, data.getBorder(),
764 data.getPixelFormat(), data.getPixelType(),
null);
765 updateSubImageImpl(gl, data, texTarget, 0, 0, 0, 0, 0, data.getWidth(), data.getHeight());
770 final int minFilter = (data.getMipmap() ? GL.GL_LINEAR_MIPMAP_LINEAR :
GL.
GL_LINEAR);
787 if ((this.target == 0) ||
790 this.target = texTarget;
794 estimatedMemorySize = data.getEstimatedMemorySize();
819 if (usingAutoMipmapGeneration && mipmapLevel != 0) {
825 updateSubImageImpl(gl, data, target, mipmapLevel, x, y, 0, 0, data.getWidth(), data.getHeight());
859 final int dstx,
final int dsty,
860 final int srcx,
final int srcy,
861 final int width,
final int height)
throws GLException {
862 if (data.isDataCompressed()) {
863 throw new GLException(
"updateSubImage specifying a sub-rectangle is not supported for compressed TextureData");
865 if (usingAutoMipmapGeneration && mipmapLevel != 0) {
871 updateSubImageImpl(gl, data, target, mipmapLevel, dstx, dsty, srcx, srcy, width, height);
897 final FloatBuffer params) {
910 final float[] params,
final int params_offset) {
939 final IntBuffer params) {
952 final int[] params,
final int params_offset) {
969 validateTexID(gl,
false);
993 return estimatedMemorySize;
1006 return usingAutoMipmapGeneration;
1013 private void updateTexCoords() {
1015 if (mustFlipVertically) {
1018 coords =
new TextureCoords(0, 0, imgWidth, imgHeight);
1021 if (mustFlipVertically) {
1022 coords =
new TextureCoords(0,
1023 (
float) imgHeight / (
float) texHeight,
1024 (
float) imgWidth / (
float) texWidth,
1028 coords =
new TextureCoords(0,
1030 (
float) imgWidth / (
float) texWidth,
1031 (
float) imgHeight / (
float) texHeight
1037 private void updateSubImageImpl(
final GL gl,
final TextureData data,
final int newTarget,
final int mipmapLevel,
1039 int srcx,
int srcy,
int width,
int height)
throws GLException {
1040 data.setHaveEXTABGR(gl.isExtensionAvailable(GLExtensions.EXT_abgr));
1041 data.setHaveGL12(gl.isExtensionAvailable(GLExtensions.VERSION_1_2));
1043 Buffer buffer = data.getBuffer();
1044 if (buffer ==
null && data.getMipmapData() ==
null) {
1049 int rowlen = data.getRowLength();
1050 int dataWidth = data.getWidth();
1051 int dataHeight = data.getHeight();
1052 if (data.getMipmapData() !=
null) {
1056 for (
int i = 0; i < mipmapLevel; i++) {
1057 width = Math.max(width / 2, 1);
1058 height = Math.max(height / 2, 1);
1060 dataWidth = Math.max(dataWidth / 2, 1);
1061 dataHeight = Math.max(dataHeight / 2, 1);
1064 buffer = data.getMipmapData()[mipmapLevel];
1087 if (srcx + width > dataWidth) {
1088 width = dataWidth - srcx;
1090 if (srcy + height > dataHeight) {
1091 height = dataHeight - srcy;
1093 if (dstx + width > texWidth) {
1094 width = texWidth - dstx;
1096 if (dsty + height > texHeight) {
1097 height = texHeight - dsty;
1100 checkCompressedTextureExtensions(gl, data);
1102 if (data.isDataCompressed()) {
1103 gl.glCompressedTexSubImage2D(newTarget, mipmapLevel,
1104 dstx, dsty, width, height,
1105 data.getInternalFormat(),
1106 buffer.remaining(), buffer);
1108 final int[] align = { 0 };
1109 final int[] rowLength = { 0 };
1110 final int[] skipRows = { 0 };
1111 final int[] skipPixels = { 0 };
1112 gl.glGetIntegerv(GL.GL_UNPACK_ALIGNMENT, align, 0);
1114 gl.glGetIntegerv(GL2ES2.GL_UNPACK_ROW_LENGTH, rowLength, 0);
1115 gl.glGetIntegerv(GL2ES2.GL_UNPACK_SKIP_ROWS, skipRows, 0);
1116 gl.glGetIntegerv(GL2ES2.GL_UNPACK_SKIP_PIXELS, skipPixels, 0);
1118 gl.glPixelStorei(GL.GL_UNPACK_ALIGNMENT, data.getAlignment());
1119 if (DEBUG && VERBOSE) {
1120 System.out.println(
"Row length = " + rowlen);
1121 System.out.println(
"skip pixels = " + srcx);
1122 System.out.println(
"skip rows = " + srcy);
1123 System.out.println(
"dstx = " + dstx);
1124 System.out.println(
"dsty = " + dsty);
1125 System.out.println(
"width = " + width);
1126 System.out.println(
"height = " + height);
1129 gl.glPixelStorei(GL2ES2.GL_UNPACK_ROW_LENGTH, rowlen);
1130 gl.glPixelStorei(GL2ES2.GL_UNPACK_SKIP_ROWS, srcy);
1131 gl.glPixelStorei(GL2ES2.GL_UNPACK_SKIP_PIXELS, srcx);
1133 if ( rowlen!=0 && rowlen!=width &&
1134 srcy!=0 && srcx!=0 ) {
1135 throw new GLException(
"rowlen and/or x/y offset only available for GL2");
1139 gl.glTexSubImage2D(newTarget, mipmapLevel,
1140 dstx, dsty, width, height,
1141 data.getPixelFormat(), data.getPixelType(),
1143 gl.glPixelStorei(GL.GL_UNPACK_ALIGNMENT, align[0]);
1145 gl.glPixelStorei(GL2ES2.GL_UNPACK_ROW_LENGTH, rowLength[0]);
1146 gl.glPixelStorei(GL2ES2.GL_UNPACK_SKIP_ROWS, skipRows[0]);
1147 gl.glPixelStorei(GL2ES2.GL_UNPACK_SKIP_PIXELS, skipPixels[0]);
1152 private void checkCompressedTextureExtensions(
final GL gl,
final TextureData data) {
1153 if (data.isDataCompressed()) {
1154 switch (data.getInternalFormat()) {
1155 case GL.GL_COMPRESSED_RGB_S3TC_DXT1_EXT:
1156 case GL.GL_COMPRESSED_RGBA_S3TC_DXT1_EXT:
1157 case GL.GL_COMPRESSED_RGBA_S3TC_DXT3_EXT:
1158 case GL.GL_COMPRESSED_RGBA_S3TC_DXT5_EXT:
1159 if (!gl.isExtensionAvailable(GLExtensions.EXT_texture_compression_s3tc) &&
1160 !gl.isExtensionAvailable(GLExtensions.NV_texture_compression_vtc)) {
1161 throw new GLException(
"DXTn compressed textures not supported by this graphics card");
1172 private boolean validateTexID(
final GL gl,
final boolean throwException) {
1174 if(
null != gl && ownsTextureID ) {
1175 final int[] tmp =
new int[1];
1176 gl.glGenTextures(1, tmp, 0);
1178 if ( 0 == texID && throwException ) {
1179 throw new GLException(
"Create texture ID invalid: texID "+texID+
", glerr 0x"+Integer.toHexString(gl.glGetError()));
1181 }
else if ( throwException ) {
1182 if( !ownsTextureID ) {
1183 throw new GLException(
"Invalid external texture ID");
1185 throw new GLException(
"No GL context given, can't create texture ID");
1193 private static boolean haveNPOT(
final GL gl) {
1194 return !disableNPOT && gl.isNPOTTextureAvailable();
1197 private static boolean haveTexRect(
final GL gl) {
1198 return (!disableTexRect &&
1199 TextureIO.isTexRectEnabled() &&
1200 gl.isExtensionAvailable(GLExtensions.ARB_texture_rectangle));
1203 private static boolean preferTexRect(
final GL gl) {
1207 if (NativeWindowFactory.TYPE_MACOSX == NativeWindowFactory.getNativeWindowType(
false)) {
1208 final String vendor = gl.glGetString(GL.GL_VENDOR);
1209 if (vendor !=
null && vendor.startsWith(
"ATI")) {
A generic exception for OpenGL errors used throughout the binding as a substitute for RuntimeExceptio...
Class holding OpenGL extension strings, commonly used by JOGL's implementation.
static final String VERSION_1_4
static final String SGIS_generate_mipmap
static final String VERSION_1_2
static final String EXT_abgr
Provides access to the OpenGL Utility Library (GLU).
int gluBuild2DMipmaps(int target, int internalFormat, int width, int height, int format, int type, java.nio.Buffer data)
Optional, throws GLException if not available in profile.
static final GLU createGLU()
Instantiates a GLU implementation object in respect to the given GL profile of this thread current GL...
Specifies texture coordinates for a rectangular area of a texture.
Represents the data for an OpenGL texture.
Represents an OpenGL texture object.
int getImageHeight()
Returns the height of the image contained within this texture.
TextureCoords getImageTexCoords()
Returns the set of texture coordinates corresponding to the entire image.
void setTexParameteri(final GL gl, final int parameterName, final int value)
Sets the OpenGL integer texture parameter for the texture's target.
void setTexParameteriv(final GL gl, final int parameterName, final IntBuffer params)
Sets the OpenGL multi-integer texture parameter for the texture's target.
void setTexParameterfv(final GL gl, final int parameterName, final FloatBuffer params)
Sets the OpenGL multi-floating-point texture parameter for the texture's target.
Texture(final GL gl, final TextureData data)
void bind(final GL gl)
Binds this texture to the given GL context.
int getHeight()
Returns the height of the allocated OpenGL texture in pixels.
int getTarget()
Returns the OpenGL "target" of this texture.
final boolean ownsTexture()
Returns whether getTextureObject() is owned by this Texture instance.
void setTexParameterf(final GL gl, final int parameterName, final float value)
Sets the OpenGL floating-point texture parameter for the texture's target.
boolean getMustFlipVertically()
Indicates whether this texture's texture coordinates must be flipped vertically in order to properly ...
void disable(final GL gl)
Disables this texture's target (e.g., GL_TEXTURE_2D) in the given GL state.
void updateImage(final GL gl, final TextureData data)
Updates the entire content area incl.
int getTextureObject()
Returns the underlying OpenGL texture object for this texture, maybe 0 if not yet generated.
void updateSubImage(final GL gl, final TextureData data, final int mipmapLevel, final int dstx, final int dsty, final int srcx, final int srcy, final int width, final int height)
Updates a subregion of the content area of this texture using the specified sub-region of the given d...
float getAspectRatio()
Returns the original aspect ratio of the image, defined as (image width) / (image height),...
void updateImage(final GL gl, final TextureData data, final int targetOverride)
Updates the content area incl.
int getWidth()
Returns the width of the allocated OpenGL texture in pixels.
void setMustFlipVertically(final boolean v)
Change whether the TextureData requires a vertical flip of the texture coords.
int getImageTarget()
Returns the image OpenGL "target" of this texture, or its sub-components if cubemap.
void setTexParameterfv(final GL gl, final int parameterName, final float[] params, final int params_offset)
Sets the OpenGL multi-floating-point texture parameter for the texture's target.
int getEstimatedMemorySize()
Returns an estimate of the amount of texture memory in bytes this Texture consumes.
void setTexParameteriv(final GL gl, final int parameterName, final int[] params, final int params_offset)
Sets the OpenGL multi-integer texture parameter for the texture's target.
int getTextureObject(final GL gl)
Returns the underlying OpenGL texture object for this texture and generates it if not done yet.
void enable(final GL gl)
Enables this texture's target (e.g., GL_TEXTURE_2D) in the given GL context's state.
int getImageWidth()
Returns the width of the image contained within this texture.
TextureCoords getSubImageTexCoords(final int x1, final int y1, final int x2, final int y2)
Returns the set of texture coordinates corresponding to the specified sub-image.
Texture(final int textureID, final boolean ownsTextureID, final int target, final int texWidth, final int texHeight, final int imgWidth, final int imgHeight, final boolean mustFlipVertically)
Constructor to wrap an OpenGL texture ID from an external library and allows some of the base methods...
boolean isUsingAutoMipmapGeneration()
Indicates whether this Texture is using automatic mipmap generation (via the OpenGL texture parameter...
Texture(final int target)
Constructor for use when creating e.g.
void destroy(final GL gl)
Destroys and nulls the underlying native texture used by this Texture instance if owned,...
void updateSubImage(final GL gl, final TextureData data, final int mipmapLevel, final int x, final int y)
Updates a subregion of the content area of this texture using the given data.
A reader and writer for DirectDraw Surface (.dds) files, which are used to describe textures.
static ByteBuffer allocateBlankBuffer(final int width, final int height, final int openGLInternalFormat)
Allocates a temporary, empty ByteBuffer suitable for use in a call to glCompressedTexImage2D.
static final int GL_GENERATE_MIPMAP
GL_VERSION_1_4, GL_VERSION_ES_1_0, GL_SGIS_generate_mipmap Alias for: GL_GENERATE_MIPMAP_SGIS Define...
static final int GL_TEXTURE_WRAP_R
GL_ES_VERSION_3_0, GL_VERSION_1_2, GL_EXT_texture3D, GL_OES_texture_3D Alias for: GL_TEXTURE_WRAP_R_E...
static final int GL_TEXTURE_RECTANGLE_ARB
GL_ARB_texture_rectangle Define "GL_TEXTURE_RECTANGLE_ARB" with expression '0x84F5',...
static final int GL_CLAMP
GL_VERSION_1_0 Define "GL_CLAMP" with expression '0x2900', CType: int
static final int GL_TEXTURE_EXTERNAL_OES
GL_OES_EGL_image_external Define "GL_TEXTURE_EXTERNAL_OES" with expression '0x8D65',...
static final int GL_TEXTURE_MAG_FILTER
GL_ES_VERSION_2_0, GL_VERSION_1_1, GL_VERSION_1_0, GL_VERSION_ES_1_0 Define "GL_TEXTURE_MAG_FILTER" w...
static final int GL_UNPACK_ALIGNMENT
GL_ES_VERSION_2_0, GL_VERSION_1_1, GL_VERSION_1_0, GL_VERSION_ES_1_0 Define "GL_UNPACK_ALIGNMENT" wit...
static final int GL_TEXTURE_2D
GL_ES_VERSION_2_0, GL_VERSION_1_1, GL_VERSION_1_0, GL_VERSION_ES_1_0 Define "GL_TEXTURE_2D" with expr...
static final int GL_TEXTURE_WRAP_S
GL_ES_VERSION_2_0, GL_VERSION_1_1, GL_VERSION_1_0, GL_VERSION_ES_1_0 Define "GL_TEXTURE_WRAP_S" with ...
static final int GL_LINEAR
GL_ES_VERSION_2_0, GL_VERSION_1_1, GL_VERSION_1_0, GL_VERSION_ES_1_0 Define "GL_LINEAR" with expressi...
void glTexParameteriv(int target, int pname, IntBuffer params)
Entry point to C language function: void {@native glTexParameteriv}(GLenum target,...
static final int GL_TEXTURE_MIN_FILTER
GL_ES_VERSION_2_0, GL_VERSION_1_1, GL_VERSION_1_0, GL_VERSION_ES_1_0 Define "GL_TEXTURE_MIN_FILTER" w...
void glTexParameterfv(int target, int pname, FloatBuffer params)
Entry point to C language function: void {@native glTexParameterfv}(GLenum target,...
static final int GL_TEXTURE_WRAP_T
GL_ES_VERSION_2_0, GL_VERSION_1_1, GL_VERSION_1_0, GL_VERSION_ES_1_0 Define "GL_TEXTURE_WRAP_T" with ...
void glTexParameteri(int target, int pname, int param)
Entry point to C language function: void {@native glTexParameteri}(GLenum target,...
static final int GL_TRUE
GL_ES_VERSION_2_0, GL_VERSION_1_1, GL_VERSION_1_0, GL_VERSION_ES_1_0 Define "GL_TRUE" with expression...
void glTexParameterf(int target, int pname, float param)
Entry point to C language function: void {@native glTexParameterf}(GLenum target,...
static final int GL_CLAMP_TO_EDGE
GL_ES_VERSION_2_0, GL_VERSION_1_2, GL_VERSION_ES_1_0, GL_SGIS_texture_edge_clamp Alias for: GL_CLAMP_...
static final int GL_TEXTURE_CUBE_MAP
GL_ES_VERSION_2_0, GL_VERSION_1_3, GL_OES_texture_cube_map, GL_ARB_texture_cube_map,...