00001 /* 00002 * PROPRIETARY INFORMATION. This software is proprietary to 00003 * Side Effects Software Inc., and is not to be reproduced, 00004 * transmitted, or disclosed in any way without written permission. 00005 * 00006 * Produced by: 00007 * Side Effects Software Inc 00008 * 477 Richmond Street West 00009 * Toronto, Ontario 00010 * Canada M5V 3E7 00011 * 416-504-9876 00012 * 00013 * NAME: VEX_VexOp.h ( VEX Library, C++) 00014 * 00015 * COMMENTS: External VEX function definition 00016 * 00017 * The signature of a VEX OP function determines the parameters the function 00018 * expects. The signature is composed as follows: 00019 * name@parms 00020 * where name is the user function name and the parms are the single character 00021 * representations of the parameters expected. The single character mnemonics 00022 * are: 00023 * F = float 00024 * I = integer 00025 * S = string 00026 * V = vector 00027 * P = vector4 (originally "point") 00028 * 3 = matrix3 00029 * 4 = matrix4 00030 * B = bsdf 00031 * 00032 * If a parameter is written to by the VexOp function, the parameter mnemonic 00033 * should be preceded by an ampersand (&) or an asterix (*). The ampersand is 00034 * used it the value of the variable is not read by the function, while the 00035 * asterix is used if the variable is read and then modified. The signature 00036 * specification is very important if the compiler is to work correctly. 00037 * 00038 * The compiler is "smart" in that if only one argument is written to (and not 00039 * read from), that argument will be flagged as the return code for the 00040 * function. 00041 * 00042 * Examples: 00043 * Signature: test@&IF 00044 * Decoded: int test(float) 00045 * 00046 * Signature: test@*IF 00047 * Decoded: void test(int &, float) 00048 * Details: The integer parameter must be set since this function 00049 * reads the argument before modifying it. 00050 * 00051 * Signature: test@S&VFF 00052 * Decoded: vector test(string; float, float) 00053 * 00054 * At this time VEXOps do not support variadic functions (i.e. var-args 00055 * functions like printf()). 00056 * 00057 */ 00058 00059 #ifndef __VEX_VexOp__ 00060 #define __VEX_VexOp__ 00061 00062 #include "VEX_API.h" 00063 00064 /// VEX operator initialization callback. When called, it should allocated 00065 /// and initialize custom state data. 00066 typedef void *(*VEX_VexOpInit)(); 00067 /// VEX operator evaluation callback. When called, the data returned by the 00068 /// VEX_VexOpInit function will be passed as the "data" argument. 00069 typedef void (*VEX_VexOpCallback)(int argc, void *argv[], void *data); 00070 /// VEX operator cleanup callback. When called, it should deallocate the data. 00071 typedef void (*VEX_VexOpCleanup)(void *data); 00072 00073 // 00074 // It's possible to give hints to the compiler as to what optimizations may be 00075 // performed on the function. The different levels of optimizations are: 00076 // 0 = No optimizations may be performed on the custom function. 00077 // 2 = If all parameters to the function are constant, then the result may 00078 // be pre-computed and cached. 00079 // The only time you would want to turn off optimization is to guarantee that 00080 // your custom function is evaluated in all cases (i.e. something like printf). 00081 // Typically, functions used in computation can be optimized by VEX. 00082 // 00083 // Turning off optimization may result in an overall performance hit. 00084 // 00085 00086 // 00087 // When a function modifies only one parameter (without reading from it), the 00088 // compiler will automatically interpret the first argument as a return code 00089 // for the function. However, if the function modifies multiple arguments, the 00090 // compiler assumes that all arguments should be passed by reference. 00091 // Sometimes, it's useful to have the first modified argument treated as a 00092 // return code rather than an actual parameter to the function. This behaviour 00093 // can be forced (if all conditions are met) by passing in a true on the 00094 // "force_return_code" parameter. 00095 // For example, something like the function: 00096 // import@&IS&F 00097 // would decode to 00098 // import(int &success, string, float &result) 00099 // But, with the force_return_code argument set to true, the function would be 00100 // interpreted as: 00101 // int import(string, float &result) 00102 // which is most likely more friendly to the user. 00103 // 00104 00105 #define VEX_OPTIMIZE_0 0 00106 #define VEX_OPTIMIZE_1 1 00107 #define VEX_OPTIMIZE_2 2 00108 00109 // The maximum number of arguments that a VEXOp can take 00110 #define MAX_VEXOP_ARGS 4096 00111 00112 typedef enum { 00113 VEX_SURFACE_CONTEXT = 0x00000001, 00114 VEX_DISPLACE_CONTEXT = 0x00000002, 00115 VEX_LIGHT_CONTEXT = 0x00000004, 00116 VEX_SHADOW_CONTEXT = 0x00000008, 00117 VEX_FOG_CONTEXT = 0x00000010, 00118 VEX_PHOTON_CONTEXT = 0x00000020, 00119 VEX_CHOP_CONTEXT = 0x00000100, 00120 VEX_POP_CONTEXT = 0x00000400, 00121 VEX_SOP_CONTEXT = 0x00000800, 00122 VEX_COP2_CONTEXT = 0x00001000, 00123 VEX_I3D_CONTEXT = 0x00010000, 00124 VEX_CVEX_CONTEXT = 0x00020000, 00125 VEX_INVALID_CONTEXT = 0x00000000 00126 } VEX_ContextType; 00127 00128 // Contexts for VEX Mantra 00129 #define VEX_SHADING_CONTEXT (VEX_SURFACE_CONTEXT | \ 00130 VEX_DISPLACE_CONTEXT | \ 00131 VEX_LIGHT_CONTEXT | \ 00132 VEX_SHADOW_CONTEXT | \ 00133 VEX_FOG_CONTEXT | \ 00134 VEX_PHOTON_CONTEXT) 00135 00136 // OP Contexts 00137 #define VEX_OP_CONTEXT (VEX_CHOP_CONTEXT | \ 00138 VEX_POP_CONTEXT | \ 00139 VEX_SOP_CONTEXT | \ 00140 VEX_COP2_CONTEXT) 00141 00142 // All contexts 00143 #define VEX_ALL_CONTEXT (VEX_SHADING_CONTEXT | \ 00144 VEX_OP_CONTEXT | \ 00145 VEX_I3D_CONTEXT | \ 00146 VEX_CVEX_CONTEXT) 00147 00148 class VEX_API VEX_VexOp { 00149 public: 00150 VEX_VexOp(const char *signature, 00151 VEX_VexOpCallback evaluator, 00152 int ctx_mask=(VEX_ALL_CONTEXT), 00153 VEX_VexOpInit init = 0, 00154 VEX_VexOpCleanup cleanup = 0, 00155 int optimize_level = VEX_OPTIMIZE_2, 00156 bool force_return_code=false); 00157 00158 ~VEX_VexOp(); 00159 00160 const char *getSignature() const { return mySignature; } 00161 int getContextMask() const { return myContextMask; } 00162 VEX_VexOpInit getInit() const { return myInit; } 00163 VEX_VexOpCallback getEvaluator() const { return myEvaluator; } 00164 VEX_VexOpCleanup getCleanup() const { return myCleanup; } 00165 int getOptimizer() const { return myOptimizeLevel; } 00166 00167 unsigned int getFlag(unsigned int f) const { return myFlags&f; } 00168 void setFlag(unsigned int f) { myFlags |= f; } 00169 void clearFlag(unsigned int f) { myFlags &= ~f; } 00170 00171 // When dealing assigning to string arguments, you must "free" the previous 00172 // string value by calling "stringFree". You must set the resulting string 00173 // to the return code from "stringAlloc". If you do your own memory 00174 // management (i.e. calling strdup() or setting strings to constant 00175 // values), you will most likely crash VEX. 00176 // For example: 00177 // void 00178 // vexStrCat(int argc, void *argv[], void *) 00179 // { 00180 // // arg[0] = result, arg[1..2] == strings to concat 00181 // char work_buf[256]; 00182 // VEX_VexOp::stringFree((char *)argv[0]); 00183 // strcpy(work_buf, (char *)argv[1]); 00184 // strcat(work_buf, (char *)argv[2]); 00185 // argv[0] = VEX_VexOp::stringAlloc(work_buf); 00186 // } 00187 // 00188 static const char *stringAlloc(const char *str); 00189 static void stringFree(const char *str); 00190 00191 // 00192 // These functions can be used to query the number of DSO's loaded by VEX 00193 // and the locations of the shadered objects loaded. 00194 // 00195 static int getNumVexOps(); 00196 static const VEX_VexOp *getVexOp(int idx); 00197 static const char *getVexOpLocation(int idx); 00198 00199 protected: 00200 // The signature of the function call. This is documented in the header 00201 // above. The constructor will duplicate the string passed in. 00202 char *mySignature; 00203 00204 // Initialization, Evaluation and Cleanup callbacks 00205 VEX_VexOpInit myInit; 00206 VEX_VexOpCallback myEvaluator; 00207 VEX_VexOpCleanup myCleanup; 00208 00209 // The contexts which this VEXOp is valid for. The mask is a bit-field 00210 // represented by or'ing the context defines above together. 00211 int myContextMask; 00212 int myOptimizeLevel; 00213 unsigned int myFlags; 00214 }; 00215 00216 extern "C" { 00217 DLLEXPORT extern void newVEXOp(void *); 00218 } 00219 00220 #endif
1.5.9