current state of openFrameworks in TD

That error is due to you trying to run a dll as an executable. Currently the .sln is setup to build a dll, which can’t be run on it’s own.

After you build the dll in Visual Studio, you can open up the respective toe file and import the dll as a parameter in the C++TOP.

If you are getting that error it means that the project was already built, and you can find the dll in the bin directory.

The error is good in this case! :laughing:

Hi Eric,

Yes, I realized that later on :slight_smile:
Thank you for the reply.

And yes, Elburz, it is indeed a good error.

Regards.

Hi,

After building the respective dll file[for the movabletexture example], I am unable to load the dll in TD. I get an error saying failed to load the .dll.

This is what I have as my relative path:
ofSetDataPathRoot(“…/…/…/of_v0.9.3_vs_release/apps/myApps/movableTexture/
OpenFrameworksTOP/bin/data/”);

location of data: D:\of_v0.9.3_vs_release\apps\myApps\movableTexture\OpenFrameworksTOP\bin\data

location of touch application file:
D:\Derivative\TouchDesigner088\bin

Any clue what might cause this issue? Thank you for checking out this post. Regards.

The set path looks fine, however that wouldn’t affect the loading of the dll. If that was set incorrectly your texture would just be blank.

If it failed to load it probably means that your compiled library is not consistent with where you’re loading it. If your TouchDesigner is 64-bit the compiled library will have to be 64-bit, and the same for if it is 32-bit. You should also be compiling under Release if you aren’t already.

This structure didn’t work for me with the property sheet already in the project. I had to place the project differently:
D:\of_v0.9.3_vs_release\apps\movableTexture\OpenFrameworksTOP\

And in OpenFrameworksTOP.cpp:

ofSetDataPathRoot("../../../../of_v0.9.8_vs_release/apps/inputTexture/inputTexture/bin/data/");

But the dll in TouchDesigner looks like this (green rectangle in upper right?)

NB: I’m using TD 62960
inputTexture_openFrameworks_TOP.png

did you ever figure out what the problem was David? I’m having the same issue trying to get this to work with TD099.

particles examples works as expected.

displaceMapTOP seems to be error’ing too and it looks like this:

Hi Sam,

I believe that issue is a result of openFrameworks not being able to find your shaders, and the reason the particle example works is because it doesn’t use any shaders. The shaders will be in your bin/data folder.

Ensure that the path in ofSetDataPathRoot is correct. The wiki is incorrect at the moment, it states that you need to use a relative path which is untrue; an absolute path would also work. If the path is correct then it is probably your slashes. openFrameworks is picky and requires forward slashes.

David,

Sorry for the very delayed response. Your problem is most likely the same as Sam’s.

A good rule of thumb from my experience with openFrameworks in TD is that if the dll loads without errors but the output looks completely wrong, then it’s probably an issue with finding the shaders.

Cheers,
Eric

Ah yes,

Thanks eric! This looks great :slight_smile:

I’m curious if anyone has figured out how to add open frameworks ‘addons’ to a project - I can’t seem to get the project generator to work which is usually how I do things.

Sam

I haven’t used the the project generator before, but what is the issue you are experiencing? Alternatively, openFrameworks provides some example Visual Studio projects for addons that could help to get started without the project generator.

Thanks for getting back to me eric!

Yeah, so I got all my plugins working. I copied all the settings over (manually) from a generated ofx project with the plugins I needed, and then I dragged in the relevant header and c++ files into a folder i made called ‘addons’ in visual studio.

And it is compiling which is pretty exciting…

The issue I’m having now is that my fbo texture reading/writing doesn’t seem to be working.

I allocate fbo in setup like:

ofFbo fbo; fbo.allocate(1280, 720, GL_RGBA);

and then in the Execute method:

ofTexture texture;
fbo.begin();
ofDrawCircle(150,150,100);
fbo.end();
texture = fbo.getTextureReference(0);
renderer->draw(texture, 0, 0, 0, 1280, 720, 0, 0, 1280, 720);

But I’m getting nothing a black screen.

same code (minus the adjusted way of calling the renderer) work as expected in a normal OFX project… is there something special about the way I need to use buffer textures for the TD renderer?

