{"id":23803519,"url":"https://github.com/d3cod3/mosaic-plugin","last_synced_at":"2025-09-06T16:32:22.009Z","repository":{"id":37255685,"uuid":"248946963","full_name":"d3cod3/Mosaic-Plugin","owner":"d3cod3","description":"Mosaic plugin template","archived":false,"fork":false,"pushed_at":"2024-11-28T14:46:08.000Z","size":95,"stargazers_count":6,"open_issues_count":1,"forks_count":1,"subscribers_count":2,"default_branch":"master","last_synced_at":"2024-11-28T15:36:18.814Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":null,"language":"C++","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/d3cod3.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2020-03-21T09:47:35.000Z","updated_at":"2024-11-28T14:46:11.000Z","dependencies_parsed_at":"2023-01-21T04:02:49.951Z","dependency_job_id":null,"html_url":"https://github.com/d3cod3/Mosaic-Plugin","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/d3cod3%2FMosaic-Plugin","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/d3cod3%2FMosaic-Plugin/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/d3cod3%2FMosaic-Plugin/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/d3cod3%2FMosaic-Plugin/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/d3cod3","download_url":"https://codeload.github.com/d3cod3/Mosaic-Plugin/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":232133657,"owners_count":18477292,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2025-01-01T22:32:09.221Z","updated_at":"2025-01-01T22:32:09.451Z","avatar_url":"https://github.com/d3cod3.png","language":"C++","readme":"# Mosaic-Plugin\nMosaic plugin template\n\n## Code Details\n\nWriting a Mosaic plugin is relatively easy, just clone this repo and open the qtcreator project to take a look at the 4 included objects/nodes templates.\n\nYou can write plugins with a single object, or you can pack multiple objects in the same plugin ( a plugin pack ). You will have access at all the openFrameworks code/libraries, ImGui and all the ofxAddons already comes as dependencies of ofxVisualProgramming addon, the core code of the Mosaic objects/nodes implementation. Lots of possibilities, indeed!\n\nLet's analize the _NumberObject_ Mosaic plugin template, included in the repo, a simple objects receiving a number cable and returning another number cable with the same value received ( a bypass object/node, not really useful, but perfect for understanding the plugin code structure ):\n\nThe header of the plugin is NumberObject.h :\n\n```c\n\n/*==============================================================================\n\n    Mosaic: Live Visual Patching Creative-Coding Platform\n    ofxVisualProgramming: A visual programming patching environment for OF\n\n    Copyright (c) 2020 Emanuele Mazza aka n3m3da \u003cemanuelemazza@d3cod3.org\u003e\n\n    Mosaic and ofxVisualProgramming is distributed under the MIT License.\n    This gives everyone the freedoms to use ofxVisualProgramming in any context:\n    commercial or non-commercial, public or private, open or closed source.\n\n    Permission is hereby granted, free of charge, to any person obtaining a\n    copy of this software and associated documentation files (the \"Software\"),\n    to deal in the Software without restriction, including without limitation\n    the rights to use, copy, modify, merge, publish, distribute, sublicense,\n    and/or sell copies of the Software, and to permit persons to whom the\n    Software is furnished to do so, subject to the following conditions:\n\n    The above copyright notice and this permission notice shall be included\n    in all copies or substantial portions of the Software.\n\n    THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS\n    OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n    FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\n    AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n    LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING\n    FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n    DEALINGS IN THE SOFTWARE.\n\n    See https://github.com/d3cod3/Mosaic-Plugin for documentation\n\n    Name:           NumberObject\n\n    Desc:           Mosaic Plugin Example - Number object\n\n    Developed by:   Emanuele Mazza aka n3m3da\n\n    Github:         https://github.com/d3cod3\n    WWW:            http://www.d3cod3.org\n\n==============================================================================*/\n\n#pragma once\n\n#include \"PatchObject.h\"\n#include \"mpGraphics.h\"\n\nclass NumberObject : public PatchObject {\n\npublic:\n\n    // CONSTRUCTOR\n    NumberObject();\n\n    // inherit virtual methods from base class PatchObject\n    // this are all methods available, you can use it all\n    // or just the one you need.\n    // for this simple object i'm going to leave commented\n    // the ones i don't need\n\n    // BASIC METHODS\n\n    // inlets/oulets instatiation\n    void              newObject() override;\n    // object setup\n    void              setupObjectContent(shared_ptr\u003cofAppGLFWWindow\u003e \u0026mainWindow) override;\n    // object update\n    void              updateObjectContent(map\u003cint,shared_ptr\u003cPatchObject\u003e\u003e \u0026patchObjects);\n    // object draw\n    void              drawObjectContent(ofTrueTypeFont *font, shared_ptr\u003cofBaseGLRenderer\u003e\u0026 glRenderer) override;\n    void              drawObjectNodeGui( ImGuiEx::NodeCanvas\u0026 _nodeCanvas ) override;\n    void              drawObjectNodeConfig() override;\n    // call on remove object\n    void              removeObjectContent(bool removeFileFromData=false) override;\n\n    // ADVANCED METHODS\n\n    // file loading objects related methods (video file, audio file, script file, etc)\n    //void              autoloadFile(string _fp) override;\n    //void              autosaveNewFile(string fromFile) override;\n\n    // audio objects related methods\n    //void              setupAudioOutObjectContent(pdsp::Engine \u0026engine) override;\n    //void              audioInObject(ofSoundBuffer \u0026inputBuffer) override;\n    //void              audioOutObject(ofSoundBuffer \u0026outputBuffer) override;\n\n    // object reset methods\n    //void              customReset() override;\n    //void              resetSystemObject() override;\n    //void              resetResolution(int fromID=-1, int newWidth=-1, int newHeight=-1) override;\n\n\n  protected:\n      mpGraphics                  mainRenderer; // reference to the main renderer ( avoid problems with openGL single thread resources access )\n      size_t                      startTime;\n      size_t                      wait;\n\n      // initialize object in factory\n      OBJECT_FACTORY_PROPS\n\n};\n\n// this is the necessary code to transform the object/node into a Mosaic plugin\n// ( check the names and change accordingly, two objects with the same name or driver name cannot co-exists )\nclass NumberObjectDriver : public PatchObjectDriver\n{\npublic:\n    NumberObjectDriver() : PatchObjectDriver(\"NumberObjectDriver\", NumberObject::version) {}\n    PatchObject* create() {return new NumberObject();}\n};\n\n```\n\nAnd the source NumberObject.cpp :\n\n```c\n\n/*==============================================================================\n\n    Mosaic: Live Visual Patching Creative-Coding Platform\n    ofxVisualProgramming: A visual programming patching environment for OF\n\n    Copyright (c) 2020 Emanuele Mazza aka n3m3da \u003cemanuelemazza@d3cod3.org\u003e\n\n    Mosaic and ofxVisualProgramming is distributed under the MIT License.\n    This gives everyone the freedoms to use ofxVisualProgramming in any context:\n    commercial or non-commercial, public or private, open or closed source.\n\n    Permission is hereby granted, free of charge, to any person obtaining a\n    copy of this software and associated documentation files (the \"Software\"),\n    to deal in the Software without restriction, including without limitation\n    the rights to use, copy, modify, merge, publish, distribute, sublicense,\n    and/or sell copies of the Software, and to permit persons to whom the\n    Software is furnished to do so, subject to the following conditions:\n\n    The above copyright notice and this permission notice shall be included\n    in all copies or substantial portions of the Software.\n\n    THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS\n    OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n    FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\n    AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n    LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING\n    FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n    DEALINGS IN THE SOFTWARE.\n\n    See https://github.com/d3cod3/Mosaic-Plugin for documentation\n\n    Name:           NumberObject\n\n    Desc:           Mosaic Plugin Example - Number object\n\n    Developed by:   Emanuele Mazza aka n3m3da\n\n    Github:         https://github.com/d3cod3\n    WWW:            http://www.d3cod3.org\n\n==============================================================================*/\n\n#include \"NumberObject.h\"\n\n//--------------------------------------------------------------\nNumberObject::NumberObject() : PatchObject(\"number object\"){\n\n    // SET YOUR INLETS/OUTLETS\n    this-\u003enumInlets  = 1;\n    this-\u003enumOutlets = 1;\n\n    // then init the pointers\n    // i have used here void* pointers\n    // and established 6 fixed type of data plus a variable\n    // one (a special purpose cable for special cases) to cast\n    // and create proper connections\n\n    // VP_LINK_NUMERIC --\u003e float\n    // VP_LINK_STRING  --\u003e string\n    // VP_LINK_ARRAY   --\u003e vector\u003cfloat\u003e\n    // VP_LINK_TEXTURE --\u003e ofTexture\n    // VP_LINK_PIXELS  --\u003e ofPixels\n    // VP_LINK_AUDIO   --\u003e ofSoundBuffer\n    // VP_LINK_SPECIAL --\u003e anything\n\n    // We'll use here simple VP_LINK_NUMERIC connections, due to the nature of the objects ( a float number bypass )\n\n    // we create/cast the inlet then as float\n    _inletParams[0] = new float();  // input\n    *(float *)\u0026_inletParams[0] = 0.0f;\n\n    // and the same for the outlet\n    _outletParams[0] = new float(); // output\n    *(float *)\u0026_outletParams[0] = 0.0f;\n\n    // we call this to init internal stuff\n    this-\u003einitInletsState();\n\n    // delay ImGui render due to unresolved bug\n    startTime = ofGetElapsedTimeMillis();\n    wait = 200;\n\n}\n\n//--------------------------------------------------------------\nvoid NumberObject::newObject(){\n    // SET OBJECT NAME AND INLETS/OUTLETS TYPES/NAMES\n    PatchObject::setName( this-\u003eobjectName );\n\n    this-\u003eaddInlet(VP_LINK_NUMERIC,\"number\");\n\n    this-\u003eaddOutlet(VP_LINK_NUMERIC,\"number\");\n}\n\n//--------------------------------------------------------------\nvoid NumberObject::setupObjectContent(shared_ptr\u003cofAppGLFWWindow\u003e \u0026mainWindow){\n\n    // SETUP your object here, as any ofApp example\n\n    //////////////////////////////////////////////\n    // LINK SHARED RENDERER\n    mainRenderer.setup(mainWindow-\u003erenderer());\n    //////////////////////////////////////////////\n\n    //////////////////////////////////////////////\n    // YOUR SETUP CODE\n\n\n    //////////////////////////////////////////////\n}\n\n//--------------------------------------------------------------\nvoid NumberObject::updateObjectContent(map\u003cint,shared_ptr\u003cPatchObject\u003e\u003e \u0026patchObjects){\n\n    // UPDATE your object here, as any ofApp example\n\n    //////////////////////////////////////////////\n    // YOUR UPDATE CODE\n    if(this-\u003einletsConnected[0]){\n        *(float *)\u0026_outletParams[0] = *(float *)\u0026_inletParams[0];\n    }\n    //////////////////////////////////////////////\n\n}\n\n//--------------------------------------------------------------\nvoid NumberObject::drawObjectContent(ofTrueTypeFont *font, shared_ptr\u003cofBaseGLRenderer\u003e\u0026 glRenderer){\n\n    // DRAW your OF code here, as any ofApp example ( check differences below )\n\n    /*\n        Due to rendering sharing needs, use internal mpGraphics methods\n        instead of starndard OF methods for drawing\n\n        ex. ofSetColor --\u003e mainRenderer.ofSetColor()\n            or:\n        ofVideoPlayer video;\n        video.load(\"video.mp4\");\n\n        video.draw(0,0); --\u003e mainRenderer.draw(video,0,0);\n     */\n\n    //////////////////////////////////////////////\n    // YOUR DRAW CODE\n    mainRenderer.ofSetColor(255,255,255);\n    //////////////////////////////////////////////\n\n}\n\n//--------------------------------------------------------------\nvoid NumberObject::drawObjectNodeGui( ImGuiEx::NodeCanvas\u0026 _nodeCanvas ){\n\n    // DRAW your ImGui object CONFIG menu and and the object main view here\n\n    ImGui::SetCurrentContext(_nodeCanvas.getContext());\n\n    // CONFIG GUI custom Menu\n    if(_nodeCanvas.BeginNodeMenu()){\n\n        ImGui::Separator();\n        ImGui::Separator();\n        ImGui::Separator();\n\n        if (ImGui::BeginMenu(\"CONFIG\"))\n        {\n\n            // the callback to the custom menu content\n            drawObjectNodeConfig();\n\n            ImGui::EndMenu();\n        }\n\n        _nodeCanvas.EndNodeMenu();\n    }\n\n    // Visualize (Object main view)\n    if( _nodeCanvas.BeginNodeContent(ImGuiExNodeView_Visualise) ){\n\n\n\n        _nodeCanvas.EndNodeContent();\n    }\n\n}\n\n//--------------------------------------------------------------\nvoid NumberObject::drawObjectNodeConfig(){\n    // DRAW your ImGui object custom CONFIG menu\n\n    // delay ImGui render due to unresolved bug\n    if(ofGetElapsedTimeMillis()-startTime \u003e wait){\n\n        // ObjectInfo(description, reference url, retinaScaleFactor)\n        ImGuiEx::ObjectInfo(\n                    \"Mosaic Plugin Example - Number object.\",\n                    \"#\", scaleFactor);\n    }\n}\n\n//--------------------------------------------------------------\nvoid NumberObject::removeObjectContent(bool removeFileFromData){\n  // anything you need to remove or stop when deleting the object\n}\n\n\n// REGISTER THE OBJECT to factory OBJECT_REGISTER(class, object name, category)\nOBJECT_REGISTER( NumberObject, \"number object\", OFXVP_OBJECT_CAT_MATH)\n\n// available categories\n// OFXVP_OBJECT_CAT_AUDIOANALYSIS\n// OFXVP_OBJECT_CAT_COMMUNICATIONS\n// OFXVP_OBJECT_CAT_CV\n// OFXVP_OBJECT_CAT_DATA\n// OFXVP_OBJECT_CAT_GUI\n// OFXVP_OBJECT_CAT_LOGIC\n// OFXVP_OBJECT_CAT_MATH\n// OFXVP_OBJECT_CAT_SCRIPTING\n// OFXVP_OBJECT_CAT_SOUND\n// OFXVP_OBJECT_CAT_TEXTURE\n// OFXVP_OBJECT_CAT_WINDOWING\n\n```\n\nSo, this is a basic Mosaic plugin structure, the last thing we need to create the plugin, is edit the plugin.cpp file ( included in the repo )\n\n```c\n\n// necessary include from Pugg plugin system\n#include \"Kernel.h\"\n\n// her we include our new Mosaic plugin ( multiple includes in case of multiple plugins in the same plugin package )\n#include \"NumberObject.h\"\n\n#ifdef _WIN32\n#  define EXPORTIT __declspec( dllexport )\n#else\n#  define EXPORTIT\n#endif\n\nextern \"C\" EXPORTIT void register_pugg_plugin(pugg::Kernel* kernel)\n{\n    // here we'll just need to add a line for every plugin in the package ( just one in this case)\n    kernel-\u003eadd_driver(new NumberObjectDriver());\n}\n\n```\n\nThen last, but not less important, we'll need to edit the name of the plugin ( or the plugin package ), and for that we'll just have to edit a line inside the .qbs qtcreator project file ( line 12 in the one from the repo) :\n\n```c\n\n  name: \"MosaicObjectTemplate\"\n\n```\n\nJust change the default **MosaicObjectTemplate** name with the one you need for your plugin/plugin package.\n\nCompile, and if everything went fine, a dynamic library will appear in the project bin/ folder (.framework for OSX, .so for linux, .dll for windows).\nJust For OSX, you'll need to get the .framework internal library and rename it to .bundle, just check the included copyPluginToMosaic.sh file:\n\n```bash\n\n#!/bin/bash\n\nSCRIPTPATH=\"$( cd \"$(dirname \"$0\")\" ; pwd -P )\"\n\nPLUGINNAME=\"MosaicObjectTemplate\"\n\ncp $SCRIPTPATH/bin/$PLUGINNAME.framework/Versions/A/$PLUGINNAME ~/Documents/Mosaic/plugins/$PLUGINNAME.bundle\n\n```\n\nThe script will rename and copy the plugin in the plugins/ Mosaic folder ( remember to have Mosaic installed and at least opened one first time, in order to have the Mosaic/ folder inside your user Documents/ folder )\n\nThat's it, you have just created your first Mosaic plugin, you can now add your custom objects/nodes to the Mosaic platform, use them for your personal works or distribute them, to share your code/knowledge and help others to learn new stuff.\n","funding_links":[],"categories":[],"sub_categories":[],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fd3cod3%2Fmosaic-plugin","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fd3cod3%2Fmosaic-plugin","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fd3cod3%2Fmosaic-plugin/lists"}