It is possible to apply a matrix to transform the (u, v) texture
coordinates of a model before rendering. In this way, you can adjust
the position, rotation, or scale of a texture, sliding the texture
around to suit your particular needs.
Use the following NodePath methods to do this:
nodePath.setTexOffset(TextureStage, uOffset, vOffset);
nodePath.setTexScale(TextureStage, uScale, vScale);
nodePath.setTexRotate(TextureStage, degrees);
|
If you don't have a particular TextureStage, use
TextureStage.getDefault() as the first parameter.
Note that the operation in each case is applied to the (u, v) texture
coordinates, not to the texture; so it will have the opposite effect
on the texture. For instance, the call nodePath.setTexScale(ts,
2, 2) will effectively double the values of the texture
coordinates on the model, which doubles the space over which the texture is applied, and thus makes the texture appear half as large.
The above methods apply a 2-d transform to your texture
coordinates, which is appropriate, since texture coordinates are
usually two-dimensional. However, sometimes you are working with 3-d texture coordinates, and you really do want to apply a 3-d transform. For those cases, there are the following methods:
nodePath.setTexPos(TextureStage, uOffset, vOffset, wOffset);
nodePath.setTexScale(TextureStage, uScale, vScale, wScale);
nodePath.setTexHpr(TextureStage, h, p, r);
|
And there is also one generic form:
nodePath.setTexTransform(TextureStage, transform);
|
This last method sets a generic
TransformState object. This is the same kind of 4x4 transform matrix
object that you can get from a NodePath via e.g.,
NodePath.getTransform() . You can also construct a new TransformState
via a number of methods like TransformState.makePos(VBase3(0, 1, 0)) . If you intend to apply a 2-d transform only, you should restrict yourself to methods like TransformState.makePos2d(VBase2(0, 1)) ; using only 2-d operations may allow the graphics backend to use a slightly simpler calculation.
Note that the texture transform is associated with a particular
TextureStage; it is not a fixed property of the model or its texture
coordinates. You can therefore apply a different texture transform to
each different TextureStage, so that if you have multiple textures in
effect on a particular node, they need not all be in the same place,
even if they all use the same texture coordinates. For instance, this
technique was used to generate the sample images in the Texture Blend Modes section. In fact, the following code was used to place this
sample texture (excerpted):
smiley = loader.loadModel('smiley.egg')
ts = TextureStage('ts')
pattern = loader.loadTexture('color_pattern.png')
smiley.setTexture(ts, pattern)
smiley.setTexScale(ts, 8, 4)
smiley.setTexOffset(ts, -4, -2)
|
and the resulting texture:
In the above example, we have applied a scale of (8, 4) to reduce the
size of the decal image substantially, and then we specified an offset
of (-4, -2) to slide it around in the positive (u, v) direction to
smiley's face (since the (0, 0) coordinate happens to be on smiley's
backside). However, these operations affect only the decal image; the
original smiley texture is unchanged from its normal position, even
though both textures are using the same texture coordinates.
|