This post will try to explain how to write and install your own VEX DSO plugin for Houdini, written in C++. The included example project creates a plugin called VexImageReader. This plugin can be used to read all sorts of images, including psd and dds files. The reader can be used in all vex context layers and is added as a function called: readimage.
The function takes as input arguments a U and V coordinate, an input string (image name) and a wrap mode. By calling the function Houdini evaluates the image at that specific coordinate and returns an interpolated color value (RGBA). The reader supports most popular image formats and reads 8, 16 and 32 bit grayscale and color images.
Before we start, download the necessary files right HERE. Inside this package you will find:
- The source code and Visual Studio 2008 project file (code)
- The FreeImage library source code (freeimage/Source)
- A compiled x64 windows DSO (build)
- A compiled x64 windows FreeImage library (freeimage/Dist)
- An otl that wraps the Vex function call in to a VOP (otl)
- An example HIP file (hipfile)
- The VEXdso include file, used by Houdini to add the VEX plugin to the houdini DSO table.
As mentioned above, I included the compiled plugin. This means you (probably) don’t have to compile your own if you run Houdini 12.5 on a Windows x64 machine. I have tested the setup with Houdini version 12.5.427, on a windows 7 x64 machine. If you have a different Houdini version or use a different operating system, you will have to compile it yourself. On windows you can use the VexImageReader Visual Studio project. For more information on how to write and build DSO’s using the HDK, please read: Setting up the HDK for Houdini 12 with Visual Studio.
The code should be cross-platform compatible. For this tutorial all code, compile and project references are relative to Visual Studio 2008.
Notes on compiling the VexImageReader DSO
Compiling a VEX DSO is pretty much the same as compiling any other DSO. The only thing worth pointing out is that (in this case) we need to link against the FreeImage library. Again, if running the configuration mentioned above, you can use the precompiled FreeImage library (freeimage/Dist). Otherwise you need to compile your own. I have included the header and source files, but you probably want to get the latest version of FreeImage right here. FreeImage is a great Open Source library project for developers who would like to support popular graphics image formats like PNG, BMP, PSD, JPEG, TIFF and others as needed by today’s multimedia applications. FreeImage is easy to use, fast, multithreading safe, compatible with all 32-bit or 64-bit versions of Windows, and cross-platform (works both with Linux and Mac OS X).
To ensure the FreeImage library is included and linked properly, point to the right header files and library by editing the Visual Studio project properties:
After compiling the project VexImageReader.dll should be stored in the Output directory specified for the project. In my case that is: $(OutDir)\vex\VexImageReader.dll. Note the vex intermediate directory. This is of great importance for Houdini in order to pick it up on launch. Why this is will be discussed in the next section.
Loading the VEX DSO in Houdini
I found it rather difficult to get Houdini to pick up the VEX plugin. After reading through the Side Effects forum, Od-Force and HDK documentation I managed to create a setup that makes Houdini import the plugin on launch.
The HDK documentation states that, in order to install the DSO you need to: create a table in the Houdini path so that the VEX engine can find your plug-ins. The table lists the location of the dynamic link objects which should be loaded by the VEX engine. In order to do this we need to know how we can add objects to this table that are recognized by the VEX engine, and therefore included.
As you might know, Houdini uses the HOUDINI_PATH variable to look for releavant data to load or initialize. It also checks some pre-determined subdirectories of the directories included in the HOUDINI_PATH. One of those is called vex. In this subdirectory it expects to find a file called VEXdso. This VEXdso file lists additional VEX dso’s that need to be added to the VEX engine. This is where I added the VexImageReader.
The package you downloaded includes the VEXdso file that is required for loading the plugin (dependencies\vex\VEXdso). Copy the VEXdso file to a location that is included in the HOUDINI_PATH and make sure it’s in a subfolder of that path called “vex”. Houdini will parse the file and now look for a plugin called VexImageReader.dll.
The path to the VEXdso file should read: %HOUDINI_PATH%\vex\VEXdso
Now Houdini knows to look for a plugin with the name VexImageReader.dll, it will try to find it using the CUSTOM_DSO_PATH variable. Again, for VEX extensions Houdini appends “vex” to paths defined in there.
The path to the plugin should read: %CUSTOM_DSO_PATH%\vex\VexImageReader.dll
I created two user variables in Windows to automate the lookup. Both variables point to the same directory and contains a “vex” subfolder. This folder will contain the VEXdso file and all the vex plugins. This way everything is in one place and easier to edit or look after.
- VEX_PATH = (YOUR PATH HERE)
- CUSTOM_DSO_PATH : %VEX_PATH%\HoudiniDSO
- HOUDINI_PATH : %VEX_PATH%\HoudiniDSO;&
The last thing to take care of is to include the location of the FreeImage.dll in the PATH variable. This way Houdini can find the FreeImage library when the function is evaluated.
If all went well Houdini is now able to add the plugin to the VEX engine. To verify that the plugin loaded correctly, type in a Houdini Textport the following: dsoinfo -vq This should print all the custom functions available to VEX and their signature.
Wrapping the function in an OTL
The plugin itself only adds a function to the VEX instruction set, accessible through code. It’s always nice to have a vop to access that functionality, so you can use it inside (for example) a vop sop. By using an inline VOP it’s easy to wrap the function in a vop operator and create an otl out of it. This otl becomes available to all the vop operators in Houdini (wow, imagine reading this without having any knowledge of the Houdini architecture. I truly hope people don’t).
When opening the example file (hipfile\image_sample.hip) you can see the function used in a SOP, COP and SHOP context. This means you can use it to manipulate geometry, composite images, build shaders and drive particles. Vex is a truly wonderful language and instruction set. Implementing your own vex extensions can be a bit tricky, and the setup is far from easy. Luckily the same settings apply for all compiled dso’s and the same setup can be used for all plugins.
Famous Last Words
The code and data included in this tutorial comes without any sort of warranty. Suggestions on how to improve the plugin are welcome! The only filter algorithm implemented is bilinear. Feel free to add other ones, this should be ‘relatively’ easy with the way the project is setup. The plugin is (should be) thread safe, did not encounter any issues with the number of threads set to 1. Images are cached and released based on the active operator.