Skip to content

Commit bd3ecdc

Browse files
committed
added ofxSyphon addon and syphon sender + syphon receiver objects
1 parent 6d25d0c commit bd3ecdc

File tree

9 files changed

+605
-68
lines changed

9 files changed

+605
-68
lines changed

README.md

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,11 @@
11

22
# ofxVisualProgramming - A visual-programming patching addon for OF
33

4-
> A collection of visual interactive objects to create/develop in a dataflow+live-coding patching environment. Embedded with Lua and Python scripting interpreter, plus live compile of GLSL Shaders version 120 and live editing/execute Bash scripts(macOS & linux) capabilities.
4+
> A collection of visual interactive objects to create/develop in a dataflow+live-coding patching environment. Embedded with Lua and Python scripting interpreter, plus live compile of GLSL Shaders from version 150 to 410, and live editing/execute Bash scripts(macOS & linux) capabilities.
55
66
![Mosaic 0.4.0](https://github.com/d3cod3/Mosaic/raw/master/process/img/28_transparent_machines04.jpg)
77
Screenshot from project [Mosaic](http://mosaic.d3cod3.org/), embedding ofxVisualProgramming
88

9-
[![ko-fi](https://www.ko-fi.com/img/githubbutton_sm.svg)](https://ko-fi.com/V7V21B90C)
109

1110
Table of Contents
1211
=================
@@ -98,6 +97,8 @@ In order to build ofxVisualProgramming, you'll need this addons:
9897

9998
#### [ofxPython](https://github.com/d3cod3/ofxPython)
10099

100+
#### [ofxSyphon](https://github.com/d3cod3/ofxSyphon)
101+
101102
#### [ofxTimeline](https://github.com/d3cod3/ofxTimeline)
102103

103104
#### [ofxWarp](https://github.com/d3cod3/ofxWarp)
@@ -134,6 +135,7 @@ git clone https://github.com/d3cod3/ofxPython
134135
git clone https://github.com/danomatika/ofxPd
135136
git clone https://github.com/d3cod3/ofxPdExternals
136137
git clone https://github.com/d3cod3/ofxPDSP
138+
git clone https://github.com/d3cod3/ofxSyphon
137139
git clone https://github.com/d3cod3/ofxTimeline
138140
git clone https://github.com/d3cod3/ofxWarp
139141
git clone https://github.com/d3cod3/ofxVisualProgramming
@@ -356,6 +358,8 @@ texture crop | X |
356358
texture to pixels | X |
357359
texture transform | X |
358360
to grayscale texture | X |
361+
syphon sender | X |
362+
syphon receiver | X |
359363
video exporter | X |
360364
video feedback | X |
361365
video gate | X |
@@ -410,6 +414,8 @@ ofxNDI original addon by [Thomas Geissl](https://github.com/thomasgeissl)
410414

411415
ofxPython original addon by [Carles F. Julià](https://github.com/chaosct)
412416

417+
ofxSyphon original addon by [Anthony Stellato](https://github.com/astellato)
418+
413419
ofxTimeline original addon by [James George and YCAM Interlab](https://github.com/YCAMInterlab/ofxTimeline)
414420

415421
ofxWarp original addon by [Elie Zananiri](https://github.com/prisonerjohn/ofxWarp)

addon_config.mk

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -75,9 +75,10 @@ common:
7575

7676
linux64:
7777
ADDON_DEPENDENCIES += ofxPd ofxPdExternals ofxPython ofxNDI
78+
ADDON_SOURCES_EXCLUDE = src/objects/video/SyphonSender% src/objects/video/SyphonReceiver%
7879

7980
msys2:
80-
ADDON_SOURCES_EXCLUDE = src/objects/scripting/BashScript% src/objects/scripting/PythonScript% src/objects/sound/PDPatch% src/objects/video/VideoSender% src/objects/video/VideoReceiver%
81+
ADDON_SOURCES_EXCLUDE = src/objects/scripting/BashScript% src/objects/scripting/PythonScript% src/objects/sound/PDPatch% src/objects/video/VideoSender% src/objects/video/VideoReceiver% src/objects/video/SyphonSender% src/objects/video/SyphonReceiver%
8182

8283
osx:
83-
ADDON_DEPENDENCIES += ofxPd ofxPdExternals ofxPython ofxNDI
84+
ADDON_DEPENDENCIES += ofxPd ofxPdExternals ofxPython ofxNDI ofxSyphon

example_ImGui/example_ImGui.qbs

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,22 @@ Project{
4949
of.frameworks: outer.concat(['QTKit']);
5050
}
5151

52+
// Include ofxSyphon on osx
53+
Properties {
54+
// osx only, additional frameworks to link with the project
55+
condition: qbs.targetOS.contains("osx") || qbs.targetOS.contains("macos")
56+
of.addons: outer.concat(['ofxSyphon'])
57+
of.frameworks: outer.concat(['Syphon'])
58+
cpp.frameworkPaths: ['../../../addons/ofxSyphon/libs/Syphon/lib/osx/']
59+
// dirty fix for compiling .mm files (not auto-detected on qt)
60+
files: outer.concat([
61+
'../../../addons/ofxSyphon/src/ofxSyphonClient.mm',
62+
'../../../addons/ofxSyphon/src/ofxSyphonServer.mm',
63+
'../../../addons/ofxSyphon/src/ofxSyphonServerDirectory.mm',
64+
'../../../addons/ofxSyphon/libs/Syphon/src/SyphonNameboundClient.m',
65+
])
66+
}
67+
5268
Depends{
5369
name: "cpp"
5470
}
Lines changed: 0 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -1,31 +1 @@
1-
ofxAssimpModelLoader
2-
ofxGui
3-
ofxKinect
4-
ofxNetwork
5-
ofxOpenCv
6-
ofxOsc
7-
ofxSvg
8-
ofxVectorGraphics
9-
ofxXmlSettings
10-
ofxAudioAnalyzer
11-
ofxAudioFile
12-
ofxBTrack
13-
ofxChromaKeyShader
14-
ofxCv
15-
ofxEasing
16-
ofxFFmpegRecorder
17-
ofxFontStash
18-
ofxGLEditor
19-
ofxJSON
20-
ofxInfiniteCanvas
21-
ofxLua
22-
ofxMidi
23-
ofxMtlMapping2D
24-
ofxNDI
25-
ofxPd
26-
ofxPdExternals
27-
ofxPDSP
28-
ofxPython
29-
ofxTimeline
301
ofxVisualProgramming
31-
ofxWarp

example_ofxVisualProgramming/ofxVisualProgramming_example.qbs

Lines changed: 19 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -17,40 +17,9 @@ Project{
1717
'src/ofApp.h',
1818
]
1919

20-
of.addons: {
21-
if(qbs.targetOS.indexOf("windows")>-1){
22-
return ['ofxAssimpModelLoader','ofxGui','ofxKinect','ofxNetwork','ofxOpenCv','ofxOsc','ofxPoco','ofxSvg','ofxVectorGraphics','ofxXmlSettings',
23-
'ofxAudioAnalyzer',
24-
'ofxBTrack',
25-
'ofxCv',
26-
'ofxFontStash',
27-
'ofxGLError',
28-
'ofxDatGui',
29-
'ofxHistoryPlot',
30-
'ofxInfiniteCanvas',
31-
'ofxLua',
32-
'ofxLoggerChannel',
33-
'ofxTimeMeasurements',
34-
'ofxVisualProgramming'
35-
]
36-
}else{
37-
return ['ofxAssimpModelLoader','ofxGui','ofxKinect','ofxNetwork','ofxOpenCv','ofxOsc','ofxPoco','ofxSvg','ofxVectorGraphics','ofxXmlSettings',
38-
'ofxAudioAnalyzer',
39-
'ofxBTrack',
40-
'ofxCv',
41-
'ofxFontStash',
42-
'ofxGLError',
43-
'ofxDatGui',
44-
'ofxHistoryPlot',
45-
'ofxInfiniteCanvas',
46-
'ofxLua',
47-
'ofxLoggerChannel',
48-
'ofxPython',
49-
'ofxTimeMeasurements',
50-
'ofxVisualProgramming'
51-
]
52-
}
53-
}
20+
of.addons: [
21+
'ofxVisualProgramming'
22+
]
5423

5524
// additional flags for the project. the of module sets some
5625
// flags by default to add the core libraries, search paths...
@@ -71,6 +40,22 @@ Project{
7140
//
7241
// cpp.compilerWrapper: 'ccache'
7342

43+
// Include ofxSyphon on osx
44+
Properties {
45+
// osx only, additional frameworks to link with the project
46+
condition: qbs.targetOS.contains("osx") || qbs.targetOS.contains("macos")
47+
of.addons: outer.concat(['ofxSyphon'])
48+
of.frameworks: outer.concat(['Syphon'])
49+
cpp.frameworkPaths: ['../../../addons/ofxSyphon/libs/Syphon/lib/osx/']
50+
// dirty fix for compiling .mm files (not auto-detected on qt)
51+
files: outer.concat([
52+
'../../../addons/ofxSyphon/src/ofxSyphonClient.mm',
53+
'../../../addons/ofxSyphon/src/ofxSyphonServer.mm',
54+
'../../../addons/ofxSyphon/src/ofxSyphonServerDirectory.mm',
55+
'../../../addons/ofxSyphon/libs/Syphon/src/SyphonNameboundClient.m',
56+
])
57+
}
58+
7459
Depends{
7560
name: "cpp"
7661
}
Lines changed: 186 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,186 @@
1+
/*==============================================================================
2+
3+
ofxVisualProgramming: A visual programming patching environment for OF
4+
5+
Copyright (c) 2021 Emanuele Mazza aka n3m3da <emanuelemazza@d3cod3.org>
6+
7+
ofxVisualProgramming is distributed under the MIT License.
8+
This gives everyone the freedoms to use ofxVisualProgramming in any context:
9+
commercial or non-commercial, public or private, open or closed source.
10+
11+
Permission is hereby granted, free of charge, to any person obtaining a
12+
copy of this software and associated documentation files (the "Software"),
13+
to deal in the Software without restriction, including without limitation
14+
the rights to use, copy, modify, merge, publish, distribute, sublicense,
15+
and/or sell copies of the Software, and to permit persons to whom the
16+
Software is furnished to do so, subject to the following conditions:
17+
18+
The above copyright notice and this permission notice shall be included
19+
in all copies or substantial portions of the Software.
20+
21+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
22+
OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
23+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
24+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
25+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
26+
FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
27+
DEALINGS IN THE SOFTWARE.
28+
29+
See https://github.com/d3cod3/ofxVisualProgramming for documentation
30+
31+
==============================================================================*/
32+
33+
#if defined(TARGET_WIN32) || defined(TARGET_LINUX)
34+
// Unavailable on windows and linux
35+
#elif !defined(OFXVP_BUILD_WITH_MINIMAL_OBJECTS)
36+
37+
#include "SyphonReceiver.h"
38+
39+
//--------------------------------------------------------------
40+
SyphonReceiver::SyphonReceiver() : PatchObject("syphon receiver"){
41+
42+
this->numInlets = 0;
43+
this->numOutlets = 1;
44+
45+
_outletParams[0] = new ofTexture(); // input
46+
47+
this->initInletsState();
48+
49+
posX = posY = drawW = drawH = 0.0f;
50+
51+
needToGrab = true;
52+
53+
this->setIsTextureObj(true);
54+
55+
}
56+
57+
//--------------------------------------------------------------
58+
void SyphonReceiver::newObject(){
59+
PatchObject::setName( this->objectName );
60+
61+
this->addOutlet(VP_LINK_TEXTURE,"textureReceived");
62+
}
63+
64+
//--------------------------------------------------------------
65+
void SyphonReceiver::setupObjectContent(shared_ptr<ofAppGLFWWindow> &mainWindow){
66+
67+
//setup our directory
68+
dir.setup();
69+
//setup our client
70+
syphonClient.setup();
71+
72+
//register for our directory's callbacks
73+
ofAddListener(dir.events.serverAnnounced, this, &SyphonReceiver::serverAnnounced);
74+
ofAddListener(dir.events.serverRetired, this, &SyphonReceiver::serverRetired);
75+
76+
dirIdx = -1;
77+
78+
}
79+
80+
//--------------------------------------------------------------
81+
void SyphonReceiver::updateObjectContent(map<int,shared_ptr<PatchObject>> &patchObjects){
82+
83+
syphonClient.bind();
84+
syphonTexture = syphonClient.getTexture();
85+
syphonClient.unbind();
86+
87+
if(needToGrab && dir.isValidIndex(dirIdx) && dir.size() > 0 && syphonTexture.isAllocated() && syphonTexture.getWidth() > 0 && syphonTexture.getHeight() > 0){
88+
needToGrab = false;
89+
static_cast<ofTexture *>(_outletParams[0])->allocate(syphonTexture.getWidth(), syphonTexture.getHeight(), GL_RGB );
90+
}
91+
92+
if(static_cast<ofTexture *>(_outletParams[0])->isAllocated() && dir.isValidIndex(dirIdx)){
93+
*static_cast<ofTexture *>(_outletParams[0]) = syphonTexture;
94+
}
95+
96+
}
97+
98+
//--------------------------------------------------------------
99+
void SyphonReceiver::drawObjectContent(ofTrueTypeFont *font, shared_ptr<ofBaseGLRenderer>& glRenderer){
100+
101+
ofSetColor(255);
102+
if(static_cast<ofTexture *>(_outletParams[0])->isAllocated()){
103+
// draw node texture preview with OF
104+
if(scaledObjW*canvasZoom > 90.0f){
105+
drawNodeOFTexture(*static_cast<ofTexture *>(_outletParams[0]), posX, posY, drawW, drawH, objOriginX, objOriginY, scaledObjW, scaledObjH, canvasZoom, this->scaleFactor);
106+
}
107+
}else{
108+
// background
109+
if(scaledObjW*canvasZoom > 90.0f){
110+
ofSetColor(34,34,34);
111+
ofDrawRectangle(objOriginX - (IMGUI_EX_NODE_PINS_WIDTH_NORMAL*this->scaleFactor/canvasZoom), objOriginY-(IMGUI_EX_NODE_HEADER_HEIGHT*this->scaleFactor/canvasZoom),scaledObjW + (IMGUI_EX_NODE_PINS_WIDTH_NORMAL*this->scaleFactor/canvasZoom),scaledObjH + (((IMGUI_EX_NODE_HEADER_HEIGHT+IMGUI_EX_NODE_FOOTER_HEIGHT)*this->scaleFactor)/canvasZoom) );
112+
}
113+
}
114+
}
115+
116+
//--------------------------------------------------------------
117+
void SyphonReceiver::drawObjectNodeGui( ImGuiEx::NodeCanvas& _nodeCanvas ){
118+
119+
// CONFIG GUI inside Menu
120+
if(_nodeCanvas.BeginNodeMenu()){
121+
ImGui::Separator();
122+
ImGui::Separator();
123+
ImGui::Separator();
124+
125+
if (ImGui::BeginMenu("CONFIG"))
126+
{
127+
128+
drawObjectNodeConfig(); this->configMenuWidth = ImGui::GetWindowWidth();
129+
130+
ImGui::EndMenu();
131+
}
132+
_nodeCanvas.EndNodeMenu();
133+
}
134+
135+
136+
// Visualize (Object main view)
137+
if( _nodeCanvas.BeginNodeContent(ImGuiExNodeView_Visualise) ){
138+
139+
// get imgui node translated/scaled position/dimension for drawing textures in OF
140+
objOriginX = (ImGui::GetWindowPos().x + ((IMGUI_EX_NODE_PINS_WIDTH_NORMAL - 1)*this->scaleFactor) - _nodeCanvas.GetCanvasTranslation().x)/_nodeCanvas.GetCanvasScale();
141+
objOriginY = (ImGui::GetWindowPos().y - _nodeCanvas.GetCanvasTranslation().y)/_nodeCanvas.GetCanvasScale();
142+
scaledObjW = this->width - (IMGUI_EX_NODE_PINS_WIDTH_NORMAL*this->scaleFactor/_nodeCanvas.GetCanvasScale());
143+
scaledObjH = this->height - ((IMGUI_EX_NODE_HEADER_HEIGHT+IMGUI_EX_NODE_FOOTER_HEIGHT)*this->scaleFactor/_nodeCanvas.GetCanvasScale());
144+
145+
146+
_nodeCanvas.EndNodeContent();
147+
}
148+
149+
// get imgui canvas zoom
150+
canvasZoom = _nodeCanvas.GetCanvasScale();
151+
152+
}
153+
154+
//--------------------------------------------------------------
155+
void SyphonReceiver::drawObjectNodeConfig(){
156+
ImGuiEx::ObjectInfo(
157+
"Receive (local network) video from the syphon. It will automatically receive the last syphon server published.",
158+
"https://mosaic.d3cod3.org/reference.php?r=syphon-receiver", scaleFactor);
159+
}
160+
161+
//--------------------------------------------------------------
162+
void SyphonReceiver::removeObjectContent(bool removeFileFromData){
163+
164+
}
165+
166+
//--------------------------------------------------------------
167+
void SyphonReceiver::serverAnnounced(ofxSyphonServerDirectoryEventArgs &arg){
168+
for( auto& dir : arg.servers ){
169+
ofLogNotice("ofxSyphonServerDirectory Server Announced")<<" Server Name: "<<dir.serverName <<" | App Name: "<<dir.appName;
170+
syphonClient.setServerName(dir.serverName);
171+
syphonClient.setApplicationName(dir.appName);
172+
}
173+
dirIdx = 0;
174+
}
175+
176+
//--------------------------------------------------------------
177+
void SyphonReceiver::serverRetired(ofxSyphonServerDirectoryEventArgs &arg){
178+
for( auto& dir : arg.servers ){
179+
ofLogNotice("ofxSyphonServerDirectory Server Retired")<<" Server Name: "<<dir.serverName <<" | App Name: "<<dir.appName;
180+
}
181+
dirIdx = 0;
182+
}
183+
184+
OBJECT_REGISTER( SyphonReceiver, "syphon receiver", OFXVP_OBJECT_CAT_TEXTURE)
185+
186+
#endif

0 commit comments

Comments
 (0)