MWorks stimulus plugin

Hi Chris,

I’m trying to build a stimulus plugin for MWorks. I’ve already checked the website and looked at some plugins (e.g. drifting grating plugin). However, it may be good to ask you some questions:

  • Are there issues related to stimulus plugins, that are implicit to MWorks beginners like me, that I should keep in mind ?
  • What’s the best way to test my plugin? I’ve tried to build the MWorks project from Github but I’m getting some semantic issues about “implicit copy constructors” that are not viable in some class definitions. Can you recommend a particular project version or are there certain steps I should know of when building the project in XCode?

Thanks a lot,
Bram

Hi Bram,

I’m trying to build a stimulus plugin for MWorks. I’ve already checked the website and looked at some plugins (e.g. drifting grating plugin).

If you haven’t already, I’d suggest looking at one or both of these:

Are there issues related to stimulus plugins, that are implicit to MWorks beginners like me, that I should keep in mind?

Mostly I’d recommend following the example of existing stimulus plugins, such as the two I just mentioned. The main thing that makes stimulus plugins hard is OpenGL, which has a pretty steep learning curve. If you like, I can help you set up your drawing code. Otherwise, if you’re not already familiar with OpenGL but would like to learn, I can recommend some books and tutorials.

What’s the best way to test my plugin? I’ve tried to build the MWorks project from Github but I’m getting some semantic issues about “implicit copy constructors” that are not viable in some class definitions. Can you recommend a particular project version or are there certain steps I should know of when building the project in XCode?

MWorks installers (both release builds and nightlies) include everything you need to compile a plugin, so there’s no need to build MWorks from source. Here’s what I’d recommend:

  1. Install the latest nightly build
  2. Install the latest version of Xcode from the Mac App Store
  3. Try building an existing stimulus plugin

If this is the first time you’re doing this, expect some issues in step #3. For one thing, in order to install the plugin, you’ll probably need to make the directory /Library/Application Support/MWorks/Plugins/Core writable by you. Also, the latest version of Xcode does not include the OS X 10.7 SDK, which MWorks is set to build against. The easiest way to work around this is to change your project settings in Xcode so that “Base SDK” is set to “Latest OS X”. There’s probably other stuff I’m not thinking of right now, so feel free to ping me as issues arise.

As for specific build issues (e.g. “implicit copy constructors”), the easiest way for me to help is to download and build your code myself. If possible, I’d recommend hosting your plugin in a public repository on GitHub. That way, if you need help resolving an issue, I can tweak your project directly and send you a pull request.

Cheers,
Chris

Hi Chris,

Thanks for the suggestions. I’ll start building the plugin and keep you posted about the progression and potential problems.
Thanks a lot,
Bram

Hi Chris,

It had to happen, I ran into problems… I’ve made a preliminary plugin which you can find on Github: https://github.com/BramVerhoef/DynamicGaborNoise. There is still some work on the dynamic part and some cleaning up to do, but I would like to test it already. For now I would like it to run with the attached experiment.

My DynamicGaborNoisePlugin plugin is based on the “MovingDots” plugin that you suggested. It builds well in Xcode. I then copy the plugin into the MWorks Core plugin folder (which is read/write). However, when I run the attached experiment in MWorks it says it cannot create the object; no Factory for dynamic_gabor_noise.

Could you have a look at it and let me know what I’m doing wrong?

I also have a couple of other questions, which I hope you can help me with:

  • When is the “load" method called, after the queue stimulus command?
  • Is it possible to control the swapping of front and back buffers, e.g. draw 10 frames in the back buffer without swapping to the front buffer, after which normal front-back swapping takes place?
  • what does "play dynamic stimulus” internally do, in contrast to “update stimulus display”?

Let me know if you need any more information from me.
Thanks a lot,
Bram

Attachment: Gabor_Noise_Experiment.zip (159 KB)

Hi Bram,

However, when I run the attached experiment in MWorks it says it cannot create the object; no Factory for dynamic_gabor_noise.

In DynamicGaborNoise::describeComponent, replace

info.setSignature("stimulus/DynamicGaborNoise");

with

info.setSignature("stimulus/dynamic_gabor_noise");

Alternatively, you could modify your experiment XML to request a stimulus of type “DynamicGaborNoise”, but the lowercase+underscores naming style is what all other MWorks components use, so I recommend that your plugin use it, too.

