Represents an OpenGL texture object. Contains convenience routines
for enabling/disabling OpenGL texture state, binding this texture,
and computing texture coordinates for both the entire image as well
as a sub-image.
Non-power-of-two restrictions
When creating an OpenGL texture object, the Texture class will
attempt to leverage the
GL_ARB_texture_non_power_of_two
and
GL_ARB_texture_rectangle
extensions (in that order) whenever possible. If neither extension
is available, the Texture class will simply upload a non-pow2-sized
image into a standard pow2-sized texture (without any special
scaling). Since the choice of extension (or whether one is used at
all) depends on the user's machine configuration, developers are
recommended to use
getImageTexCoords()
and
getSubImageTexCoords(int,int,int,int)
, as those methods will calculate the
appropriate texture coordinates for the situation.
One caveat in this approach is that certain texture wrap modes
(e.g.
GL_REPEAT
) are not legal when the GL_ARB_texture_rectangle
extension is in use. Another issue to be aware of is that in the
default pow2 scenario, if the original image does not have pow2
dimensions, then wrapping may not work as one might expect since
the image does not extend to the edges of the pow2 texture. If
texture wrapping is important, it is recommended to use only
pow2-sized images with the Texture class.
Performance Tips
For best performance, try to avoid calling
enable()
/
bind()
/
disable()
any more than necessary. For
example, applications using many Texture objects in the same scene
may want to reduce the number of calls to both
enable()
and
disable()
. To do this it is necessary to call
getTarget()
to make sure the OpenGL texture target is the same for
all of the Texture objects in use; non-power-of-two textures using
the GL_ARB_texture_rectangle extension use a different target than
power-of-two textures using the GL_TEXTURE_2D target. Note that
when switching between textures it is necessary to call
bind()
, but when drawing many triangles all using the same texture,
for best performance only one call to
bind()
should be made.
Alpha premultiplication and blending
The mathematically correct way to perform blending in OpenGL
(with the SrcOver "source over destination" mode, or any other
Porter-Duff rule) is to use "premultiplied color components", which
means the R/G/ B color components have already been multiplied by
the alpha value. To make things easier for developers, the Texture
class will automatically convert non-premultiplied image data into
premultiplied data when storing it into an OpenGL texture. As a
result, it is important to use the correct blending function; for
example, the SrcOver rule is expressed as:
gl.glBlendFunc(GL.GL_ONE, GL.GL_ONE_MINUS_SRC_ALPHA);
Also, when using a texture function like
GL_MODULATE
where
the current color plays a role, it is important to remember to make
sure that the color is specified in a premultiplied form, for
example:
float a = ...;
float r = r * a;
float g = g * a;
float b = b * a;
gl.glColor4f(r, g, b, a);
For reference, here is a list of the Porter-Duff compositing rules
and the associated OpenGL blend functions (source and destination
factors) to use in the face of premultiplied alpha:
Rule | Source | Dest
|
Clear | GL_ZERO | GL_ZERO
|
Src | GL_ONE | GL_ZERO
|
SrcOver | GL_ONE | GL_ONE_MINUS_SRC_ALPHA
|
DstOver | GL_ONE_MINUS_DST_ALPHA | GL_ONE
|
SrcIn | GL_DST_ALPHA | GL_ZERO
|
DstIn | GL_ZERO | GL_SRC_ALPHA
|
SrcOut | GL_ONE_MINUS_DST_ALPHA | GL_ZERO
|
DstOut | GL_ZERO | GL_ONE_MINUS_SRC_ALPHA
|
Dst | GL_ZERO | GL_ONE
|
SrcAtop | GL_DST_ALPHA | GL_ONE_MINUS_SRC_ALPHA
|
DstAtop | GL_ONE_MINUS_DST_ALPHA | GL_SRC_ALPHA
|
AlphaXor | GL_ONE_MINUS_DST_ALPHA | GL_ONE_MINUS_SRC_ALPHA
|
bind
public void bind()
throws GLException
Binds this texture to the current GL context. This method is a
shorthand equivalent of the following OpenGL code:
gl.glBindTexture(texture.getTarget(), texture.getTextureObject());
See the
performance tips above for hints
on how to maximize performance when using many Texture objects.
GLException
- if no OpenGL context was current or if any
OpenGL-related errors occurred
disable
public void disable()
throws GLException
Disables this texture's target (e.g., GL_TEXTURE_2D) in the
current GL context's state. This method is a shorthand equivalent
of the following OpenGL code:
gl.glDisable(texture.getTarget());
See the
performance tips above for hints
on how to maximize performance when using many Texture objects.
GLException
- if no OpenGL context was current or if any
OpenGL-related errors occurred
dispose
public void dispose()
throws GLException
Disposes the native resources used by this texture object.
GLException
- if no OpenGL context was current or if any
OpenGL-related errors occurred
enable
public void enable()
throws GLException
Enables this texture's target (e.g., GL_TEXTURE_2D) in the
current GL context's state. This method is a shorthand equivalent
of the following OpenGL code:
gl.glEnable(texture.getTarget());
See the
performance tips above for hints
on how to maximize performance when using many Texture objects.
GLException
- if no OpenGL context was current or if any
OpenGL-related errors occurred
getAspectRatio
public float getAspectRatio()
Returns the original aspect ratio of the image, defined as (image
width) / (image height), before any scaling that might have
occurred as a result of using the GLU mipmap routines.
getEstimatedMemorySize
public int getEstimatedMemorySize()
Returns an estimate of the amount of texture memory in bytes
this Texture consumes. It should only be treated as an estimate;
most applications should not need to query this but instead let
the OpenGL implementation page textures in and out as
necessary.
getHeight
public int getHeight()
Returns the height of the allocated OpenGL texture in pixels.
Note that the texture height will be greater than or equal to the
height of the image contained within.
- the height of the texture
getImageHeight
public int getImageHeight()
getImageTexCoords
public TextureCoords getImageTexCoords()
Returns the set of texture coordinates corresponding to the
entire image. If the TextureData indicated that the texture
coordinates must be flipped vertically, the returned
TextureCoords will take that into account.
- the texture coordinates corresponding to the entire image
getImageWidth
public int getImageWidth()
getMustFlipVertically
public boolean getMustFlipVertically()
Indicates whether this texture's texture coordinates must be
flipped vertically in order to properly display the texture. This
is handled automatically by
getImageTexCoords
and
getSubImageTexCoords
, but applications may generate or otherwise
produce texture coordinates which must be corrected.
getSubImageTexCoords
public TextureCoords getSubImageTexCoords(int x1,
int y1,
int x2,
int y2)
Returns the set of texture coordinates corresponding to the
specified sub-image. The (x1, y1) and (x2, y2) points are
specified in terms of pixels starting from the lower-left of the
image. (x1, y1) should specify the lower-left corner of the
sub-image and (x2, y2) the upper-right corner of the sub-image.
If the TextureData indicated that the texture coordinates must be
flipped vertically, the returned TextureCoords will take that
into account; this should not be handled by the end user in the
specification of the y1 and y2 coordinates.
- the texture coordinates corresponding to the specified sub-image
getTarget
public int getTarget()
Returns the OpenGL "target" of this texture.
- the OpenGL target of this texture
getTextureObject
public int getTextureObject()
Returns the underlying OpenGL texture object for this texture.
Most applications will not need to access this, since it is
handled automatically by the bind() and dispose() APIs.
getWidth
public int getWidth()
Returns the width of the allocated OpenGL texture in pixels.
Note that the texture width will be greater than or equal to the
width of the image contained within.
isUsingAutoMipmapGeneration
public boolean isUsingAutoMipmapGeneration()
Indicates whether this Texture is using automatic mipmap
generation (via the OpenGL texture parameter
GL_GENERATE_MIPMAP). This will automatically be used when
mipmapping is requested via the TextureData and either OpenGL
1.4 or the GL_SGIS_generate_mipmap extension is available. If
so, updates to the base image (mipmap level 0) will
automatically propagate down to the lower mipmap levels. Manual
updates of the mipmap data at these lower levels will be
ignored.
setTexParameterf
public void setTexParameterf(int parameterName,
float value)
Sets the OpenGL floating-point texture parameter for the
texture's target. This gives control over parameters such as
GL_TEXTURE_MAX_ANISOTROPY_EXT. Causes this texture to be bound to
the current texture state.
setTexParameterfv
public void setTexParameterfv(int parameterName,
FloatBuffer params)
Sets the OpenGL multi-floating-point texture parameter for the
texture's target. Causes this texture to be bound to the current
texture state.
setTexParameterfv
public void setTexParameterfv(int parameterName,
float[] params,
int params_offset)
Sets the OpenGL multi-floating-point texture parameter for the
texture's target. Causes this texture to be bound to the current
texture state.
setTexParameteri
public void setTexParameteri(int parameterName,
int value)
Sets the OpenGL integer texture parameter for the texture's
target. This gives control over parameters such as
GL_TEXTURE_WRAP_S and GL_TEXTURE_WRAP_T, which by default are set
to GL_CLAMP_TO_EDGE if OpenGL 1.2 is supported on the current
platform and GL_CLAMP if not. Causes this texture to be bound to
the current texture state.
setTexParameteriv
public void setTexParameteriv(int parameterName,
IntBuffer params)
Sets the OpenGL multi-integer texture parameter for the texture's
target. Causes this texture to be bound to the current texture
state.
setTexParameteriv
public void setTexParameteriv(int parameterName,
int[] params,
int params_offset)
Sets the OpenGL multi-integer texture parameter for the texture's
target. Causes this texture to be bound to the current texture
state.
updateImage
public void updateImage(TextureData data)
throws GLException
Updates the entire content area of this texture using the data in
the given image.
GLException
- if no OpenGL context was current or if any
OpenGL-related errors occurred
updateImage
public void updateImage(TextureData data,
int target)
throws GLException
Updates the content area of the specified target of this texture
using the data in the given image. In general this is intended
for construction of cube maps.
GLException
- if no OpenGL context was current or if any
OpenGL-related errors occurred
updateSubImage
public void updateSubImage(TextureData data,
int mipmapLevel,
int x,
int y)
throws GLException
Updates a subregion of the content area of this texture using the
given data. If automatic mipmap generation is in use (see
isUsingAutoMipmapGeneration
),
updates to the base (level 0) mipmap will cause the lower-level
mipmaps to be regenerated, and updates to other mipmap levels
will be ignored. Otherwise, if automatic mipmap generation is not
in use, only updates the specified mipmap level and does not
re-generate mipmaps if they were originally produced or loaded.
data
- the image data to be uploaded to this texturemipmapLevel
- 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.x
- the x offset (in pixels) relative to the lower-left corner
of this texturey
- the y offset (in pixels) relative to the lower-left corner
of this texture
GLException
- if no OpenGL context was current or if any
OpenGL-related errors occurred
updateSubImage
public void updateSubImage(TextureData data,
int mipmapLevel,
int dstx,
int dsty,
int srcx,
int srcy,
int width,
int height)
throws GLException
Updates a subregion of the content area of this texture using the
specified sub-region of the given data. If automatic mipmap
generation is in use (see
isUsingAutoMipmapGeneration
), updates to the base (level 0)
mipmap will cause the lower-level mipmaps to be regenerated, and
updates to other mipmap levels will be ignored. Otherwise, if
automatic mipmap generation is not in use, 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.
data
- the image data to be uploaded to this texturemipmapLevel
- 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.dstx
- the x offset (in pixels) relative to the lower-left corner
of this texture where the update will be applieddsty
- the y offset (in pixels) relative to the lower-left corner
of this texture where the update will be appliedsrcx
- the x offset (in pixels) relative to the lower-left corner
of the supplied TextureData from which to fetch the update rectanglesrcy
- the y offset (in pixels) relative to the lower-left corner
of the supplied TextureData from which to fetch the update rectanglewidth
- the width (in pixels) of the rectangle to be updatedheight
- the height (in pixels) of the rectangle to be updated
GLException
- if no OpenGL context was current or if any
OpenGL-related errors occurred