ValueTexture: Server basics

A ValueTexture is a plug-in server that implements a texture that can compute a color or percentage value.

Overview

Texture layers are item types with texture-related interfaces, but those are very complex and hard to use. So to make things easier we created the Value Texture server. Every value texture server becomes an item type, so it has some package-like features. It also runs as a modifier so it has some eval modifier-like features. Basically it serves as a lightweight way to create a texture layer that can be used for color or scalar effects.

Headers

  • ‘’’shade (lx-shade.hpp)’’’
    • ‘’CLxImpl_ValueTexture’’

  • ‘’’action (lx-action.hpp)’’’
    • ‘’CLxUser_Evaluation’’

  • ‘’’package (lx-package.hpp)’’’
    • ‘’CLxUser_AddChannel’’

  • ‘’’value (lx-value.hpp)’’’
    • ‘’CLxUser_Attributes’’

  • ‘’’vector (lx-vector.hpp)’’’
    • ‘’CLxUser_PacketService’’

(none special)

Sample Methods

The plug-in server class derives from CLxImpl_ValueTexture, and exports the ILxValueTexture interface. For speed purposes the class will also want to keep the packet service ready to hand.

1
         CLxUser_PacketService   pkt_service;

ValueTexture::SetupChannels()

Like a package, a value texture server must define its channels. The SetupChannels() method is identical to the one used by Package: Server basics.

1
2
3
4
5
         LxResult
 vtx_SetupChannels (
         ILxUnknownID            addChan)
 {
         CLxUser_AddChannel      ac (addChan);
1
2
3
4
         ac.NewChannel ("myInput", "percent");
         ac.SetDefault (1.0, 1);
         return LXe_OK;
 }

ValueTexture::LinkChannels()

The value texture reads its channel values in a modifier context. That means that it has to declare the channels it wants to read using the Evaluation Interface. This is also a good place to cache the offsets for any vector packets that it wants to read.

1
2
3
4
5
6
         LxResult
 vtx_LinkChannels (
         ILxUnknownID            eval,
         ILxUnknownID            item)
 {
         CLxUser_Evaluation      ev (eval);
1
2
3
4
         idx_value = ev.AddChan (item, "myInput");
         tin_offset = pkt_service.GetOffset (LXsCATEGORY_SAMPLE, LXsP_TEXTURE_INPUT);
         return LXe_OK;
 }

ValueTexture::ReadChannels()

Linking channels occurs once as items are added or their relationships are changed. Reading channels then happens any time channel values change. For example changing time may cause channels to be read again if they are animated. Values are read from an Attributes Interface using the index cached when linking channels. The values are then stored in an allocated data structure which is returned from the method.

1
2
3
4
5
6
7
         LxResult
 vtx_ReadChannels (
         ILxUnknownID            attr,
         void                  **ppvData)
 {
         CLxUser_Attributes      at (attr);
         RendData               *rd = new RendData;
1
2
3
4
         rd->value  = at.Float (idx_value);
         ppvData[0] = rd;
         return LXe_OK;
 }

ValueTexture::Evaluate()

Evaluation actually performs the texture computation. This may happen thousands or even millions of times per frame, so it’s intended to be as fast as possible. The private data struct containing channel values is passed as data. The plug-in can read common input packets from the vector given their offset, and the results are written to the texture output packet, already extracted from the vector as an argument. Values may be written as scalar or vector.

Note also that this is a void function. Anything that can fail, such as allocations, should already have been done as part of reading channels. The texture evaluation is assumed to succeed and there is no allowance for failure.

1
2
3
4
5
6
7
8
9
         void
 vtx_Evaluate (
         ILxUnknownID            vector,
         LXpTextureOutput       *tOut,
         void                   *data)
 {
         RendData               *rd = (RendData *) data;
         LXpTextureInput                *tInp;
         LXtFVector              rgb;
1
2
         tInp = (LXpTextureInput *) pkt_service.FastPacket (vector, tin_offset);
         compute_rgb_from_pos (rd->value, tInp, rgb);
1
2
3
4
5
6
         tOut->direct   = 1;
         tOut->alpha[0] = 1.0;
         tOut->value[0] = LXx_VLEN (rgb);
         if (tInp->context == LXi_TFX_COLOR)
                 LXx_VCPY (tOut->color[0], rgb);
 }

ValueTexture::Cleanup()

The allocated private struct is freed by the Cleanup() method.

1
2
3
4
5
         void
 vtx_Cleanup (
         void                   *data)
 {
         RendData               *rd = (RendData *) data;
1
2
         delete rd;
 }

Extensions

The value texture server can also present a ChannelUI Interface for configuring the UI of its channels.

The ValueTexture::Customize() method can be passed a ValueTextureCustom Interface to allow for further customization of the texture’s evaluation.