When is the “load" method called, after the queue stimulus command?

It depends on the value of the stimulus’s “deferred”" parameter. If “deferred” is omitted or set to “no”, then “load” is called when the stimulus instance is created, at experiment load time. If “deferred” is “yes”, then “load” is called the first time the stimulus is queued. Finally, if “deferred” is “explicit”, then “load” is never called implicitly, and the stimulus must be loaded explicitly via a “load_stimulus” action.

Is it possible to control the swapping of front and back buffers, e.g. draw 10 frames in the back buffer without swapping to the front buffer, after which normal front-back swapping takes place?

No, you can’t control buffer swapping. It might be possible for a plugin to render to an off-screen framebuffer and blit to the display buffer as needed, but I’d have to think about that some more.

Can you explain why you’d want to do this? Maybe there’s another solution that would meet your needs.

what does "play dynamic stimulus” internally do, in contrast to “update stimulus display”?

“update_stimulus_display” is required any time you want to change the set of stimuli being displayed. Stimulus queue/dequeue actions don’t take effect until you invoke “update_stimulus_display”.

“play_dynamic_stimulus” invokes the “play” method of a dynamic stimulus class. Subclasses of StandardDynamicStimulus won’t draw unless they’re playing, so in order to make them visible, you have to queue them and start them playing.

Since, in many cases, this is more confusing and annoying than useful, a while back I added an “autoplay” parameter to StandardDynamicStimulus (and thereby its subclasses). If “autoplay” is set to “YES”, then the first time the stimulus is asked to draw itself (typically when you invoke “update_stimulus_display” after queuing it), it will start playing automatically. Hence, by using “autoplay”, you can avoid invoking “play_dynamic_stimulus” altogether.

Cheers,
Chris

Hi Chris,

Thanks a lot for your reply!

MWorks is now able to construct a new object for the plugin. However, it cannot load my plugin. After some searching I discovered that my MWorks runs on OpenGl 2.1 and GLSL 1.20. My plugin is build for OpenGL 3.2 or higher and GLSL 3.30 or higher; e.g. using vertexArrays, uniform buffers and objects. At least, this holds for the context that I get from "OpenGLContextLock ctxLock = display->setCurrent(0);”. You can already guess my next question: How can I upgrade OpenGL and GLSL? I’m running on Mavericks which supports OpenGL up to 4.1.

Greetings,
Bram

Hi Bram,

How can I upgrade OpenGL and GLSL?

Unfortunately, in order for stimulus classes to use OpenGL 3.2+, the entire MWorks stimulus display infrastructure will have to be reworked and updated. This isn’t something that can be decided on a plugin-by-plugin basis.

Moving MWorks to the modern OpenGL stack has been on my radar even since it became available, but doing so will be a major undertaking with no obvious benefit to MWorks users (and probably some detriment, since things are likely to get broken and/or changed in incompatible ways in the process). Hence, I’m not sure when it’s going to happen, although I’m confident it will happen eventually, if only because Apple will eventually drop support for legacy OpenGL.

A possible transitional solution would be to add an entirely new, independent stimulus display infrastructure based on GL 3.2+, which your experiment could select at run time. New stimuli could be added (and old ones ported) to the new implementation without upsetting the old one. However, in order for this to be useful, we’d probably need to port most of the existing builtin stimuli, which is still a large job.

For the time being, the most expedient thing is probably to rework your plugin to work with OpenGL 2.1. I know that’s not an appealing solution, but any other route entails several months (or more) of development work, and you probably don’t want to wait that long.

Chris

Hi Chris,

I agree, that is really unfortunate. I’ll have to think about this.
Thanks for your reply.

Greetings,
Bram

Hi Chris,

I may have found a way to generate the stimulus in OpenGL 2.10 without having too make too many compromises.
I’ll keep you posted.

Greetings,
Bram

Hi Chris,

I changed the stimulus to work with OpenGL 2.1 and GLSL 1.20. The plugin is working nicely with MWorks now.

Thanks for your help.
Greetings,
Bram

Hi Bram,

I changed the stimulus to work with OpenGL 2.1 and GLSL 1.20. The plugin is working nicely with MWorks now.

Great! If you need further assistance, please let me know.

Chris