Usage examples
The JCGLTexturesType
interfaces expose functions that
will allocate textures of formats supported by the current
implementation. The interfaces only expose textures that are
required
to be supported by OpenGL 3.3 core.
In order to use a texture in OpenGL, the texture must be bound
to a texture unit. There are a
limited number of texture units available
, and so the API requires the user to obtain access
to a list of the current units:
A texture unit may have at most one texture bound to it at any
one time. This is in slight contrast to the way that the OpenGL
API normally works: The OpenGL API specifies that a given texture
unit may have multiple textures bound to a given texture unit as long
as all of the textures are of a different type
(two-dimensional, cube map, etc). However, it then states that
it is not legal to pass that texture
unit to multiple different uniform parameters in a shading program.
There is, therefore, very little practical utility to binding multiple
textures to a single texture unit, and exposing such behaviour in the
API complicates tracking of state and makes programs slightly more
difficult to reason about. The
jcanephora API therefore imposes
a simple restriction: One texture per texture unit.
To allocate a
256 * 256
RGBA texture, 8 bits per channel (four bytes per pixel),
with nearest-neighbour filtering and repeat wrapping around
both axes:
Once allocated, the texture will remain bound to the texture
unit u until explicitly unbound.
The jcanephora exposes both
two-dimensional and cube map textures. See the relevant superinterfaces.
Cube map coordinate systems
Note that in the OpenGL specification, cube textures arbitrarily
use a left-handed coordinate system as opposed to OpenGL's right-handed system.
This is a frequent source of errors in programs. See the following fragment
shader:
The program calculates a reflection vector
r from the eye-space incident vector
f_position and eye-space surface normal
f_normal. It transforms
r back into world-space, giving
u, and then uses u
to index into the cube texture. This would be textbook-correct, if OpenGL
didn't arbitrarily use a left-handed coordinate system for cube textures!
The coordinates u are obviously specified
in a right-handed coordinate system. The practical results of this are that
all of the cube texture faces will be displayed upside down, and the
familiar concept of the negative Z axis meaning "forwards" will be reversed.
The jcanephora package contains support
for using right-handed cube maps in OpenGL, consistent with the
right-handed coordinate system used in most OpenGL programs. In order
to use right-handed cube maps, the following steps are required:
The earlier example shader becomes:
This approach means that both the loading and generation of cube textures
is consistent with that of 2D textures and the rest of OpenGL, and the
complexity of addressing the textures is limited to one function call in
shaders. Renderers that produce cube maps do not need to use unusual
projection matrices to "flip" the coordinate system when rendering, and
everything works according to the principles of least astonishment!
The correct solution to the problem would have been for the cube map
coordinate system to have been in a consistent right-handed coordinate
space to begin with.