One of the annoying things about using openFrameworks with TD is that a good amount of the code uses the oF window’s renderer, which we don’t want. We want it to use our ofGLProgrammableRenderer that we allocate in our CPlusPlus TOP class. In the code that you sent me, fbo.allocate(1280, 720, GL_RGBA); appears to be the culprit.

In that allocate method it does not assign a renderer, but instead uses ofGetGLRenderer(), which will grab the incorrect one (you’ll want to use your member variable renderer).

Thankfully it seems ofFbo already provided an alternative. If you call void ofFbo::allocate(Settings _settings) instead, and pass an ofFbo::Settings with your ofGLProgrammableRenderer then ofGetGLRenderer() won’t be called and you should be okay.

Let me know if that fixes your issue.

Thanks again for your response. That seems logical to me!!

Although, I’m having some difficulty with this. Firstly, the ofFbo::Settings object had its render attribute set as private with no setters/getters so I needed to modify the class to make it public so that i could swap it out.

My renderer is defined like this:

renderer = new ofGLProgrammableRenderer(&myWindow);

When I try and swap the renderer like this (it is a shared_ptr(?)):

settings.renderer.swap(renderer);

I run into an error where it says:

So I started trying to change the definition of the ofFbo::Settings class to use the ofGLProgrammable renderer - but this seems to break other things down the line.

I’m planning on doing a whole find and replace on the whole project to use the ofGLProgrammable renderer. But is there a simple thing that I’m missing here?

I believe ofFbo::Settings constructor takes a renderer shared_ptr, so no need to change the code. I would just change your member renderer to be a shared_ptr instead of a raw pointer and then pass that to the constructor.

Eric,

sorry this is turning into such an extended help session - but I am determined to get this!

So my first attempt to pass in the programmable renderer into my buffer looked like this:

 ofGLProgrammableRenderer *renderer;
renderer = new ofGLProgrammableRenderer(&myWindow);
std::shared_ptr<ofGLProgrammableRenderer> sharedRenderer(renderer);
ofFbo::Settings settings(sharedRenderer);

However it seems that doing this causes some kind of fatal runtime ‘crash’ in touch when I try and load the file. In my simplified ‘test’ ofx project, I’m able to get this to code to compile and run no problems. There must be something in your C++ wrapper for TD causing this problem, and I’m not entirely sure how to test what is causing the runtime error in a standard open frameworks environment.

What I do know is that the problem line on my end is:

std::shared_ptr<ofGLProgrammableRenderer> sharedRenderer(renderer);

If I remove the ‘renderer’ from the constructor, Touch will open up the dll - no problems. But I get a plain black screen.

From what I have read - It seems this is bad practice anyway. The raw pointer should not exist outside of the shared pointer.

So attempting to resolve this I tried to instantiate the renderer as a shared_ptr in the first place:

shared_ptr<ofGLProgrammableRenderer> *renderer; renderer = shared_ptr<ofGLProgrammableRenderer>(new ofGLProgrammableRenderer(&myWindow));

but then I run into the problem that it seems this ‘shared_ptr’ version of the renderer doesn’t have all the methods necessary to compile. For example

Really appreciate your patience and help! Will happily contribute a tutorial or example if I can figure it out- Seems like a FBO example would be a useful thing to have when a lot of OFX programmers are not such hardcore C++ coders…

Thanks again,

Sam

It seems you still have the renderer as a raw pointer there; I would change the class to have a shared_ptr renderer member:

shared_ptr<ofGLProgrammableRenderer> renderer;

Then, allocate it using the make_shared function in the constructor of your TOP:

myTOP::myTOP() : renderer(make_shared<ofGLProgrammableRenderer>(&myWindow)) {}

Then, you’ll be able to pass it to your Settings constructor and not have to worry about anything going out of scope.

Let me know if you’re still having trouble.

Thanks again eric :slight_smile:,

Seems I’m still having troubles. I think I am correctly creating the shared_ptr renderer now based on the advice you have given me and I’m able to get the inputTexture example running in TD fine with it!

By creating the shared pointer in an initialization list:

OpenFrameworksTOP::OpenFrameworksTOP(const OP_NodeInfo* info) : myNodeInfo(info), renderer(make_shared<ofGLProgrammableRenderer>(&myWindow))

and passing that into the fbo in the setup method:

