Parametric params are new for 1.2 and are optinally supported by host applications. They are specified via the
kOfxParamTypeParametric
identifier passed into
OfxParameterSuiteV1::paramDefine
.
These parameters are somewhat more complex than normal parameters and require their own set of functions to manage and manipulate them. The new OfxParametricParameterSuiteV1 is there to do that.
All the defines and suite definitions for parameteric parameters are defined in the file
ofxParametricParam.h
Parametric parameters are in effect 'functions' a plug-in can ask a host to arbitrarily evaluate for some value 'x'. A classic use case would be for constructing look-up tables, a plug-in would ask the host to evaluate one at multiple values from 0 to 1 and use that to fill an array.
A host would probably represent this to a user as a cubic curve in a standard curve editor interface, or possibly through scripting. The user would then use this to define the 'shape' of the parameter.
The evaluation of such params is not the same as animation, they are returning values based on some arbitrary argument orthogonal to time, so to evaluate such a param, you need to pass a parametric position and time.
Often, you would want such a parametric parameter to be multi-dimensional, for example, a colour look-up table might want three values, one for red, green and blue. Rather than declare three separate parametric parameters, so a parametric parameter can be multi-dimensional.
Due to the nature of the underlying data, you cannot call certain functions in the ordinary parameter suite when manipulating a parametric parameter. All functions in the standard parameter suite are valid when called on a parametric parameter, with the exception of the following....
OfxParameterSuiteV1::paramDefine
. The descriptor returned by this call have several non standard parameter properties available. These are
Seeing as we need to pass in the parametric position and dimenstion to evaluate, parametric parameters need a new evaluation mechanism. They do this with the OfxParametricParameterSuiteV1::parametricParamGetValue function. This function returns the value of the parameter at the given time, for the given dimension, adt the given parametric position,.
Parametric parameters are effectively interfaces to some sort of host based curve library. To get/set/delete points in the curve that represents a parameter, the new suite has several functions available to manipulate control points of the underlying curve.
To set the default value of a parametric parameter to anything but the identity, you use the control point setting functions in the new suite to set up a curve on the
descriptor
returned by
OfxParameterSuiteV1::paramDefine
. Any instances later created, will have that curve as a default.
This simple example defines a colour lookup table, defines a default, and show how to evaluate the curve
// describe our parameter in static OfxStatus describeInContext( OfxImageEffectHandle effect, OfxPropertySetHandle inArgs) { .... // define it OfxPropertySetHandle props; gParamHost->paramDefine(paramSet, kOfxParamTypeParametric, "lookupTable", & props); // set standard names and labeles gPropHost->propSetString(props, kOfxParamPropHint, 0, "Colour lookup table"); gPropHost->propSetString(props, kOfxParamPropScriptName, 0, "lookupTable"); gPropHost->propSetString(props, kOfxPropLabel, 0, "Lookup Table"); // define it as three dimensional gPropHost->propSetInt(props, kOfxParamPropParametricDimension, 0, 3); // label our dimensions are r/g/b gPropHost->propSetString(props, kOfxParamPropDimensionLabel, 0, "red"); gPropHost->propSetString(props, kOfxParamPropDimensionLabel, 1, "green"); gPropHost->propSetString(props, kOfxParamPropDimensionLabel, 2, "blue"); // set the UI colour for each dimension for(int component = 0; component < 3; ++component) { gPropHost->propSetDouble(props, kOfxParamPropParametricUIColour, component * 3 + 0, component % 3 == 0 ? 1 : 0); gPropHost->propSetDouble(props, kOfxParamPropParametricUIColour, component * 3 + 1, component % 3 == 1 ? 1 : 0); gPropHost->propSetDouble(props, kOfxParamPropParametricUIColour, component * 3 + 2, component % 3 == 2 ? 1 : 0); } // set the min/max parametric range to 0..1 gPropHost->propSetDouble(props, kOfxParamPropParametricRange, 0, 0.0); gPropHost->propSetDouble(props, kOfxParamPropParametricRange, 1, 1.0); // set a default curve, this example sets an invert OfxParamHandle descriptor; gParamHost->paramGetHandle(paramSet, "lookupTable", &descriptor, NULL); for(int component = 0; component < 3; ++component) { // add a control point at 0, value is 1 gParametricParamHost->parametricParamAddControlPoint(descriptor, component, // curve to set 0.0, // time, ignored in this case, as we are not adding a ket 0.0, // parametric position, zero 1.0, // value to be, 1 false); // don't add a key // add a control point at 1, value is 0 gParametricParamHost->parametricParamAddControlPoint(descriptor, component, 0.0, 1.0, 0.0, false); } ... } void render8Bits(double currentFrame, otherStuff...) { ... // make three luts from our curves unsigned char lut[3][256]; OfxParamHandle param; gParamHost->paramGetHandle(paramSet, "lookupTable", ¶m, NULL); for(int component = 0; component < 3; ++component) { for(int position = 0; position < 256; ++position) { // position to evaluate the param at float parametricPos = float(position)/255.0f; // evaluate the parametric param float value; gParametricParamHost->parametricParamGetValue(param, component, currentFrame, parametricPos, &value); value = value * 255; value = clamp(value, 0, 255); // set that in the lut lut[dimension][position] = (unsigned char)value; } } ... }