Plugin Template

< All Topics

Plugin Template

Getting Started

 

With the tools installed and the environment set up, we can now create a basic FFGL plugin template to use for all of our future FFGL projects.

There are 3 different types of plugins that you can create in FFGL: sources, effects and mixers.

Source

 

Does not require any video input and creates its own video output. Source plugins are often used for generative contents and visuals.

Effect

 

Needs at least one video input to apply effects on. Effect plugins are useful for creating video filters such as blur, inversion and color mixing.

Mixer

 

Mixers are effect plugins that need at least two video inputs to create an output. The plugin will mix the inputs in some shape or form to create the output frame. Depending on what the host software actually provides to the plugin as the second input, mixers can be used to create a variety of effects.

Setting up the Template

 

Setting up a template is a matter of using one of the base classes of the FFGL SDK to inherit from and adding additional functionality as needed.

 

To simplify things, you can download the FFGL templates created by the Morph team and use all of their existing functionality or modify them to suit your needs. There are two templates provided: a more basic type and a more advanced type. The advanced template has features such as:

 

  • Audio processing for audio-reactive plugins
  • Multipass rendering

 

We will discuss these concepts in more detail in the next sections of this series.

 

To set up either one of the provided templates with the SDK, copy it to ffgl-master/build/windows. For simplicity, we will look at FFGLTemplate but the advanced template can be set up in the exact same way.

 

The file inside the FFGLTemplate project can be copied to create a new plugin that uses the same settings and functionality.

 

Open the FFGLTemplate folder, you should have:

 

  • FFGLTemplate.vcxproj
  • FFGLTemplate.vcxproj.filters
  • FFGLTemplate.h
  • FFGLTemplate.cpp

 

 

Copy FFGLTemplate.vcxproj and FFGLTemplate.vcxproj.filters to ffgl-master/build/windows.

 

Create a folder named FFGLTemplate in ffgl-master/source/plugins and copy FFGLTemplate.h and FFGLTemplate.cpp inside it.

 

We will use these files to create a new plugin NewFFGLPlugin by following the steps below:

 

In ffgl-master/build/windows, copy FFGLTemplate.vcxproj and FFGLTemplate.vcxproj.filters and rename them to NewFFGLPlugin.vcxproj and NewFFGLPlugin.vcxproj.filter.

 

In ffgl-master/source/plugins, copy the FFGLTemplate folder, rename it to NewFFGLPlugin. Rename the files inside to NewFFGLPlugin.h and NewFFGLPlugin.cpp.

 

Open FFGLPlugins.sln located in ffgl-master/build/windows. In the Solution Explorer tab, right click on FFGLPlugins > sources / effects / mixers and click Add > Existing Project… then select the NewFFGLPlugin.vcxproj file you just created.

 

A project named NewFFGLPlugin should now appear as a subproject of FFGLPlugin under effect, sources or mixers.

 

Notice that the new project still lists the source files (.h and .cpp) of the project it was copied from. Right click these files and click Remove to remove them from the project.

 

Right click NewFFGLPlugin and click Add > Existing Item… and select NewFFGLPlugin.h and NewFFGLPlugin.cpp you created in ffgl-master/source/plugins.

Plugin Class

 

The Plugin class (FFGLPlugin.h /  FFGLPlugin.cpp located in ffgl-master/source/lib/ffglquickstart) that the template inherits from is the simplest base class to use for since it provides a lot of convenience methods and tools that minimize coding.

 

This class uses 4 key functions to render a frame using the OpenGL API:

 

  • InitGL
  • DeInitGL
  • ProcessOpenGL
  • Render

 

We will override (modify) the default code in these methods to suit our needs. Most of the code shown here is standard and will not be modified for basic plugins.

InitGL

 

This method creates any OpenGL resources (FBOs, textures etc.) we need for rendering.

 

FFResult FFGLTemplate::InitGL( const FFGLViewportStruct* vp )
{
std::string fragmentShaderCode = CreateFragmentShader( fragmentShaderBase );
vertexShaderCode = vertexShader;
fragmentShaderCode += fragmentShader;
if( !shader.Compile( vertexShaderCode, fragmentShaderCode ) ){
DeInitGL();
return FF_FAIL;
}
if( !quad.Initialise() ){
DeInitGL();
return FF_FAIL;
}
//Use base-class init as success result so that it retains the viewport.
return CFFGLPlugin::InitGL( vp );
}

DeInitGL

 

This method deletes the OpenGL resources we created in InitGL.

 

FFResult FFGLTemplate::DeInitGL()
{
shader.FreeGLResources();
quad.Release();
return FF_SUCCESS;
}

ProcessOpenGL

 

This method is where the rendering takes place. FFGL parameter values are sent to the GPU and if the plugin uses any host-provided values like time, delta time and resolution, they are also used here. Finally, this method calls the Render method to actually render an output frame.

 

FFResult FFGLTemplate::ProcessOpenGL( const ProcessOpenGLStruct* ) inputTextures)
{
UpdateAudioAndTime();
//Scoped shader binding:
//binds the shader program and releases it at the end of this method
ScopedShaderBinding shaderBinding( shader.GetGLID() );
//Update all parameters that this plugin registered to the shader
SendDefaultParams( shader );
SendParams( shader );
//Use base-class init as success result so that it retains the viewport.
return Render( inputTextures );
}

Render

 

ProcessOpenGL relies on this method to do the actual rendering, so this is where we will do most of our coding.

 

FFResult FFGLTemplate::Render( ProcessOpenGLStruct* inputTextures )
{
quad.Draw();
return FF_SUCCESS;
}

 

Previous: Introduction

Next: First Plugin