Table of Contents |
---|
Pure-virtual and default implementation in the RixShadingPlugin API
Note |
---|
Because the |
Interactive editing and Options / Render State queries.
RenderMan 23 introduces the possibility of editing displays and LPEs during an interactive rendering session, without needing to restart the entire rendering session (e.g. translate the entire scene again).
...
Note |
---|
The restriction to |
RixPlugin::CreateInstanceData() and RixPlugin::SynchronizeInstanceData()
Plugin Instance Initialization
The return type of RixShadingPlugin::CreateInstanceData()
has been changed from int
to void
.
...
In 23, the renderer directly inspects the value of InstanceData::data
to detect if the plugin instance allocated private instance data. The (newly introduced) SynchronizeInstanceData()
will then be given a chance to update the contents of this private instance data, before the pointer is provided to the usual shading plugin methods.
Plugin Instance Synchronization
RixShadingPlugin::SynchronizeInstanceData()
is a new API that allows user to update the private instance data associated with a plugin instance.
...
Code Block | ||
---|---|---|
| ||
enum SynchronizeHints { k_None = 0x00000000, k_All = 0xFFFFFFFF }; |
Example
Let's consider a plugin instance with a non-trivial RixShadingPlugin::CreateInstanceData()
method, using option queries and storing the returned values in its own private instance data class.
...
Code Block | ||
---|---|---|
| ||
void MyBxdfFactory::CreateInstanceData(RixContext& ctx, RtUString const handle, RixParameterList const* plist, InstanceData* result) { // We do not allocate any memory for the private instance data here. This is done for each // render in SynchronizeInstanceData(). // We want SynchronizeInstanceData() to be called in all cases. result->synchronizeHints = RixShadingPlugin::SynchronizeHints::k_All; } void MyBxdfFactory::SynchronizeInstanceData(RixContext& ctx, RtUString const handle, RixParameterList const* plist, uint32_t editHints, InstanceData* result) { // Because this method is called before each render, we need to make sure we properly delete // the private instance data that was created for the previous render. if (result->data && result->freefunc) { (result->freefunc)(result->data); } MyInstanceData* data = new MyInstanceData; // This method uses the RixRenderState object to query options values, that are then stored in // the `data` structure. RixRenderState* rst = (RixRenderState*)ctx.GetRixInterface(k_RixRenderState); doSomething(rst, data); result->data = data; result->freefunc = &ReleaseMyInstanceData; } |
RixProjectionFactory::CreateProjection() and RixProjection::RenderBegin()
For similar reasons, the RixProjection
API has changed. Previously, the RixIntegratorEnvironment
structure was provided to RixProjectionFactory::CreateProjection()
:
...
Any code previously in the RixProjection
constructor that was using RixIntegratorEnvironment
should now live in RixProjection::RenderBegin()
.
RixIntegratorEnvironment::deepMetric
Previously, the projection plugins were allowed to modify the value of RixIntegratorEnvironment::deepMetric
during the creation of the RixProjection
object. This is not the case anymore, and in RixProjection::RenderBegin()
, this structure is now read-only.
...
Code Block |
---|
RixSCDetail GetProperty( ProjectionProperty property, void const** result) const override { switch (property) { case k_DicingHint: *result = &dicingHint; return k_RixSCUniform; break; case k_DeepMetric: *result = &deepMetric; return k_RixSCUniform; break; case k_FieldOfView: *result = &fovHint; return k_RixSCUniform; break; default: return k_RixSCInvalidDetail; } } |
RixIntegratorFactory
The integrator plugins are now using a Factory, similarly to RixProjection.
In general, it should be sufficient adding something like this to the existing integrator plugins:
Code Block |
---|
class MyIntegratorFactory : public RixIntegratorFactory
{
public:
virtual RixSCParamInfo const* GetParamTable() override;
virtual void Synchronize(RixContext&, RixSCSyncMsg, RixParameterList const*) override
{}
virtual int Init(RixContext& ctx, RtUString const) override
{
return 0;
};
virtual void Finalize(RixContext&) override{};
virtual RixIntegrator* CreateIntegrator(RixContext& rixCtx, RtUString const handle,
RixParameterList const* pList) override;
virtual void DestroyIntegrator(RixIntegrator const* integrator) override;
};
RixIntegrator* MyIntegratorFactory::CreateIntegrator(RixContext& rixCtx, RtUString const handle,
RixParameterList const* pList)
{
PIXAR_ARGUSED(handle);
PIXAR_ARGUSED(pList);
return new MyIntegrator(this, rixCtx);
}
void MyIntegratorFactory::DestroyIntegrator(RixIntegrator const* integrator)
{
delete static_cast<MyIntegrator const*>(integrator);
} |
And replace the existing RIX_INTEGRATORCREATE
and RIX_INTEGRATORDELETE
by the following:
Code Block |
---|
RIX_INTEGRATORFACTORYCREATE
{
PIXAR_ARGUSED(hint);
return new MyIntegratorFactory();
}
RIX_INTEGRATORFACTORYDESTROY
{
delete ((MyIntegratorFactory*)factory);
} |