ofFbo::Settings settings(renderer); settings.width = 1280; settings.height = 720 fbo.allocate(settings);

However as soon as I run fbo.begin() it seems to break the renderer (no errors but a dead grey screen in TD). This happens even if I don’t use the buffer in the renderer or draw anything inside.

I’ve had a peer into fbo.begin and it seems that this function isn’t evaluating to truthy:

auto renderer = settings.renderer.lock();

so the renderer in the FBO doesn’t ‘begin’:

if(renderer){ ofLog(OF_LOG_NOTICE, "got a renderer"); renderer->begin(*this,setupScreen); }

But that wouldn’t really explain why it breaks the TD render :confused:

I’ve created a gist this time with the only slightly modified version of the inputTexture example I’m working with:

[url]https://gist.github.com/samhains/08f8e1e312bd11efe5327789d04e234a[/url]

I had a quick look and renderer->begin() is being called, but I imagine it’s conflicting with our begin() function and breaks it as a result.

I’ll have a closer look at what’s going on and perhaps make an ofFbo example as well.

Also, just an FYI, you won’t be able to use functions like ofDrawCircle, and should instead use ofGLProgrammableRenderer::drawCircle … etc.

Hey Sam,

The issue here is that TD’s CPlusPlus TOP FBO is left unbound after ofFbo::end, so you must simply rebind it after you are done using an ofFbo and want to use TD’s instead. TD’s FBO index is stored in the TOP Context class. You can rebind like so:

glBindFramebuffer(GL_FRAMEBUFFER, context->getFBOIndex());

Here is the chunk of code in ::setup

void OpenFrameworksTOP::setup() 
{
	glewInit();
	renderer->setup(3, 2);

	ofFbo::Settings settings(renderer);
	settings.width = 1280;
	settings.height = 720;
	settings.numSamples = 0;
	settings.internalformat = GL_RGBA;
	fbo.allocate(settings);

#ifdef TARGET_OPENGLES
	shader.load("shadersES2/shader");
#else

	if(ofIsGLProgrammableRenderer())
	{
		shader.load("shadersGL3/shader");
	}
	else
	{
		shader.load("shadersGL2/shader");
	}
#endif

	isSetup = true;
}

and ::execute

void
OpenFrameworksTOP::execute(const TOP_OutputFormatSpecs* outputFormat,
							OP_Inputs* inputs,
							TOP_Context *context)
{
	double xPos = inputs->getParDouble("Translation");

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

	// Use the first input TOP (here we assume it exists but in reality it might not)
	const OP_TOPInput *topInput = inputs->getInputTOP(0);
	ofTexture texture;
	texture.setUseExternalTextureID(topInput->textureIndex);
	texture.texData.width = topInput->width;
	texture.texData.height = topInput->height;
	texture.texData.tex_w = topInput->width;
	texture.texData.tex_h = topInput->height;
	texture.texData.tex_t = 1.0f;
	texture.texData.tex_u = 1.0f;
	texture.texData.textureTarget = topInput->textureType;
	texture.texData.bFlipTexture = true;

	// Need to use a ofAppNoWindow so that openFrameworks doesn't create a conflicting
	// OpenGL context. We want to use TouchDesigner's context in ::execute
	ofSetupOpenGL(&myWindow, width, height, OF_WINDOW);

	context->beginGLCommands();

	// shaders must be loaded within the TouchDesigner context
	if (!isSetup)
	{
		setup();
	}

	fbo.begin();
	renderer->clear(255, 255, 255, 0);
	renderer->draw(texture, 0, 0, 0, 1280, 720, 0, 0, 1280, 720);
	fbo.end();

	auto t = fbo.getTexture();

	glBindFramebuffer(GL_FRAMEBUFFER, context->getFBOIndex());

	begin();

	shader.setUniform1f("xPos", (float)-xPos);
	renderer->draw(t, 0, 0, 0, 1280, 720, 0, 0, 1280, 720);

	end();

	context->endGLCommands();
}

Hey eric,

thank you so much for looking into this!

I’ve carefully swapped out my code for yours but all I’m getting is a black screen.

was your code working? any chance you could share?

This is what my code looks like…

gist.github.com/samhains/f884cf … a3f1f50779