Multiple shaders in a single DLL/DSO

You can have as many shaders as you want in a DLL (or .so shared library for you Linux folks). When Arnold loads the DLL, it will call the node_loader entry point to get the list of available shaders. Each shader should be defined in its own source code file, which then has to export its methods with the following macro:

AI_SHADER_NODE_EXPORT_METHODS(MyShaderMethods);

 

The MyShaderMethods name can be replaced by anything else, as long as it is unique for this DLL.

These methods are then imported from the file where node_loader is defined:

extern AtNodeMethods* MyShaderMethods;
extern AtNodeMethods* MyOtherShaderMethods;

 

The node_loader function has the following signature:

bool node_loader(int i, AtNodeLib *node)

 

When Arnold loads the DLL, it will call this entry point several times, each time increasing the index i, until one of the calls returns FALSE. So, for example, if you have two shaders, your node_loader function should return TRUE for values of i between 0 and 1 (inclusive), and FALSE for all other values. Then, for values in the [0..1] range, it should set the corresponding shader data in the AtNodeLib struct.

The easiest way to do this is using a switch statement like this:

enum SHADERS
{
   MY_SHADER,
   MY_OTHER_SHADER
};

node_loader
{
   switch (i) 
   {     
      case MY_SHADER:
         node->methods     = (AtNodeMethods*) MyShaderMethods;
         node->output_type = AI_TYPE_RGB;
         node->name        = "MyShader";
         node->node_type   = AI_NODE_SHADER;
      break;

      case MY_OTHER_SHADER:
         node->methods     = (AtNodeMethods*) MyOtherShaderMethods;
         node->output_type = AI_TYPE_RGBA;
         node->name        = "MyOtherShader";
         node->node_type   = AI_NODE_SHADER;
      break;

      default:
         return false;      
   }

   sprintf(node->version, AI_VERSION);
   return true;
}

 

 
  • No labels