From TouchDesigner 088 Wiki

TouchDesigner has an infrastructure to process and render openFrameworks projects within the TouchDesigner process via a CPlusPlus TOP.

Note: As of now the default openFrameworks only builds dlls for 32-Bit TouchDesigner Projects.

Download Examples here:


1) Download openFrameworks and unzip it to your working directory.

2) Copy the following folder in the TouchDesigner install folder:

   C:/Program Files/Derivative/TouchDesigner088/Samples/CPlusPlus/TOP

to the following directory in the unzipped openFrameworks folder:


Rename the folder to your project's name.

Note: This is not strictly necessary, but it makes it a lot easier because openFrameworks includes a property sheet that lists all the "Additional Include Directories" relative to the root of the openFrameworks folder. Otherwise all the include directories would have to be added manually.

3) Open the Visual Studio Solution (.sln) from the folder you just copied over. You must use Visual Studio 2012 or higher to be able to compile openFrameworks.

4) In Visual Studio, right click on the solution in the "Solution Explorer" and click "Add > Existing Project".

5) Locate the folder where openFrameworks was unzipped and select:


6) Right click on the CPlusPlusTOPExample project and click "Project Dependencies". Check the box next to openframeworksLib in the Dependencies page. Click OK.

7) Right click on the CPlusPlusTOPExample project and click References. Click "Add New Reference" and check the box next to openframeworksLib. Click OK.

8) Right click on the CPlusPlusTOPExample project and click Properties. Find "Configuration Properties > General" and set "Output Directory" to $(SolutionDir)\bin

9) Click "View > Property Manager". Expand the CPlusPlus TOP project. For each of the debug folders, right click and click "Add Existing Property Sheet". Locate the folder where openFrameworks was unzipped and select:


10) Do the same for the release folders, except instead select:


11) Go back to the "Solution Explorer" and open TOP_CPlusPlusBase.h. Remove the following lines:

   #include <windows.h>
   #include <cstdio>

and replace them with:

   #include "ofMain.h"

12) In CPlusPlusTOPExample.h, add

   #include "ofAppNoWindow.h"

and add the members

   ofAppNoWindow myWindow;
   ofGLProgrammableRenderer *renderer;

to the class body for the TOP.

13) In CPlusPlusTOPExample.cpp: Add the following lines to the constructor method CPlusPlusTOPExample::CPlusPlusTOPExample:

   renderer = new ofGLProgrammableRenderer(&myWindow);

where xRes and yRes are the resolution width and height respectively. Because the application being run is TouchDesigner, openFrameworks will search the installed TouchDesigner's bin for /data by default. If you have any shaders/images to load then ofSetDataPathRoot(relative_path_to_new_dir); is necessary to give openFrameworks the path to the /data directory.
Note: relative_path_to_new_dir is a relative path from the executable (in this case the installed TouchDesigner, which should be located under Program Files) to the desired /data directory.
Example: ofSetDataPathRoot("../../../../of_v0.9.3_vs_release/apps/myApps/CPlusPlusTOPExample/bin/data/")

14) Create a CPlusPlusTOPExample::setup function to be called only once:

 void CPlusPlusTOPExample::setup() 
   renderer->setup(3, 2);
// load any shaders, images, etc }

In addition to glewInit(); and renderer->setup(3, 2); this is where you should load any shaders or images.

15) At the top of CPlusPlusTOPExample::execute query any custom parameters.

16) Query for the resolution width and height:

 int width = outputFormat->width;
 int height = outputFormat->height;

Then setup the window with the width and height of the C++TOP:

 ofSetupOpenGL(&myWindow, width, height, OF_WINDOW);

17) Enclose the rest of CPlusPlusTOPExample::execute with:

// ... rest of your code

18) Add CPlusPlusTOPExample::setup call enclosed by context

19) For any rendering in openFrameworks it's necessary to enclose it with:

// any binding of shaders/images, drawing, etc.

Example CPlusPlusTOPExample::execute after steps 15-19

 void CPlusPlusTOPExample::execute(const TOP_OutputFormatSpecs* outputFormat, OP_Inputs* inputs, TOP_Context *context) 
   // query custom parameters 
int width = outputFormat->width; int height = outputFormat->height;
ofSetupOpenGL(&myWindow, width, height, OF_WINDOW);
if(!isSetup) { setup(); }
renderer->startRender(); renderer->setupScreen();
// any binding of shaders/images, drawing, etc.
context->endGLCommands(); }

20) Build the project. All the DLLs required to use the CPlusPlus TOP are in the following directory in the folder where openFrameworks was unzipped:


It is important that all the DLLs remain together in the same directory because of dependencies. TouchDesigner will automatically load the other required DLLs if they are in the same directory.

Translating openFrameworks code to work within TouchDesigner

The creation of an ofAppNoWindow using the above steps will cause many openFrameworks functions to break down and ofGetCurrentRenderer(), which queries the renderer of the window, is to blame for this.
The renderer holds much of the useful renderering functionality, however ofAppNoWindow has an ofNoopRenderer which is missing crucial functionality. As a result ofGetCurrentRenderer() returns an unusable renderer that will either lead to a crash or do nothing.
In order to render in TouchDesigner using openFrameworks ofGetCurrentRenderer() must be bypassed, meaning any function that calls ofGetCurrentRenderer() cannot be used. This is exactly why an ofGLProgrammableRenderer object is created in steps 12-13.
To translate any openFrameworks function that calls ofGetCurrentRenderer(), look at the source and see how it uses the renderer, then move that functionality to your CPlusPlusTOPExample using the created ofGLProgrammableRenderer object.
openFrameworks is open source so you will need to look at the source code to see specifically what functions need to be changed. All drawing, binding, and transforming will need to be changed.

Example of binding a shader:




Using Input TOPs

The following code is an example of how to use input TOPs with openFrameworks:

CPlusPlusTOPExample::execute(const TOP_OutputFormatSpecs* outputFormat,
				const TOP_InputArrays* arrays,
				void* reserved)
	// ...
	// Use the first input TOP (here we assume it exists but in reality it might not)
	const TOP_TOPInput *topInput = &arrays->TOPInputs[0];
	ofTexture texture;
	texture.texData.width = topInput->width;
	texture.texData.height = topInput->height;
	texture.texData.tex_w = topInput->width;
	texture.texData.tex_h = topInput->height;
	texture.texData.textureTarget = topInput->textureType;
	// ...