Sometimes it is useful to be able to change or apply textures through a script. Imagine, for example, a button or switch where you want to change the appearance when the user clicks on it.

There are a number of functions in the LSL library for dealing with textures. In this post I will cover the most basic of them. I’ll go into more details in subsequent posts.

Applying a Texture

Applying a texture to a prim is probably the simplest thing that can be done when scripting textures. You can use the llSetTexture function to do this, which simply needs the texture, and the side to apply the texture to. I’ll discuss prim sides a bit later, but for the example I’ll use the ALL_SIDES constant, which will apply the texture to all sides of the prim.

There are two different ways of specifying the texture. You can either use the name of the texture, or you can use the asset UUID of the texture.

To use the name, the texture must be included in the prim’s contents (just drag the texture from your inventory into the contents list of the prim).

Assume we have a texture called “test”. This script will apply the texture to all sides of the prim when the prim is touched:

default
{
    touch_start(int number)
    {
        llSetTexture("test", ALL_SIDES);
    }
}

Alternatively, we can specify the asset UUID. To find the UUID, right-click on the texture in your inventory, and select the Copy Asset UUID option. You can then paste the result into the script, like so:

default
{
    touch_start(int number)
    {
        llSetTexture("3c8f1c70-671a-4cb6-9f06-58b95c77e6a6", ALL_SIDES);
    }
}

The advantage with using the UUID is that the texture does not need to be in the prim’s inventory, it only needs to exist somewhere in SL’s asset server.

Note that the asset UUID in the above code is a real one, and will get you a “test card” pattern that you can use for testing offsets (see below).

Aside: What happens if you upload a texture into your inventory, get the UUID for it, then delete the texture? Will the texture vanish from Second Life altogether? No, it won’t. Once a texture is uploaded, it is permanently added to the asset server, and deleting it from your inventory has no effect on it — you simply won’t be able to refer to it by name any longer. It will still exist on the server, and you can still use the UUID to refer to it in a script.

Sides

Suppose you want to apply a texture to just one side of a prim. To do this you simply specify the side number:

llSetTexture(“test”, 1);

Ah, but how do you know which side has which number? That’s the tricky bit. Assume that you have just rezzed a cube, and haven’t rotated it in any way. The sides will be numbered as follows:

top: 0
side with lowest y: 1
side with highest x: 2
side with highest y: 3
side with lowest x: 4
bottom: 5

If you hollow the cube, side 5 is the inside (yes, all four interior sides count as a single side), and the bottom becomes side 6.

Working out the side numbers for a rotated cube, or for a more complex prim, gets rather more difficult, and can involve a lot of trial and error. A better way is to use the debug menu. If you don’t have the debug menu displayed, press CTRL+ALT+D to reveal it.

To get information about one side of a prim, tick the ‘Select Texture’ option in the build dialog, select the prim side that you want to know about, then press CTRL+SHIFT+ALT+T. Information about the prim side will be displayed, including the side number.

Scaling and Offsetting

Once a texture is applied, you can scale and offset it using the llScaleTexture and llOffsetTexture functions.

llScaleTexture(0.5, 2.0, ALL_SIDES);

llOffsetTexture(0.5, 0.0, ALL_SIDES);

The horizontal and vertical parameters taken by these functions are exactly the same as those on the texture tab of the build dialog, so you can use the build dialog to help find the appropriate values.

If you have already worked with textures you will know that a scaling of 1.0 x 1.0 will fit the texture to the size of the prim, whereas higher values will tile the texture, and lower values will only display part of the texture.

For example, a value of 0.25 will display one quarter of the texture, stretching it to fit the prim. Which quarter of the texture is actually displayed depends on the offset, and the way in which the offset works is not immediately obvious.

Basically, the offset is from the centre of the texture. An offset of 0.0 x 0.0 will therefore centre the texture. How other offset values affect the texture is easier to explain using an actual example.

Here is the testcard texture which I mentioned above, applied initially with an offset of 0.0 x 0.0:

Test Card example 1

If you change the horizontal offset to 0.25 you get this:

Test Card example 2

Try changing the horizontal scaling to 0.25, and the horizontal offset to 0.0. This produces the following, which is actually displaying the centre of the scaled texture, showing half of one band of colour, and half of the other.

Test Card example 3

To offset it so that we are centred in a band of colour, we need to use an offset of 1/8, or 0.125. Set the horizontal offset to this value, and we get a single band.

Test Card example 4

To centre each band in turn, use the following offsets:

-0.375
-0.125
0.125
0.375

Obviously, this only works when the horizontal scale is 0.25.

Using scaling and offsetting to select just one portion of a texture can help to make more efficient use of textures, especially if you have a prim which needs to sometimes change appearance — you can pack the different images into a single texture, and select the appropriate part of the texture using the scale and offset. The alternative method is to have multiple textures, but this means that when the texture is changed, there is a delay while the new texture is loaded. Using the scale and offset method, the texture is already fully loaded, and the prim changes appearance almost instantly.

I’ll cover this more in a later post.

Links

You will find a lot of useful information about the texture-handling functions on the LSL Wiki:

LSL Wiki