#pragma once #include #include #include #include "../ffgl/FFGLPluginInfo.h" #include "../ffgl/FFGLPluginSDK.h" #include "../ffgl/FFGLLib.h" #include "../ffglex/FFGLShader.h" #include "../ffglex/FFGLScreenQuad.h" #include "../ffglex/FFGLUtilities.h" #include "../ffglex/FFGLScopedShaderBinding.h" #include "FFGLUtils.h" #include "FFGLAudio.h" #include "FFGLRandom.h" namespace ffglqs { class Param; class ParamRange; class ParamOption; class ParamFFT; class ParamText; typedef CFFGLPluginInfo PluginInstance; struct PluginInfo { std::string id, name, description, about; int majorVersion = 1; int minorVersion = 0; PluginInfo( std::string id, std::string name ) : id( id ), name( name ) { } }; class Plugin : public CFFGLPlugin { public: Plugin( bool supportTopLeftTextureOrientation = false ); ~Plugin(); /// This method allows to create the plugin description. /// This is what makes your plugin available in the exported library file. template< typename PluginType > static PluginInstance CreatePlugin( PluginInfo infos, FFUInt32 type ); /// Implementation of the FFGL InitGL instance specific function. This function allocates /// the OpenGL resources the plugin needs during its lifetime. If the shader fails to /// compile we return FF_FAIL. /// /// \param viewPort Pointer to a FFGLViewportStruct structure (see the definition in FFGL.h /// and the description in the FFGL specification). /// \return This implementation returns FF_SUCCESS if the shader did compile /// correctly FF_FAIL otherwise. FFResult InitGL( const FFGLViewportStruct* viewPort ) override; /// Implementation of the FFGL ProcessOpenGL instance specific function. It is in this function that /// the actual rendering occur. /// /// \param inputTextures This is a parameter containing info about input texture if there is some. /// \return This implementation always returns FF_SUCCESS. FFResult ProcessOpenGL( ProcessOpenGLStruct* inputTextures ) override; /// Implementation of the FFGL DeInitGL instance specific function. This function frees /// any OpenGL resources the plugin has allocated /// /// \return This implementation always returns FF_SUCCESS. FFResult DeInitGL() override; /// You can override this function to allocate any ressource you will need, shader for example. If any error /// occured (shader fails to compile for example), return FF_FAIL. /// \return FF_FAIL if any error occured else FF_SUCCESS virtual FFResult Init() { return FF_SUCCESS; } /// You can override this function to do something just before the main shader call. It can for example be usefull /// if you have to react to certains parameter change in a specific way and / or send custom uniform to the shader virtual void Update() { } /// The default implementation will just call glDraw with the main shader. You can override this if your plugin needs /// to do more complex things, like calling multiple shaders. /// \return FF_FAIL if any error occured else FF_SUCCESS virtual FFResult Render( ProcessOpenGLStruct* inputTextures ); /// Use this function to free any ressource allocated in your init() function virtual void Clean() { } /// This function allows to include snippet of code that are provided in Utils.h. This allows plugin /// programmer to not rewrite common code in each plugin. For example, code to get a random number, /// map a value from a range to another, and simplex noise are currently available. /// \param snippet The id of a snippet to include. void Include( shader::snippet_id snippet ); /// This function will call the function just above for each snippets in the set. /// \param snippets A set of snippets to include. void Include( std::set< shader::snippet_id > snippets ); /// In this function we assemble the different bit of the fragment shader into one and try to compile it. /// This allows to add all the default uniform to the begining of the shader so you don't /// have to do it manually. It also permits to add any included snippet to it. /// \param base The base of your shader, usually just the void main() function /// \return The full shader as a string std::string CreateFragmentShader( std::string base ); /// This function is called by the plugin before each render it allows to update all the params that /// are sent to the main shader. void UpdateAudioAndTime(); /// This function will send all the parameter registered by your plugin to the shader. /// \param shader The shader to send the params void SendParams( ffglex::FFGLShader& shader ); /// This function will send all the default parameter (like time, bpm, resolution...) to the shader. /// \param shader The shader to send the params void SendDefaultParams( ffglex::FFGLShader& shader ); /// This function is called by the host to get a string representation of any parameter. /// It will just return the value of the current param as a char*. /// \param index The index of the parameter to display /// \return The char* representation of the parameter char* GetParameterDisplay( unsigned int index ) override; /// This function is called by the host to set a value to a specific param thanks to its index. /// \param index The index of the parameter to set /// \param value The value to assign to the param /// \return FF_SUCCESS if we managed to find the parameter and set its value FFResult SetFloatParameter( unsigned int index, float value ) override; /// This function is called by the host to get the float value of a Param thanks to its index. /// \param index The index of the parameter to get /// \return The float value of the parameter float GetFloatParameter( unsigned int index ) override; /// This function is called by the host to set the text value of a ParamText. /// \param index The index of the parameter to set /// \param value The text to assign to the param /// \return FF_SUCCESS if we managed to find the parameter and set its value FFResult SetTextParameter( unsigned int index, const char* value ) override; /// This function is called by the host to get the text value of a ParamText. /// \param index The index of the parameter to get /// \return The text assigned to the parameter char* GetTextParameter( unsigned int index ) override; /// This function is called by the host when the current sample rate has changed. /// \param sampleRate The new sample rate void SetSampleRate( unsigned int sampleRate ) override; /// This function must be called in the constructor of your plugin. It will allows to /// construct the full fragment shader. In order to simplify the development of plugin /// it is InitGL that takes care of defining all the parameters so that the shader can acces /// them. /// \param base The fragment shader void SetFragmentShader( std::string base ); /// This function allows you to add a new parameter to the plugin. There is differents kind of /// parameters available, you can check them in Params.h. Adding a parameter allows the plugin to be /// aware of them, make them available to the host and take of all the communication with it. /// It also allows the plugin to automatically pass the current value of each parameters to the /// shader before drawing. /// \param param The parameter to add void AddParam( std::shared_ptr< Param > param ); /// This function handle the special case where the parameter is a ParamRange /// \param param The parameter to add void AddParam( std::shared_ptr< ParamRange > param ); /// This function handle the special case where the parameter is a ParamOption (When you have the /// choice between different option). /// \param param The parameter to add void AddParam( std::shared_ptr< ParamOption > param ); /// This function handle the special case where the parameter is a ParamFFT /// \param param The parameter to add void AddParam( std::shared_ptr< ParamFFT > fft ); /// This function allows to create a Hue color param, for exemple in Resolume this will display a /// color picker, which is very handy to choose your color. /// \param name The name of the parameter to add void AddHueColorParam( std::string name ); /// This function allows to create a RGB color param, in Resolume it is displayed as three sliders for /// each Red, Green and Blue. /// \param name The name of the parameter to add void AddRGBColorParam( std::string name ); /// This function allows to check if a certains index corresponds to a Hue color. Internally, it is /// represented as three Params. It checks if the current one and the two followings are actually /// corresponding to a Hue color. /// \param index The index of the first parameter that could correspond to a Hue color. bool IsHueColor( int index ); /// This function allows to check if a certains index corresponds to a RGB color. Internally, it is /// represented as three Params. It checks if the current one and the two followings are actually /// corresponding to a RGB color. /// \param index The index of the first parameter that could correspond to a RGB color. bool IsRGBColor( int index ); /// This function allows to get a parameter by it's name. /// \param name The name of the parameter to get. /// \return The parameter if we managed to find it. std::shared_ptr< Param > GetParam( std::string name ); /// This function allows to get an option parameter by it's name. /// \param name The name of the parameter to get. /// \return The parameter if we managed to find it. std::shared_ptr< ParamOption > GetParamOption( std::string name ); /// This function allows to get a text parameter by it's name. /// \param name The name of the parameter to get. /// \return The parameter if we managed to find it. std::shared_ptr< ParamText > GetParamText( std::string name ); protected: std::string fragmentShaderBase; std::vector< std::shared_ptr< Param > > params; std::map< std::shared_ptr< ParamFFT >, Audio > audioParams; ffglex::FFGLShader shader; ffglex::FFGLScreenQuad quad; float timeNow = 0; float deltaTime = 0; float lastUpdate = 0; int frame = 0; std::chrono::time_point< std::chrono::high_resolution_clock > t_start = std::chrono::high_resolution_clock::now(); Random random; std::set< shader::snippet_id > includedSnippets; std::string fragmentShaderCodeStart = R"( #version 410 core out vec4 fragColor; uniform vec2 resolution; uniform float time; uniform float deltaTime; uniform int frame; uniform float bpm; uniform float phase; )"; std::string vertexShaderCode; // This function will consume the value for all ParamTrigger void consumeAllTrigger(); }; template< typename PluginType > inline PluginInstance Plugin::CreatePlugin( PluginInfo infos, FFUInt32 type ) { return PluginInstance( PluginFactory< PluginType >,// Create method, allows the host to create a new instance of the plugin infos.id.c_str(), // Plugin unique ID infos.name.c_str(), // Plugin name 2, // API major version number 1, // API minor version number infos.majorVersion, // Plugin major version number infos.minorVersion, // Plugin minor version number type, // Plugin type infos.description.c_str(), // Plugin description infos.about.c_str() // About ); } }//End namespace ffglqs