Texture
defines a texture object to be used to display an image on a piece of geometry. The image to be displayed is defined by the Image
class. All attributes required for texture mapping are contained within this class. This includes mipmapping if desired, magnificationFilter options, apply options and correction options. Default values are as follows: minificationFilter - NearestNeighborNoMipMaps, magnificationFilter - NearestNeighbor, wrap - EdgeClamp on S,T and R, apply - Modulate, environment - None.
@see com.ardor3d.image.Image
A Texture wraps a standard OpenGL ES texture.
A Texture can be managed. If the OpenGL context is lost all managed textures get invalidated. This happens when a user switches to another application or receives an incoming call. Managed textures get reloaded automatically.
A Texture has to be bound via the {@link Texture#bind()} method in order for it to be applied to geometry. The texture will bebound to the currently active texture unit specified via {@link GLCommon#glActiveTexture(int)}.
You can draw {@link Pixmap}s to a texture at any time. The changes will be automatically uploaded to texture memory. This is of course not extremely fast so use it with care. It also only works with unmanaged textures.
A Texture must be disposed when it is no longer used
@author badlogicgames@gmail.comTexture
defines a texture object to be used to display an image on a piece of geometry. The image to be displayed is defined by the Image
class. All attributes required for texture mapping are contained within this class. This includes mipmapping if desired, magnificationFilter options, apply options and correction options. Default values are as follows: minificationFilter - NearestNeighborNoMipMaps, magnificationFilter - NearestNeighbor, wrap - EdgeClamp on S,T and R, apply - Modulate, environment - None.
@see com.jme3.texture.Image
@author Mark Powell
@author Joshua Slack
@version $Id: Texture.java 4131 2009-03-19 20:15:28Z blaine.dev $
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 {@link #enable} /{@link #bind} / {@link #disable} any more than necessary. Forexample, applications using many Texture objects in the same scene may want to reduce the number of calls to both {@link #enable} and{@link #disable}. To do this it is necessary to call {@link #getTarget} to make sure the OpenGL texture target is the same forall 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 {@link #bind}, but when drawing many triangles all using the same texture, for best performance only one call to {@link #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 |
Each Texture object has the following properties:
j0 = trunc(v - 0.5)
i1 = i0 + 1
j1 = j0 + 1
a = frac(u - 0.5)
b = frac(v - 0.5)
T' = (1-a)*(1-b)*Ti0j0 + a*(1-b)*Ti1j0 + (1-a)*b*Ti0j1 + a*b*Ti1j1
i1 = trunc(u - 0.5) | i2 = i1 + 1 | i3 = i2 + 1 | i0 = i1 - 1 |
j1 = trunc(v - 0.5) | j3 = j2 + 1 | j2 = j1 + 1 | j0 = j1 - 1 |
a = frac(u - 0.5) | |||
b = frac(v - 0.5) |
T' = f(1+a) * f(1+b) * Ti0j0 + f(a) * f(1+b) * Ti1j0 + f(1-a) * f(1+b) * Ti2j0 + f(2-a) * f(1+b) * Ti3j0 +
f(1+a) * f(b) * Ti0j1 + f(a) * f(b) * Ti1j1 + f(1-a) * f(b) * Ti2j1 + f(2-a) * f(b) * Ti3j1 +
f(1+a) * f(1-b) * Ti0j2 + f(a) * f(1-b) * Ti1j2 + f(1-a) * f(1-b) * Ti2j2 + f(2-a) * f(1-b) * Ti3j2 +
f(1+a) * f(2-b) * Ti0j3 + f(a) * f(2-b) * Ti1j3 + f(1-a) * f(2-b) * Ti2j3 + f(2-a) * f(2-b) * Ti3j3
Note that as of Java 3D 1.5, the texture width and height are no longer required to be an exact power of two. However, not all graphics devices supports non-power-of-two textures. If non-power-of-two texture mapping is unsupported on a particular Canvas3D, textures with a width or height that are not an exact power of two are ignored for that canvas. @see Canvas3D#queryProperties
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|