Texture FunctionsAvailability LightWave® 6.0Component Layout, Modeler Header lwtxtr.h The Texture Functions global gives plug-ins access to LightWave®'s texture engine. A plug-in can create and use textures to modulate its parameters, and it can read and modify the settings of existing textures. Global Call LWTextureFuncs *txfunc; txfunc = global( LWTEXTUREFUNCS_GLOBAL, GFUSE_TRANSIENT );The global function returns a pointer to an LWTextureFuncs. typedef struct st_LWTextureFuncs { LWTxtrContextID (*contextCreate)(LWTxtrParamFuncs); void (*contextDestroy) (LWTxtrContextID); void (*contextAddParam)(LWTxtrContextID, LWTxtrParamDesc); LWTextureID (*create) (int returnType, const char *name, LWTxtrContextID, void *userdata); void (*destroy) (LWTextureID); void (*copy) (LWTextureID to, LWTextureID from); void (*newtime) (LWTextureID, LWTime, LWFrame); void (*cleanup) (LWTextureID); void (*load) (LWTextureID, const LWLoadState *); void (*save) (LWTextureID, const LWSaveState *); double (*evaluate) (LWTextureID, LWMicropolID, double *); void (*setEnvGroup) (LWTextureID, LWChanGroupID); LWTLayerID (*firstLayer) (LWTextureID); LWTLayerID (*lastLayer) (LWTextureID); LWTLayerID (*nextLayer) (LWTextureID, LWTLayerID); LWTLayerID (*layerAdd) (LWTextureID, int type); void (*layerSetType) (LWTLayerID, int type); int (*layerType) (LWTLayerID); double (*layerEvaluate)(LWTLayerID, LWMicropolID, double *); LWChanGroupID (*layerEnvGrp) (LWTLayerID); int (*setParam) (LWTLayerID, int tag, void *data); int (*getParam) (LWTLayerID, int tag, void *data); void (*evaluateUV) (LWTLayerID, int wAxis, int oAxis, double oPos[3], double wPos[3], double uv[2]); double (*noise) (double p[3]); void * (*userData) (LWTextureID); LWChanGroupID (*envGroup) (LWTextureID); LWTextureID (*texture) (LWTLayerID); const char * (*name) (LWTextureID); int (*type) (LWTextureID); LWTxtrContextID (*context) (LWTextureID); } LWTextureFuncs;It's helpful to divide these functions into three categories according to whether they deal with contexts, handler calls, or texture settings. Plug-ins that use textures to modify their own parameters will mostly use functions in the first two groups, since typically the texture settings are supplied by the user through the Texture Editor. The last group is more often useful when plug-ins want to query or modify existing textures. Contexts Some texture layer types use additional parameters to modify the texture value. Currently this is a gradient thing. The texture context is used to populate and support the Input Parameter menu for gradient layers in the Texture Editor.
contextDestroy( context ) contextAddParam( context, param ) The functions in this group call the texture's handler callbacks. See the document for the procedural texture plug-in class for more information about the other side of these calls. In most cases, you'll call these from within your own plug-in's handler callbacks. In all cases, however, these functions must be called in proper handler order. The newtime function, for example, must be called before calling evaluate.
TRT_VECTOR TRT_COLOR TRT_PERCENT TRT_SCALAR TRT_DISPLACEMENTThe name is used to identify the texture in the user interface. The context is a context ID returned by contextCreate, or NULL if you don't want to add any input parameters for the texture. The userdata is any data you'd like to associate with the texture. You can retrieve it using the userdata function. copy( to, from ) newtime( texture, time, frame ) cleanup( texture ) load( texture, loadstate ) save( texture, savestate ) alpha = evaluate( texture, micropol, value ) These functions are used to get and set the data that defines a texture.
tlayer = firstLayer( texture ) tlayer = lastLayer( texture ) tlayer = nextLayer( texture, tlayer ) tlayer = layerAdd( texture, type ) TLT_IMAGE layerSetType( tlayer, type ) type = layerType( tlayer ) alpha = layerEvaluate( tlayer, micropol, value ) changroup = layerEnvGroup( tlayer ) result = setParam( tlayer, tag, value ) result = getParam( tlayer, tag, value ) TXTAG_POSI (double [3]) TXTAG_ROTA (double [3]) TXTAG_SIZE (double [3]) TXPRJ_PLANAR TXPRJ_CYLINDRICAL TXPRJ_SPHERICAL TXPRJ_CUBIC TXPRJ_FRONT TXPRJ_UVMAP TXTAG_HWRP (double *) TXTAG_HREPEAT (int *) TXRPT_RESET TXRPT_REPEAT TXRPT_MIRROR TXRPT_EDGETXTAG_ACTIVE (int *) TXTAG_INVERT (int *) TXTAG_BLEND (int *) TXTAG_INPUT (int *) TXTAG_AUVN (char *) TXTAG_AUVU (char *) TXTAG_AUVC (int *) TXTAG_AUVO (char *)
data = userData( texture ) changroup = envGroup( texture ) id = texture( layer ) tname = name( texture ) datatype = type( texture ) ctxt = context( texture ) The argument to the contextCreate function is an LWTxtrParamFuncs, which contains callbacks for evaluating the input parameters. These callbacks are functions in your plug-in that determine the value of the parameter. typedef struct st_LWTxtrParamFuncs { double (*paramEvaluate)(LWTxtrParamDesc *, int paramnum, LWMicropol *, gParamData); gParamData (*paramTime) (void *userData, LWTxtrParamDesc *, int paramnum, LWTime, LWFrame); void (*paramCleanup) (LWTxtrParamDesc *, int paramnum, gParamData); } LWTxtrParamFuncs;
pdata = paramTime( userdata, pdesc, pindex, time, frame ) paramCleanup( pdesc, pindex, pdata ) The second argument to contextAddParam is a description of the parameter contained in an LWTxtrParamDesc structure. This structure is also passed to your parameter callbacks. typedef struct st_LWTxtrParamDesc{ char *name; double start; double end; int type; int flags; int itemType; LWItemID itemID; char *itemName; } LWTxtrParamDesc;
start, end type LWIPT_FLOAT LWIPT_DISTANCE LWIPT_PERCENT LWIPT_ANGLE LWGF_FIXED_MIN itemType, itemID, itemName LWGI_NONE LWGI_OBJECT LWGI_LIGHT LWGI_CAMERA LWGI_BONE LWGI_VMAP The micropolygon provides the geometry information used to evaluate a texture. You need to initialize one of these before calling evaluate or layerEvaluate. You also receive one of these in your parameter callbacks. typedef struct st_LWMicropol { double oPos[3]; double wPos[3]; double oScl[3]; double gNorm[3]; double wNorm[3]; double ray[3]; double bumpHeight; double txVal; double spotSize; double raySource[3]; double rayLength; double cosine; double oXfrm[9]; double wXfrm[9]; LWItemID objID; LWItemID srfID; LWPntID verts[4]; float weights[4]; float vertsWPos[4][3]; int polNum; int oAxis; int wAxis; int context; LWIlluminateFunc *illuminate; LWRayTraceFunc *rayTrace; LWRayCastFunc *rayCast; LWRayShadeFunc *rayShade; void *userData; LWPolID polygon; LWVertexIndexes *VertexIndexes;Almost all of the micropolygon fields correspond to fields of the same name in LWShaderAccess. See the shader page for descriptions of those fields.
ray txVal srfID context TCC_ANY In LightWave® 8.2, the server name for this global (LWTEXTUREFUNCS_GLOBAL) was NOT incremented; although the VertexIndexes member was added to LWMicroPol. The TXTAG_INPUT, TXTAG_AUVN, TXTAG_AUVU, TXTAG_AUVC, and TXTAG_AUVO tags were also added to LWTextureFuncs. In LightWave® 7.5, the server name for this global (LWTEXTUREFUNCS_GLOBAL) was incremented from "Texture Functions 2" to "Texture Functions 3", and the TXTAG_ACTIVE, TXTAG_INVERT and TXTAG_BLEND tags were added to LWTextureFuncs. Example The txchan sample contains motion, channel, image filter and environment plug-ins, all of which use a texture to modulate their data. The texture layers are defined by the user and evaluated through the Texture Functions global. The following code fragment demonstrates how to extract UV values for image maps associated with a surface. #include <lwserver.h> #include <lwsurf.h> #include <lwtxtr.h> LWSurfaceFuncs *surff; LWTextureFuncs *txtrf; LWSurfaceID surf; LWTextureID tex; LWTLayerID tlayer; int type;As always, you need to get the globals before you can use them. surff = global( LWSURFACEFUNCS_GLOBAL, GFUSE_TRANSIENT ); txtrf = global( LWTEXTUREFUNCS_GLOBAL, GFUSE_TRANSIENT );Each surface has many channels (Color, Diffuse, Luminous, Specular, etc.), and each channel can be textured. If a channel is textured, the texture can have many layers. It's at the level of the texture layer that you want to look for UVs. tex = surff->getTex( surf, SURF_COLR ); if ( tex ) { tlayer = txtrf->firstLayer( tex ); while ( tlayer ) { type = txtrf->layerType( tlayer ); if ( type == TLT_IMAGE ) {Now you have an image texture layer. You can ask what the projection is. int proj; txtrf->getParam( tlayer, TXTAG_PROJ, &proj ); if ( proj == TXPRJ_UVMAP ) {If the projection type is UV, get the vmap. void *vmap; txtrf->getParam( tlayer, TXTAG_VMAP, &vmap );Use this with the mesh edit pointVSet and pointVEval functions to get the UVs. (You can also use the mesh info pntVSet, pntVGet and pntVPGet functions.) edit->pointVSet( edit->state, vmap, 0, NULL ); for each point edit->pointVEval( edit->state, pntID, polID, uv ); } else {If the projection is not UV, use evaluateUV. for each point txtrf->evaluateUV( tlayer, wAxis, oAxis, oPos, wPos, uv ); } } tlayer = txtrf->layerNext( tlayer ); } } |