├── .gitignore ├── bin └── data │ ├── config.json │ ├── shaders │ ├── .DS_Store │ ├── invertShader.frag │ ├── internal │ │ ├── cumulativeAdd.frag │ │ └── vertex.vert │ ├── webcam.frag │ ├── textureTest.frag │ ├── hueShader.frag │ ├── rgbRotateShader.frag │ ├── blendShader.frag │ ├── vignetteShader.frag │ ├── feedbackShader.frag │ ├── maskShader.frag │ ├── shaderchain_logo.frag │ ├── mouse_cellular.frag │ ├── moon_mist_noise.frag │ ├── multisample-hueshift.frag │ ├── blurShader.frag │ ├── Noise.frag │ ├── bokehShader.frag │ ├── feedbackAudioShader.frag │ ├── raymarchObjectShader.frag │ ├── 2d_kifs_audio.frag │ ├── terrain_raymarcher.frag │ └── raymarchKifsShader.frag │ ├── textures │ ├── video.mp4 │ └── noise_loop.png │ ├── includes │ ├── hue.glsl │ ├── blending.glsl │ ├── hg_sdfs.glsl │ └── noise.glsl │ └── presets │ ├── mouse_cellular.json │ ├── webcam_rgb_rotate.json │ ├── blendframes.json │ ├── video_test.json │ ├── default.json │ ├── audio2dKifs.json │ ├── terrain_raymarcher.json │ └── Kifs.json ├── README.md ├── src ├── Parameters │ ├── Parameter.cpp │ ├── ColorParameter.h │ ├── AudioFloatParameter.h │ ├── BoolParameter.h │ ├── IntParameter.h │ ├── Vector2Parameter.h │ ├── Vector3Parameter.h │ ├── Vector4Parameter.h │ ├── CameraParameter.h │ ├── FloatParameter.h │ ├── BoolParameter.cpp │ ├── IntParameter.cpp │ ├── ColorParameter.cpp │ ├── Parameter.h │ ├── FloatParameter.cpp │ ├── Vector2Parameter.cpp │ ├── TextureParameter.h │ ├── Vector3Parameter.cpp │ ├── CameraParameter.cpp │ ├── Vector4Parameter.cpp │ ├── AudioFloatParameter.cpp │ └── TextureParameter.cpp ├── RenderStruct.h ├── PassesGui.h ├── main.cpp ├── PassesGui.cpp ├── gui │ ├── MidiMapper.h │ ├── TextureInputSelectionView.h │ ├── ofxGuiTextureInput.h │ ├── TextureInputSelectionView.cpp │ ├── ofxGuiTextureInput.cpp │ └── MidiMapper.cpp ├── ofApp.h ├── FFTManager.h ├── ofApp.cpp ├── PNGRenderer.h ├── ShaderPass.h ├── ShaderChain.h ├── FFTManager.cpp ├── PNGRenderer.cpp └── ShaderPass.cpp ├── addons.make ├── Makefile ├── LICENSE ├── ofShaderChain.qbs └── config.make /.gitignore: -------------------------------------------------------------------------------- 1 | bin/ 2 | obj/ 3 | .DS_Store 4 | -------------------------------------------------------------------------------- /bin/data/config.json: -------------------------------------------------------------------------------- 1 | { 2 | "ffmpeg" : "/usr/local/bin/ffmpeg" 3 | } 4 | 5 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | This project now exists at https://git.sr.ht/~connorbell/ShaderChain 2 | 3 | github supports ICE 4 | -------------------------------------------------------------------------------- /bin/data/shaders/.DS_Store: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/connorbell/ShaderChain/HEAD/bin/data/shaders/.DS_Store -------------------------------------------------------------------------------- /bin/data/textures/video.mp4: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/connorbell/ShaderChain/HEAD/bin/data/textures/video.mp4 -------------------------------------------------------------------------------- /src/Parameters/Parameter.cpp: -------------------------------------------------------------------------------- 1 | #include "Parameter.h" 2 | 3 | Parameter::~Parameter() { 4 | close(); 5 | } 6 | -------------------------------------------------------------------------------- /bin/data/textures/noise_loop.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/connorbell/ShaderChain/HEAD/bin/data/textures/noise_loop.png -------------------------------------------------------------------------------- /addons.make: -------------------------------------------------------------------------------- 1 | ofxFft 2 | ofxGui 3 | ofxJSON 4 | ofxMidi 5 | ofxAutoReloadedShader 6 | ofxGuiExtended2 7 | ofxSortableList2 8 | -------------------------------------------------------------------------------- /bin/data/shaders/invertShader.frag: -------------------------------------------------------------------------------- 1 | #version 150 2 | 3 | uniform sampler2D _MainTexture; 4 | 5 | in vec2 texCoord; 6 | out vec4 outputColor; 7 | 8 | void main() 9 | { 10 | vec4 color = texture(_MainTexture, texCoord); 11 | color.rgb = 1.-color.rgb; 12 | outputColor = color; 13 | } 14 | -------------------------------------------------------------------------------- /bin/data/includes/hue.glsl: -------------------------------------------------------------------------------- 1 | // https://gist.github.com/mairod/a75e7b44f68110e1576d77419d608786#gistcomment-3195243 2 | 3 | vec3 hueShift(vec3 color, float hue) { 4 | const vec3 k = vec3(0.57735, 0.57735, 0.57735); 5 | float cosAngle = cos(hue); 6 | return vec3(color * cosAngle + cross(k, color) * sin(hue) + k * dot(k, color) * (1.0 - cosAngle)); 7 | } 8 | -------------------------------------------------------------------------------- /bin/data/shaders/internal/cumulativeAdd.frag: -------------------------------------------------------------------------------- 1 | #version 150 2 | 3 | uniform sampler2D _CumulativeTexture; 4 | uniform sampler2D _IncomingTexture; 5 | 6 | uniform float factor; 7 | 8 | in vec2 texCoord; 9 | 10 | out vec4 outputColor; 11 | 12 | void main() 13 | { 14 | vec4 c = texture(_CumulativeTexture, (texCoord)); 15 | c.rgb += texture(_IncomingTexture, (texCoord)).rgb * factor; 16 | c.a = 1.0; 17 | outputColor = c; 18 | } 19 | -------------------------------------------------------------------------------- /Makefile: -------------------------------------------------------------------------------- 1 | Name=ShaderChain 2 | # Attempt to load a config.make file. 3 | # If none is found, project defaults in config.project.make will be used. 4 | ifneq ($(wildcard config.make),) 5 | include config.make 6 | endif 7 | 8 | # make sure the the OF_ROOT location is defined 9 | ifndef OF_ROOT 10 | OF_ROOT=$(realpath ../..) 11 | endif 12 | 13 | # call the project makefile! 14 | include $(OF_ROOT)/libs/openFrameworksCompiled/project/makefileCommon/compile.project.mk 15 | -------------------------------------------------------------------------------- /src/RenderStruct.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | class FFTManager; 4 | class ShaderPass; 5 | 6 | struct RenderStruct { 7 | float time; 8 | int frame; 9 | int numBlendFrames; 10 | FFTManager *fft; 11 | ofVideoGrabber *vidGrabber; 12 | std::vector *passes; 13 | bool isOfflineRendering = false; 14 | ofFbo *lastBuffer; // This is updated throughout the render process for each pass. Probably don't use this. 15 | glm::vec2 mousePosition; 16 | }; 17 | -------------------------------------------------------------------------------- /src/PassesGui.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | #include "ShaderPass.h" 5 | #include "ofxGuiExtended2.h" 6 | #include "ofxSortableList.h" 7 | 8 | class PassesGui { 9 | public: 10 | 11 | PassesGui(); 12 | ~PassesGui(); 13 | 14 | ofxSortableList *passButtons; 15 | ofxGuiButton addPassButton; 16 | 17 | void Setup(std::vector *passes); 18 | ofxGuiContainer *panel; 19 | 20 | private: 21 | ofxGui gui; 22 | std::vector *passes; 23 | }; 24 | -------------------------------------------------------------------------------- /bin/data/shaders/webcam.frag: -------------------------------------------------------------------------------- 1 | /* 2 | { 3 | "parameters" : [ 4 | { 5 | "name" : "webcamTex", 6 | "show" : true, 7 | "type" : "texture", 8 | "textureIndex" : 2, 9 | "textype": "Webcam" 10 | } 11 | ] 12 | } 13 | */ 14 | #version 150 15 | 16 | uniform sampler2D _MainTexture; 17 | uniform vec2 _Resolution; 18 | 19 | uniform sampler2D webcamTex; 20 | 21 | in vec2 texCoord; 22 | out vec4 outputColor; 23 | 24 | void main() 25 | { 26 | vec4 c = texture(webcamTex,texCoord); 27 | outputColor = c; 28 | } 29 | -------------------------------------------------------------------------------- /src/main.cpp: -------------------------------------------------------------------------------- 1 | #include "ofMain.h" 2 | #include "ofApp.h" 3 | 4 | 5 | //======================================================================== 6 | int main( ){ 7 | 8 | #ifdef OF_TARGET_OPENGLES 9 | ofGLESWindowSettings settings; 10 | settings.glesVersion=2; 11 | #else 12 | ofGLWindowSettings settings; 13 | settings.setGLVersion(3,2); 14 | #endif 15 | ofCreateWindow(settings); 16 | 17 | // this kicks off the running of my app 18 | // can be OF_WINDOW or OF_FULLSCREEN 19 | // pass in width and height too: 20 | ofRunApp(new ofApp()); 21 | 22 | } 23 | -------------------------------------------------------------------------------- /src/Parameters/ColorParameter.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include 3 | 4 | #include "Parameter.h" 5 | 6 | class ColorParameter : public Parameter { 7 | public: 8 | ofParameter value; 9 | int *midi; 10 | 11 | ColorParameter(std::string uniform, float r, float g, float b, float a, bool show, int *midi); 12 | virtual void UpdateShader(ofxAutoReloadedShader *shader, RenderStruct *renderStruct) override; 13 | virtual void AddToGui(ofxGuiGroup2 *gui) override; 14 | virtual void UpdateJson(Json::Value &val) override; 15 | virtual void UpdateMidi(int index, float val) override; 16 | }; 17 | -------------------------------------------------------------------------------- /src/PassesGui.cpp: -------------------------------------------------------------------------------- 1 | #include "PassesGui.h" 2 | 3 | PassesGui::PassesGui() { 4 | this->panel = gui.addContainer(); 5 | passButtons = panel->add("Passes"); 6 | this->panel->setPosition(ofPoint(0, 210)); 7 | } 8 | 9 | PassesGui::~PassesGui() { 10 | 11 | } 12 | 13 | void PassesGui::Setup(std::vector *passes) { 14 | passButtons->clear(); 15 | this->passes = passes; 16 | for (int i = 0; i < passes->size(); i++) { 17 | ofParameter text; 18 | text.set(passes->at(i)->displayName); 19 | passButtons->add(text); 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /bin/data/shaders/textureTest.frag: -------------------------------------------------------------------------------- 1 | /* 2 | { 3 | "parameters" : [ 4 | { 5 | "name" : "inputTex", 6 | "show" : true, 7 | "type" : "texture", 8 | "filePath" : "textures/noise_loop.jpg", 9 | "textureIndex" : 2 10 | } 11 | ] 12 | } 13 | */ 14 | #version 150 15 | 16 | uniform sampler2D _MainTexture; 17 | uniform vec2 _Resolution; 18 | 19 | uniform sampler2D inputTex; 20 | 21 | in vec2 texCoord; 22 | 23 | out vec4 outputColor; 24 | 25 | void main() 26 | { 27 | vec4 c = texture(inputTex, texCoord); 28 | c.rgb = mix(texture(_MainTexture, texCoord).rgb, c.rgb, 1.); 29 | outputColor = c; 30 | } 31 | -------------------------------------------------------------------------------- /src/Parameters/AudioFloatParameter.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include 3 | 4 | #include "Parameter.h" 5 | #include "FloatParameter.h" 6 | 7 | class AudioFloatParameter : public FloatParameter { 8 | public: 9 | glm::vec2 frequencyRange; 10 | float scaleFactor; 11 | float expFactor; 12 | bool accumulate; 13 | 14 | AudioFloatParameter(std::string uniform, float currentValue, glm::vec2 range, glm::vec2 frequencyRange, float scaleFactor, float expFactor, bool accumulate, bool show, int midi); 15 | void UpdateShader(ofxAutoReloadedShader *shader, RenderStruct *renderStruct); 16 | void UpdateJson(Json::Value &val); 17 | }; 18 | -------------------------------------------------------------------------------- /bin/data/shaders/internal/vertex.vert: -------------------------------------------------------------------------------- 1 | #version 150 2 | 3 | // these are for the programmable pipeline system 4 | uniform mat4 modelViewProjectionMatrix; 5 | uniform mat4 textureMatrix; 6 | 7 | in vec4 position; 8 | in vec2 texcoord; 9 | in vec4 normal; 10 | in vec4 color; 11 | 12 | out vec2 texCoord; 13 | out vec2 uv; 14 | 15 | void main() 16 | { 17 | #ifdef INTEL_CARD 18 | color = vec4(1.0); // for intel HD cards 19 | normal = vec4(1.0); // for intel HD cards 20 | #endif 21 | 22 | uv = texcoord; 23 | texCoord = texcoord; 24 | uv.y = 1. - uv.y; 25 | 26 | gl_Position = modelViewProjectionMatrix * position; 27 | } 28 | -------------------------------------------------------------------------------- /src/Parameters/BoolParameter.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include 3 | 4 | #include "Parameter.h" 5 | 6 | class BoolParameter : public Parameter { 7 | public: 8 | ofParameter value; 9 | glm::vec2 range; 10 | int midiIndex; 11 | 12 | BoolParameter(std::string uniform, bool currentValue, bool show, int midi); 13 | virtual void UpdateShader(ofxAutoReloadedShader *shader, RenderStruct *renderStruct) override; 14 | virtual void AddToGui(ofxGuiGroup2 *gui) override; 15 | virtual void UpdateJson(Json::Value &val) override; 16 | virtual void UpdateMidi(int index, float value) override; 17 | virtual void BindMidi(int midiIndices[]) override; 18 | }; 19 | -------------------------------------------------------------------------------- /src/Parameters/IntParameter.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include 3 | 4 | #include "Parameter.h" 5 | 6 | class IntParameter : public Parameter { 7 | public: 8 | ofParameter value; 9 | glm::vec2 range; 10 | int midiIndex; 11 | 12 | IntParameter(std::string uniform, int currentValue, glm::vec2 range, bool show, int midi); 13 | virtual void UpdateShader(ofxAutoReloadedShader *shader, RenderStruct *renderStruct) override; 14 | virtual void AddToGui(ofxGuiGroup2 *gui) override; 15 | virtual void UpdateJson(Json::Value &val) override; 16 | virtual void UpdateMidi(int index, float value) override; 17 | virtual void BindMidi(int midiIndices[]) override; 18 | }; 19 | -------------------------------------------------------------------------------- /src/gui/MidiMapper.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include "ofxGuiExtended2.h" 3 | class RenderStruct; 4 | 5 | class MidiMapper { 6 | 7 | public: 8 | void show(ofxGui *gui, RenderStruct *renderData); 9 | ofxGuiContainer *container = nullptr; 10 | bool isShowing = false; 11 | void midiSet(int val); 12 | 13 | private: 14 | ofParameter cancelButton; 15 | ofParameter statusLabel; 16 | void cancelButtonPressed(); 17 | std::vector midiButtons; 18 | void midiButtonPressed(); 19 | RenderStruct *renderStruct; 20 | string targetUniform = ""; 21 | int targetIndex = -1; 22 | int subUniform = -1; 23 | 24 | int indexFromSub(string s); 25 | }; 26 | -------------------------------------------------------------------------------- /src/Parameters/Vector2Parameter.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include 3 | 4 | #include "Parameter.h" 5 | 6 | class Vector2Parameter : public Parameter { 7 | public: 8 | ofParameter value; 9 | glm::vec2 range; 10 | int *midi; 11 | 12 | Vector2Parameter(std::string uniform, ofVec2f defaultVal, bool show, glm::vec2 range, int *midi); 13 | virtual void UpdateShader(ofxAutoReloadedShader *shader, RenderStruct *renderStruct) override; 14 | virtual void AddToGui(ofxGuiGroup2 *gui) override; 15 | virtual void UpdateJson(Json::Value &val) override; 16 | virtual void UpdateMidi(int index, float val) override; 17 | virtual void bindMidi(int midiIndex, int subParamIndex) override; 18 | }; 19 | -------------------------------------------------------------------------------- /src/Parameters/Vector3Parameter.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include 3 | 4 | #include "Parameter.h" 5 | 6 | class Vector3Parameter : public Parameter { 7 | public: 8 | ofParameter value; 9 | glm::vec2 range; 10 | int *midi; 11 | 12 | Vector3Parameter(std::string uniform, ofVec3f defaultVal, bool show, glm::vec2 range, int *midi); 13 | virtual void UpdateShader(ofxAutoReloadedShader *shader, RenderStruct *renderStruct) override; 14 | virtual void AddToGui(ofxGuiGroup2 *gui) override; 15 | virtual void UpdateJson(Json::Value &val) override; 16 | virtual void UpdateMidi(int index, float val) override; 17 | virtual void bindMidi(int midiIndex, int subParamIndex) override; 18 | }; 19 | -------------------------------------------------------------------------------- /src/Parameters/Vector4Parameter.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include 3 | 4 | #include "Parameter.h" 5 | 6 | class Vector4Parameter : public Parameter { 7 | public: 8 | ofParameter value; 9 | glm::vec2 range; 10 | int *midi; 11 | 12 | Vector4Parameter(std::string uniform, ofVec3f defaultVal, bool show, glm::vec2 range, int *midi); 13 | virtual void UpdateShader(ofxAutoReloadedShader *shader, RenderStruct *renderStruct) override; 14 | virtual void AddToGui(ofxGuiGroup2 *gui) override; 15 | virtual void UpdateJson(Json::Value &val) override; 16 | virtual void UpdateMidi(int index, float val) override; 17 | virtual void bindMidi(int midiIndex, int subParamIndex) override; 18 | }; 19 | -------------------------------------------------------------------------------- /bin/data/shaders/hueShader.frag: -------------------------------------------------------------------------------- 1 | /* 2 | { 3 | "wantsLastBuffer" : true, 4 | 5 | "parameters" : [ 6 | { 7 | "name" : "shift", 8 | "range" : { 9 | "x" : 0, 10 | "y" : 6.28318 11 | }, 12 | "show" : true, 13 | "type" : "float", 14 | "value" : 1.0 15 | } 16 | ] 17 | } 18 | */ 19 | 20 | #version 150 21 | #pragma include "includes/hue.glsl" 22 | 23 | uniform sampler2D _MainTexture; 24 | uniform vec2 _Resolution; 25 | 26 | uniform float shift; 27 | 28 | in vec2 texCoord; 29 | out vec4 outputColor; 30 | 31 | void main() 32 | { 33 | vec4 c = texture(_MainTexture, texCoord); 34 | c.rgb = hueShift(c.rgb, shift); 35 | outputColor = c; 36 | } 37 | -------------------------------------------------------------------------------- /src/ofApp.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "ofMain.h" 4 | #include "ShaderChain.h" 5 | #include "ShaderPass.h" 6 | 7 | class ofApp : public ofBaseApp{ 8 | public: 9 | ofApp(); 10 | ~ofApp(); 11 | float resolutionX = 500; 12 | float resolutionY = 500; 13 | ShaderChain shaderChain; 14 | 15 | void keyPressed(int key); 16 | void keyReleased(int key); 17 | void mouseMoved(int x, int y); 18 | void mouseDragged(int x, int y, int button); 19 | void mousePressed(int x, int y, int button); 20 | void mouseReleased(int x, int y, int button); 21 | void windowResized(int w, int h); 22 | void dragEvent(ofDragInfo dragInfo); 23 | void gotMessage(ofMessage msg); 24 | void setup(); 25 | void update(); 26 | void draw(); 27 | }; 28 | -------------------------------------------------------------------------------- /src/Parameters/CameraParameter.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include 3 | 4 | #include "Parameter.h" 5 | 6 | class CameraParameter : public Parameter { 7 | 8 | public: 9 | 10 | CameraParameter(glm::vec3 pos, glm::vec3 rot); 11 | ~CameraParameter(); 12 | ofParameter position; 13 | ofVec3f left; 14 | ofVec3f right; 15 | ofVec3f up; 16 | virtual void UpdateShader(ofxAutoReloadedShader *shader, RenderStruct *renderStruct) override; 17 | virtual void AddToGui(ofxGuiGroup2 *gui) override; 18 | virtual void UpdateJson(Json::Value &val) override; 19 | 20 | 21 | void keyPressed(int key); 22 | void keyReleased(int key); 23 | 24 | private: 25 | ofNode camera; 26 | float mouseMoveSpeed = 6.0; 27 | 28 | 29 | }; 30 | -------------------------------------------------------------------------------- /src/Parameters/FloatParameter.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include 3 | 4 | #include "Parameter.h" 5 | 6 | class FloatParameter : public Parameter { 7 | public: 8 | ofParameter value; 9 | glm::vec2 range; 10 | int midiIndex; 11 | 12 | FloatParameter(std::string uniform, float currentValue, glm::vec2 range, bool show, int midi); 13 | virtual void UpdateShader(ofxAutoReloadedShader *shader, RenderStruct *renderStruct) override; 14 | virtual void AddToGui(ofxGuiGroup2 *gui) override; 15 | virtual void UpdateJson(Json::Value &val) override; 16 | virtual void UpdateMidi(int index, float value) override; 17 | virtual void BindMidi(int midiIndices[]) override; 18 | virtual void bindMidi(int index, int subParamIndex) override; 19 | virtual Json::Value getDict() override; 20 | }; 21 | -------------------------------------------------------------------------------- /bin/data/shaders/rgbRotateShader.frag: -------------------------------------------------------------------------------- 1 | /* 2 | { 3 | "parameters" : [ 4 | { 5 | "name" : "colMult", 6 | "range" : { 7 | "x" : 0, 8 | "y" : 20 9 | }, 10 | "show" : true, 11 | "type" : "vec3", 12 | "value" : { 13 | "x" : 2.5, 14 | "y" : 5.0, 15 | "z" : 10.0 16 | } 17 | }, 18 | { 19 | "name" : "phase", 20 | "range" : { 21 | "x" : 0, 22 | "y" : 20 23 | }, 24 | "show" : true, 25 | "type" : "float", 26 | "value" : 0.5 27 | } 28 | ] 29 | } 30 | */ 31 | 32 | #version 150 33 | 34 | uniform sampler2D _MainTexture; 35 | uniform vec3 colMult; 36 | uniform float phase; 37 | 38 | in vec2 uv; 39 | in vec2 texCoord; 40 | 41 | out vec4 outputColor; 42 | 43 | void main() 44 | { 45 | vec4 color = texture(_MainTexture, texCoord); 46 | color.a = 1.0; 47 | color.rgb = sin(color.rgb * colMult + phase) * 0.5 + 0.5; 48 | outputColor = color; 49 | } 50 | -------------------------------------------------------------------------------- /bin/data/presets/mouse_cellular.json: -------------------------------------------------------------------------------- 1 | { 2 | "blend" : 1, 3 | "data" : [ 4 | { 5 | "parameters" : [ 6 | { 7 | "name" : "periods", 8 | "range" : { 9 | "x" : 1, 10 | "y" : 15 11 | }, 12 | "show" : true, 13 | "type" : "float", 14 | "value" : 11.1195650100708 15 | }, 16 | { 17 | "name" : "hueAmp", 18 | "range" : { 19 | "x" : 1, 20 | "y" : 15 21 | }, 22 | "show" : true, 23 | "type" : "float", 24 | "value" : 5.793478488922119 25 | } 26 | ], 27 | "shaderName" : "shaders/mouse_cellular" 28 | } 29 | ], 30 | "duration" : 6.283180236816406, 31 | "fps" : 30, 32 | "res" : { 33 | "x" : 1920, 34 | "y" : 1080 35 | }, 36 | "scale" : 0.635937511920929 37 | } 38 | 39 | -------------------------------------------------------------------------------- /bin/data/shaders/blendShader.frag: -------------------------------------------------------------------------------- 1 | /* 2 | { 3 | "parameters" : [ 4 | { 5 | "name" : "blendTex", 6 | "show" : true, 7 | "type" : "texture", 8 | "textureIndex" : 1 9 | } 10 | ] 11 | } 12 | */ 13 | #version 150 14 | 15 | uniform sampler2D _MainTexture; 16 | uniform vec2 _Resolution; 17 | 18 | uniform sampler2D blendTex; 19 | uniform vec2 blendTex_res; 20 | 21 | in vec2 uv; 22 | in vec2 texCoord; 23 | out vec4 outputColor; 24 | 25 | float blendSoftLight(float base, float blend) { 26 | return (blend<0.5)?(2.0*base*blend+base*base*(1.0-2.0*blend)):(sqrt(base)*(2.0*blend-1.0)+2.0*base*(1.0-blend)); 27 | } 28 | 29 | vec3 blendSoftLight(vec3 base, vec3 blend) { 30 | return vec3(blendSoftLight(base.r,blend.r),blendSoftLight(base.g,blend.g),blendSoftLight(base.b,blend.b)); 31 | } 32 | 33 | void main() 34 | { 35 | vec4 mainCol = texture(_MainTexture, texCoord); 36 | vec4 blendCol = texture(blendTex, texCoord); 37 | 38 | outputColor = vec4(blendSoftLight(mainCol.rgb, blendCol.rgb), 1.0); 39 | } 40 | -------------------------------------------------------------------------------- /bin/data/shaders/vignetteShader.frag: -------------------------------------------------------------------------------- 1 | /* 2 | { 3 | "parameters" : [ 4 | { 5 | "name" : "strength", 6 | "range" : { 7 | "x" : 0, 8 | "y" : 1 9 | }, 10 | "show" : true, 11 | "type" : "float", 12 | "value" : 0.6326530575752258 13 | }, 14 | { 15 | "name" : "power", 16 | "range" : { 17 | "x" : 0, 18 | "y" : 1 19 | }, 20 | "show" : true, 21 | "type" : "float", 22 | "value" : 0.5 23 | } 24 | ] 25 | } 26 | */ 27 | #version 150 28 | 29 | uniform sampler2D _MainTexture; 30 | uniform vec2 _Resolution; 31 | 32 | uniform float strength; 33 | uniform float power; 34 | 35 | in vec2 uv; 36 | in vec2 texCoord; 37 | 38 | out vec4 outputColor; 39 | 40 | void main() 41 | { 42 | vec2 uv_c = uv * 2. - 1.; 43 | vec4 c = texture(_MainTexture, texCoord); 44 | vec4 col = vec4(pow(c.rgb, vec3(power)), 1.0); 45 | 46 | outputColor = mix(vec4(.0,0.,0.,1.0), col, clamp(1. - smoothstep(0.,1., length(uv_c) * strength),0., 1.)); 47 | } 48 | -------------------------------------------------------------------------------- /src/Parameters/BoolParameter.cpp: -------------------------------------------------------------------------------- 1 | #include "BoolParameter.h" 2 | 3 | BoolParameter::BoolParameter(std::string uniform, bool currentValue, bool show, int midi) { 4 | this->uniform = uniform; 5 | this->value = currentValue; 6 | this->range = range; 7 | this->show = show; 8 | this->midiIndex = midi; 9 | } 10 | 11 | void BoolParameter::UpdateShader(ofxAutoReloadedShader *shader, RenderStruct *renderStruct) { 12 | shader->setUniform1f(this->uniform, this->value ? 1 : 0); 13 | } 14 | 15 | void BoolParameter::AddToGui(ofxGuiGroup2 *gui) { 16 | if (this->show) { 17 | gui->add(value.set(this->uniform,this->value)); 18 | } 19 | } 20 | 21 | void BoolParameter::UpdateJson(Json::Value &val) { 22 | val["value"] = (bool)this->value; 23 | val["show"] = this->show; 24 | val["type"] = "bool"; 25 | } 26 | 27 | void BoolParameter::UpdateMidi(int index, float value) { 28 | if (this->midiIndex == index) { 29 | //this->value = ofLerp(this->range.x, this->range.y, value/127.0); 30 | } 31 | } 32 | 33 | void BoolParameter::BindMidi(int midiIndices[]) { 34 | this->midiIndex = midiIndices[0]; 35 | } 36 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2020 Connor Bell 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /src/Parameters/IntParameter.cpp: -------------------------------------------------------------------------------- 1 | #include "IntParameter.h" 2 | 3 | IntParameter::IntParameter(std::string uniform, int currentValue, glm::vec2 range, bool show, int midi) { 4 | this->uniform = uniform; 5 | this->value = currentValue; 6 | this->range = range; 7 | this->show = show; 8 | this->midiIndex = midi; 9 | } 10 | 11 | void IntParameter::UpdateShader(ofxAutoReloadedShader *shader, RenderStruct *renderStruct) { 12 | shader->setUniform1f(this->uniform, this->value); 13 | } 14 | 15 | void IntParameter::AddToGui(ofxGuiGroup2 *gui) { 16 | if (this->show) { 17 | gui->add(value.set(this->uniform,this->value,(int)this->range.x,(int)this->range.y)); 18 | } 19 | } 20 | 21 | void IntParameter::UpdateJson(Json::Value &val) { 22 | val["value"] = (int)this->value; 23 | val["show"] = this->show; 24 | val["type"] = "int"; 25 | val["range"]["x"] = this->range.x; 26 | val["range"]["y"] = this->range.y; 27 | } 28 | 29 | void IntParameter::UpdateMidi(int index, float value) { 30 | if (this->midiIndex == index) { 31 | //this->value = ofLerp(this->range.x, this->range.y, value/127.0); 32 | } 33 | } 34 | 35 | void IntParameter::BindMidi(int midiIndices[]) { 36 | this->midiIndex = midiIndices[0]; 37 | } 38 | -------------------------------------------------------------------------------- /src/gui/TextureInputSelectionView.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include 3 | #include "ofMain.h" 4 | #include "ofxGuiExtended2.h" 5 | 6 | class TextureInputSelectionView { 7 | 8 | public: 9 | ofxGui gui; 10 | ofxGuiContainer *panel; 11 | 12 | ofParameter openFromFileButton; 13 | ofParameter openFromAudioButton; 14 | ofParameter openFromWebcamButton; 15 | ofParameter cancelButton; 16 | 17 | vector bufferButtons; 18 | vector*> bufferParameters; 19 | vector passNames; 20 | 21 | ofEvent selectedFilePathChanged; 22 | ofEvent wantsWebcamChanged; 23 | ofEvent wantsAudioChanged; 24 | ofEvent selectedBufferChanged; 25 | 26 | ofEvent hideEvent; 27 | 28 | string selectedFilePath; 29 | bool isShowingFileDialogue = false; 30 | 31 | TextureInputSelectionView(); 32 | ~TextureInputSelectionView(); 33 | void show(); 34 | void hide(); 35 | void deleteParams(); 36 | 37 | void updateWebcam(bool val); 38 | void openFromFileButtonPressed(); 39 | void openFromWebcamButtonPressed(); 40 | void openFromBufferPressed(); 41 | void bufferButtonPressed(); 42 | void cancelButtonPressed(); 43 | void audioButtonPressed(); 44 | void updateAudio(bool val); 45 | }; 46 | -------------------------------------------------------------------------------- /src/Parameters/ColorParameter.cpp: -------------------------------------------------------------------------------- 1 | #include "ColorParameter.h" 2 | 3 | ColorParameter::ColorParameter(std::string uniform, float r, float g, float b, float a, bool show, int *midi) { 4 | this->uniform = uniform; 5 | this->value = ofColor(r, g, b, a); 6 | this->show = show; 7 | this->midi = new int[4]; 8 | this->midi[0] = midi[0]; 9 | this->midi[1] = midi[1]; 10 | this->midi[2] = midi[2]; 11 | this->midi[3] = midi[3]; 12 | } 13 | 14 | void ColorParameter::UpdateShader(ofxAutoReloadedShader *shader, RenderStruct *renderStruct) { 15 | shader->setUniform4f(this->uniform, (float)this->value->r/255.0, (float)this->value->g/255.0, (float)this->value->b/255.0, (float)this->value->a/255.0); 16 | } 17 | 18 | void ColorParameter::AddToGui(ofxGuiGroup2 *gui) { 19 | if (this->show) { 20 | gui->add(value.set(uniform, value, ofColor(0,0),ofColor(255,255))); 21 | } 22 | } 23 | 24 | void ColorParameter::UpdateJson(Json::Value &val) { 25 | val["value"]["r"] = this->value->r; 26 | val["value"]["g"] = this->value->g; 27 | val["value"]["b"] = this->value->b; 28 | val["value"]["a"] = this->value->a; 29 | val["show"] = this->show; 30 | val["type"] = "color"; 31 | } 32 | 33 | void ColorParameter::UpdateMidi(int index, float val) { 34 | if (this->midi[0] == index) { 35 | 36 | } else if (this->midi[1] == index) { 37 | 38 | } else if (this->midi[2] == index) { 39 | 40 | } 41 | } 42 | -------------------------------------------------------------------------------- /bin/data/shaders/feedbackShader.frag: -------------------------------------------------------------------------------- 1 | /* 2 | { 3 | "parameters" : [ 4 | { 5 | "name" : "intensity", 6 | "range" : { 7 | "x" : 0, 8 | "y" : 1 9 | }, 10 | "show" : true, 11 | "type" : "float", 12 | "value" : 0.75 13 | }, 14 | { 15 | "name" : "scale", 16 | "range" : { 17 | "x" : 0, 18 | "y" : 2 19 | }, 20 | "show" : true, 21 | "type" : "float", 22 | "value" : 1.0 23 | }, 24 | { 25 | "name" : "lastTex", 26 | "show" : true, 27 | "type" : "texture", 28 | "textype" : "Last", 29 | "textureIndex" : 2 30 | } 31 | ] 32 | } 33 | */ 34 | 35 | #version 150 36 | 37 | uniform sampler2D _MainTexture; 38 | uniform sampler2D lastTex; 39 | uniform float intensity; 40 | uniform float scale; 41 | uniform float _Time; 42 | uniform vec2 _Resolution; 43 | 44 | in vec2 texCoord; 45 | out vec4 outputColor; 46 | 47 | void pR(inout vec2 p, float a) { 48 | p = cos(a)*p + sin(a)*vec2(p.y, -p.x); 49 | } 50 | 51 | void main() 52 | { 53 | vec4 color = texture(_MainTexture, texCoord); 54 | 55 | vec2 uv = texCoord; 56 | 57 | uv = (uv - 0.5) * scale + 0.5; 58 | 59 | vec4 lastColor = texture(lastTex, uv); 60 | color.rgb += lastColor.rgb * intensity; // * (1. + audio*.4); 61 | outputColor = clamp(vec4(color), vec4(0.0), vec4(1.0)); 62 | } 63 | -------------------------------------------------------------------------------- /src/FFTManager.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "ofxEasyFft.h" 4 | #include "ofxGuiExtended2.h" 5 | 6 | typedef enum { 7 | InputStateNone, 8 | InputStateMicInput, 9 | InputStateSoundFile 10 | } InputState; 11 | 12 | class FFTManager { 13 | public: 14 | FFTManager(); 15 | ~FFTManager(); 16 | 17 | int numSamples = 512; 18 | 19 | ofxEasyFft *fft; 20 | ofTexture audioTexture; 21 | unsigned char lastBuffer[1024]; 22 | ofSoundPlayer soundPlayer; 23 | InputState currentState = InputStateNone; 24 | string soundFilePath; 25 | 26 | ofParameterGroup parameterGroup; 27 | ofParameter playingState; 28 | ofParameter volume; 29 | ofParameter isMicrophoneEnabled; 30 | ofParameter dampening; 31 | ofParameter removeTrackButton; 32 | 33 | void Stop(); 34 | void Update(); 35 | void StartMicInput(); 36 | void loadSoundFile(string filePath); 37 | void UpdateShader(ofShader *shader, int textureIndex); 38 | void setPaused(bool val); 39 | void setTime(float time); 40 | void resetSongIfPlaying(); 41 | void addToGui(ofxGuiContainer *container); 42 | 43 | private: 44 | bool isPaused = true; 45 | float soundFileDuration = 0.0; 46 | ofxGuiMenu* audioMenu = nullptr; 47 | 48 | void micToggled(bool &val); 49 | void volumeToggled(float &val); 50 | void stopMicInput(); 51 | void removeAudioTrack(); 52 | void reloadAudioMenu(); 53 | ofxGuiButton *removeTrackGuiButton; 54 | }; 55 | -------------------------------------------------------------------------------- /bin/data/presets/webcam_rgb_rotate.json: -------------------------------------------------------------------------------- 1 | { 2 | "blend" : 1, 3 | "data" : [ 4 | { 5 | "parameters" : [ 6 | { 7 | "filePath" : "", 8 | "name" : "webcamTex", 9 | "show" : true, 10 | "targetBufferName" : "", 11 | "textureIndex" : 2, 12 | "textype" : "Webcam", 13 | "type" : "texture" 14 | } 15 | ], 16 | "shaderName" : "shaders/webcam" 17 | }, 18 | { 19 | "parameters" : [ 20 | { 21 | "name" : "colMult", 22 | "range" : { 23 | "x" : 0, 24 | "y" : 20 25 | }, 26 | "show" : true, 27 | "type" : "vec3", 28 | "value" : { 29 | "x" : 10.1136360168457, 30 | "y" : 14.20454502105713, 31 | "z" : 12.95454502105713 32 | } 33 | }, 34 | { 35 | "name" : "phase", 36 | "range" : { 37 | "x" : 0, 38 | "y" : 20 39 | }, 40 | "show" : true, 41 | "type" : "float", 42 | "value" : 0 43 | } 44 | ], 45 | "shaderName" : "shaders/rgbRotateShader" 46 | } 47 | ], 48 | "duration" : 6.283180236816406, 49 | "fps" : 30, 50 | "res" : { 51 | "x" : 640, 52 | "y" : 480 53 | }, 54 | "scale" : 1.299479246139526 55 | } 56 | -------------------------------------------------------------------------------- /src/Parameters/Parameter.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include 3 | 4 | #include "ofMain.h" 5 | #include "ofxGuiExtended2.h" 6 | #include "ofxAutoReloadedShader.h" 7 | #include "ofxJSON.h" 8 | #include "TextureInputSelectionView.h" 9 | #include "RenderStruct.h" 10 | 11 | typedef enum { 12 | ImageFile, 13 | VideoFile, 14 | Buffer, 15 | Webcam, 16 | Last, 17 | Audio, 18 | None 19 | } TextureSourceType; 20 | 21 | class ShaderPass; 22 | 23 | class Parameter { 24 | public: 25 | 26 | ~Parameter(); 27 | std::string uniform; 28 | bool show; 29 | TextureInputSelectionView *selectionView; 30 | string parentBufferName; 31 | string type = ""; 32 | 33 | virtual void UpdateShader(ofxAutoReloadedShader *shader, RenderStruct *renderStruct) {} 34 | virtual void AddToGui(ofxGuiGroup2 *gui) {} 35 | virtual void UpdateJson(Json::Value &val) {} 36 | virtual void UpdateMidi(int midiIndex, float value) {} 37 | virtual void BindMidi(int midiIndices[]) {} 38 | virtual void bindMidi(int midiIndex, int subParamIndex) {} 39 | virtual void update(RenderStruct *renderStruct) {} 40 | virtual void startOfflineRender() {} 41 | virtual void stopOfflineRender() {} 42 | virtual bool isMouseHoveredOver() { return false; } 43 | virtual void handleInputFile(string s) {} 44 | virtual TextureSourceType getTextureSourceType() { return None; } 45 | virtual void playbackDidToggleState(bool isPaused) {} 46 | virtual void close() {}; 47 | virtual Json::Value getDict() { return Json::Value(); }; 48 | }; 49 | -------------------------------------------------------------------------------- /bin/data/includes/blending.glsl: -------------------------------------------------------------------------------- 1 | /* 2 | 3 | The MIT License (MIT) Copyright (c) 2015 Jamie Owen 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: 6 | 7 | The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. 8 | 9 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 10 | 11 | */ 12 | 13 | vec3 blendOverlay(vec3 base, vec3 blend) { 14 | return vec3(blendOverlay(base.r,blend.r),blendOverlay(base.g,blend.g),blendOverlay(base.b,blend.b)); 15 | } 16 | 17 | vec3 blendHardLight(vec3 base, vec3 blend) { 18 | return blendOverlay(blend,base); 19 | } 20 | 21 | vec3 blendSoftLight(vec3 base, vec3 blend) { 22 | return vec3(blendSoftLight(base.r,blend.r),blendSoftLight(base.g,blend.g),blendSoftLight(base.b,blend.b)); 23 | } 24 | -------------------------------------------------------------------------------- /bin/data/presets/blendframes.json: -------------------------------------------------------------------------------- 1 | { 2 | "blend" : 111, 3 | "data" : [ 4 | { 5 | "parameters" : [ 6 | { 7 | "name" : "focalLength", 8 | "range" : { 9 | "x" : 0, 10 | "y" : 10 11 | }, 12 | "show" : true, 13 | "type" : "float", 14 | "value" : 1.14130437374115 15 | }, 16 | { 17 | "name" : "minDist", 18 | "range" : { 19 | "x" : 0, 20 | "y" : 0.1000000014901161 21 | }, 22 | "show" : false, 23 | "type" : "float", 24 | "value" : 0.001000000047497451 25 | }, 26 | { 27 | "name" : "maxDist", 28 | "range" : { 29 | "x" : 0, 30 | "y" : 15 31 | }, 32 | "show" : true, 33 | "type" : "float", 34 | "value" : 12.30978298187256 35 | }, 36 | { 37 | "name" : "bgColor", 38 | "show" : true, 39 | "type" : "color", 40 | "value" : { 41 | "a" : 0, 42 | "b" : 255, 43 | "g" : 255, 44 | "r" : 255 45 | } 46 | } 47 | ], 48 | "shaderName" : "shaders/raymarchObjectShader" 49 | } 50 | ], 51 | "duration" : 6.283180236816406, 52 | "fps" : 30, 53 | "res" : { 54 | "x" : 500, 55 | "y" : 500 56 | }, 57 | "scale" : 1 58 | } 59 | -------------------------------------------------------------------------------- /bin/data/shaders/maskShader.frag: -------------------------------------------------------------------------------- 1 | /* 2 | { 3 | "parameters" : [ 4 | { 5 | "name" : "blendTex", 6 | "show" : true, 7 | "type" : "texture", 8 | "textureIndex" : 1 9 | }, 10 | { 11 | "name" : "maskTex", 12 | "show" : true, 13 | "type" : "texture", 14 | "textureIndex" : 2 15 | }, 16 | { 17 | "name" : "targetMaskCol", 18 | "show" : true, 19 | "type" : "color", 20 | "value" : { 21 | "r" : 0, 22 | "g" : 0, 23 | "b" : 0, 24 | "a" : 1 25 | } 26 | }, 27 | { 28 | "name" : "tolerance", 29 | "range" : { 30 | "x" : 0, 31 | "y" : 1 32 | }, 33 | "show" : true, 34 | "type" : "float", 35 | "value" : 1.0 36 | }, 37 | { 38 | "name" : "invert", 39 | "show" : true, 40 | "type" : "bool", 41 | "value" : false 42 | } 43 | ] 44 | } 45 | */ 46 | #version 150 47 | 48 | uniform sampler2D _MainTexture; 49 | uniform vec2 _Resolution; 50 | 51 | uniform sampler2D blendTex; 52 | 53 | uniform sampler2D maskTex; 54 | 55 | uniform vec4 targetMaskCol; 56 | 57 | uniform float tolerance; 58 | 59 | uniform bool invert; 60 | in vec2 uv; 61 | in vec2 texCoord; 62 | 63 | out vec4 outputColor; 64 | 65 | void main() 66 | { 67 | vec4 mainCol = texture(_MainTexture, texCoord); 68 | vec4 blendCol = texture(blendTex, texCoord); 69 | vec4 maskCol = texture(maskTex, texCoord); 70 | 71 | vec3 fade = abs(maskCol.rgb - targetMaskCol.rgb) * tolerance; 72 | if (invert) fade = 1. - fade; 73 | outputColor = mix(mainCol, blendCol, clamp(length(fade), 0., 1.)); 74 | } 75 | -------------------------------------------------------------------------------- /src/gui/ofxGuiTextureInput.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "ofxGuiElement.h" 4 | #include "TextureInputSelectionView.h" 5 | 6 | class ofxGuiTextureInput : public ofxGuiElement { 7 | public: 8 | 9 | ofxGuiTextureInput(std::string canvasName="", TextureInputSelectionView *selectionView = nullptr, const ofJson& config = ofJson()); 10 | ofxGuiTextureInput(std::string canvasName, ofBaseDraws * graphics, const ofJson& config = ofJson()); 11 | ofxGuiTextureInput(std::string canvasName, ofBaseDraws * graphics, float w, float h = 0); 12 | virtual ~ofxGuiTextureInput(); 13 | TextureInputSelectionView *selectionView; 14 | 15 | virtual float getMinWidth() override; 16 | virtual float getMinHeight() override; 17 | 18 | void setAutoHeight(); 19 | void setAutoWidth(); 20 | 21 | ofEvent showEvent; 22 | 23 | virtual void setGraphics(ofBaseDraws* graphics); 24 | 25 | virtual ofAbstractParameter & getParameter() override; 26 | virtual bool mouseReleased(ofMouseEventArgs & args) override; 27 | 28 | static std::string getClassType(); 29 | 30 | protected: 31 | 32 | void setup(std::string canvasName = "", float w = 0, float h = 0); 33 | 34 | virtual std::vector getClassTypes() override; 35 | 36 | bool setValue(float mx, float my, bool bCheckBounds) override { 37 | return false; 38 | } 39 | virtual void render() override; 40 | virtual void generateDraw() override; 41 | 42 | virtual void onResize(DOM::ResizeEventArgs& args); 43 | 44 | ofPath bg; 45 | ofVboMesh textMesh; 46 | ofBaseDraws * graphics; 47 | ofParameter label; 48 | bool _bLoaded; 49 | bool resizing = false; 50 | bool autoWidth, autoHeight; 51 | 52 | }; 53 | -------------------------------------------------------------------------------- /src/Parameters/FloatParameter.cpp: -------------------------------------------------------------------------------- 1 | #include "FloatParameter.h" 2 | 3 | FloatParameter::FloatParameter(std::string uniform, float currentValue, glm::vec2 range, bool show, int midi) { 4 | this->uniform = uniform; 5 | this->value = currentValue; 6 | this->range = range; 7 | this->show = show; 8 | this->midiIndex = midi; 9 | this->type = "float"; 10 | } 11 | 12 | void FloatParameter::UpdateShader(ofxAutoReloadedShader *shader, RenderStruct *renderStruct) { 13 | shader->setUniform1f(this->uniform, this->value); 14 | } 15 | 16 | void FloatParameter::AddToGui(ofxGuiGroup2 *gui) { 17 | if (this->show) { 18 | gui->add(value.set(this->uniform,this->value,this->range.x,this->range.y)); 19 | } 20 | } 21 | 22 | void FloatParameter::UpdateJson(Json::Value &val) { 23 | val["name"] = uniform; 24 | val["value"] = (float)this->value; 25 | val["show"] = this->show; 26 | val["type"] = "float"; 27 | val["range"]["x"] = this->range.x; 28 | val["range"]["y"] = this->range.y; 29 | } 30 | 31 | void FloatParameter::UpdateMidi(int index, float value) { 32 | if (this->midiIndex == index) { 33 | this->value = ofLerp(this->range.x, this->range.y, value/127.0); 34 | } 35 | } 36 | 37 | void FloatParameter::BindMidi(int midiIndices[]) { 38 | this->midiIndex = midiIndices[0]; 39 | } 40 | 41 | void FloatParameter::bindMidi(int index, int subParamIndex) { 42 | this->midiIndex = index; 43 | } 44 | Json::Value FloatParameter::getDict() { 45 | Json::Value val; 46 | val["name"] = uniform; 47 | val["value"] = (float)this->value; 48 | val["show"] = this->show; 49 | val["type"] = "float"; 50 | val["range"]["x"] = this->range.x; 51 | val["range"]["y"] = this->range.y; 52 | return val; 53 | } 54 | -------------------------------------------------------------------------------- /src/Parameters/Vector2Parameter.cpp: -------------------------------------------------------------------------------- 1 | #include "Vector2Parameter.h" 2 | 3 | Vector2Parameter::Vector2Parameter(std::string uniform, ofVec2f defaultVal, bool show, glm::vec2 range, int *midi) { 4 | this->uniform = uniform; 5 | this->value = defaultVal; 6 | this->show = show; 7 | this->range = range; 8 | this->midi = new int[2]; 9 | this->midi[0] = midi[0]; 10 | this->midi[1] = midi[1]; 11 | this->type = "vec2"; 12 | } 13 | 14 | void Vector2Parameter::UpdateShader(ofxAutoReloadedShader *shader, RenderStruct *renderStruct) { 15 | shader->setUniform2f(this->uniform, this->value->x, this->value->y); 16 | } 17 | 18 | void Vector2Parameter::AddToGui(ofxGuiGroup2 *gui) { 19 | if (this->show) { 20 | value.set(this->uniform,this->value, ofVec2f(range.x,range.x),ofVec3f(range.y,range.y)); 21 | gui->add(value); 22 | } 23 | } 24 | 25 | void Vector2Parameter::UpdateJson(Json::Value &val) { 26 | val["value"]["x"] = this->value->x; 27 | val["value"]["y"] = this->value->y; 28 | val["range"]["x"] = this->range.x; 29 | val["range"]["y"] = this->range.y; 30 | val["show"] = this->show; 31 | val["type"] = "vec2"; 32 | } 33 | 34 | void Vector2Parameter::UpdateMidi(int index, float val) { 35 | if (this->midi[0] == index) { 36 | float adjustedValue = ofLerp(this->range.x, this->range.y, val/127.0); 37 | this->value = glm::vec2(adjustedValue, this->value->y); 38 | } else if (this->midi[1] == index) { 39 | float adjustedValue = ofLerp(this->range.x, this->range.y, val/127.0); 40 | this->value = glm::vec2(this->value->x, adjustedValue); 41 | } 42 | } 43 | 44 | void Vector2Parameter::bindMidi(int midiIndex, int subParamIndex) { 45 | this->midi[subParamIndex] = midiIndex; 46 | } 47 | -------------------------------------------------------------------------------- /src/Parameters/TextureParameter.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "Parameter.h" 4 | #include "ofxGuiExtended2.h" 5 | #include "ofxGuiTextureInput.h" 6 | 7 | class TextureParameter : public Parameter { 8 | 9 | public: 10 | TextureParameter(string uniform, string filePath, int textureIndex, bool show, string texType, string targetBufferName); 11 | ofImage value; 12 | string filePath; 13 | TextureSourceType type; 14 | int textureIndex; 15 | ofVideoPlayer videoFile; 16 | string targetBufferName; 17 | ofxGuiTextureInput *texInput; 18 | //ofGstVideoPlayer gstreamer; 19 | void updateTextureFromFile(string &s); 20 | void wantsWebcamChanged(bool &val); 21 | void wantsBufferChanged(string &val); 22 | void onShowSelectionView(); 23 | void onHideSelectionView(); 24 | void updateToNewType(TextureSourceType t); 25 | 26 | virtual void UpdateShader(ofxAutoReloadedShader *shader, RenderStruct *renderStruct) override; 27 | virtual void AddToGui(ofxGuiGroup2 *gui) override; 28 | virtual void UpdateJson(Json::Value &val) override; 29 | virtual void update(RenderStruct *renderStruct) override; 30 | virtual void startOfflineRender() override; 31 | virtual void stopOfflineRender() override; 32 | virtual bool isMouseHoveredOver() override; 33 | virtual void handleInputFile(string s) override; 34 | virtual TextureSourceType getTextureSourceType() override; 35 | virtual void playbackDidToggleState(bool isPaused) override; 36 | virtual void close() override; 37 | 38 | private: 39 | string getTextureType(); 40 | TextureSourceType getTypeFromString(string s); 41 | void startDoingThingForType(); 42 | void wantsAudioChanged(bool &val); 43 | bool listenersAdded = false; 44 | void closeVideoFile(); 45 | }; 46 | -------------------------------------------------------------------------------- /bin/data/presets/video_test.json: -------------------------------------------------------------------------------- 1 | { 2 | "blend" : 1, 3 | "data" : [ 4 | { 5 | "parameters" : [ 6 | { 7 | "filePath" : "textures/video.mp4", 8 | "name" : "inputTex", 9 | "show" : true, 10 | "targetBufferName" : "", 11 | "textureIndex" : 2, 12 | "textype" : "VideoFile", 13 | "type" : "texture" 14 | } 15 | ], 16 | "shaderName" : "shaders/textureTest" 17 | }, 18 | { 19 | "parameters" : [ 20 | { 21 | "name" : "intensity", 22 | "range" : { 23 | "x" : 0, 24 | "y" : 1 25 | }, 26 | "show" : true, 27 | "type" : "float", 28 | "value" : 0.1793478280305862 29 | }, 30 | { 31 | "name" : "scale", 32 | "range" : { 33 | "x" : 0, 34 | "y" : 2 35 | }, 36 | "show" : true, 37 | "type" : "float", 38 | "value" : 0.532608687877655 39 | }, 40 | { 41 | "filePath" : "", 42 | "name" : "lastTex", 43 | "show" : true, 44 | "targetBufferName" : "", 45 | "textureIndex" : 2, 46 | "textype" : "Last", 47 | "type" : "texture" 48 | } 49 | ], 50 | "shaderName" : "shaders/feedbackShader" 51 | }, 52 | { 53 | "shaderName" : "shaders/invertShader" 54 | } 55 | ], 56 | "duration" : 6.283180236816406, 57 | "fps" : 30, 58 | "res" : { 59 | "x" : 500, 60 | "y" : 500 61 | }, 62 | "scale" : 1 63 | } 64 | -------------------------------------------------------------------------------- /bin/data/shaders/shaderchain_logo.frag: -------------------------------------------------------------------------------- 1 | /* 2 | { 3 | "parameters" : [ 4 | { 5 | "name" : "size", 6 | "range" : { 7 | "x" : 0, 8 | "y" : 0.5 9 | }, 10 | "show" : true, 11 | "type" : "float", 12 | "value" : 0.1086956486105919 13 | } 14 | ] 15 | } 16 | */ 17 | #version 150 18 | 19 | uniform float size; 20 | uniform float _Time; 21 | 22 | in vec2 uv; 23 | out vec4 outputColor; 24 | 25 | float box(vec2 uv, vec2 s) { 26 | vec2 q = abs(uv) - s; 27 | return length(max(q,0.0)) + min(max(q.x,q.y),0.0); 28 | } 29 | 30 | void pR(inout vec2 p, float a) { 31 | p = cos(a)*p + sin(a)*vec2(p.y, -p.x); 32 | } 33 | 34 | void main() 35 | { 36 | vec4 color = vec4(0., 0., 0., 1.); 37 | vec2 uv = uv * 2.0 - 1.0; 38 | float angle = atan(uv.y, uv.x); 39 | pR(uv, -0.1+sin(_Time*2. + length(uv)*4. + angle*4.) * 0.05); 40 | 41 | float circleSize = size; 42 | 43 | vec2 topPos = uv-vec2(0.,circleSize); 44 | vec2 bottomPos = uv+vec2(0.,circleSize); 45 | float circleBottom = length(bottomPos) - circleSize; 46 | 47 | float dist = 0.0; 48 | float a = atan(bottomPos.y, bottomPos.x); 49 | float tempA = mod(a + 3.14159 + 0.5, 6.28318); 50 | float progress = smoothstep(-0.3, 2.05470795, tempA); 51 | 52 | float edge = (a < 1.570795 && a > -3.2) ? 1.0 : 0.0; 53 | 54 | dist += (1.-smoothstep(0.0, 0.01, abs(circleBottom))) * edge; 55 | 56 | a = atan(topPos.y, topPos.x); 57 | 58 | float tempB = mod( a+1.570795*0.25, 6.28318); 59 | progress *= smoothstep(0., 2., tempB); 60 | 61 | edge = (a < -1.570795 || a > .3) ? 1.0 : 0.0; 62 | 63 | float circleTop = length(topPos) - circleSize; 64 | 65 | dist += (1.-smoothstep(0.0, 0.01, abs(circleTop))) * edge; 66 | 67 | color = vec4(vec3(dist), progress); 68 | outputColor = color; 69 | } 70 | -------------------------------------------------------------------------------- /bin/data/shaders/mouse_cellular.frag: -------------------------------------------------------------------------------- 1 | /* 2 | { 3 | "parameters" : [ 4 | { 5 | "name" : "periods", 6 | "range" : { 7 | "x" : 1, 8 | "y" : 15 9 | }, 10 | "show" : true, 11 | "type" : "float", 12 | "value" : 2.82608699798584 13 | }, 14 | { 15 | "name" : "hueAmp", 16 | "range" : { 17 | "x" : 1, 18 | "y" : 15 19 | }, 20 | "show" : true, 21 | "type" : "float", 22 | "value" : 5.793478488922119 23 | } 24 | ] 25 | } 26 | */ 27 | 28 | #version 150 29 | #pragma include "includes/hue.glsl" 30 | 31 | uniform sampler2D _MainTexture; 32 | uniform vec2 _Resolution; 33 | uniform float _Time; 34 | uniform vec2 _Mouse; 35 | 36 | uniform float periods; 37 | uniform float hueAmp; 38 | 39 | in vec2 uv; 40 | out vec4 outputColor; 41 | 42 | // 2D Random by Patricio Gonzalez Vivo https://thebookofshaders.com/12/ 43 | vec2 random2(vec2 st){ 44 | st = vec2( dot(st,vec2(127.1,311.7)), 45 | dot(st,vec2(269.5,183.3)) ); 46 | return fract(sin(st)*43758.5453123); 47 | } 48 | 49 | // Cell Noise by Patricio Gonzalez Vivo https://thebookofshaders.com/12/ 50 | float cellNoise(in vec2 st) { 51 | 52 | vec2 cell = floor(st); 53 | vec2 pos = fract(st); 54 | float res = 1e20; 55 | 56 | for (int i = -1; i <= 1; i++) { 57 | for (int j = -1; j <= 1; j++) { 58 | vec2 neighbour = vec2(float(i), float(j)); 59 | vec2 point = random2(cell + neighbour); 60 | res = min(res, distance(neighbour + point, pos)); 61 | } 62 | } 63 | 64 | res = min(res, distance(st, _Mouse*round(periods))); 65 | return res; 66 | } 67 | 68 | void main() 69 | { 70 | float n = cellNoise(uv * round(periods)); 71 | vec3 col = hueShift(vec3(1.0, 0.25, 0.25), _Time + n*hueAmp); 72 | outputColor = vec4(col, 1.0); 73 | } 74 | -------------------------------------------------------------------------------- /bin/data/shaders/moon_mist_noise.frag: -------------------------------------------------------------------------------- 1 | /* 2 | { 3 | "parameters" : [ 4 | { 5 | "name" : "gradientTex", 6 | "show" : true, 7 | "type" : "texture", 8 | "filePath" : "textures/gradient.png", 9 | "textureIndex" : 2 10 | }, 11 | { 12 | "name" : "freq", 13 | "range" : { 14 | "x" : 0, 15 | "y" : 50 16 | }, 17 | "show" : true, 18 | "type" : "float", 19 | "value" : 5.0 20 | } 21 | ] 22 | } 23 | */ 24 | #version 150 25 | #pragma include "includes/noise.glsl" 26 | 27 | uniform sampler2D _MainTexture; 28 | uniform vec2 _Resolution; 29 | uniform float _Time; 30 | 31 | uniform sampler2D gradientTex; 32 | 33 | uniform float freq; 34 | 35 | in vec2 uv; 36 | out vec4 outputColor; 37 | 38 | vec3 curl(vec3 pos) { 39 | vec3 eps = vec3(1., 0., 0.); 40 | vec3 res = vec3(0.); 41 | 42 | float n1 = snoise(pos + eps.yxy); 43 | float n2 = snoise(pos - eps.yxy); 44 | float a = (n1 - n2) / (2 * eps.x); 45 | 46 | n1 = snoise(pos + eps.yyx); 47 | n2 = snoise(pos - eps.yyx); 48 | float b = (n1 - n2) / (2 * eps.x); 49 | 50 | res.x = a - b; 51 | 52 | n1 = snoise(pos + eps.yyx); 53 | n2 = snoise(pos - eps.yyx); 54 | a = (n1 - n2) / (2 * eps.x); 55 | 56 | n1 = snoise(pos + eps.xyy); 57 | n2 = snoise(pos - eps.xyy); 58 | b = (n1 - n2) / (2 * eps.x); 59 | 60 | res.x = a - b; 61 | 62 | n1 = snoise(pos + eps.xyy); 63 | n2 = snoise(pos - eps.xyy); 64 | a = (n1 - n2) / (2 * eps.x); 65 | 66 | n1 = snoise(pos + eps.yxy); 67 | n2 = snoise(pos - eps.yxy); 68 | b = (n1 - n2) / (2 * eps.x); 69 | 70 | res.z = a - b; 71 | 72 | return res; 73 | } 74 | 75 | 76 | void main() 77 | { 78 | vec2 uv = uv; 79 | uv.x *= _Resolution.x / _Resolution.y; 80 | vec3 p = vec3(uv, _Time*0.05 ); 81 | vec3 c = curl(p*freq); 82 | c = texture(gradientTex, vec2(mod(length(c) + _Time*.5, 500.), 0.)).rgb; 83 | outputColor = vec4(c, 1.0); 84 | } 85 | -------------------------------------------------------------------------------- /bin/data/shaders/multisample-hueshift.frag: -------------------------------------------------------------------------------- 1 | /* 2 | { 3 | "parameters" : [ 4 | { 5 | "name" : "offsetVal", 6 | "range" : { 7 | "x" : 0, 8 | "y" : 40 9 | }, 10 | "show" : true, 11 | "type" : "float", 12 | "value" : 30 13 | } 14 | ] 15 | } 16 | */ 17 | #version 150 18 | #pragma include "includes/hue.glsl" 19 | 20 | uniform sampler2D _MainTexture; 21 | uniform vec2 _Resolution; 22 | 23 | uniform float offsetVal; 24 | 25 | uniform vec4 bgColor; 26 | uniform vec4 letterColor; 27 | uniform float _Time; 28 | 29 | in vec2 uv; 30 | in vec2 texCoord; 31 | 32 | out vec4 outputColor; 33 | 34 | float box(vec2 uv, vec2 s) { 35 | vec2 q = abs(uv) - s; 36 | return length(max(q,0.0)) + min(max(q.x,q.y),0.0); 37 | } 38 | 39 | void main() 40 | { 41 | const int iter = 8; 42 | 43 | // Add all of the samples to a total, which you divide by the number of samples later to compute the average 44 | vec3 result = vec3(0.); 45 | 46 | // This is the radius of the circle 47 | float taper = texture(_MainTexture, texCoord).a; 48 | vec2 texel = vec2(1.)/_Resolution; 49 | 50 | vec2 uv_c = uv * 2.0 - 1.0; 51 | for (int i = 0; i < iter; i++) { 52 | 53 | // Compute the angle of the current circle point 54 | float angle = float(i)/float(iter)*2.*3.14159; 55 | 56 | // Calculate the offset 57 | vec2 offs = vec2(cos(angle + _Time), sin(angle+_Time))*offsetVal*texel; 58 | 59 | offs = mix(offs, normalize(uv_c)*0.05, vec2(clamp(1.-taper,0., 1.))); 60 | 61 | // Sample the texture and hue shift it based on the angle around the circle 62 | vec3 col1 = texture(_MainTexture, texCoord + offs.xy).rgb; 63 | result += hueShift(vec3(0.,col1.g,col1.b), angle)*8.; 64 | } 65 | 66 | vec3 base = result/float(iter) ; 67 | vec4 col = vec4(base , 1.0); 68 | //col = vec4(vec3(taper) , 1.0); 69 | 70 | //col.rgb = pow(col.rgb, vec3(.5)); 71 | outputColor = col; 72 | } 73 | -------------------------------------------------------------------------------- /bin/data/shaders/blurShader.frag: -------------------------------------------------------------------------------- 1 | /* 2 | { 3 | "parameters" : [ 4 | { 5 | "name" : "blurSize", 6 | "range" : { 7 | "x" : 1, 8 | "y" : 32 9 | }, 10 | "show" : true, 11 | "type" : "float", 12 | "value" : 1.0 13 | }, 14 | { 15 | "name" : "brightness", 16 | "range" : { 17 | "x" : 0, 18 | "y" : 32 19 | }, 20 | "show" : true, 21 | "type" : "float", 22 | "value" : 1.0 23 | } 24 | ] 25 | } 26 | */ 27 | #version 150 28 | 29 | uniform sampler2D _MainTexture; 30 | uniform vec2 _Resolution; 31 | 32 | uniform float blurSize; 33 | uniform float brightness; 34 | uniform int samples; 35 | 36 | uniform bool invert; 37 | in vec2 uv; 38 | in vec2 texCoord; 39 | 40 | out vec4 outputColor; 41 | 42 | float normpdf(in float x, in float sigma) { 43 | return 0.39894*exp(-0.5*x*x/(sigma*sigma))/sigma; 44 | } 45 | 46 | void main() 47 | { 48 | vec3 base = vec3(0.); 49 | 50 | // Gaussian blur by mrharicot https://www.shadertoy.com/view/XdfGDH 51 | const int mSize = 13; 52 | const int kSize = (mSize-1)/2; 53 | float kernel[mSize]; 54 | 55 | //create the 1-D kernel 56 | float sigma = blurSize; 57 | float Z = .0; 58 | 59 | for (int j = 0; j <= kSize; ++j) { 60 | kernel[kSize+j] = kernel[kSize-j] = normpdf(float(j), sigma); 61 | } 62 | 63 | //get the normalization factor (as the gaussian has been clamped) 64 | for (int j = 0; j < mSize; ++j) { 65 | Z += kernel[j]; 66 | } 67 | 68 | //read out the texels 69 | vec2 texelSize = vec2(1.) / _Resolution; 70 | 71 | for (int i=-kSize; i <= kSize; ++i) 72 | { 73 | for (int j=-kSize; j <= kSize; ++j) 74 | { 75 | base += kernel[kSize+j]*kernel[kSize+i]*texture(_MainTexture, (texCoord+vec2(float(i),float(j))*texelSize) ).rgb; 76 | } 77 | } 78 | vec4 b = vec4(base/(Z*Z), 1.0); 79 | b.rgb = pow(b.rgb, vec3(brightness)); 80 | outputColor = vec4(b); 81 | } 82 | -------------------------------------------------------------------------------- /src/Parameters/Vector3Parameter.cpp: -------------------------------------------------------------------------------- 1 | #include "Vector3Parameter.h" 2 | 3 | Vector3Parameter::Vector3Parameter(std::string uniform, ofVec3f defaultVal, bool show, glm::vec2 range, int *midi) { 4 | this->uniform = uniform; 5 | this->value = defaultVal; 6 | this->show = show; 7 | this->range = range; 8 | this->midi = new int[3]; 9 | this->midi[0] = midi[0]; 10 | this->midi[1] = midi[1]; 11 | this->midi[2] = midi[2]; 12 | this->type = "vec3"; 13 | } 14 | 15 | void Vector3Parameter::UpdateShader(ofxAutoReloadedShader *shader, RenderStruct *renderStruct) { 16 | shader->setUniform3f(this->uniform, this->value->x, this->value->y, this->value->z); 17 | } 18 | 19 | void Vector3Parameter::AddToGui(ofxGuiGroup2 *gui) { 20 | if (this->show) { 21 | value.set(this->uniform,this->value, ofVec3f(range.x,range.x,range.x),ofVec3f(range.y,range.y,range.y)); 22 | gui->add(value); 23 | } 24 | } 25 | 26 | void Vector3Parameter::UpdateJson(Json::Value &val) { 27 | val["value"]["x"] = this->value->x; 28 | val["value"]["y"] = this->value->y; 29 | val["value"]["z"] = this->value->z; 30 | val["range"]["x"] = this->range.x; 31 | val["range"]["y"] = this->range.y; 32 | val["show"] = this->show; 33 | val["type"] = "vec3"; 34 | } 35 | 36 | void Vector3Parameter::UpdateMidi(int index, float val) { 37 | if (this->midi[0] == index) { 38 | float adjustedValue = ofLerp(this->range.x, this->range.y, val/127.0); 39 | this->value = glm::vec3(adjustedValue, this->value->y, this->value->z); 40 | } else if (this->midi[1] == index) { 41 | float adjustedValue = ofLerp(this->range.x, this->range.y, val/127.0); 42 | this->value = glm::vec3(this->value->x, adjustedValue, this->value->z); 43 | } else if (this->midi[2] == index) { 44 | float adjustedValue = ofLerp(this->range.x, this->range.y, val/127.0); 45 | this->value = glm::vec3(this->value->x, this->value->y, adjustedValue); 46 | } 47 | } 48 | 49 | void Vector3Parameter::bindMidi(int midiIndex, int subParamIndex) { 50 | this->midi[subParamIndex] = midiIndex; 51 | } 52 | -------------------------------------------------------------------------------- /src/ofApp.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | #include "ofApp.h" 4 | 5 | ofApp::ofApp() { 6 | 7 | } 8 | ofApp::~ofApp() { 9 | 10 | } 11 | 12 | //-------------------------------------------------------------- 13 | void ofApp::setup(){ 14 | glm::vec2 res = glm::vec2(480, 270); 15 | ofSetWindowShape(1920, 1080); 16 | ofSetWindowPosition(0, 0); 17 | ofSetWindowTitle("ShaderChain"); 18 | this->shaderChain.Setup(res); 19 | } 20 | 21 | //-------------------------------------------------------------- 22 | void ofApp::update(){ 23 | this->shaderChain.update(); 24 | } 25 | 26 | //-------------------------------------------------------------- 27 | void ofApp::draw(){ 28 | this->shaderChain.draw(); 29 | } 30 | 31 | //-------------------------------------------------------------- 32 | void ofApp::dragEvent(ofDragInfo info) { 33 | this->shaderChain.dragEvent(info); 34 | } 35 | 36 | //-------------------------------------------------------------- 37 | void ofApp::keyPressed(int key){ 38 | this->shaderChain.KeyPressed(key); 39 | } 40 | 41 | //-------------------------------------------------------------- 42 | void ofApp::keyReleased(int key){ 43 | 44 | } 45 | 46 | //-------------------------------------------------------------- 47 | void ofApp::mouseMoved(int x, int y){ 48 | 49 | } 50 | 51 | //-------------------------------------------------------------- 52 | void ofApp::mouseDragged(int x, int y, int button){ 53 | 54 | } 55 | 56 | //-------------------------------------------------------------- 57 | void ofApp::mousePressed(int x, int y, int button){ 58 | this->shaderChain.isMouseDown = true; 59 | } 60 | 61 | //-------------------------------------------------------------- 62 | void ofApp::mouseReleased(int x, int y, int button){ 63 | this->shaderChain.isMouseDown = false; 64 | } 65 | 66 | //-------------------------------------------------------------- 67 | void ofApp::windowResized(int w, int h){ 68 | this->shaderChain.windowResized(w, h); 69 | } 70 | 71 | //-------------------------------------------------------------- 72 | void ofApp::gotMessage(ofMessage msg){ 73 | 74 | } 75 | -------------------------------------------------------------------------------- /src/PNGRenderer.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | #include "ofMain.h" 5 | #include "ofxGuiExtended2.h" 6 | #include "FFTManager.h" 7 | 8 | class PNGRenderer { 9 | 10 | public: 11 | string renderDirectory = "renders/"; 12 | ofParameter spaceBufferLabel; 13 | 14 | ofParameter statusLabel; 15 | 16 | ofParameter resolutionX; 17 | ofParameter resolutionY; 18 | 19 | ofParameterGroup fileGroup; 20 | ofParameter presetDisplayName; 21 | ofParameter presetDisplayNameLabel; 22 | 23 | ofParameter newPresetButton; 24 | ofParameter saveAsPresetButton; 25 | ofParameter savePresetButton; 26 | ofParameter openFileButton; 27 | ofParameter mapMidiButton; 28 | ofParameter webExportButton; 29 | ofParameter updateShaderJsonButton; 30 | 31 | ofParameter displayScaleParam; 32 | ofParameter frameskip; 33 | ofParameter numLoops; 34 | ofParameter numBlendFrames; 35 | ofParameter animduration; 36 | ofParameter FPS; 37 | ofParameter encodeMp4Button; 38 | ofParameter encodeGifButton; 39 | 40 | ofParameterGroup renderParameterGroup; 41 | ofParameterGroup pngSavingGroup; 42 | ofParameterGroup gifMenuGroup; 43 | ofParameterGroup vidMenuGroup; 44 | ofParameter gifNumColors; 45 | ofParameter gifResolutionScale; 46 | 47 | PNGRenderer(float animduration, int fps, glm::vec2 resolution); 48 | string presetFilePath; 49 | 50 | bool isCapturing = false; 51 | 52 | float Tick(); 53 | void Start(); 54 | void WritePNG(ofFbo *buffer); 55 | void AddToGui(ofxGuiContainer *panel, ofxGuiContainer *statusLabelPanel, FFTManager *fft); 56 | void UpdateResolution(int w, int h); 57 | void updatePath(string s); 58 | ofParameter preview; 59 | ofParameter saveButton; 60 | int totalFrames; 61 | int currentFrame; 62 | 63 | private: 64 | int renderedFrames; 65 | ofxGuiButton *saveFramesButton; 66 | void saveButtonPressed(); 67 | }; 68 | -------------------------------------------------------------------------------- /src/Parameters/CameraParameter.cpp: -------------------------------------------------------------------------------- 1 | #include "CameraParameter.h" 2 | #include "ofMain.h" 3 | 4 | CameraParameter::CameraParameter(glm::vec3 pos, glm::vec3 rot) { 5 | this->camera.setPosition(pos); 6 | this->camera.setOrientation(rot); 7 | } 8 | 9 | CameraParameter::~CameraParameter() { 10 | //ofUnregisterKeyEvents(this); 11 | } 12 | 13 | void CameraParameter::UpdateShader(ofxAutoReloadedShader *shader, RenderStruct *renderStruct) { 14 | 15 | bool isMouseDown = ofGetMousePressed(0); 16 | 17 | if (ofGetKeyPressed('w')) { 18 | camera.move(-camera.getLookAtDir() * ofGetLastFrameTime()); 19 | } 20 | if (ofGetKeyPressed('s')) { 21 | camera.move(camera.getLookAtDir() * ofGetLastFrameTime()); 22 | } 23 | if (ofGetKeyPressed('d')) { 24 | camera.move(camera.getXAxis() * ofGetLastFrameTime()); 25 | } 26 | if (ofGetKeyPressed('a')) { 27 | camera.move(-camera.getXAxis() * ofGetLastFrameTime()); 28 | } 29 | 30 | if (isMouseDown && !renderStruct->isOfflineRendering) { 31 | float xDelta = ofGetMouseX() - ofGetPreviousMouseX(); 32 | float yDelta = ofGetMouseY() - ofGetPreviousMouseY(); 33 | 34 | camera.panDeg(xDelta * ofGetLastFrameTime() * mouseMoveSpeed); 35 | camera.tiltDeg(- yDelta * ofGetLastFrameTime() * mouseMoveSpeed); 36 | } 37 | 38 | shader->setUniform3f("_CamPos", camera.getPosition()); 39 | shader->setUniform3f("_CamForward", camera.getZAxis()); 40 | shader->setUniform3f("_CamUp", camera.getYAxis()); 41 | shader->setUniform3f("_CamRight", camera.getXAxis()); 42 | } 43 | 44 | void CameraParameter::AddToGui(ofxGuiGroup2 *gui) { 45 | // ofRegisterKeyEvents(this); 46 | } 47 | 48 | void CameraParameter::UpdateJson(Json::Value &val) { 49 | val["value"]["pos"]["x"] = camera.getX(); 50 | val["value"]["pos"]["y"] = camera.getY(); 51 | val["value"]["pos"]["z"] = camera.getZ(); 52 | 53 | glm::vec3 rot = camera.getOrientationEulerDeg(); 54 | val["value"]["rot"]["x"] = rot.x; 55 | val["value"]["rot"]["y"] = rot.y; 56 | val["value"]["rot"]["z"] = rot.z; 57 | 58 | val["type"] = "camera"; 59 | } 60 | -------------------------------------------------------------------------------- /src/Parameters/Vector4Parameter.cpp: -------------------------------------------------------------------------------- 1 | #include "Vector4Parameter.h" 2 | 3 | Vector4Parameter::Vector4Parameter(std::string uniform, ofVec3f defaultVal, bool show, glm::vec2 range, int *midi) { 4 | this->uniform = uniform; 5 | this->value = defaultVal; 6 | this->show = show; 7 | this->range = range; 8 | this->midi = new int[4]; 9 | this->midi[0] = midi[0]; 10 | this->midi[1] = midi[1]; 11 | this->midi[2] = midi[2]; 12 | this->midi[3] = midi[3]; 13 | this->type = "vec4"; 14 | } 15 | 16 | void Vector4Parameter::UpdateShader(ofxAutoReloadedShader *shader, RenderStruct *renderStruct) { 17 | shader->setUniform4f(this->uniform, this->value->x, this->value->y, this->value->z, this->value->w); 18 | } 19 | 20 | void Vector4Parameter::AddToGui(ofxGuiGroup2 *gui) { 21 | if (this->show) { 22 | value.set(this->uniform,this->value, ofVec4f(range.x,range.x,range.x, range.x), ofVec4f(range.y,range.y,range.y, range.y)); 23 | gui->add(value); 24 | } 25 | } 26 | 27 | void Vector4Parameter::UpdateJson(Json::Value &val) { 28 | val["value"]["x"] = this->value->x; 29 | val["value"]["y"] = this->value->y; 30 | val["value"]["z"] = this->value->z; 31 | val["range"]["x"] = this->range.x; 32 | val["range"]["y"] = this->range.y; 33 | val["show"] = this->show; 34 | val["type"] = "vec4"; 35 | } 36 | 37 | void Vector4Parameter::UpdateMidi(int index, float val) { 38 | if (this->midi[0] == index) { 39 | float adjustedValue = ofLerp(this->range.x, this->range.y, val/127.0); 40 | this->value = glm::vec3(adjustedValue, this->value->y, this->value->z); 41 | } else if (this->midi[1] == index) { 42 | float adjustedValue = ofLerp(this->range.x, this->range.y, val/127.0); 43 | this->value = glm::vec3(this->value->x, adjustedValue, this->value->z); 44 | } else if (this->midi[2] == index) { 45 | float adjustedValue = ofLerp(this->range.x, this->range.y, val/127.0); 46 | this->value = glm::vec3(this->value->x, this->value->y, adjustedValue); 47 | } 48 | } 49 | 50 | void Vector4Parameter::bindMidi(int midiIndex, int subParamIndex) { 51 | this->midi[subParamIndex] = midiIndex; 52 | } 53 | -------------------------------------------------------------------------------- /bin/data/shaders/Noise.frag: -------------------------------------------------------------------------------- 1 | /* 2 | { 3 | "parameters" : [ 4 | { 5 | "name" : "edges", 6 | "range" : { 7 | "x" : 0, 8 | "y" : 50 9 | }, 10 | "show" : true, 11 | "type" : "float", 12 | "value" : 5.0 13 | }, 14 | { 15 | "name" : "periods", 16 | "range" : { 17 | "x" : 0, 18 | "y" : 150 19 | }, 20 | "show" : true, 21 | "type" : "float", 22 | "value" : 5.0 23 | }, 24 | { 25 | "name" : "octaves", 26 | "range" : { 27 | "x" : 0, 28 | "y" : 15 29 | }, 30 | "show" : true, 31 | "type" : "float", 32 | "value" : 10 33 | } 34 | ] 35 | } 36 | */ 37 | 38 | #version 150 39 | #pragma include "includes/hue.glsl" 40 | 41 | uniform sampler2D _MainTexture; 42 | uniform vec2 _Resolution; 43 | uniform float edges; 44 | uniform float periods; 45 | uniform float octaves; 46 | 47 | in vec2 uv; 48 | out vec4 outputColor; 49 | 50 | // 2D Random 51 | float random (in vec2 st) { 52 | return fract(sin(dot(st.xy, 53 | vec2(12.9898,78.233))) 54 | * 43758.5453123); 55 | } 56 | 57 | // 2D Noise based on Morgan McGuire @morgan3d 58 | // https://www.shadertoy.com/view/4dS3Wd 59 | float noise (in vec2 st, in float edges) { 60 | st *= edges; 61 | vec2 i = floor(st); 62 | vec2 f = fract(st); 63 | 64 | // Four corners in 2D of a tile, restricting the domain of the space 65 | float a = random(mod(i, edges)); 66 | float b = random(mod(i + vec2(1.0, 0.0), edges)); 67 | float c = random(mod(i + vec2(0.0, 1.0), edges)); 68 | float d = random(mod(i + vec2(1.0, 1.0), edges)); 69 | 70 | // Smooth Interpolation 71 | vec2 u = smoothstep(0.,1.,f); 72 | 73 | // Mix 4 coorners porcentages 74 | return mix(a, b, u.x) + 75 | (c - a)* u.y * (1.0 - u.x) + 76 | (d - b) * u.x * u.y; 77 | } 78 | 79 | float fbm(in vec2 st, in float edges) { 80 | float n = 0.; 81 | float scale = .55; 82 | 83 | for (int i = 0; i < floor(octaves); i += 1) { 84 | n += noise(st, edges) * scale; 85 | scale *= 0.5; 86 | st *= 2.; 87 | } 88 | return n; 89 | } 90 | 91 | 92 | void main() 93 | { 94 | float n = fbm(uv*round(periods), round(edges)); 95 | outputColor = vec4(vec3(n), 1.0); 96 | } 97 | -------------------------------------------------------------------------------- /src/Parameters/AudioFloatParameter.cpp: -------------------------------------------------------------------------------- 1 | #include "AudioFloatParameter.h" 2 | 3 | AudioFloatParameter::AudioFloatParameter(std::string uniform, float currentValue, glm::vec2 range, glm::vec2 frequencyRange, float scaleFactor, float expFactor, bool accumulate, bool show, int midi) 4 | : FloatParameter(uniform, currentValue, range, show, midi) { 5 | this->uniform = uniform; 6 | this->value = currentValue; 7 | this->range = range; 8 | this->frequencyRange = frequencyRange; 9 | this->scaleFactor = scaleFactor; 10 | this->expFactor = expFactor; 11 | this->accumulate = accumulate; 12 | this->show = show; 13 | this->midiIndex = midi; 14 | } 15 | 16 | void AudioFloatParameter::UpdateShader(ofxAutoReloadedShader *shader, RenderStruct *renderStruct) { 17 | float *buffer = ofSoundGetSpectrum(1024); 18 | int binx = (int)(this->frequencyRange.x*1024/22050); 19 | int biny = (int)(this->frequencyRange.y*1024/22050); 20 | float sum = 0; 21 | 22 | // sum the bins that correspond to the specified frequency range 23 | for(int i=binx;iexpFactor)*this->scaleFactor; 29 | 30 | // Divide the sum by the current number of blend frames 31 | sum /= renderStruct->numBlendFrames; 32 | 33 | // either accumulate, OR scale value (roughly) to range, then clip 34 | if(this->accumulate) { 35 | this->value += sum; 36 | while(this->value > this->range.y) this->value -= (this->range.y-this->range.x); 37 | } else { 38 | this->value = sum*(this->range.y - this->range.x) + this->range.x; 39 | this->value = this->value > this->range.y ? this->range.y : (float)this->value; 40 | this->value = this->value < this->range.x ? this->range.x : (float)this->value; 41 | } 42 | shader->setUniform1f(this->uniform, this->value); 43 | } 44 | 45 | void AudioFloatParameter::UpdateJson(Json::Value &val) { 46 | val["show"] = this->show; 47 | val["type"] = "audioFloat"; 48 | val["range"]["x"] = this->range.x; 49 | val["range"]["y"] = this->range.y; 50 | val["frequencyRange"]["x"] = this->frequencyRange.x; 51 | val["frequencyRange"]["y"] = this->frequencyRange.y; 52 | val["scaleFactor"] = this->scaleFactor; 53 | val["expFactor"] = this->expFactor; 54 | val["accumulate"] = this->accumulate; 55 | } 56 | -------------------------------------------------------------------------------- /bin/data/shaders/bokehShader.frag: -------------------------------------------------------------------------------- 1 | /* 2 | { 3 | "parameters" : [ 4 | { 5 | "name" : "startFocusDist", 6 | "range" : { 7 | "x" : 0, 8 | "y" : 10 9 | }, 10 | "show" : true, 11 | "type" : "float", 12 | "value" : 0.3571428656578064 13 | }, 14 | { 15 | "name" : "endFocusDist", 16 | "range" : { 17 | "x" : 0, 18 | "y" : 10 19 | }, 20 | "show" : true, 21 | "type" : "float", 22 | "value" : 1.275510191917419 23 | }, 24 | { 25 | "name" : "ramp", 26 | "range" : { 27 | "x" : 0, 28 | "y" : 1 29 | }, 30 | "show" : true, 31 | "type" : "float", 32 | "value" : 0.25 33 | }, 34 | { 35 | "name" : "blurSize", 36 | "range" : { 37 | "x" : 0, 38 | "y" : 16 39 | }, 40 | "show" : true, 41 | "type" : "float", 42 | "value" : 4 43 | } 44 | ] 45 | } 46 | */ 47 | 48 | #version 150 49 | 50 | uniform sampler2D _MainTexture; 51 | uniform vec2 _Resolution; 52 | 53 | in vec2 uv; 54 | out vec4 outputColor; 55 | 56 | uniform float startFocusDist; 57 | uniform float endFocusDist; 58 | uniform float ramp; 59 | uniform float blurSize; 60 | 61 | // This buffer does some bokeh based on the alpha channel of buffer A which is the distance of the surface from the pixel. 62 | 63 | float normpdf(in float x, in float sigma) { 64 | return 0.39894*exp(-0.5*x*x/(sigma*sigma))/sigma; 65 | } 66 | 67 | void main() { 68 | vec3 base = vec3(0.); 69 | 70 | // Gaussian blur by mrharicot https://www.shadertoy.com/view/XdfGDH 71 | const int mSize = 15; 72 | const int kSize = (mSize-1)/2; 73 | float kernel[mSize]; 74 | float depth = texture(_MainTexture, uv).a; 75 | 76 | //create the 1-D kernel 77 | 78 | float sigma = blurSize*((1.-smoothstep(startFocusDist, startFocusDist + ramp, depth) + smoothstep(endFocusDist - ramp, endFocusDist, depth))); 79 | sigma = max(0.001, sigma); 80 | float Z = .0; 81 | vec2 texelSize = vec2(1.) / _Resolution; 82 | 83 | for (int j = 0; j <= kSize; ++j) { 84 | kernel[kSize+j] = kernel[kSize-j] = normpdf(float(j), sigma); 85 | } 86 | 87 | //get the normalization factor (as the gaussian has been clamped) 88 | for (int j = 0; j < mSize; ++j) { 89 | Z += kernel[j]; 90 | } 91 | 92 | //read out the texels 93 | for (int i=-kSize; i <= kSize; ++i) 94 | { 95 | for (int j=-kSize; j <= kSize; ++j) 96 | { 97 | base += kernel[kSize+j]*kernel[kSize+i]*texture(_MainTexture, (uv+vec2(float(i),float(j))*texelSize) ).rgb; 98 | } 99 | } 100 | vec4 b = vec4(base/(Z*Z), 1.0); 101 | 102 | outputColor = vec4(b); 103 | } 104 | -------------------------------------------------------------------------------- /src/ShaderPass.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | #include 5 | #include 6 | #include "ofMain.h" 7 | 8 | #include "ofxAutoReloadedShader.h" 9 | #include "ofxJSON.h" 10 | 11 | #include "Parameters/Parameter.h" 12 | #include "Parameters/FloatParameter.h" 13 | #include "Parameters/Vector2Parameter.h" 14 | #include "Parameters/Vector3Parameter.h" 15 | #include "Parameters/Vector4Parameter.h" 16 | #include "Parameters/TextureParameter.h" 17 | #include "Parameters/ColorParameter.h" 18 | #include "Parameters/BoolParameter.h" 19 | #include "Parameters/IntParameter.h" 20 | #include "Parameters/CameraParameter.h" 21 | #include "Parameters/AudioFloatParameter.h" 22 | 23 | #include "ofxAutoReloadedShader.h" 24 | #include "FFTManager.h" 25 | #include "RenderStruct.h" 26 | 27 | class ShaderPass { 28 | public: 29 | std::string filePath; 30 | std::string vertexShaderPath = "shaders/internal/vertex.vert"; 31 | std::string displayName; 32 | std::vector> params; 33 | glm::vec2 targetResolution; 34 | float scale; 35 | ofxAutoReloadedShader shader; 36 | ofxGuiGroup2 *parameterGroup; 37 | ofFbo buffer; 38 | ofFbo lastBuffer; 39 | ofFbo renderBuffer; 40 | ofPlanePrimitive plane; 41 | bool wantsLastBuffer = false; 42 | ShaderPass(); 43 | ~ShaderPass(); 44 | ShaderPass(std::string shaderPath, glm::vec2 res); 45 | 46 | void Load(std::string shaderPath, glm::vec2 res); 47 | void LoadFromJson(Json::Value &json, float width, float height); 48 | 49 | void AddFloatParameter(std::string s, float startValue, glm::vec2 range, bool show, int midi); 50 | void AddIntParameter(std::string s, int startValue, glm::vec2 range, bool show, int midi); 51 | void AddBoolParameter(std::string s, bool startValue, bool show, int midi); 52 | void AddVector2Parameter(std::string s, glm::vec2 val, bool show, glm::vec2 range, int midi[]); 53 | void AddVector3Parameter(std::string s, glm::vec3 val, bool show, glm::vec2 range, int midi[]); 54 | void AddVector4Parameter(std::string s, glm::vec4 val, bool show, glm::vec2 range, int midi[]); 55 | void AddTextureParameter(string s, string filePath, int textureIndex, bool show, string texType, string targetBufferName); 56 | void AddAudioFloatParameter(std::string s, float startValue, glm::vec2 range, glm::vec2 frequencyRange, float scaleFactor, float expFactor, bool accumulate, bool show, int midi); 57 | void AddColorParameter(string s, float r, float g, float b, float a, bool show, int midi[]); 58 | void addCameraParameter(glm::vec3 pos, glm::vec3 rot); 59 | void Render(ofFbo *previousBuffer, RenderStruct *renderStruct); 60 | void SetInputTexture(ofFbo *buffer); 61 | void UpdateTime(float time); 62 | void UpdateResolution(int x, int y); 63 | void LoadJsonParametersFromLoadedShader(); 64 | void AddToGui(ofxGuiContainer *gui, TextureInputSelectionView *selectionView); 65 | void LoadDisplayNameFromFileName(); 66 | void update(RenderStruct *renderStruct); 67 | void startOfflineRender(); 68 | void stopOfflineRender(); 69 | void updateShaderJson(); 70 | private: 71 | ofxJSON json; 72 | void LoadParametersFromJson(Json::Value &json); 73 | }; 74 | -------------------------------------------------------------------------------- /src/ShaderChain.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include 3 | 4 | #include "ofxGuiExtended2.h" 5 | #include "ofxMidi.h" 6 | #include "ofxJSON.h" 7 | #include "MidiMapper.h" 8 | #include "ShaderPass.h" 9 | #include "PNGRenderer.h" 10 | #include "FFTManager.h" 11 | #include "PassesGui.h" 12 | #include "TextureInputSelectionView.h" 13 | 14 | class ShaderChain: public ofxMidiListener { 15 | public: 16 | 17 | string defaultPresetPath = "presets/default.json"; 18 | vector passes; 19 | float time; 20 | ofParameter isRunning; 21 | ofxMidiIn midiIn; 22 | ofxJSONElement result; 23 | bool isMouseDown; 24 | ofFbo cumulativeBuffer; 25 | ofFbo cumulativeBufferSwap; 26 | ofFbo cumulativeDrawBuffer; 27 | 28 | ofShader cumulativeShader; 29 | 30 | ShaderChain(glm::vec2 res); 31 | ShaderChain() {} 32 | ~ShaderChain(); 33 | void Setup(glm::vec2 res); 34 | void SetupGui(); 35 | void BeginSaveFrames(); 36 | void update(); 37 | void draw(); 38 | 39 | void KeyPressed(int key); 40 | void newMidiMessage(ofxMidiMessage& eventArgs); 41 | void WriteToJson(); 42 | void ReadFromJson(std::string path); 43 | void SetupMidi(); 44 | void dragEvent(ofDragInfo info); 45 | void windowResized(int w, int h); 46 | static string getSlash() { 47 | #if defined(WIN32) || defined(_WIN32) || defined(__WIN32) && !defined(__CYGWIN__) 48 | return "\\"; 49 | #else 50 | return "/"; 51 | #endif 52 | } 53 | 54 | private: 55 | PNGRenderer *pngRenderer; 56 | ofxGui gui; 57 | ofxGuiContainer *guiGlobal; 58 | ofxGuiContainer *statusContainer; 59 | 60 | PassesGui *passesGui; 61 | ofxGuiContainer *parameterPanel = nullptr; 62 | FFTManager fft; 63 | TextureInputSelectionView textureInputSelectionView; 64 | ofVideoGrabber vidGrabber; 65 | string ffmpegCommand = "ffmpeg"; 66 | 67 | float mouseMoveSpeed = 10.0; 68 | 69 | bool showGui; 70 | bool isShowingFileDialogue; 71 | 72 | int frame; 73 | RenderStruct renderStruct; 74 | 75 | void openDefaultPreset(); 76 | void RenderPasses(); 77 | void removed(RemovedElementData& data); 78 | void moved(MovingElementData& data); 79 | void UpdateResolutionIfChanged(bool force); 80 | void OpenFilePressed(); 81 | void savePresetAsPressed(); 82 | void LoadPassFromFile(string path); 83 | void playingChanged(bool &val); 84 | void updateStatusText(string s); 85 | void loadMp3(string filePath); 86 | void processFileInput(string filePath); 87 | void saveVideo(string outputFilename); 88 | void encodeMp4Pressed(); 89 | void encodeGifPressed(); 90 | ofPlanePrimitive cumulativeRenderPlane; 91 | void startWebcam(); 92 | void toggleWebcam(bool &val); 93 | void stopWebcam(); 94 | void freeUnusedResources(); 95 | void pauseResourcesForCurrentPlaybackState(); 96 | string createUniqueFilePath(string path); 97 | bool mouseScrolled(ofMouseEventArgs & args); 98 | void loadFfmpegPath(); 99 | void midiButtonPressed(); 100 | MidiMapper midiMapper; 101 | 102 | void newPresetButtonPressed(); 103 | void updateShaderJsonPressed(); 104 | }; 105 | -------------------------------------------------------------------------------- /bin/data/shaders/feedbackAudioShader.frag: -------------------------------------------------------------------------------- 1 | /* 2 | { 3 | "parameters" : [ 4 | { 5 | "name" : "intensity", 6 | "range" : { 7 | "x" : 0, 8 | "y" : 1 9 | }, 10 | "show" : true, 11 | "type" : "float", 12 | "value" : 0.75 13 | }, 14 | { 15 | "name" : "scale", 16 | "range" : { 17 | "x" : 0, 18 | "y" : 2 19 | }, 20 | "show" : true, 21 | "type" : "float", 22 | "value" : 1.0 23 | }, 24 | { 25 | "name" : "lastColMult", 26 | "value" : { 27 | "x" : 0, 28 | "y" : 1, 29 | "z" : 1 30 | }, 31 | "show" : true, 32 | "type" : "color" 33 | }, 34 | { 35 | "name" : "hue", 36 | "range" : { 37 | "x" : 0, 38 | "y" : 5 39 | }, 40 | "show" : true, 41 | "type" : "float", 42 | "value" : 0.1 43 | }, 44 | { 45 | "name" : "_NoiseTexture", 46 | "show" : true, 47 | "type" : "texture", 48 | "filePath" : "textures/noise_loop.png", 49 | "textureIndex" : 3 50 | }, 51 | { 52 | "name" : "audioTex", 53 | "show" : true, 54 | "type" : "texture", 55 | "textype" : "Audio", 56 | "textureIndex" : 3 57 | }, 58 | { 59 | "name" : "lastTex", 60 | "show" : true, 61 | "type" : "texture", 62 | "textype" : "Last", 63 | "textureIndex" : 2 64 | } 65 | ] 66 | } 67 | */ 68 | 69 | #version 150 70 | #pragma include "includes/hue.glsl" 71 | 72 | uniform sampler2D _MainTexture; 73 | uniform sampler2D lastTex; 74 | uniform sampler2D audioTex; 75 | 76 | uniform sampler2D _NoiseTexture; 77 | 78 | uniform float intensity; 79 | uniform float scale; 80 | uniform float hue; 81 | 82 | uniform float _Time; 83 | uniform vec2 _Resolution; 84 | 85 | uniform vec4 lastColMult; 86 | 87 | in vec2 texCoord; 88 | 89 | out vec4 outputColor; 90 | 91 | void main() 92 | { 93 | vec4 color = texture(_MainTexture, texCoord); 94 | 95 | vec2 texCoord_c = (gl_FragCoord.xy / _Resolution) * 2.0 - 1.0; 96 | float a = atan(texCoord_c.y, texCoord_c.x); 97 | vec2 texCoord_c_p = texCoord_c; 98 | texCoord_c_p.x *= _Resolution.x / _Resolution.y; 99 | float angleNoise = texture(_NoiseTexture, vec2((sin(1.57+a*2)*0.5+0.5)*400, (sin(-_Time*10.5 + length(texCoord_c_p)*0.25)*0.5+0.5)*126)).r; 100 | 101 | float audio = texture(audioTex, vec2(angleNoise, 0.)).r * clamp(length(texCoord_c)-0.125, 0., 1.)*4.; 102 | float l = length(texCoord_c)*0.5*(1.-audio*0.015); 103 | vec2 texCoord = vec2(cos(a), sin(a)) * l + 0.5; 104 | 105 | texCoord = (texCoord - 0.5) * scale + 0.5; 106 | 107 | vec4 lastColor = texture(lastTex, texCoord); 108 | float difference = min(1.,distance(lastColor.rgb, color.rgb)+.5); 109 | lastColor.rgb *= lastColMult.rgb; 110 | lastColor.rgb = hueShift(lastColor.rgb, hue); 111 | color.rgb += lastColor.rgb * min(10., (1. + audio) * intensity); 112 | outputColor = clamp(vec4(color), vec4(0.0), vec4(1.0)); 113 | } 114 | -------------------------------------------------------------------------------- /bin/data/presets/default.json: -------------------------------------------------------------------------------- 1 | { 2 | "blend" : 1, 3 | "data" : [ 4 | { 5 | "parameters" : [ 6 | { 7 | "name" : "size", 8 | "range" : { 9 | "x" : 0, 10 | "y" : 0.5 11 | }, 12 | "show" : true, 13 | "type" : "float", 14 | "value" : 0.25 15 | } 16 | ], 17 | "shaderName" : "shaders/shaderchain_logo" 18 | }, 19 | { 20 | "parameters" : [ 21 | { 22 | "name" : "offsetVal", 23 | "range" : { 24 | "x" : 0, 25 | "y" : 40 26 | }, 27 | "show" : true, 28 | "type" : "float", 29 | "value" : 25.86956405639648 30 | } 31 | ], 32 | "shaderName" : "shaders/multisample-hueshift" 33 | }, 34 | { 35 | "parameters" : [ 36 | { 37 | "name" : "blurSize", 38 | "range" : { 39 | "x" : 1, 40 | "y" : 32 41 | }, 42 | "show" : true, 43 | "type" : "float", 44 | "value" : 14.60869598388672 45 | }, 46 | { 47 | "name" : "brightness", 48 | "range" : { 49 | "x" : 0, 50 | "y" : 2 51 | }, 52 | "show" : true, 53 | "type" : "float", 54 | "value" : 0.5652173757553101 55 | } 56 | ], 57 | "shaderName" : "shaders/blurShader" 58 | }, 59 | { 60 | "parameters" : [ 61 | { 62 | "filePath" : "", 63 | "name" : "blendTex", 64 | "show" : true, 65 | "targetBufferName" : "multisample-hueshift", 66 | "textureIndex" : 2, 67 | "textype" : "Buffer", 68 | "type" : "texture" 69 | } 70 | ], 71 | "shaderName" : "shaders/blendShader" 72 | }, 73 | { 74 | "parameters" : [ 75 | { 76 | "name" : "intensity", 77 | "range" : { 78 | "x" : 0, 79 | "y" : 1 80 | }, 81 | "show" : true, 82 | "type" : "float", 83 | "value" : 0.5978260636329651 84 | }, 85 | { 86 | "name" : "scale", 87 | "range" : { 88 | "x" : 0, 89 | "y" : 2 90 | }, 91 | "show" : true, 92 | "type" : "float", 93 | "value" : 0.8804348111152649 94 | }, 95 | { 96 | "filePath" : "", 97 | "name" : "lastTex", 98 | "show" : true, 99 | "targetBufferName" : "", 100 | "textureIndex" : 2, 101 | "textype" : "Last", 102 | "type" : "texture" 103 | } 104 | ], 105 | "shaderName" : "shaders/feedbackShader" 106 | } 107 | ], 108 | "duration" : 6.283180236816406, 109 | "fps" : 30, 110 | "res" : { 111 | "x" : 500, 112 | "y" : 500 113 | }, 114 | "scale" : 1 115 | } 116 | 117 | -------------------------------------------------------------------------------- /bin/data/shaders/raymarchObjectShader.frag: -------------------------------------------------------------------------------- 1 | /* 2 | { 3 | "parameters" : [ 4 | { 5 | "name" : "focalLength", 6 | "range" : { 7 | "x" : 0, 8 | "y" : 10 9 | }, 10 | "show" : true, 11 | "type" : "float", 12 | "value" : 1.14130437374115 13 | }, 14 | { 15 | "name" : "minDist", 16 | "range" : { 17 | "x" : 0, 18 | "y" : 0.1000000014901161 19 | }, 20 | "show" : false, 21 | "type" : "float", 22 | "value" : 0.001000000047497451 23 | }, 24 | { 25 | "name" : "maxDist", 26 | "range" : { 27 | "x" : 0, 28 | "y" : 15 29 | }, 30 | "show" : true, 31 | "type" : "float", 32 | "value" : 12.30978298187256 33 | } 34 | ] 35 | } 36 | */ 37 | #version 150 38 | #pragma include "includes/hg_sdfs.glsl" 39 | 40 | uniform sampler2D tex0; 41 | uniform float _Time; 42 | uniform vec2 _Resolution; 43 | uniform vec3 _CamPos; 44 | uniform vec3 _CamForward; 45 | uniform vec3 _CamRight; 46 | uniform vec3 _CamUp; 47 | 48 | uniform float focalLength; 49 | 50 | uniform float minDist; 51 | uniform float maxDist; 52 | 53 | uniform vec4 bgColor; 54 | 55 | in vec2 uv; 56 | out vec4 outputColor; 57 | 58 | void pR(inout vec2 p, float a) { 59 | p = cos(a)*p + sin(a)*vec2(p.y, -p.x); 60 | } 61 | 62 | float map(in vec3 pos) { 63 | pos.z += cos(_Time) + smoothstep(1., 5., mod(_Time,6.28318)) * 20.; 64 | pos = mod(pos, vec3(1.))-vec3(.5); 65 | float dist = fBox(pos, vec3(0.05)); 66 | return dist; 67 | } 68 | 69 | float march(in vec3 camPos, in vec3 rayDir) { 70 | 71 | float dist = minDist; 72 | 73 | for (int i = 0; i < 35; i++) { 74 | vec3 p = camPos + rayDir * dist; 75 | float res = map(p); 76 | if (res <= minDist) break; 77 | dist += res; 78 | if (res >= maxDist) break; 79 | } 80 | 81 | return dist; 82 | } 83 | 84 | vec3 calcNormal(in vec3 pos) { 85 | vec3 eps = vec3(0.001, 0.0, 0.0); 86 | return normalize(vec3(map(pos + eps) - map(pos - eps), 87 | map(pos + eps.yxz) - map(pos - eps.yxz), 88 | map(pos + eps.yzx) - map(pos - eps.yzx))); 89 | } 90 | 91 | vec4 render(in vec3 camPos, in vec3 rayDir) { 92 | 93 | float dist = march(camPos, rayDir); 94 | vec3 fPos = camPos + rayDir * dist; 95 | vec3 nor = calcNormal(fPos); 96 | vec3 col = vec3(0.); 97 | float fres = (1.+dot(rayDir, nor)); 98 | col *= fres; 99 | col = mix(col, bgColor.rgb, clamp(dist/maxDist, 0.0, 1.0)); 100 | return vec4(col, dist); 101 | } 102 | #define AA 1 103 | 104 | void main() 105 | { 106 | vec4 color = vec4(0.); 107 | for (int j = 0; j < AA; j++) { 108 | for (int k = 0; k < AA; k++) 109 | { 110 | float f = focalLength + sin(_Time); 111 | vec2 o = vec2(float(j), float(k)) / float(AA); 112 | vec2 uv_c = uv * 2. - 1. ; 113 | uv_c.x *= _Resolution.x/_Resolution.y; 114 | vec3 ray = normalize (vec3(1., 0., 0.) * uv_c.x + 115 | vec3(0., 1., 0.) * uv_c.y + 116 | vec3(0., 0., 1.) * f); 117 | 118 | color += vec4(render(vec3(0.), ray)); 119 | } 120 | } 121 | 122 | color /= float(AA * AA); 123 | outputColor = color; 124 | } 125 | -------------------------------------------------------------------------------- /ofShaderChain.qbs: -------------------------------------------------------------------------------- 1 | import qbs 2 | import qbs.Process 3 | import qbs.File 4 | import qbs.FileInfo 5 | import qbs.TextFile 6 | import "../../../libs/openFrameworksCompiled/project/qtcreator/ofApp.qbs" as ofApp 7 | 8 | Project{ 9 | property string of_root: "../../.." 10 | 11 | ofApp { 12 | name: { return ShaderChain } 13 | 14 | files: [ 15 | 'src/FFTManager.cpp', 16 | 'src/FFTManager.h', 17 | 'src/PNGRenderer.cpp', 18 | 'src/PNGRenderer.h', 19 | 'src/Parameters/FloatParameter.cpp', 20 | 'src/Parameters/FloatParameter.h', 21 | 'src/Parameters/Parameter.cpp', 22 | 'src/Parameters/Parameter.h', 23 | 'src/Parameters/TextureParameter.cpp', 24 | 'src/Parameters/TextureParameter.h', 25 | 'src/Parameters/Vector3Parameter.cpp', 26 | 'src/Parameters/Vector3Parameter.h', 27 | 'src/ShaderChain.cpp', 28 | 'src/ShaderChain.h', 29 | 'src/ShaderPass.cpp', 30 | 'src/ShaderPass.h', 31 | 'src/main.cpp', 32 | 'src/ofApp.cpp', 33 | 'src/ofApp.h', 34 | 'src/ofxAutoReloadedShader.cpp', 35 | 'src/ofxAutoReloadedShader.h', 36 | ] 37 | 38 | of.addons: [ 39 | 'ofxFft', 40 | 'ofxGui', 41 | 'ofxJSON', 42 | 'ofxMidi', 43 | ] 44 | 45 | // additional flags for the project. the of module sets some 46 | // flags by default to add the core libraries, search paths... 47 | // this flags can be augmented through the following properties: 48 | of.pkgConfigs: [] // list of additional system pkgs to include 49 | of.includePaths: [] // include search paths 50 | of.cFlags: [] // flags passed to the c compiler 51 | of.cxxFlags: [] // flags passed to the c++ compiler 52 | of.linkerFlags: [] // flags passed to the linker 53 | of.defines: [] // defines are passed as -D to the compiler 54 | // and can be checked with #ifdef or #if in the code 55 | of.frameworks: [] // osx only, additional frameworks to link with the project 56 | of.staticLibraries: [] // static libraries 57 | of.dynamicLibraries: [] // dynamic libraries 58 | 59 | // other flags can be set through the cpp module: http://doc.qt.io/qbs/cpp-module.html 60 | // eg: this will enable ccache when compiling 61 | // 62 | // cpp.compilerWrapper: 'ccache' 63 | 64 | Depends{ 65 | name: "cpp" 66 | } 67 | 68 | // common rules that parse the include search paths, core libraries... 69 | Depends{ 70 | name: "of" 71 | } 72 | 73 | // dependency with the OF library 74 | Depends{ 75 | name: "openFrameworks" 76 | } 77 | } 78 | 79 | property bool makeOF: true // use makfiles to compile the OF library 80 | // will compile OF only once for all your projects 81 | // otherwise compiled per project with qbs 82 | 83 | 84 | property bool precompileOfMain: false // precompile ofMain.h 85 | // faster to recompile when including ofMain.h 86 | // but might use a lot of space per project 87 | 88 | references: [FileInfo.joinPaths(of_root, "/libs/openFrameworksCompiled/project/qtcreator/openFrameworks.qbs")] 89 | } 90 | -------------------------------------------------------------------------------- /bin/data/includes/hg_sdfs.glsl: -------------------------------------------------------------------------------- 1 | //////////////////////////////////////////////////////////////// 2 | // 3 | // HG_SDF 4 | // 5 | // GLSL LIBRARY FOR BUILDING SIGNED DISTANCE BOUNDS 6 | // 7 | // version 2016-01-10 8 | // 9 | // Check http://mercury.sexy/hg_sdf for updates 10 | // and usage examples. Send feedback to spheretracing@mercury.sexy. 11 | // 12 | // Brought to you by MERCURY http://mercury.sexy 13 | // 14 | // 15 | // 16 | // Released as Creative Commons Attribution-NonCommercial (CC BY-NC) 17 | // 18 | //////////////////////////////////////////////////////////////// 19 | #define PHI (sqrt(5)*0.5 + 0.5) 20 | // 21 | // "Generalized Distance Functions" by Akleman and Chen. 22 | // see the Paper at https://www.viz.tamu.edu/faculty/ergun/research/implicitmodeling/papers/sm99.pdf 23 | // 24 | // This set of constants is used to construct a large variety of geometric primitives. 25 | // Indices are shifted by 1 compared to the paper because we start counting at Zero. 26 | // Some of those are slow whenever a driver decides to not unroll the loop, 27 | // which seems to happen for fIcosahedron und fTruncatedIcosahedron on nvidia 350.12 at least. 28 | // Specialized implementations can well be faster in all cases. 29 | // 30 | float fPlane(vec3 p, vec3 n, float distanceFromOrigin) { 31 | return dot(p, n) + distanceFromOrigin; 32 | } 33 | 34 | float vmax(vec3 v) { 35 | return max(max(v.x, v.y), v.z); 36 | } 37 | 38 | float fBox(vec3 p, vec3 b) { 39 | vec3 d = abs(p) - b; 40 | return length(max(d, vec3(0))) + vmax(min(d, vec3(0))); 41 | } 42 | 43 | const vec3 GDFVectors[19] = vec3[]( 44 | normalize(vec3(1, 0, 0)), 45 | normalize(vec3(0, 1, 0)), 46 | normalize(vec3(0, 0, 1)), 47 | 48 | normalize(vec3(1, 1, 1 )), 49 | normalize(vec3(-1, 1, 1)), 50 | normalize(vec3(1, -1, 1)), 51 | normalize(vec3(1, 1, -1)), 52 | 53 | normalize(vec3(0, 1, PHI+1)), 54 | normalize(vec3(0, -1, PHI+1)), 55 | normalize(vec3(PHI+1, 0, 1)), 56 | normalize(vec3(-PHI-1, 0, 1)), 57 | normalize(vec3(1, PHI+1, 0)), 58 | normalize(vec3(-1, PHI+1, 0)), 59 | 60 | normalize(vec3(0, PHI, 1)), 61 | normalize(vec3(0, -PHI, 1)), 62 | normalize(vec3(1, 0, PHI)), 63 | normalize(vec3(-1, 0, PHI)), 64 | normalize(vec3(PHI, 1, 0)), 65 | normalize(vec3(-PHI, 1, 0)) 66 | ); 67 | 68 | // Version with variable exponent. 69 | // This is slow and does not produce correct distances, but allows for bulging of objects. 70 | float fGDF(vec3 p, float r, float e, int begin, int end) { 71 | float d = 0; 72 | for (int i = begin; i <= end; ++i) 73 | d += pow(abs(dot(p, GDFVectors[i])), e); 74 | return pow(d, 1/e) - r; 75 | } 76 | 77 | // Version with without exponent, creates objects with sharp edges and flat faces 78 | float fGDF(vec3 p, float r, int begin, int end) { 79 | float d = 0; 80 | for (int i = begin; i <= end; ++i) 81 | d = max(d, abs(dot(p, GDFVectors[i]))); 82 | return d - r; 83 | } 84 | 85 | // Primitives follow: 86 | 87 | float fOctahedron(vec3 p, float r, float e) { 88 | return fGDF(p, r, e, 3, 6); 89 | } 90 | 91 | float fDodecahedron(vec3 p, float r, float e) { 92 | return fGDF(p, r, e, 13, 18); 93 | } 94 | 95 | float fIcosahedron(vec3 p, float r, float e) { 96 | return fGDF(p, r, e, 3, 12); 97 | } 98 | 99 | float fTruncatedOctahedron(vec3 p, float r, float e) { 100 | return fGDF(p, r, e, 0, 6); 101 | } 102 | 103 | float fTruncatedIcosahedron(vec3 p, float r, float e) { 104 | return fGDF(p, r, e, 3, 18); 105 | } 106 | 107 | float fOctahedron(vec3 p, float r) { 108 | return fGDF(p, r, 3, 6); 109 | } 110 | 111 | float fDodecahedron(vec3 p, float r) { 112 | return fGDF(p, r, 13, 18); 113 | } 114 | 115 | float fIcosahedron(vec3 p, float r) { 116 | return fGDF(p, r, 3, 12); 117 | } 118 | 119 | float fTruncatedOctahedron(vec3 p, float r) { 120 | return fGDF(p, r, 0, 6); 121 | } 122 | 123 | float fTruncatedIcosahedron(vec3 p, float r) { 124 | return fGDF(p, r, 3, 18); 125 | } 126 | -------------------------------------------------------------------------------- /src/gui/TextureInputSelectionView.cpp: -------------------------------------------------------------------------------- 1 | #include "TextureInputSelectionView.h" 2 | 3 | TextureInputSelectionView::TextureInputSelectionView() { 4 | this->panel = gui.addContainer(); 5 | 6 | this->openFromFileButton.addListener(this, &TextureInputSelectionView::openFromFileButtonPressed); 7 | this->openFromWebcamButton.addListener(this, &TextureInputSelectionView::openFromWebcamButtonPressed); 8 | this->cancelButton.addListener(this, &TextureInputSelectionView::cancelButtonPressed); 9 | this->openFromAudioButton.addListener(this, &TextureInputSelectionView::audioButtonPressed); 10 | this->panel->setEnabled(false); 11 | } 12 | 13 | TextureInputSelectionView::~TextureInputSelectionView() { 14 | deleteParams(); 15 | } 16 | 17 | void TextureInputSelectionView::deleteParams() { 18 | for (unsigned int i = 0; i < bufferParameters.size(); i++) { 19 | delete bufferParameters[i]; 20 | } 21 | bufferParameters.clear(); 22 | } 23 | 24 | void TextureInputSelectionView::show() { 25 | this->panel->clear(); 26 | deleteParams(); 27 | this->bufferButtons.clear(); 28 | this->panel->add(openFromFileButton.set("Open From File"), ofJson({{"type", "fullsize"}, {"text-align", "center"}})); 29 | this->panel->add(openFromWebcamButton.set("Webcam"), ofJson({{"type", "fullsize"}, {"text-align", "center"}})); 30 | this->panel->add(openFromAudioButton.set("Audio"), ofJson({{"type", "fullsize"}, {"text-align", "center"}})); 31 | 32 | for (unsigned int i = 0; i < passNames.size(); i++) { 33 | ofParameter *passParameter = new ofParameter(); 34 | passParameter->addListener(this, &TextureInputSelectionView::bufferButtonPressed); 35 | bufferParameters.push_back(passParameter); 36 | ofxGuiButton *btn = this->panel->add(passParameter->set(passNames[i]), ofJson({{"type", "fullsize"}, {"text-align", "center"}}) ); 37 | this->bufferButtons.push_back(btn); 38 | } 39 | 40 | this->panel->add(cancelButton.set("Cancel"), ofJson({{"type", "fullsize"}, {"text-align", "center"}})); 41 | 42 | this->panel->setPosition(ofPoint(ofGetWidth()/2-this->panel->getWidth()/2, ofGetHeight()/2-this->panel->getHeight()/2)); 43 | 44 | this->panel->setEnabled(true); 45 | } 46 | 47 | void TextureInputSelectionView::hide() { 48 | this->panel->setEnabled(false); 49 | ofNotifyEvent(hideEvent); 50 | } 51 | 52 | void TextureInputSelectionView::openFromFileButtonPressed() { 53 | if (!this->panel->isEnabled()) return; 54 | 55 | cout << "Open from file" << endl; 56 | 57 | if (!isShowingFileDialogue) { 58 | isShowingFileDialogue = true; 59 | ofFileDialogResult result = ofSystemLoadDialog("Load file",system("pwd")); 60 | if (result.bSuccess) { 61 | ofNotifyEvent(selectedFilePathChanged, result.filePath); 62 | } 63 | hide(); 64 | isShowingFileDialogue = false; 65 | } 66 | } 67 | 68 | void TextureInputSelectionView::openFromWebcamButtonPressed() { 69 | if (!this->panel->isEnabled()) return; 70 | 71 | hide(); 72 | updateWebcam(true); 73 | } 74 | 75 | void TextureInputSelectionView::bufferButtonPressed() { 76 | if (!this->panel->isEnabled()) return; 77 | 78 | for (unsigned int i = 0; i < bufferButtons.size(); i++) { 79 | if (bufferButtons[i]->isMouseOver()) { 80 | string s = bufferButtons[i]->getName(); 81 | ofNotifyEvent(selectedBufferChanged, s); 82 | break; 83 | } 84 | } 85 | hide(); 86 | } 87 | 88 | void TextureInputSelectionView::updateWebcam(bool val) { 89 | ofNotifyEvent(wantsWebcamChanged, val); 90 | } 91 | 92 | void TextureInputSelectionView::cancelButtonPressed() { 93 | hide(); 94 | } 95 | 96 | void TextureInputSelectionView::audioButtonPressed() { 97 | if (!this->panel->isEnabled()) return; 98 | updateAudio(true); 99 | hide(); 100 | } 101 | 102 | void TextureInputSelectionView::updateAudio(bool val) { 103 | ofNotifyEvent(wantsAudioChanged, val); 104 | } 105 | -------------------------------------------------------------------------------- /bin/data/includes/noise.glsl: -------------------------------------------------------------------------------- 1 | // Simplex 3D Noise 2 | // by Ian McEwan, Ashima Arts 3 | // 4 | vec4 permute(vec4 x){return mod(((x*34.0)+1.0)*x, 289.0);} 5 | vec4 taylorInvSqrt(vec4 r){return 1.79284291400159 - 0.85373472095314 * r;} 6 | 7 | float snoise(vec3 v){ 8 | const vec2 C = vec2(1.0/6.0, 1.0/3.0) ; 9 | const vec4 D = vec4(0.0, 0.5, 1.0, 2.0); 10 | 11 | // First corner 12 | vec3 i = floor(v + dot(v, C.yyy) ); 13 | vec3 x0 = v - i + dot(i, C.xxx) ; 14 | 15 | // Other corners 16 | vec3 g = step(x0.yzx, x0.xyz); 17 | vec3 l = 1.0 - g; 18 | vec3 i1 = min( g.xyz, l.zxy ); 19 | vec3 i2 = max( g.xyz, l.zxy ); 20 | 21 | // x0 = x0 - 0. + 0.0 * C 22 | vec3 x1 = x0 - i1 + 1.0 * C.xxx; 23 | vec3 x2 = x0 - i2 + 2.0 * C.xxx; 24 | vec3 x3 = x0 - 1. + 3.0 * C.xxx; 25 | 26 | // Permutations 27 | i = mod(i, 289.0 ); 28 | vec4 p = permute( permute( permute( 29 | i.z + vec4(0.0, i1.z, i2.z, 1.0 )) 30 | + i.y + vec4(0.0, i1.y, i2.y, 1.0 )) 31 | + i.x + vec4(0.0, i1.x, i2.x, 1.0 )); 32 | 33 | // Gradients 34 | // ( N*N points uniformly over a square, mapped onto an octahedron.) 35 | float n_ = 1.0/7.0; // N=7 36 | vec3 ns = n_ * D.wyz - D.xzx; 37 | 38 | vec4 j = p - 49.0 * floor(p * ns.z *ns.z); // mod(p,N*N) 39 | 40 | vec4 x_ = floor(j * ns.z); 41 | vec4 y_ = floor(j - 7.0 * x_ ); // mod(j,N) 42 | 43 | vec4 x = x_ *ns.x + ns.yyyy; 44 | vec4 y = y_ *ns.x + ns.yyyy; 45 | vec4 h = 1.0 - abs(x) - abs(y); 46 | 47 | vec4 b0 = vec4( x.xy, y.xy ); 48 | vec4 b1 = vec4( x.zw, y.zw ); 49 | 50 | vec4 s0 = floor(b0)*2.0 + 1.0; 51 | vec4 s1 = floor(b1)*2.0 + 1.0; 52 | vec4 sh = -step(h, vec4(0.0)); 53 | 54 | vec4 a0 = b0.xzyw + s0.xzyw*sh.xxyy ; 55 | vec4 a1 = b1.xzyw + s1.xzyw*sh.zzww ; 56 | 57 | vec3 p0 = vec3(a0.xy,h.x); 58 | vec3 p1 = vec3(a0.zw,h.y); 59 | vec3 p2 = vec3(a1.xy,h.z); 60 | vec3 p3 = vec3(a1.zw,h.w); 61 | 62 | //Normalise gradients 63 | vec4 norm = taylorInvSqrt(vec4(dot(p0,p0), dot(p1,p1), dot(p2, p2), dot(p3,p3))); 64 | p0 *= norm.x; 65 | p1 *= norm.y; 66 | p2 *= norm.z; 67 | p3 *= norm.w; 68 | 69 | // Mix final noise value 70 | vec4 m = max(0.6 - vec4(dot(x0,x0), dot(x1,x1), dot(x2,x2), dot(x3,x3)), 0.0); 71 | m = m * m; 72 | return 42.0 * dot( m*m, vec4( dot(p0,x0), dot(p1,x1), 73 | dot(p2,x2), dot(p3,x3) ) ); 74 | } 75 | 76 | //noise function from 77 | //https://gist.github.com/patriciogonzalezvivo/670c22f3966e662d2f83 78 | float rand(vec2 n) { 79 | return fract(sin(dot(n, vec2(12.9898, 4.1414))) * 43758.5453); 80 | } 81 | 82 | float noise(vec2 p){ 83 | vec2 ip = floor(p); 84 | vec2 u = fract(p); 85 | u = u*u*(3.0-2.0*u); 86 | 87 | float res = mix( 88 | mix(rand(ip),rand(ip+vec2(1.0,0.0)),u.x), 89 | mix(rand(ip+vec2(0.0,1.0)),rand(ip+vec2(1.0,1.0)),u.x),u.y); 90 | return res*res; 91 | } 92 | 93 | float fbm(vec2 p) { 94 | float r = 0.0; 95 | float amp = 1.0; 96 | float freq = 1.0; 97 | for(int i = 0; i < 10; i++) { 98 | r += amp * noise(freq*p); 99 | amp *= 0.5; 100 | freq *= 1.0/0.5; 101 | } 102 | return r; 103 | } 104 | vec2 hash( vec2 p ) // replace this by something better 105 | { 106 | p = vec2( dot(p,vec2(127.1,311.7)), dot(p,vec2(269.5,183.3)) ); 107 | return -1.0 + 2.0*fract(sin(p)*43758.5453123); 108 | } 109 | 110 | float snoise( in vec2 p ) 111 | { 112 | const float K1 = 0.366025404; // (sqrt(3)-1)/2; 113 | const float K2 = 0.211324865; // (3-sqrt(3))/6; 114 | 115 | vec2 i = floor( p + (p.x+p.y)*K1 ); 116 | vec2 a = p - i + (i.x+i.y)*K2; 117 | float m = step(a.y,a.x); 118 | vec2 o = vec2(m,1.0-m); 119 | vec2 b = a - o + K2; 120 | vec2 c = a - 1.0 + 2.0*K2; 121 | vec3 h = max( 0.5-vec3(dot(a,a), dot(b,b), dot(c,c) ), 0.0 ); 122 | vec3 n = h*h*h*h*vec3( dot(a,hash(i+0.0)), dot(b,hash(i+o)), dot(c,hash(i+1.0))); 123 | return dot( n, vec3(70.0) ); 124 | } 125 | float fbm(vec3 p) { 126 | float r = 0.0; 127 | float amp = .8; 128 | float freq = 1.0; 129 | for(int i = 0; i < 10; i++) { 130 | r += amp * snoise(freq*p); 131 | amp *= 0.55; 132 | freq *= 1.0/0.55; 133 | } 134 | return r; 135 | } 136 | -------------------------------------------------------------------------------- /src/gui/ofxGuiTextureInput.cpp: -------------------------------------------------------------------------------- 1 | // Fork of ofxGuiExtended ofxGuiTextureInput.cpp 2 | 3 | #include "ofxGuiTextureInput.h" 4 | #include "ofGraphics.h" 5 | using namespace std; 6 | 7 | ofxGuiTextureInput::~ofxGuiTextureInput(){ 8 | ofRemoveListener(resize, this, &ofxGuiTextureInput::onResize); 9 | } 10 | 11 | ofxGuiTextureInput::ofxGuiTextureInput(std::string canvasName, TextureInputSelectionView *selectionView, const ofJson& config) { 12 | _bLoaded = false; 13 | graphics = nullptr; 14 | setup(canvasName); 15 | _setConfig(config); 16 | this->selectionView = selectionView; 17 | } 18 | 19 | ofxGuiTextureInput::ofxGuiTextureInput(std::string canvasName, ofBaseDraws * graphics, const ofJson& config) 20 | :ofxGuiElement(){ 21 | _bLoaded = false; 22 | setGraphics(graphics); 23 | setup(canvasName); 24 | _setConfig(config); 25 | } 26 | 27 | ofxGuiTextureInput::ofxGuiTextureInput(std::string canvasName, ofBaseDraws * graphics, float w, float h){ 28 | _bLoaded = false; 29 | setGraphics(graphics); 30 | setup(canvasName,w,h); 31 | } 32 | 33 | void ofxGuiTextureInput::setup(std::string canvasName, float w, float h){ 34 | autoWidth = false; 35 | autoHeight = false; 36 | setName(canvasName); 37 | if(_bLoaded){ 38 | if(w == 0){ 39 | if(h == 0){ 40 | w = getWidth(); 41 | }else{ 42 | w = h * graphics->getWidth() / graphics->getHeight(); 43 | } 44 | } 45 | h = w * graphics->getHeight() / graphics->getWidth(); 46 | ofxGuiElement::setSize(w,h); 47 | } 48 | setTheme(); 49 | ofAddListener(resize, this, &ofxGuiTextureInput::onResize); 50 | } 51 | 52 | void ofxGuiTextureInput::setGraphics(ofBaseDraws *graphics){ 53 | if(graphics){ 54 | if(graphics->getHeight() != 0 && graphics->getWidth() != 0){ 55 | _bLoaded = true; 56 | this->graphics = graphics; 57 | }else{ 58 | ofLogWarning("ofxGuiTextureInput:setGraphics()", "graphics cannot be loaded, width = 0 or height = 0"); 59 | } 60 | }else{ 61 | ofLogWarning("ofxGuiTextureInput:setGraphics()", "graphics is nullptr"); 62 | } 63 | } 64 | 65 | float ofxGuiTextureInput::getMinWidth(){ 66 | float _width = 0; 67 | if(showName){ 68 | _width += ofxGuiElement::getTextWidth(getName()) + 2*textPadding; 69 | } 70 | return _width; 71 | } 72 | 73 | float ofxGuiTextureInput::getMinHeight(){ 74 | if(showName){ 75 | return ofxGuiElement::getTextHeight(getName()); 76 | } 77 | return 0; 78 | } 79 | 80 | void ofxGuiTextureInput::setAutoHeight(){ 81 | autoHeight = true; 82 | autoWidth = false; 83 | setHeight(getWidth() * graphics->getHeight() / graphics->getWidth()); 84 | } 85 | 86 | void ofxGuiTextureInput::setAutoWidth(){ 87 | autoHeight = false; 88 | autoWidth = true; 89 | setWidth(getHeight() * graphics->getWidth() / graphics->getHeight()); 90 | } 91 | 92 | void ofxGuiTextureInput::onResize(DOM::ResizeEventArgs &args){ 93 | if(autoHeight){ 94 | setHeight(args.shape().width * graphics->getHeight() / graphics->getWidth()); 95 | } 96 | if(autoWidth){ 97 | setWidth(args.shape().height * graphics->getWidth() / graphics->getHeight()); 98 | } 99 | } 100 | 101 | void ofxGuiTextureInput::generateDraw(){ 102 | ofxGuiElement::generateDraw(); 103 | 104 | if(showName){ 105 | textMesh = getTextMesh(getName(), textPadding, getHeight() - textPadding); 106 | } 107 | } 108 | 109 | void ofxGuiTextureInput::render(){ 110 | 111 | ofxGuiElement::render(); 112 | 113 | ofColor c = ofGetStyle().color; 114 | 115 | if(_bLoaded && graphics){ 116 | graphics->draw(0, 0, getWidth(), getHeight()); 117 | } 118 | 119 | if(showName){ 120 | ofBlendMode blendMode = ofGetStyle().blendingMode; 121 | if(blendMode != OF_BLENDMODE_ALPHA){ 122 | ofEnableAlphaBlending(); 123 | } 124 | ofSetColor(textColor); 125 | 126 | bindFontTexture(); 127 | textMesh.draw(); 128 | unbindFontTexture(); 129 | 130 | ofSetColor(c); 131 | if(blendMode != OF_BLENDMODE_ALPHA){ 132 | ofEnableBlendMode(blendMode); 133 | } 134 | } 135 | } 136 | 137 | ofAbstractParameter & ofxGuiTextureInput::getParameter(){ 138 | return label; 139 | } 140 | 141 | std::string ofxGuiTextureInput::getClassType(){ 142 | return "graphics"; 143 | } 144 | 145 | vector ofxGuiTextureInput::getClassTypes(){ 146 | vector types = ofxGuiElement::getClassTypes(); 147 | types.push_back(getClassType()); 148 | return types; 149 | } 150 | 151 | 152 | bool ofxGuiTextureInput::mouseReleased(ofMouseEventArgs & args){ 153 | if (isMouseOver()) { 154 | ofNotifyEvent(showEvent); 155 | selectionView->show(); 156 | } 157 | return false; 158 | } 159 | -------------------------------------------------------------------------------- /bin/data/presets/audio2dKifs.json: -------------------------------------------------------------------------------- 1 | { 2 | "blend" : 1, 3 | "data" : [ 4 | { 5 | "parameters" : [ 6 | { 7 | "name" : "cellOffset", 8 | "range" : { 9 | "x" : 0, 10 | "y" : 1 11 | }, 12 | "show" : true, 13 | "type" : "float", 14 | "value" : 0.3478260934352875 15 | }, 16 | { 17 | "name" : "phase", 18 | "range" : { 19 | "x" : 0, 20 | "y" : 6.28000020980835 21 | }, 22 | "show" : true, 23 | "type" : "float", 24 | "value" : 1.228695631027222 25 | }, 26 | { 27 | "name" : "startScale", 28 | "range" : { 29 | "x" : 0.1000000014901161, 30 | "y" : 1 31 | }, 32 | "show" : true, 33 | "type" : "float", 34 | "value" : 0.2858695685863495 35 | }, 36 | { 37 | "name" : "scalingFactor", 38 | "range" : { 39 | "x" : 0.1000000014901161, 40 | "y" : 2 41 | }, 42 | "show" : true, 43 | "type" : "float", 44 | "value" : 1.339130520820618 45 | }, 46 | { 47 | "name" : "offset", 48 | "range" : { 49 | "x" : 0, 50 | "y" : 1 51 | }, 52 | "show" : true, 53 | "type" : "vec2", 54 | "value" : { 55 | "x" : 1, 56 | "y" : 0 57 | } 58 | }, 59 | { 60 | "accumulate" : true, 61 | "expFactor" : 2, 62 | "frequencyRange" : { 63 | "x" : 10, 64 | "y" : 200 65 | }, 66 | "name" : "audioac", 67 | "range" : { 68 | "x" : 0, 69 | "y" : 6.283185482025146 70 | }, 71 | "scaleFactor" : 0.2000000029802322, 72 | "show" : true, 73 | "type" : "audioFloat" 74 | } 75 | ], 76 | "shaderName" : "shaders/2d_kifs_audio" 77 | }, 78 | { 79 | "parameters" : [ 80 | { 81 | "name" : "intensity", 82 | "range" : { 83 | "x" : 0, 84 | "y" : 1 85 | }, 86 | "show" : true, 87 | "type" : "float", 88 | "value" : 0.79347825050354 89 | }, 90 | { 91 | "name" : "scale", 92 | "range" : { 93 | "x" : 0, 94 | "y" : 2 95 | }, 96 | "show" : true, 97 | "type" : "float", 98 | "value" : 1 99 | }, 100 | { 101 | "name" : "lastColMult", 102 | "show" : true, 103 | "type" : "color", 104 | "value" : { 105 | "a" : 0, 106 | "b" : 168, 107 | "g" : 113, 108 | "r" : 165 109 | } 110 | }, 111 | { 112 | "name" : "hue", 113 | "range" : { 114 | "x" : 0, 115 | "y" : 5 116 | }, 117 | "show" : true, 118 | "type" : "float", 119 | "value" : 0.7880434989929199 120 | }, 121 | { 122 | "filePath" : "textures/noise_loop.png", 123 | "name" : "_NoiseTexture", 124 | "show" : true, 125 | "targetBufferName" : "", 126 | "textureIndex" : 3, 127 | "textype" : "ImageFile", 128 | "type" : "texture" 129 | }, 130 | { 131 | "filePath" : "", 132 | "name" : "audioTex", 133 | "show" : true, 134 | "targetBufferName" : "", 135 | "textureIndex" : 3, 136 | "textype" : "Audio", 137 | "type" : "texture" 138 | }, 139 | { 140 | "filePath" : "", 141 | "name" : "lastTex", 142 | "show" : true, 143 | "targetBufferName" : "", 144 | "textureIndex" : 2, 145 | "textype" : "Last", 146 | "type" : "texture" 147 | } 148 | ], 149 | "shaderName" : "shaders/feedbackAudioShader" 150 | } 151 | ], 152 | "duration" : 6.283180236816406, 153 | "fps" : 30, 154 | "res" : { 155 | "x" : 1920, 156 | "y" : 1080 157 | }, 158 | "scale" : 1 159 | } 160 | 161 | -------------------------------------------------------------------------------- /bin/data/shaders/2d_kifs_audio.frag: -------------------------------------------------------------------------------- 1 | /* 2 | { 3 | "parameters" : [ 4 | { 5 | "name" : "cellOffset", 6 | "range" : { 7 | "x" : 0, 8 | "y" : 1 9 | }, 10 | "show" : true, 11 | "type" : "float", 12 | "midi" : 1, 13 | "value" : 0.1 14 | }, 15 | { 16 | "name" : "phase", 17 | "range" : { 18 | "x" : 0, 19 | "y" : 6.28 20 | }, 21 | "show" : true, 22 | "type" : "float", 23 | "midi" : 2, 24 | "value" : 1.0 25 | }, 26 | { 27 | "name" : "startScale", 28 | "range" : { 29 | "x" : 0.1, 30 | "y" : 1 31 | }, 32 | "show" : true, 33 | "type" : "float", 34 | "midi" : 3, 35 | "value" : 0.5 36 | }, 37 | { 38 | "name" : "scalingFactor", 39 | "range" : { 40 | "x" : 0.1, 41 | "y" : 2 42 | }, 43 | "show" : true, 44 | "type" : "float", 45 | "midi" : 4, 46 | "value" : 0.5 47 | }, 48 | { 49 | "name" : "offset", 50 | "range" : { 51 | "x" : 0, 52 | "y" : 1 53 | }, 54 | "show" : true, 55 | "type" : "vec2", 56 | "value" : { 57 | "x": 0.5, 58 | "y": 0.5 59 | }, 60 | "midi" : { 61 | "x": 5, 62 | "y": 6 63 | } 64 | }, 65 | { 66 | "name" : "audioac", 67 | "range" : { 68 | "x" : 0, 69 | "y" : 6.2831853 70 | }, 71 | "frequencyRange" : { 72 | "x" : 0, 73 | "y" : 200 74 | }, 75 | "scaleFactor" : 0.2, 76 | "expFactor" : 2, 77 | "accumulate" : true, 78 | "show" : true, 79 | "type" : "audioFloat", 80 | "value" : 0 81 | } 82 | ] 83 | } 84 | */ 85 | 86 | #version 150 87 | 88 | in vec2 uv; 89 | out vec4 outputColor; 90 | 91 | uniform float _Time; 92 | uniform sampler2D _MainTexture; 93 | uniform vec2 _Resolution; 94 | 95 | uniform float cellOffset; 96 | uniform float startScale; 97 | uniform float scalingFactor; 98 | uniform float phase; 99 | uniform vec2 offset; 100 | uniform float audioac; 101 | 102 | void pR(inout vec2 p, float a) { 103 | p = cos(a)*p + sin(a)*vec2(p.y, -p.x); 104 | } 105 | 106 | vec2 hash( vec2 p ) // replace this by something better 107 | { 108 | p = vec2( dot(p,vec2(127.1,311.7)), dot(p,vec2(269.5,183.3)) ); 109 | return -1.0 + 2.0*fract(sin(p)*43758.5453123); 110 | } 111 | 112 | float noise( in vec2 p ) 113 | { 114 | const float K1 = 0.366025404; // (sqrt(3)-1)/2; 115 | const float K2 = 0.211324865; // (3-sqrt(3))/6; 116 | 117 | vec2 i = floor( p + (p.x+p.y)*K1 ); 118 | vec2 a = p - i + (i.x+i.y)*K2; 119 | float m = step(a.y,a.x); 120 | vec2 o = vec2(m,1.0-m); 121 | vec2 b = a - o + K2; 122 | vec2 c = a - 1.0 + 2.0*K2; 123 | vec3 h = max( 0.5-vec3(dot(a,a), dot(b,b), dot(c,c) ), 0.0 ); 124 | vec3 n = h*h*h*h*vec3( dot(a,hash(i+0.0)), dot(b,hash(i+o)), dot(c,hash(i+1.0))); 125 | return dot( n, vec3(70.0) ); 126 | } 127 | 128 | 129 | float fbm(in vec2 x) 130 | { 131 | const int passes = 2; 132 | float res = 0.; 133 | float scale = 1.0; 134 | 135 | for (int i = 0; i < passes; i++) 136 | { 137 | res += noise(x) * scale; 138 | x *= 2.0; 139 | scale *= 0.666; 140 | } 141 | return res; 142 | } 143 | 144 | float sdBox( vec2 p, vec2 b ) 145 | { 146 | vec2 d = abs(p) - b; 147 | return length(max(d,0.0)) 148 | + min(max(d.x,d.y),0.0); // remove this line for an only partially signed sdf 149 | } 150 | 151 | float coolBox(vec2 uv, vec2 b) 152 | { 153 | float dist = sdBox(uv, b); 154 | return smoothstep(0.01, 0.0, abs(dist)); 155 | } 156 | 157 | float shape (vec2 uv, float size, float t) 158 | { 159 | return mix(coolBox(uv, vec2(size)), 160 | smoothstep(0.001, -0.001, max(-(length(uv)-size),length(uv)-size*1.025)), t); 161 | } 162 | 163 | vec2 opU(vec2 a, vec2 b) 164 | { 165 | return a.x > b.x ? a : b; 166 | } 167 | 168 | void main() { 169 | vec2 uv = uv; 170 | float t = audioac * 2.; 171 | 172 | vec2 centerOffset = vec2(cos(t), sin(t))*0.015; 173 | uv += centerOffset; 174 | 175 | float scale = startScale; 176 | 177 | vec2 dist = vec2(0., -1.); 178 | const int passes = 6; 179 | 180 | vec2 offs = offset; 181 | uv = uv * 2.0 - 1.0; 182 | uv.x *= _Resolution.x / _Resolution.y; 183 | 184 | for (int i = 0; i < passes; i++) 185 | { 186 | uv = abs(uv); 187 | 188 | scale /= scalingFactor; 189 | 190 | vec2 cell = floor(uv / scale); 191 | 192 | offs.xy *= (1. + sin(cell.x+cell.y+float(i)*0.5+t)*cellOffset); 193 | 194 | uv -= offs * scale; 195 | pR(uv, t + phase + float(i)*0.25+ noise(vec2(cell.x+cell.y+float(i),t))*cellOffset); 196 | dist = opU(dist,vec2(shape(uv, scale, 0.5), i)); 197 | } 198 | 199 | vec4 col = vec4(1.); 200 | col.rgb = vec3(dist.x); 201 | 202 | outputColor = col; 203 | } 204 | -------------------------------------------------------------------------------- /src/FFTManager.cpp: -------------------------------------------------------------------------------- 1 | #include "FFTManager.h" 2 | 3 | FFTManager::FFTManager() { 4 | fft = nullptr; 5 | playingState.set("-"); 6 | dampening.set("Dampening", dampening, 0.0, 1.0); 7 | isMicrophoneEnabled.set("Use Microphone", isMicrophoneEnabled); 8 | volume.set("Volume", volume, 0.0, 1.0); 9 | removeTrackButton.set("Remove track"); 10 | this->volume = 1.0; 11 | } 12 | 13 | FFTManager::~FFTManager() { 14 | if (fft != nullptr) { 15 | delete fft; 16 | } 17 | } 18 | 19 | void FFTManager::StartMicInput() { 20 | fft = new ofxEasyFft(); 21 | fft->setup(1024, OF_FFT_WINDOW_HAMMING); 22 | fft->setUseNormalization(true); 23 | playingState.set("Mic Input"); 24 | currentState = InputStateMicInput; 25 | } 26 | 27 | void FFTManager::stopMicInput() { 28 | if (currentState == InputStateMicInput) { 29 | currentState = InputStateNone; 30 | playingState.set("-"); 31 | } 32 | } 33 | 34 | void FFTManager::addToGui(ofxGuiContainer *container) { 35 | parameterGroup.setName("Audio"); 36 | 37 | audioMenu = container->addMenu(parameterGroup); 38 | 39 | this->dampening = 0.85; 40 | this->isMicrophoneEnabled = false; 41 | 42 | reloadAudioMenu(); 43 | this->volume.addListener(this, &FFTManager::volumeToggled); 44 | this->isMicrophoneEnabled.addListener(this, &FFTManager::micToggled); 45 | this->removeTrackButton.addListener(this, &FFTManager::removeAudioTrack); 46 | } 47 | 48 | void FFTManager::reloadAudioMenu() { 49 | if (audioMenu != nullptr) { 50 | audioMenu->clear(); 51 | audioMenu->add(playingState); 52 | audioMenu->add(dampening); 53 | audioMenu->add(volume); 54 | audioMenu->add(isMicrophoneEnabled); 55 | removeTrackGuiButton = audioMenu->add(removeTrackButton, ofJson({{"type", "fullsize"}, {"text-align", "center"}})); 56 | removeTrackGuiButton->setEnabled(false); 57 | } 58 | } 59 | 60 | void FFTManager::Update() { 61 | 62 | if (currentState == InputStateMicInput) { 63 | fft->update(); 64 | 65 | vector& buffer = fft->getBins(); 66 | int n = MIN(numSamples, buffer.size()); 67 | unsigned char signal[512*3]; 68 | int audioIndex = 0; 69 | for (int i = 0; i < numSamples*3; i+=3) { 70 | float v = MIN(255,buffer.at(audioIndex%buffer.size())) * 255; 71 | signal[i] = (unsigned char) v; 72 | signal[i+1] = (unsigned char)v; 73 | signal[i+2] = (unsigned char)v; 74 | audioIndex++; 75 | } 76 | audioTexture.loadData(signal, numSamples, 1, GL_RGB); 77 | 78 | int lastBufferIndex = 0; 79 | for (int i = 0; i < numSamples*3; i+=3) { 80 | lastBuffer[lastBufferIndex] = signal[i]; 81 | lastBufferIndex++; 82 | } 83 | } 84 | 85 | else if (currentState == InputStateSoundFile) { 86 | if (isPaused) { 87 | return; 88 | } 89 | 90 | float *buffer = ofSoundGetSpectrum(numSamples); 91 | unsigned char signal[512*3]; 92 | int audioIndex = 0; 93 | for (int i = 0; i < numSamples*3; i+=3) { 94 | float v = MIN(255,buffer[audioIndex] * 255 + (float)lastBuffer[audioIndex] * dampening ); // FFT 95 | signal[i] = (unsigned char) v; 96 | signal[i+1] = (unsigned char) v; 97 | signal[i+2] = (unsigned char) v; 98 | audioIndex++; 99 | } 100 | 101 | audioTexture.loadData(signal, numSamples, 1, GL_RGB); 102 | 103 | int lastBufferIndex = 0; 104 | for (int i = 0; i < numSamples*3; i+=3) { 105 | lastBuffer[lastBufferIndex] = signal[i]; 106 | lastBufferIndex++; 107 | } 108 | } 109 | } 110 | 111 | void FFTManager::UpdateShader(ofShader *shader, int textureIndex) { 112 | shader->setUniformTexture("_AudioTexture", audioTexture, textureIndex); 113 | } 114 | 115 | void FFTManager::loadSoundFile(string filePath) { 116 | soundFilePath = filePath; 117 | audioTexture.allocate(numSamples,1,GL_RGB); 118 | soundPlayer.load(filePath); 119 | soundPlayer.play(); 120 | 121 | soundPlayer.setPosition(0.5); 122 | soundFileDuration = (soundPlayer.getPositionMS() / 1000) * 2.0; 123 | 124 | cout << "duration " << soundFileDuration << endl; 125 | soundPlayer.setPosition(0.0); 126 | 127 | soundPlayer.play(); 128 | soundPlayer.setLoop(true); 129 | currentState = InputStateSoundFile; 130 | isPaused = false; 131 | 132 | playingState.set("Playing audio input"); 133 | removeTrackGuiButton->setEnabled(true); 134 | 135 | } 136 | 137 | void FFTManager::removeAudioTrack() { 138 | if (soundPlayer.isLoaded()) { 139 | playingState.set("-"); 140 | soundPlayer.stop(); 141 | soundPlayer.unload(); 142 | currentState = InputStateNone; 143 | removeTrackGuiButton->setEnabled(false); 144 | } 145 | } 146 | 147 | void FFTManager::setPaused(bool val) { 148 | soundPlayer.setPaused(val); 149 | isPaused = val; 150 | } 151 | 152 | void FFTManager::setTime(float time) { 153 | //soundPlayer.setPaused(true); 154 | 155 | if (currentState != InputStateNone) { 156 | float t = fmod(time,soundFileDuration) * 1000.; 157 | soundPlayer.setPositionMS(t); 158 | } 159 | } 160 | 161 | void FFTManager::resetSongIfPlaying() { 162 | setTime(0.0); 163 | } 164 | 165 | void FFTManager::volumeToggled(float &val) { 166 | soundPlayer.setVolume(val); 167 | } 168 | 169 | void FFTManager::micToggled(bool &val) { 170 | if (val) { 171 | StartMicInput(); 172 | } else { 173 | stopMicInput(); 174 | } 175 | } 176 | -------------------------------------------------------------------------------- /bin/data/presets/terrain_raymarcher.json: -------------------------------------------------------------------------------- 1 | { 2 | "blend" : 1, 3 | "data" : [ 4 | { 5 | "parameters" : [ 6 | { 7 | "name" : "focalLength", 8 | "range" : { 9 | "x" : 0, 10 | "y" : 10 11 | }, 12 | "show" : true, 13 | "type" : "float", 14 | "value" : 1.25 15 | }, 16 | { 17 | "name" : "minDist", 18 | "range" : { 19 | "x" : 0, 20 | "y" : 0.1000000014901161 21 | }, 22 | "show" : false, 23 | "type" : "float", 24 | "value" : 0.001000000047497451 25 | }, 26 | { 27 | "name" : "maxDist", 28 | "range" : { 29 | "x" : 0, 30 | "y" : 40 31 | }, 32 | "show" : true, 33 | "type" : "float", 34 | "value" : 1.30434775352478 35 | }, 36 | { 37 | "name" : "bgColor", 38 | "show" : true, 39 | "type" : "color", 40 | "value" : { 41 | "a" : 185, 42 | "b" : 0, 43 | "g" : 0, 44 | "r" : 10 45 | } 46 | }, 47 | { 48 | "name" : "noiseX", 49 | "range" : { 50 | "x" : -10, 51 | "y" : 10 52 | }, 53 | "show" : true, 54 | "type" : "float", 55 | "value" : -0.9782606363296509 56 | }, 57 | { 58 | "name" : "noiseY", 59 | "range" : { 60 | "x" : -10, 61 | "y" : 10 62 | }, 63 | "show" : true, 64 | "type" : "float", 65 | "value" : -1.630434989929199 66 | }, 67 | { 68 | "filePath" : "textures/noise_loop.png", 69 | "name" : "noiseTex", 70 | "show" : true, 71 | "targetBufferName" : "", 72 | "textureIndex" : 2, 73 | "textype" : "ImageFile", 74 | "type" : "texture" 75 | }, 76 | { 77 | "name" : "", 78 | "type" : "camera", 79 | "value" : { 80 | "pos" : { 81 | "x" : 1.77033543586731, 82 | "y" : 0.09315027296543121, 83 | "z" : 2.565384149551392 84 | }, 85 | "rot" : { 86 | "x" : 163.0872344970703, 87 | "y" : -1.255888342857361, 88 | "z" : 0.09346394240856171 89 | } 90 | } 91 | } 92 | ], 93 | "shaderName" : "shaders/terrain_raymarcher" 94 | }, 95 | { 96 | "parameters" : [ 97 | { 98 | "name" : "startFocusDist", 99 | "range" : { 100 | "x" : 0, 101 | "y" : 10 102 | }, 103 | "show" : true, 104 | "type" : "float", 105 | "value" : 0.2127659469842911 106 | }, 107 | { 108 | "name" : "endFocusDist", 109 | "range" : { 110 | "x" : 0, 111 | "y" : 10 112 | }, 113 | "show" : true, 114 | "type" : "float", 115 | "value" : 0.6382978558540344 116 | }, 117 | { 118 | "name" : "ramp", 119 | "range" : { 120 | "x" : 0, 121 | "y" : 1 122 | }, 123 | "show" : true, 124 | "type" : "float", 125 | "value" : 0.1489361673593521 126 | }, 127 | { 128 | "name" : "blurSize", 129 | "range" : { 130 | "x" : 0, 131 | "y" : 16 132 | }, 133 | "show" : true, 134 | "type" : "float", 135 | "value" : 4 136 | } 137 | ], 138 | "shaderName" : "shaders/bokehShader" 139 | }, 140 | { 141 | "parameters" : [ 142 | { 143 | "name" : "shift", 144 | "range" : { 145 | "x" : 0, 146 | "y" : 6.283180236816406 147 | }, 148 | "show" : true, 149 | "type" : "float", 150 | "value" : 3.995283126831055 151 | } 152 | ], 153 | "shaderName" : "shaders/hueShader" 154 | }, 155 | { 156 | "parameters" : [ 157 | { 158 | "name" : "strength", 159 | "range" : { 160 | "x" : 0, 161 | "y" : 1 162 | }, 163 | "show" : true, 164 | "type" : "float", 165 | "value" : 0.6326530575752258 166 | }, 167 | { 168 | "name" : "power", 169 | "range" : { 170 | "x" : 0, 171 | "y" : 1 172 | }, 173 | "show" : true, 174 | "type" : "float", 175 | "value" : 0.5 176 | } 177 | ], 178 | "shaderName" : "shaders/vignetteShader" 179 | } 180 | ], 181 | "duration" : 6.283180236816406, 182 | "fps" : 30, 183 | "res" : { 184 | "x" : 500, 185 | "y" : 500 186 | }, 187 | "scale" : 1.222916722297668 188 | } 189 | 190 | -------------------------------------------------------------------------------- /src/gui/MidiMapper.cpp: -------------------------------------------------------------------------------- 1 | #include "MidiMapper.h" 2 | #include "RenderStruct.h" 3 | #include "ShaderPass.h" 4 | 5 | void MidiMapper::show(ofxGui *gui, RenderStruct *renderData) { 6 | if (container == nullptr) { 7 | container = gui->addContainer(); 8 | } 9 | isShowing = true; 10 | renderStruct = renderData; 11 | container->clear(); 12 | midiButtons.clear(); 13 | this->container->add(statusLabel.set("Click uniform then midi")); 14 | for (unsigned int i = 0; i < renderData->passes->size(); i++) { 15 | for (unsigned j = 0; j < renderData->passes->at(i)->params.size(); j++) { 16 | if (renderData->passes->at(i)->params[j]->type == "float") { 17 | ofParameter midiButton; 18 | ofxGuiButton *btn = this->container->add(midiButton.set(renderData->passes->at(i)->params[j]->uniform), ofJson({{"type", "fullsize"}, {"text-align", "center"}})); 19 | midiButtons.push_back(btn); 20 | } 21 | else if (renderData->passes->at(i)->params[j]->type == "vec4") { 22 | ofParameter midiXButton; 23 | ofParameter midiYButton; 24 | ofParameter midiZButton; 25 | ofParameter midiWButton; 26 | 27 | ofxGuiButton *btnX = this->container->add(midiXButton.set(renderData->passes->at(i)->params[j]->uniform + " x"), ofJson({{"type", "fullsize"}, {"text-align", "center"}})); 28 | midiButtons.push_back(btnX); 29 | ofxGuiButton *btnY = this->container->add(midiYButton.set(renderData->passes->at(i)->params[j]->uniform + " y"), ofJson({{"type", "fullsize"}, {"text-align", "center"}})); 30 | midiButtons.push_back(btnY); 31 | ofxGuiButton *btnZ = this->container->add(midiZButton.set(renderData->passes->at(i)->params[j]->uniform + " z"), ofJson({{"type", "fullsize"}, {"text-align", "center"}})); 32 | midiButtons.push_back(btnZ); 33 | ofxGuiButton *btnW = this->container->add(midiWButton.set(renderData->passes->at(i)->params[j]->uniform + " w"), ofJson({{"type", "fullsize"}, {"text-align", "center"}})); 34 | midiButtons.push_back(btnW); 35 | } else if (renderData->passes->at(i)->params[j]->type == "vec3") { 36 | ofParameter midiXButton; 37 | ofParameter midiYButton; 38 | ofParameter midiZButton; 39 | 40 | ofxGuiButton *btnX = this->container->add(midiXButton.set(renderData->passes->at(i)->params[j]->uniform + " x"), ofJson({{"type", "fullsize"}, {"text-align", "center"}})); 41 | midiButtons.push_back(btnX); 42 | ofxGuiButton *btnY = this->container->add(midiYButton.set(renderData->passes->at(i)->params[j]->uniform + " y"), ofJson({{"type", "fullsize"}, {"text-align", "center"}})); 43 | midiButtons.push_back(btnY); 44 | ofxGuiButton *btnZ = this->container->add(midiZButton.set(renderData->passes->at(i)->params[j]->uniform + " z"), ofJson({{"type", "fullsize"}, {"text-align", "center"}})); 45 | midiButtons.push_back(btnZ); 46 | } else if (renderData->passes->at(i)->params[j]->type == "vec2") { 47 | ofParameter midiXButton; 48 | ofParameter midiYButton; 49 | 50 | ofxGuiButton *btnX = this->container->add(midiXButton.set(renderData->passes->at(i)->params[j]->uniform + " x"), ofJson({{"type", "fullsize"}, {"text-align", "center"}})); 51 | midiButtons.push_back(btnX); 52 | ofxGuiButton *btnY = this->container->add(midiYButton.set(renderData->passes->at(i)->params[j]->uniform + " y"), ofJson({{"type", "fullsize"}, {"text-align", "center"}})); 53 | midiButtons.push_back(btnY); 54 | } 55 | } 56 | } 57 | 58 | for (int i = 0; i < midiButtons.size(); i++) { 59 | midiButtons[i]->addListener(this, &MidiMapper::midiButtonPressed); 60 | } 61 | 62 | cancelButton.addListener(this,&MidiMapper::cancelButtonPressed); 63 | this->container->add(cancelButton.set("Close"), ofJson({{"type", "fullsize"}, {"text-align", "center"}})); 64 | this->container->setPosition(ofPoint(ofGetWidth()/2-this->container->getWidth()/2, ofGetHeight()/2-this->container->getHeight()/2)); 65 | this->container->setEnabled(true); 66 | } 67 | 68 | void MidiMapper::midiSet(int val) { 69 | if (targetUniform == "" || val == -1) return; 70 | 71 | statusLabel = "set " + targetUniform + " to " + to_string(val); 72 | 73 | for (unsigned int i = 0; i < renderStruct->passes->size(); i++) { 74 | for (unsigned j = 0; j < renderStruct->passes->at(i)->params.size(); j++) { 75 | if (targetUniform == renderStruct->passes->at(i)->params[j]->uniform) { 76 | renderStruct->passes->at(i)->params[j]->bindMidi(val, subUniform); 77 | break; 78 | } 79 | } 80 | } 81 | 82 | targetUniform = ""; 83 | targetIndex = -1; 84 | subUniform = -1; 85 | } 86 | 87 | void MidiMapper::cancelButtonPressed() { 88 | this->container->setEnabled(false); 89 | isShowing = false; 90 | } 91 | 92 | void MidiMapper::midiButtonPressed() { 93 | for (unsigned int i = 0; i < midiButtons.size(); i++) { 94 | if (midiButtons[i]->isMouseOver()) { 95 | string name = midiButtons[i]->getName(); 96 | 97 | if (name.find(' ') != std::string::npos) { 98 | targetUniform = name.substr(0, name.find_last_of(" ")); 99 | auto sub = name.substr(name.find_last_of(" ") + 1); 100 | subUniform = indexFromSub(sub); 101 | statusLabel = "mapping " + targetUniform + " " + sub; 102 | } else { 103 | targetUniform = name; 104 | statusLabel = "mapping " + name; 105 | } 106 | 107 | break; 108 | } 109 | } 110 | } 111 | 112 | int MidiMapper::indexFromSub(string s) { 113 | if (s == "x") { 114 | return 0; 115 | } else if (s == "y") { 116 | return 1; 117 | } else if (s == "z") { 118 | return 2; 119 | } else if (s == "w") { 120 | return 3; 121 | } 122 | return 0; 123 | } 124 | -------------------------------------------------------------------------------- /bin/data/shaders/terrain_raymarcher.frag: -------------------------------------------------------------------------------- 1 | /* 2 | { 3 | "parameters" : [ 4 | { 5 | "midi" : 1, 6 | "name" : "focalLength", 7 | "range" : { 8 | "x" : 0, 9 | "y" : 10 10 | }, 11 | "show" : true, 12 | "type" : "float", 13 | "value" : 2.5 14 | }, 15 | { 16 | "name" : "minDist", 17 | "range" : { 18 | "x" : 0, 19 | "y" : 0.1000000014901161 20 | }, 21 | "show" : false, 22 | "type" : "float", 23 | "value" : 0.001000000047497451 24 | }, 25 | { 26 | "name" : "maxDist", 27 | "range" : { 28 | "x" : 0, 29 | "y" : 40 30 | }, 31 | "show" : true, 32 | "type" : "float", 33 | "value" : 10. 34 | }, 35 | { 36 | "name" : "bgColor", 37 | "show" : true, 38 | "type" : "color", 39 | "value" : { 40 | "r" : 0, 41 | "g" : 1, 42 | "b" : 0, 43 | "a" : 0 44 | } 45 | }, 46 | { 47 | "name" : "noiseX", 48 | "range" : { 49 | "x" : -10, 50 | "y" : 10 51 | }, 52 | "show" : true, 53 | "type" : "float", 54 | "value" : 0 55 | }, 56 | { 57 | "name" : "noiseY", 58 | "range" : { 59 | "x" : -10, 60 | "y" : 10 61 | }, 62 | "show" : true, 63 | "type" : "float", 64 | "value" : 0 65 | }, 66 | { 67 | "name" : "noiseTex", 68 | "show" : true, 69 | "type" : "texture", 70 | "filePath" : "textures/noise_loop.png", 71 | "textureIndex" : 2 72 | }, 73 | { 74 | "type" : "camera", 75 | "value" : { 76 | "pos" : { 77 | "x" : 1.0, 78 | "y" : 4.0, 79 | "z" : 0.0 80 | }, 81 | "rot" : { 82 | "x" : 0.0, 83 | "y" : 0.0, 84 | "z" : 0.0 85 | } 86 | } 87 | } 88 | ] 89 | } 90 | */ 91 | 92 | #version 150 93 | #pragma include "includes/noise.glsl" 94 | #pragma include "includes/hg_sdfs.glsl" 95 | #pragma include "includes/hue.glsl" 96 | 97 | uniform float _Time; 98 | uniform vec2 _Resolution; 99 | uniform vec3 _CamPos; 100 | uniform vec3 _CamForward; 101 | uniform vec3 _CamRight; 102 | uniform vec3 _CamUp; 103 | 104 | uniform float focalLength; 105 | 106 | uniform float minDist; 107 | uniform float maxDist; 108 | uniform float noiseX; 109 | uniform float noiseY; 110 | 111 | uniform sampler2D noiseTex; 112 | 113 | uniform vec4 bgColor; 114 | 115 | in vec2 uv; 116 | in vec2 texCoord; 117 | 118 | out vec4 outputColor; 119 | 120 | void pR(inout vec2 p, float a) { 121 | p = cos(a)*p + sin(a)*vec2(p.y, -p.x); 122 | } 123 | float smin( float d1, float d2, float k ) { 124 | float h = clamp( 0.5 + 0.5*(d2-d1)/k, 0.0, 1.0 ); 125 | return mix( d2, d1, h ) - k*h*(1.0-h); 126 | } 127 | 128 | float map(in vec2 pos) { 129 | vec2 noiseUv = mod(abs((pos*0.5+vec2(noiseX, noiseY))), vec2(1.)); 130 | float n = texture(noiseTex, noiseUv).r; 131 | n += cos(n*25.+ _Time*2.)*0.05; 132 | n*=0.4; 133 | n = min(0.35, n); 134 | n = pow(n, 1.5); 135 | float dist = -n ; 136 | return dist; 137 | } 138 | 139 | float map2(in vec3 pos) { 140 | //pos.y += 0.1; 141 | pos.x += 0.15; 142 | //pos.z += 0.5; 143 | pos = mod(pos - .5, 1.) - .5; 144 | float s = 0.065; 145 | pR(pos.xz, _Time*0.5); 146 | float b = fOctahedron(pos,0.125); 147 | //b = max(b, -(length(pos)-0.145)); 148 | return b; 149 | } 150 | float march(in vec3 camPos, in vec3 rayDir) { 151 | 152 | float dist = minDist; 153 | 154 | for (int i = 0; i < 45; i++) { 155 | vec3 p = camPos + rayDir * dist; 156 | float res = map2(p); 157 | if (res <= minDist) break; 158 | dist += res; 159 | if (dist >= maxDist) break; 160 | } 161 | 162 | return dist; 163 | } 164 | 165 | float terrainMarch(in vec3 camPos, in vec3 rayDir) { 166 | float dt = 0.0025; 167 | float dist = minDist; 168 | float lastY = 0.; 169 | float lastHeight = 0.; 170 | 171 | for (int i = 0; i < 550; i++) { 172 | vec3 p = camPos + rayDir * dist; 173 | float res = map(p.xz); 174 | if (p.y < res) { 175 | return dist - dt + dt*(lastHeight-lastY)/(p.y-lastY-res+lastHeight); 176 | } 177 | dist += dt; 178 | if (res >= maxDist) return -1; 179 | lastY = p.y; 180 | lastHeight = res; 181 | } 182 | 183 | return dist; 184 | } 185 | 186 | vec3 calcNormal2(in vec3 pos) { 187 | vec3 eps = vec3(0.001, 0.0, 0.0); 188 | return normalize(vec3(map2(pos + eps) - map2(pos - eps), 189 | map2(pos + eps.yxz) - map2(pos - eps.yxz), 190 | map2(pos + eps.yzx) - map2(pos - eps.yzx))); 191 | } 192 | 193 | vec3 calcNormal(in vec3 p) { 194 | float eps = 0.001; 195 | 196 | return normalize( vec3( map(vec2(p.x-eps,p.z)) - map(vec2(p.x+eps,p.z)), 197 | 2.0f*eps, 198 | map(vec2(p.x,p.z-eps)) - map(vec2(p.x,p.z+eps)) ) ); 199 | } 200 | 201 | vec4 render(in vec3 camPos, in vec3 rayDir) { 202 | 203 | float dist = terrainMarch(camPos, rayDir); 204 | float dist2 = march(camPos, rayDir); 205 | 206 | float h = clamp( 0.5 + 0.5*(dist2-dist)/0.1, 0.0, 1.0 ); 207 | 208 | float mixDist = 0.; 209 | if (dist > 100) { mixDist = dist2; h = 0.; } 210 | 211 | else { mixDist = mix( dist2, dist, h ) - 0.1*h*(1.0-h); } 212 | 213 | vec3 fPos = camPos + rayDir * mixDist; 214 | vec3 nor = mix(calcNormal2(fPos), calcNormal(fPos), h); 215 | 216 | vec3 col = nor.grb * 0.5 + 0.5; 217 | float fres = (1.+dot(rayDir, nor)); 218 | col *= fres; 219 | col = pow(col, vec3(1.)); 220 | //col = hueShift(col, (_Time / 25.) * 3.14159 * 2.); 221 | 222 | col = mix(col, bgColor.rgb, smoothstep(-0.05,-0.2, fPos.y)); 223 | col = mix(col, bgColor.rgb, smoothstep(maxDist - .25, maxDist, mixDist)); 224 | return vec4(clamp(col.rgb, vec3(0.), vec3(1.)), mixDist); 225 | } 226 | #define AA 1 227 | 228 | void main() 229 | { 230 | vec4 color = vec4(0.); 231 | for (int j = 0; j < AA; j++) { 232 | for (int k = 0; k < AA; k++) 233 | { 234 | vec2 o = vec2(float(j), float(k)) / float(AA); 235 | vec2 uv = (uv + o/_Resolution) * 2. - 1. ; 236 | uv.x *= _Resolution.x/_Resolution.y; 237 | 238 | vec3 ray = normalize ((_CamRight) * uv.x + 239 | (_CamUp) * uv.y + 240 | (_CamForward) * focalLength); 241 | 242 | color += vec4(render(_CamPos, ray)); 243 | } 244 | } 245 | 246 | color /= float(AA * AA); 247 | outputColor = color; 248 | } 249 | -------------------------------------------------------------------------------- /src/PNGRenderer.cpp: -------------------------------------------------------------------------------- 1 | #include "PNGRenderer.h" 2 | #include 3 | #include 4 | 5 | #include "ShaderChain.h" 6 | 7 | PNGRenderer::PNGRenderer(float animduration, int fps, glm::vec2 resolution) { 8 | this->animduration = animduration; 9 | this->FPS = fps; 10 | this->presetFilePath = ""; 11 | this->presetDisplayName = ""; 12 | this->currentFrame = 0; 13 | this->totalFrames = animduration * fps; 14 | this->resolutionX = resolution.x; 15 | this->resolutionY = resolution.y; 16 | this->gifResolutionScale = 1.0; 17 | this->displayScaleParam = 1.0; 18 | this->renderedFrames = 1; 19 | this->frameskip = 1; 20 | this->FPS = 30; 21 | this->numLoops = 1; 22 | this->numBlendFrames = 1; 23 | this->preview = false; 24 | } 25 | 26 | void PNGRenderer::AddToGui(ofxGuiContainer *panel, ofxGuiContainer *statusLabelPanel, FFTManager *fft) { 27 | 28 | statusLabelPanel->add(statusLabel.set("Playing")); 29 | panel->add(spaceBufferLabel.set(" ")); 30 | panel->addFpsPlotter(); 31 | 32 | fileGroup.setName("File"); 33 | 34 | ofxGuiMenu* fileMenu = panel->addMenu(fileGroup); 35 | 36 | fft->addToGui(panel); 37 | 38 | 39 | fileMenu->add(presetDisplayNameLabel.set("Preset: default")); 40 | fileMenu->add(newPresetButton.set("New Preset"), ofJson({{"type", "fullsize"}, {"text-align", "center"}})); 41 | fileMenu->add(openFileButton.set("Open File"), ofJson({{"type", "fullsize"}, {"text-align", "center"}})); 42 | fileMenu->add(saveAsPresetButton.set("Save Preset As…"), ofJson({{"type", "fullsize"}, {"text-align", "center"}})); 43 | fileMenu->add(savePresetButton.set("Save Preset"), ofJson({{"type", "fullsize"}, {"text-align", "center"}})); 44 | fileMenu->add(updateShaderJsonButton.set("Update Shader JSON"), ofJson({{"type", "fullsize"}, {"text-align", "center"}})); 45 | fileMenu->add(mapMidiButton.set("Midi Mapper"), ofJson({{"type", "fullsize"}, {"text-align", "center"}})); 46 | 47 | vidMenuGroup.setName("Mp4"); 48 | vidMenuGroup.add(numLoops.set("Num loops", numLoops, 1, 32)); 49 | 50 | renderParameterGroup.setName("Render"); 51 | 52 | gifNumColors = 256; 53 | gifMenuGroup.setName("Gif"); 54 | gifMenuGroup.add(gifNumColors.set("Colors", gifNumColors, 1, 255)); 55 | 56 | ofxGuiMenu* renderingMenu = panel->addMenu(renderParameterGroup); 57 | renderingMenu->add(resolutionX.set("Res x", resolutionX, 1, 4096)); 58 | renderingMenu->add(resolutionY.set("Res y", resolutionY, 1, 4096)); 59 | renderingMenu->add(animduration.set("Duration ", animduration, 0, 10000000)); 60 | renderingMenu->add(FPS.set("FPS", FPS, 1, 1000)); 61 | renderingMenu->add(numBlendFrames.set("Blend Frames", numBlendFrames, 1, 128)); 62 | renderingMenu->add(frameskip.set("Frameskip", frameskip, 1, 10)); 63 | renderingMenu->add(preview.set("Preview", preview)); 64 | saveFramesButton = renderingMenu->add(saveButton.set("Save Frames"), ofJson({{"type", "fullsize"}, {"text-align", "center"}})); 65 | 66 | panel->add(displayScaleParam.set("Display scale", displayScaleParam, 0.1, 5.0)); 67 | 68 | ofxGuiMenu* gifGroup = renderingMenu->addMenu(gifMenuGroup); 69 | ofxGuiMenu* vidGroup = renderingMenu->addMenu(vidMenuGroup); 70 | gifGroup->add(gifResolutionScale.set("Scale", gifResolutionScale, 0.0, 1.0)); 71 | gifGroup->add(encodeGifButton.set("Encode gif"), ofJson({{"type", "fullsize"}, {"text-align", "center"}})); 72 | vidGroup->add(encodeMp4Button.set("Encode mp4"), ofJson({{"type", "fullsize"}, {"text-align", "center"}})); 73 | } 74 | 75 | float PNGRenderer::Tick() { 76 | float progress = (float)this->currentFrame / this->totalFrames; 77 | 78 | this->currentFrame = (this->currentFrame+1) % this->totalFrames; 79 | this->renderedFrames++; 80 | this->statusLabel = ("Rendered " + to_string(renderedFrames) + "/" + to_string(totalFrames) + " frames"); 81 | 82 | if (this->renderedFrames == this->totalFrames) { 83 | this->isCapturing = false; 84 | saveFramesButton->setName("Save Frames"); 85 | saveFramesButton->updateLayout(); 86 | } 87 | 88 | return progress * this->animduration; 89 | } 90 | 91 | void PNGRenderer::WritePNG(ofFbo *buffer) { 92 | ofPixels outputPixels; 93 | outputPixels.allocate(this->resolutionX, this->resolutionY, OF_IMAGE_COLOR); 94 | int totalZeros = (int)floor(log10 (((float)this->totalFrames))); 95 | int totalZerosNeeded = totalZeros - (int)floor(log10 (((float)this->currentFrame))); 96 | if (this->currentFrame == 0) totalZerosNeeded = totalZeros; 97 | 98 | std::string s = ""; 99 | for (int i = 0; i < totalZerosNeeded; i++) s += "0"; 100 | 101 | s += std::to_string(this->currentFrame); 102 | buffer->readToPixels(outputPixels); 103 | string destFilePath = this->renderDirectory + this->presetDisplayName.get() + "_" + s + ".png"; 104 | cout << destFilePath << endl; 105 | 106 | ofSaveImage(outputPixels, destFilePath, OF_IMAGE_QUALITY_BEST); 107 | } 108 | 109 | void PNGRenderer::Start() { 110 | if (this->isCapturing) { 111 | saveFramesButton->setName("Save Frames"); 112 | this->isCapturing = false; 113 | return; 114 | } 115 | this->currentFrame = 0; 116 | this->renderedFrames = 0; 117 | this->totalFrames = animduration * FPS; 118 | this->isCapturing = true; 119 | 120 | saveFramesButton->setName("Cancel"); 121 | } 122 | 123 | void PNGRenderer::updatePath(string s) { 124 | if (s == "") return; 125 | 126 | #if defined(WIN32) || defined(_WIN32) || defined(__WIN32) && !defined(__CYGWIN__) 127 | 128 | replace(s.begin(), s.end(), '/', '\\'); 129 | static const std::string slash = "\\"; 130 | #else 131 | static const std::string slash = "/"; 132 | #endif 133 | 134 | string file = s.substr(s.find_last_of(slash) + 1); 135 | 136 | // add json extension if needed 137 | int indexOfPeriod = file.find_last_of("."); 138 | if (indexOfPeriod == std::string::npos) { 139 | file += ".json"; 140 | s += ".json"; 141 | indexOfPeriod = file.find_last_of("."); 142 | } 143 | 144 | string fileWithoutExtension = file.substr(0, indexOfPeriod); 145 | 146 | presetDisplayName.set(fileWithoutExtension); 147 | presetDisplayNameLabel.set("Preset: " + presetDisplayName.get()); 148 | presetFilePath = s; 149 | } 150 | 151 | void PNGRenderer::UpdateResolution(int w, int h) { 152 | this->resolutionX = w; 153 | this->resolutionY = h; 154 | } 155 | -------------------------------------------------------------------------------- /config.make: -------------------------------------------------------------------------------- 1 | ################################################################################ 2 | # CONFIGURE PROJECT MAKEFILE (optional) 3 | # This file is where we make project specific configurations. 4 | ################################################################################ 5 | 6 | ################################################################################ 7 | # OF ROOT 8 | # The location of your root openFrameworks installation 9 | # (default) OF_ROOT = ../.. 10 | ################################################################################ 11 | # OF_ROOT = ../.. 12 | 13 | ################################################################################ 14 | # PROJECT ROOT 15 | # The location of the project - a starting place for searching for files 16 | # (default) PROJECT_ROOT = . (this directory) 17 | # 18 | ################################################################################ 19 | # PROJECT_ROOT = . 20 | 21 | ################################################################################ 22 | # PROJECT SPECIFIC CHECKS 23 | # This is a project defined section to create internal makefile flags to 24 | # conditionally enable or disable the addition of various features within 25 | # this makefile. For instance, if you want to make changes based on whether 26 | # GTK is installed, one might test that here and create a variable to check. 27 | ################################################################################ 28 | # None 29 | 30 | ################################################################################ 31 | # PROJECT EXTERNAL SOURCE PATHS 32 | # These are fully qualified paths that are not within the PROJECT_ROOT folder. 33 | # Like source folders in the PROJECT_ROOT, these paths are subject to 34 | # exlclusion via the PROJECT_EXLCUSIONS list. 35 | # 36 | # (default) PROJECT_EXTERNAL_SOURCE_PATHS = (blank) 37 | # 38 | # Note: Leave a leading space when adding list items with the += operator 39 | ################################################################################ 40 | # PROJECT_EXTERNAL_SOURCE_PATHS = 41 | 42 | ################################################################################ 43 | # PROJECT EXCLUSIONS 44 | # These makefiles assume that all folders in your current project directory 45 | # and any listed in the PROJECT_EXTERNAL_SOURCH_PATHS are are valid locations 46 | # to look for source code. The any folders or files that match any of the 47 | # items in the PROJECT_EXCLUSIONS list below will be ignored. 48 | # 49 | # Each item in the PROJECT_EXCLUSIONS list will be treated as a complete 50 | # string unless teh user adds a wildcard (%) operator to match subdirectories. 51 | # GNU make only allows one wildcard for matching. The second wildcard (%) is 52 | # treated literally. 53 | # 54 | # (default) PROJECT_EXCLUSIONS = (blank) 55 | # 56 | # Will automatically exclude the following: 57 | # 58 | # $(PROJECT_ROOT)/bin% 59 | # $(PROJECT_ROOT)/obj% 60 | # $(PROJECT_ROOT)/%.xcodeproj 61 | # 62 | # Note: Leave a leading space when adding list items with the += operator 63 | ################################################################################ 64 | # PROJECT_EXCLUSIONS = 65 | 66 | ################################################################################ 67 | # PROJECT LINKER FLAGS 68 | # These flags will be sent to the linker when compiling the executable. 69 | # 70 | # (default) PROJECT_LDFLAGS = -Wl,-rpath=./libs 71 | # 72 | # Note: Leave a leading space when adding list items with the += operator 73 | # 74 | # Currently, shared libraries that are needed are copied to the 75 | # $(PROJECT_ROOT)/bin/libs directory. The following LDFLAGS tell the linker to 76 | # add a runtime path to search for those shared libraries, since they aren't 77 | # incorporated directly into the final executable application binary. 78 | ################################################################################ 79 | # PROJECT_LDFLAGS=-Wl,-rpath=./libs 80 | 81 | ################################################################################ 82 | # PROJECT DEFINES 83 | # Create a space-delimited list of DEFINES. The list will be converted into 84 | # CFLAGS with the "-D" flag later in the makefile. 85 | # 86 | # (default) PROJECT_DEFINES = (blank) 87 | # 88 | # Note: Leave a leading space when adding list items with the += operator 89 | ################################################################################ 90 | # PROJECT_DEFINES = 91 | 92 | ################################################################################ 93 | # PROJECT CFLAGS 94 | # This is a list of fully qualified CFLAGS required when compiling for this 95 | # project. These CFLAGS will be used IN ADDITION TO the PLATFORM_CFLAGS 96 | # defined in your platform specific core configuration files. These flags are 97 | # presented to the compiler BEFORE the PROJECT_OPTIMIZATION_CFLAGS below. 98 | # 99 | # (default) PROJECT_CFLAGS = (blank) 100 | # 101 | # Note: Before adding PROJECT_CFLAGS, note that the PLATFORM_CFLAGS defined in 102 | # your platform specific configuration file will be applied by default and 103 | # further flags here may not be needed. 104 | # 105 | # Note: Leave a leading space when adding list items with the += operator 106 | ################################################################################ 107 | # PROJECT_CFLAGS = 108 | 109 | ################################################################################ 110 | # PROJECT OPTIMIZATION CFLAGS 111 | # These are lists of CFLAGS that are target-specific. While any flags could 112 | # be conditionally added, they are usually limited to optimization flags. 113 | # These flags are added BEFORE the PROJECT_CFLAGS. 114 | # 115 | # PROJECT_OPTIMIZATION_CFLAGS_RELEASE flags are only applied to RELEASE targets. 116 | # 117 | # (default) PROJECT_OPTIMIZATION_CFLAGS_RELEASE = (blank) 118 | # 119 | # PROJECT_OPTIMIZATION_CFLAGS_DEBUG flags are only applied to DEBUG targets. 120 | # 121 | # (default) PROJECT_OPTIMIZATION_CFLAGS_DEBUG = (blank) 122 | # 123 | # Note: Before adding PROJECT_OPTIMIZATION_CFLAGS, please note that the 124 | # PLATFORM_OPTIMIZATION_CFLAGS defined in your platform specific configuration 125 | # file will be applied by default and further optimization flags here may not 126 | # be needed. 127 | # 128 | # Note: Leave a leading space when adding list items with the += operator 129 | ################################################################################ 130 | # PROJECT_OPTIMIZATION_CFLAGS_RELEASE = 131 | # PROJECT_OPTIMIZATION_CFLAGS_DEBUG = 132 | 133 | ################################################################################ 134 | # PROJECT COMPILERS 135 | # Custom compilers can be set for CC and CXX 136 | # (default) PROJECT_CXX = (blank) 137 | # (default) PROJECT_CC = (blank) 138 | # Note: Leave a leading space when adding list items with the += operator 139 | ################################################################################ 140 | # PROJECT_CXX = 141 | # PROJECT_CC = 142 | -------------------------------------------------------------------------------- /bin/data/shaders/raymarchKifsShader.frag: -------------------------------------------------------------------------------- 1 | /* 2 | { 3 | "parameters" : [ 4 | { 5 | "midi" : 1, 6 | "name" : "focalLength", 7 | "range" : { 8 | "x" : 0, 9 | "y" : 10 10 | }, 11 | "show" : true, 12 | "type" : "float", 13 | "value" : 2.5 14 | }, 15 | { 16 | "name" : "minDist", 17 | "range" : { 18 | "x" : 0, 19 | "y" : 0.1000000014901161 20 | }, 21 | "show" : false, 22 | "type" : "float", 23 | "value" : 0.001000000047497451 24 | }, 25 | { 26 | "name" : "maxDist", 27 | "range" : { 28 | "x" : 0, 29 | "y" : 15 30 | }, 31 | "show" : true, 32 | "type" : "float", 33 | "value" : 2.5 34 | }, 35 | { 36 | "name" : "bgColor", 37 | "show" : true, 38 | "type" : "color", 39 | "value" : { 40 | "r" : 0, 41 | "g" : 1, 42 | "b" : 0, 43 | "a" : 0 44 | } 45 | }, 46 | { 47 | "name" : "startScale", 48 | "range" : { 49 | "x" : 0, 50 | "y" : 2 51 | }, 52 | "show" : true, 53 | "type" : "float", 54 | "value" : 0.75 55 | }, 56 | { 57 | "name" : "scaleFactor", 58 | "range" : { 59 | "x" : 0, 60 | "y" : 1 61 | }, 62 | "type" : "float", 63 | "show" : true, 64 | "value" : 0.575 65 | }, 66 | { 67 | "name" : "offset", 68 | "range" : { 69 | "x" : 0, 70 | "y" : 4 71 | }, 72 | "show" : true, 73 | "type" : "vec3", 74 | "value" : { 75 | "x" : 0.75, 76 | "y" : 1, 77 | "z" : 2 78 | } 79 | }, 80 | { 81 | "name" : "spaceSize", 82 | "range" : { 83 | "x" : 0, 84 | "y" : 5 85 | }, 86 | "show" : true, 87 | "type" : "vec3", 88 | "value" : { 89 | "x" : 3, 90 | "y" : 3, 91 | "z" : 3 92 | } 93 | }, 94 | { 95 | "name" : "distScalar", 96 | "range" : { 97 | "x" : 0, 98 | "y" : 2 99 | }, 100 | "show" : true, 101 | "type" : "float", 102 | "value" : 0.5 103 | }, 104 | { 105 | "name" : "rotationPhaseX", 106 | "range" : { 107 | "x" : 0, 108 | "y" : 7 109 | }, 110 | "show" : true, 111 | "type" : "float", 112 | "value" : 2.5 113 | }, 114 | { 115 | "name" : "rotationPhaseY", 116 | "range" : { 117 | "x" : 0, 118 | "y" : 7 119 | }, 120 | "show" : true, 121 | "type" : "float", 122 | "value" : 2.5 123 | }, 124 | { 125 | "name" : "animationAmpX", 126 | "range" : { 127 | "x" : 0, 128 | "y" : 0.5 129 | }, 130 | "show" : true, 131 | "type" : "float", 132 | "value" : 0.05 133 | }, 134 | { 135 | "name" : "animationAmpY", 136 | "range" : { 137 | "x" : 0, 138 | "y" : 0.5 139 | }, 140 | "show" : true, 141 | "type" : "float", 142 | "value" : 0.015 143 | }, 144 | { 145 | "type" : "camera", 146 | "value" : { 147 | "pos" : { 148 | "x" : 1.0, 149 | "y" : 2.0, 150 | "z" : 1.0 151 | }, 152 | "rot" : { 153 | "x" : 0.0, 154 | "y" : 0.0, 155 | "z" : 0.0 156 | } 157 | } 158 | } 159 | ] 160 | } 161 | */ 162 | #version 150 163 | #pragma include "includes/hg_sdfs.glsl" 164 | 165 | uniform sampler2D tex0; 166 | uniform float _Time; 167 | uniform vec2 _Resolution; 168 | uniform vec3 _CamPos; 169 | uniform vec3 _CamForward; 170 | uniform vec3 _CamRight; 171 | uniform vec3 _CamUp; 172 | 173 | uniform float focalLength; 174 | 175 | uniform float minDist; 176 | uniform float maxDist; 177 | 178 | uniform float startScale; 179 | uniform float scaleFactor; 180 | uniform float distScalar; 181 | uniform float rotationPhaseX; 182 | uniform float rotationPhaseY; 183 | uniform float animationAmpX; 184 | uniform float animationAmpY; 185 | 186 | uniform vec3 offset; 187 | uniform vec3 spaceSize; 188 | 189 | 190 | uniform vec4 bgColor; 191 | 192 | in vec2 uv; 193 | out vec4 outputColor; 194 | 195 | void pR(inout vec2 p, float a) { 196 | p = cos(a)*p + sin(a)*vec2(p.y, -p.x); 197 | } 198 | float smin( float d1, float d2, float k ) { 199 | float h = clamp( 0.5 + 0.5*(d2-d1)/k, 0.0, 1.0 ); 200 | return mix( d2, d1, h ) - k*h*(1.0-h); 201 | } 202 | 203 | float map(in vec3 pos) { 204 | vec3 originalPos = pos - _CamPos - _CamForward; 205 | 206 | float scale = startScale; 207 | vec3 spacesize = spaceSize; 208 | float distFromCam = length(pos)*distScalar; 209 | 210 | // Divide the space into cells 211 | pos.xyz = mod(pos.xyz, spacesize) - spacesize*0.5; 212 | 213 | vec3 p = pos; 214 | 215 | float res = 1e20; 216 | 217 | for (int i = 0; i < 8; i++) { 218 | p.xyz = abs(p.xyz); 219 | 220 | float phase = _Time+float(i)*0.25+distFromCam*2.; 221 | vec2 anim = vec2(cos(phase), sin(phase)); 222 | vec3 offs = offset + vec3(0., anim*0.025); 223 | 224 | p -= offs * scale; 225 | 226 | pR(p.xz,-distFromCam+rotationPhaseY+anim.x*animationAmpY); 227 | pR(p.zy,distFromCam+rotationPhaseX+anim.y*animationAmpX); 228 | 229 | float octa = fOctahedron(p, scale); 230 | 231 | res = min(res,octa); 232 | scale *= scaleFactor; 233 | } 234 | 235 | // Animate the pos of the icosahedron 236 | pR(originalPos.xy, .2+sin(_Time)*0.2); 237 | pR(originalPos.xz, _Time); 238 | 239 | // Smooth min blend the fractal terrain with itself with a param around zero to give it a scaling effect 240 | res = smin(res, res, -0.025+ sin(-0.5+_Time-length(vec3(pos.x*0.5,pos.y*0.9,pos.z))*12.)*0.05); 241 | res = smin(res, fIcosahedron(originalPos,.175), 0.1); 242 | 243 | return res; 244 | } 245 | 246 | float march(in vec3 camPos, in vec3 rayDir) { 247 | 248 | float dist = minDist; 249 | 250 | for (int i = 0; i < 65; i++) { 251 | vec3 p = camPos + rayDir * dist; 252 | float res = map(p); 253 | if (res <= minDist) break; 254 | dist += res; 255 | if (res >= maxDist) break; 256 | } 257 | 258 | return dist; 259 | } 260 | 261 | vec3 calcNormal(in vec3 pos) { 262 | vec3 eps = vec3(0.001, 0.0, 0.0); 263 | return normalize(vec3(map(pos + eps) - map(pos - eps), 264 | map(pos + eps.yxz) - map(pos - eps.yxz), 265 | map(pos + eps.yzx) - map(pos - eps.yzx))); 266 | } 267 | 268 | vec4 render(in vec3 camPos, in vec3 rayDir) { 269 | 270 | float dist = march(camPos, rayDir); 271 | vec3 fPos = camPos + rayDir * dist; 272 | vec3 nor = calcNormal(fPos); 273 | vec3 col = nor * 0.5 + 0.5; 274 | float fres = (1.+dot(rayDir, nor)); 275 | col *= fres; 276 | col = pow(col, vec3(0.666)); 277 | col = mix(col, bgColor.rgb, clamp(dist/maxDist, 0.0, 1.0)); 278 | return vec4(col, dist); 279 | } 280 | #define AA 1 281 | 282 | void main() 283 | { 284 | vec4 color = vec4(0.); 285 | for (int j = 0; j < AA; j++) { 286 | for (int k = 0; k < AA; k++) 287 | { 288 | vec2 o = vec2(float(j), float(k)) / float(AA); 289 | vec2 uv = (uv + o / _Resolution) * 2. - 1. ; 290 | uv.x *= _Resolution.x/_Resolution.y; 291 | vec3 ray = normalize (_CamRight * uv.x + 292 | _CamUp * uv.y + 293 | _CamForward * focalLength); 294 | 295 | color += vec4(render(_CamPos, ray)); 296 | } 297 | } 298 | 299 | color /= float(AA * AA); 300 | outputColor = color; 301 | } 302 | -------------------------------------------------------------------------------- /bin/data/presets/Kifs.json: -------------------------------------------------------------------------------- 1 | { 2 | "blend" : 1, 3 | "data" : [ 4 | { 5 | "parameters" : [ 6 | { 7 | "name" : "focalLength", 8 | "range" : { 9 | "x" : 0, 10 | "y" : 10 11 | }, 12 | "show" : true, 13 | "type" : "float", 14 | "value" : 2.5 15 | }, 16 | { 17 | "name" : "minDist", 18 | "range" : { 19 | "x" : 0, 20 | "y" : 0.1000000014901161 21 | }, 22 | "show" : false, 23 | "type" : "float", 24 | "value" : 0.001000000047497451 25 | }, 26 | { 27 | "name" : "maxDist", 28 | "range" : { 29 | "x" : 0, 30 | "y" : 15 31 | }, 32 | "show" : true, 33 | "type" : "float", 34 | "value" : 7.739362239837646 35 | }, 36 | { 37 | "name" : "bgColor", 38 | "show" : true, 39 | "type" : "color", 40 | "value" : { 41 | "a" : 0, 42 | "b" : 0, 43 | "g" : 1, 44 | "r" : 0 45 | } 46 | }, 47 | { 48 | "name" : "startScale", 49 | "range" : { 50 | "x" : 0, 51 | "y" : 2 52 | }, 53 | "show" : true, 54 | "type" : "float", 55 | "value" : 0.2553191483020782 56 | }, 57 | { 58 | "name" : "scaleFactor", 59 | "range" : { 60 | "x" : 0, 61 | "y" : 1 62 | }, 63 | "show" : true, 64 | "type" : "float", 65 | "value" : 0.5957446694374084 66 | }, 67 | { 68 | "name" : "offset", 69 | "range" : { 70 | "x" : 0, 71 | "y" : 4 72 | }, 73 | "show" : true, 74 | "type" : "vec3", 75 | "value" : { 76 | "x" : 1.840909123420715, 77 | "y" : 1.136363625526428, 78 | "z" : 2.090909004211426 79 | } 80 | }, 81 | { 82 | "name" : "spaceSize", 83 | "range" : { 84 | "x" : 0, 85 | "y" : 5 86 | }, 87 | "show" : true, 88 | "type" : "vec3", 89 | "value" : { 90 | "x" : 2.897727251052856, 91 | "y" : 3, 92 | "z" : 3 93 | } 94 | }, 95 | { 96 | "name" : "distScalar", 97 | "range" : { 98 | "x" : 0, 99 | "y" : 2 100 | }, 101 | "show" : true, 102 | "type" : "float", 103 | "value" : 0.4893617033958435 104 | }, 105 | { 106 | "name" : "rotationPhaseX", 107 | "range" : { 108 | "x" : 0, 109 | "y" : 7 110 | }, 111 | "show" : true, 112 | "type" : "float", 113 | "value" : 0 114 | }, 115 | { 116 | "name" : "rotationPhaseY", 117 | "range" : { 118 | "x" : 0, 119 | "y" : 7 120 | }, 121 | "show" : true, 122 | "type" : "float", 123 | "value" : 2.941489458084106 124 | }, 125 | { 126 | "name" : "animationAmpX", 127 | "range" : { 128 | "x" : 0, 129 | "y" : 0.5 130 | }, 131 | "show" : true, 132 | "type" : "float", 133 | "value" : 0.146276593208313 134 | }, 135 | { 136 | "name" : "animationAmpY", 137 | "range" : { 138 | "x" : 0, 139 | "y" : 0.5 140 | }, 141 | "show" : true, 142 | "type" : "float", 143 | "value" : 0.109707422554493 144 | }, 145 | { 146 | "name" : "", 147 | "type" : "camera", 148 | "value" : { 149 | "pos" : { 150 | "x" : 2.942674160003662, 151 | "y" : 2.825608968734741, 152 | "z" : -2.82723593711853 153 | }, 154 | "rot" : { 155 | "x" : 43.1596565246582, 156 | "y" : 2.802085876464844, 157 | "z" : -5.233835697174072 158 | } 159 | } 160 | } 161 | ], 162 | "shaderName" : "shaders/raymarchKifsShader" 163 | }, 164 | { 165 | "parameters" : [ 166 | { 167 | "name" : "startFocusDist", 168 | "range" : { 169 | "x" : 0, 170 | "y" : 10 171 | }, 172 | "show" : true, 173 | "type" : "float", 174 | "value" : 0.585106372833252 175 | }, 176 | { 177 | "name" : "endFocusDist", 178 | "range" : { 179 | "x" : 0, 180 | "y" : 10 181 | }, 182 | "show" : true, 183 | "type" : "float", 184 | "value" : 1.808510541915894 185 | }, 186 | { 187 | "name" : "ramp", 188 | "range" : { 189 | "x" : 0, 190 | "y" : 1 191 | }, 192 | "show" : true, 193 | "type" : "float", 194 | "value" : 0.09574468433856964 195 | }, 196 | { 197 | "name" : "blurSize", 198 | "range" : { 199 | "x" : 0, 200 | "y" : 16 201 | }, 202 | "show" : true, 203 | "type" : "float", 204 | "value" : 4 205 | } 206 | ], 207 | "shaderName" : "shaders/bokehShader" 208 | }, 209 | { 210 | "parameters" : [ 211 | { 212 | "name" : "intensity", 213 | "range" : { 214 | "x" : 0, 215 | "y" : 1 216 | }, 217 | "show" : true, 218 | "type" : "float", 219 | "value" : 0.4972826838493347 220 | }, 221 | { 222 | "name" : "scale", 223 | "range" : { 224 | "x" : 0, 225 | "y" : 2 226 | }, 227 | "show" : true, 228 | "type" : "float", 229 | "value" : 1 230 | }, 231 | { 232 | "filePath" : "", 233 | "name" : "lastTex", 234 | "show" : true, 235 | "targetBufferName" : "", 236 | "textureIndex" : 2, 237 | "textype" : "Last", 238 | "type" : "texture" 239 | } 240 | ], 241 | "shaderName" : "shaders/feedbackShader" 242 | }, 243 | { 244 | "parameters" : [ 245 | { 246 | "name" : "shift", 247 | "range" : { 248 | "x" : 0, 249 | "y" : 6.283180236816406 250 | }, 251 | "show" : true, 252 | "type" : "float", 253 | "value" : 2.97085165977478 254 | } 255 | ], 256 | "shaderName" : "shaders/hueShader" 257 | }, 258 | { 259 | "parameters" : [ 260 | { 261 | "name" : "strength", 262 | "range" : { 263 | "x" : 0, 264 | "y" : 1 265 | }, 266 | "show" : true, 267 | "type" : "float", 268 | "value" : 0.6326530575752258 269 | }, 270 | { 271 | "name" : "power", 272 | "range" : { 273 | "x" : 0, 274 | "y" : 1 275 | }, 276 | "show" : true, 277 | "type" : "float", 278 | "value" : 0.9021739363670349 279 | } 280 | ], 281 | "shaderName" : "shaders/vignetteShader" 282 | } 283 | ], 284 | "duration" : 6.283180236816406, 285 | "fps" : 30, 286 | "res" : { 287 | "x" : 500, 288 | "y" : 500 289 | }, 290 | "scale" : 1 291 | } 292 | -------------------------------------------------------------------------------- /src/Parameters/TextureParameter.cpp: -------------------------------------------------------------------------------- 1 | #include "TextureParameter.h" 2 | #include "ShaderPass.h" 3 | 4 | TextureParameter::TextureParameter(string uniform, string filePath, int textureIndex, bool show, string texType, string targetBufferName) { 5 | this->textureIndex = textureIndex; 6 | this->filePath = filePath; 7 | this->uniform = uniform; 8 | // auto player = ofPtr(&gstreamer); 9 | //this->videoFile.setPlayer(player); 10 | this->show = show; 11 | this->type = getTypeFromString(texType); 12 | this->targetBufferName = targetBufferName; 13 | } 14 | 15 | void TextureParameter::close() { 16 | closeVideoFile(); 17 | } 18 | 19 | void TextureParameter::update(RenderStruct *renderStruct) { 20 | if (this->type == VideoFile) { 21 | if (renderStruct->isOfflineRendering) { 22 | this->videoFile.update(); 23 | this->videoFile.nextFrame(); 24 | 25 | } else { 26 | if (this->videoFile.isPlaying()) { 27 | this->videoFile.update(); 28 | } 29 | } 30 | } 31 | } 32 | 33 | void TextureParameter::updateToNewType(TextureSourceType t) { 34 | if (this->type == Webcam && t != Webcam) { 35 | texInput->selectionView->updateWebcam(false); 36 | } 37 | if (this->type == VideoFile) { 38 | closeVideoFile(); 39 | } 40 | this->type = t; 41 | } 42 | 43 | void TextureParameter::UpdateShader(ofxAutoReloadedShader *shader, RenderStruct *renderStruct) { 44 | 45 | if (this->type == ImageFile) { 46 | if (this->value.isAllocated()) { 47 | shader->setUniformTexture(this->uniform, this->value.getTexture(), this->textureIndex); 48 | shader->setUniform2f(this->uniform+"_res", this->value.getWidth(), this->value.getHeight()); 49 | this->texInput->setGraphics(&this->value.getTexture()); 50 | } 51 | } else if (this->type == VideoFile) { 52 | if (this->videoFile.isLoaded() && this->videoFile.getWidth() > 0) { 53 | this->texInput->setGraphics(&this->videoFile.getTexture()); 54 | shader->setUniformTexture(this->uniform, this->videoFile.getTexture(), 1); 55 | shader->setUniform2f(this->uniform+"_res", this->videoFile.getWidth(), this->videoFile.getHeight()); 56 | } 57 | } else if (this->type == Webcam) { 58 | renderStruct->vidGrabber->update(); 59 | this->texInput->setGraphics(&renderStruct->vidGrabber->getTexture()); 60 | shader->setUniformTexture(this->uniform, renderStruct->vidGrabber->getTexture(), this->textureIndex); 61 | shader->setUniform2f(this->uniform+"_res", renderStruct->vidGrabber->getWidth(), renderStruct->vidGrabber->getHeight()); 62 | } else if (this->type == Buffer || this->type == Last) { 63 | 64 | int targetBufferIndex = -1; 65 | 66 | for (unsigned int i = 0; i < renderStruct->passes->size(); i++) { 67 | if (renderStruct->passes->at(i)->displayName == targetBufferName) { 68 | targetBufferIndex = i; 69 | break; 70 | } 71 | } 72 | 73 | if (targetBufferIndex != -1) { 74 | 75 | if (this->type == Buffer) { 76 | this->texInput->setGraphics(&renderStruct->passes->at(targetBufferIndex)->buffer.getTexture()); 77 | shader->setUniformTexture(this->uniform, renderStruct->passes->at(targetBufferIndex)->buffer.getTexture(), this->textureIndex); 78 | shader->setUniform2f(this->uniform+"_res", renderStruct->passes->at(targetBufferIndex)->buffer.getWidth(), renderStruct->passes->at(targetBufferIndex)->buffer.getHeight()); 79 | } 80 | } 81 | if (this->type == Last) { 82 | if (renderStruct->lastBuffer->isAllocated()) { 83 | this->texInput->setGraphics(&renderStruct->lastBuffer->getTexture()); 84 | shader->setUniformTexture(this->uniform, renderStruct->lastBuffer->getTexture(), textureIndex); 85 | shader->setUniformTexture(this->uniform, renderStruct->lastBuffer->getTexture(), this->textureIndex); 86 | shader->setUniform2f(this->uniform+"_res", renderStruct->lastBuffer->getWidth(), renderStruct->lastBuffer->getHeight()); 87 | } 88 | } 89 | } else if (type == Audio) { 90 | if (renderStruct->fft->audioTexture.isAllocated()) { 91 | this->texInput->setGraphics(&renderStruct->fft->audioTexture); 92 | shader->setUniformTexture(this->uniform, renderStruct->fft->audioTexture, this->textureIndex); 93 | shader->setUniform2f(this->uniform+"_res", renderStruct->fft->audioTexture.getWidth(), renderStruct->fft->audioTexture.getHeight()); 94 | } 95 | } 96 | } 97 | 98 | void TextureParameter::AddToGui(ofxGuiGroup2 *gui) { 99 | if (this->show) { 100 | texInput = gui->add(this->uniform, &value.getTexture(), ofJson({{"height", 200}})); 101 | texInput->selectionView = selectionView; 102 | ofAddListener(texInput->showEvent, this, &TextureParameter::onShowSelectionView); 103 | } 104 | startDoingThingForType(); 105 | } 106 | 107 | void TextureParameter::onShowSelectionView() { 108 | ofAddListener(selectionView->selectedFilePathChanged, this, &TextureParameter::updateTextureFromFile); 109 | ofAddListener(selectionView->wantsWebcamChanged, this, &TextureParameter::wantsWebcamChanged); 110 | ofAddListener(selectionView->selectedBufferChanged, this, &TextureParameter::wantsBufferChanged); 111 | ofAddListener(selectionView->wantsAudioChanged, this, &TextureParameter::wantsAudioChanged); 112 | 113 | listenersAdded = true; 114 | } 115 | 116 | void TextureParameter::onHideSelectionView() { 117 | if (listenersAdded) { 118 | ofRemoveListener(selectionView->selectedFilePathChanged, this, &TextureParameter::updateTextureFromFile); 119 | ofRemoveListener(selectionView->wantsWebcamChanged, this, &TextureParameter::wantsWebcamChanged); 120 | ofRemoveListener(selectionView->selectedBufferChanged, this, &TextureParameter::wantsBufferChanged); 121 | ofRemoveListener(selectionView->wantsAudioChanged, this, &TextureParameter::wantsAudioChanged); 122 | 123 | listenersAdded = false; 124 | } 125 | } 126 | 127 | void TextureParameter::updateTextureFromFile(string &s) { 128 | 129 | auto dataPathIndex = s.rfind("data"); 130 | string relativeFileName = ""; 131 | 132 | if (dataPathIndex != std::string::npos) { 133 | s = s.substr(dataPathIndex + 5); 134 | } 135 | 136 | auto extension = s.substr(s.find_last_of(".") + 1); 137 | 138 | if (extension == "png" || extension == "jpg" || extension == "jpeg" || extension == "bmp" || extension == "gif") { 139 | this->value.load(s); 140 | updateToNewType(ImageFile); 141 | filePath = s; 142 | } 143 | 144 | else if (extension == "mp4" || extension == "mov" || extension == "avi" || extension == "mkv") { 145 | updateToNewType(VideoFile); 146 | this->videoFile.load(s); 147 | this->videoFile.setUseTexture(true); 148 | this->videoFile.play(); 149 | filePath = s; 150 | } 151 | onHideSelectionView(); 152 | } 153 | 154 | void TextureParameter::wantsWebcamChanged(bool &val) { 155 | if (val) { 156 | updateToNewType(Webcam); 157 | } 158 | onHideSelectionView(); 159 | } 160 | 161 | void TextureParameter::wantsBufferChanged(string &val) { 162 | 163 | if (val == this->parentBufferName) { 164 | updateToNewType(Last); 165 | } else { 166 | updateToNewType(Buffer); 167 | } 168 | 169 | targetBufferName = val; 170 | onHideSelectionView(); 171 | } 172 | 173 | void TextureParameter::startDoingThingForType() { 174 | if (type == ImageFile || type == VideoFile) { 175 | updateTextureFromFile(filePath); 176 | } 177 | else if (type == Webcam) { 178 | texInput->selectionView->updateWebcam(true); 179 | } 180 | } 181 | 182 | void TextureParameter::UpdateJson(Json::Value &val) { 183 | val["name"] = this->uniform; 184 | val["filePath"] = this->filePath; 185 | val["textureIndex"] = this->textureIndex; 186 | val["show"] = this->show; 187 | val["type"] = "texture"; 188 | val["textype"] = getTextureType(); 189 | val["targetBufferName"] = targetBufferName; 190 | } 191 | 192 | void TextureParameter::startOfflineRender() { 193 | if (type == VideoFile) { 194 | this->videoFile.setPaused(true); 195 | cout << "set fbf" << endl; 196 | //gstreamer.setFrameByFrame(true); 197 | cout << "set paused" << endl; 198 | 199 | //this->videoFile.setPaused(true); 200 | cout << "set frame 0" << endl; 201 | 202 | this->videoFile.setFrame(0); 203 | this->videoFile.update(); 204 | 205 | } 206 | } 207 | 208 | void TextureParameter::stopOfflineRender() { 209 | if (type == VideoFile) { 210 | // gstreamer.setFrameByFrame(false); 211 | //this->videoFile.setPaused(false); 212 | 213 | //gstreamer.setFrameByFrame(false); 214 | //this->videoFile.setPaused(false); 215 | //this->videoFile.play(); 216 | } 217 | } 218 | 219 | string TextureParameter::getTextureType() { 220 | if (type == ImageFile) { 221 | return "ImageFile"; 222 | } else if (type == VideoFile) { 223 | return "VideoFile"; 224 | } else if (type == Webcam) { 225 | return "Webcam"; 226 | } else if (type == Buffer) { 227 | return "Buffer"; 228 | } else if (type == Last) { 229 | return "Last"; 230 | } else if (type == Audio) { 231 | return "Audio"; 232 | } 233 | return ""; 234 | } 235 | 236 | TextureSourceType TextureParameter::getTypeFromString(string s) { 237 | if (s == "VideoFile") { 238 | return VideoFile; 239 | } else if (s == "Webcam") { 240 | return Webcam; 241 | } else if (s == "Buffer") { 242 | return Buffer; 243 | } else if (s == "Last") { 244 | return Last; 245 | } else if (s == "Audio") { 246 | return Audio; 247 | } 248 | return ImageFile; 249 | } 250 | 251 | bool TextureParameter::isMouseHoveredOver() { 252 | return texInput->isMouseOver(); 253 | } 254 | 255 | void TextureParameter::handleInputFile(string s) { 256 | updateTextureFromFile(s); 257 | } 258 | 259 | TextureSourceType TextureParameter::getTextureSourceType() { 260 | return type; 261 | } 262 | 263 | void TextureParameter::playbackDidToggleState(bool isPaused) { 264 | if (type == VideoFile) { 265 | if (isPaused) { 266 | this->videoFile.setPaused(true); 267 | } else { 268 | this->videoFile.setPaused(false); 269 | } 270 | } 271 | } 272 | 273 | void TextureParameter::wantsAudioChanged(bool &val) { 274 | updateToNewType(Audio); 275 | } 276 | 277 | void TextureParameter::closeVideoFile() { 278 | if (videoFile.isLoaded() || videoFile.isPlaying()) { 279 | videoFile.stop(); 280 | videoFile.close(); 281 | } 282 | } 283 | -------------------------------------------------------------------------------- /src/ShaderPass.cpp: -------------------------------------------------------------------------------- 1 | #include "ShaderPass.h" 2 | #include "ShaderChain.h" 3 | 4 | #include 5 | 6 | ShaderPass::ShaderPass() { 7 | 8 | } 9 | 10 | ShaderPass::ShaderPass(std::string shaderPath, glm::vec2 res) { 11 | Load(shaderPath, res); 12 | } 13 | 14 | void ShaderPass::Load(std::string shaderPath, glm::vec2 res) { 15 | this->shader.load(vertexShaderPath, shaderPath + ".frag", ""); 16 | this->filePath = shaderPath; 17 | this->scale = 1.0; 18 | this->targetResolution = glm::vec2(res.x * scale, res.y * scale); 19 | this->parameterGroup = nullptr; 20 | this->LoadDisplayNameFromFileName(); 21 | UpdateResolution(this->targetResolution.x, this->targetResolution.y); 22 | } 23 | 24 | ShaderPass::~ShaderPass(){ 25 | 26 | for (unsigned int i = 0; i < this->params.size(); i++) { 27 | params[i]->close(); 28 | } 29 | params.clear(); 30 | } 31 | 32 | void ShaderPass::LoadDisplayNameFromFileName() { 33 | int indexOfLastForwardSlash = this->filePath.find_last_of("/"); 34 | int indexOfLastBackSlash = this->filePath.find_last_of("\\"); 35 | 36 | if (indexOfLastForwardSlash != std::string::npos) { 37 | this->displayName = this->filePath.substr(indexOfLastForwardSlash + 1); 38 | } else if (indexOfLastBackSlash != std::string::npos) { 39 | this->displayName = this->filePath.substr(indexOfLastBackSlash + 1); 40 | } else { 41 | this->displayName = this->filePath; 42 | } 43 | } 44 | 45 | void ShaderPass::UpdateResolution(int x, int y) { 46 | this->targetResolution = glm::vec2(x * scale, y * scale); 47 | this->buffer.allocate(targetResolution.x, targetResolution.y, GL_RGBA32F); 48 | this->renderBuffer.allocate(targetResolution.x, targetResolution.y, GL_RGBA32F); 49 | 50 | if (wantsLastBuffer) { 51 | this->lastBuffer.allocate(targetResolution.x, targetResolution.y, GL_RGBA32F); 52 | } 53 | this->plane.set(this->targetResolution.x, this->targetResolution.y, 2, 2); 54 | this->plane.setPosition({this->targetResolution.x/2, this->targetResolution.y/2, 0.0f}); 55 | } 56 | 57 | void ShaderPass::AddBoolParameter(std::string s, bool startValue, bool show, int midi) { 58 | auto ptr = std::make_unique(s, startValue, show, midi); 59 | this->params.push_back(std::move(ptr)); 60 | } 61 | 62 | void ShaderPass::addCameraParameter(glm::vec3 pos, glm::vec3 rot) { 63 | auto ptr = std::make_unique(pos, rot); 64 | this->params.push_back(std::move(ptr)); 65 | } 66 | 67 | void ShaderPass::AddIntParameter(std::string s, int startValue, glm::vec2 range, bool show, int midi) { 68 | auto ptr = std::make_unique(s, startValue, range, show, midi); 69 | this->params.push_back(std::move(ptr)); 70 | } 71 | 72 | void ShaderPass::AddFloatParameter(std::string s, float startValue, glm::vec2 range, bool show, int midi) { 73 | auto ptr = std::make_unique(s, startValue, range, show, midi); 74 | this->params.push_back(std::move(ptr)); 75 | } 76 | 77 | void ShaderPass::AddAudioFloatParameter(std::string s, float startValue, glm::vec2 range, glm::vec2 frequencyRange, float scaleFactor, float expFactor, bool accumulate, bool show, int midi) { 78 | auto ptr = std::make_unique(s, startValue, range, frequencyRange, scaleFactor, expFactor, accumulate, show, midi); 79 | this->params.push_back(std::move(ptr)); 80 | } 81 | 82 | void ShaderPass::AddVector2Parameter(std::string s, glm::vec2 val, bool show, glm::vec2 range, int midi[]) { 83 | auto ptr = std::make_unique(s, val, show, range, midi); 84 | this->params.push_back(std::move(ptr)); 85 | } 86 | 87 | void ShaderPass::AddVector3Parameter(std::string s, glm::vec3 val, bool show, glm::vec2 range, int midi[]) { 88 | auto ptr = std::make_unique(s, val, show, range, midi); 89 | this->params.push_back(std::move(ptr)); 90 | } 91 | 92 | void ShaderPass::AddVector4Parameter(std::string s, glm::vec4 val, bool show, glm::vec2 range, int midi[]) { 93 | auto ptr = std::make_unique(s, val, show, range, midi); 94 | this->params.push_back(std::move(ptr)); 95 | } 96 | 97 | void ShaderPass::AddTextureParameter(string s, string filePath, int textureIndex, bool show, string texType, string targetBufferName) { 98 | auto ptr = std::make_unique(s, filePath, textureIndex, show, texType, targetBufferName); 99 | ptr->parentBufferName = displayName; 100 | this->params.push_back(std::move(ptr)); 101 | } 102 | 103 | void ShaderPass::AddColorParameter(string s, float r, float g, float b, float a, bool show, int midi[]) { 104 | auto ptr = std::make_unique(s, r, g, b, a, show, midi); 105 | this->params.push_back(std::move(ptr)); 106 | } 107 | 108 | void ShaderPass::update(RenderStruct *renderStruct) { 109 | for (unsigned int i = 0; i < this->params.size(); i++) { 110 | this->params[i]->update(renderStruct); 111 | } 112 | } 113 | 114 | void ShaderPass::Render(ofFbo *previousBuffer, RenderStruct *renderStruct) { 115 | this->buffer.begin(); 116 | this->shader.begin(); 117 | 118 | UpdateTime(renderStruct->time); 119 | 120 | if (previousBuffer != nullptr) { 121 | SetInputTexture(previousBuffer); 122 | } 123 | this->shader.setUniform2f("_Resolution", this->targetResolution.x, this->targetResolution.y); 124 | this->shader.setUniform2f("_Mouse", renderStruct->mousePosition.x, renderStruct->mousePosition.y); 125 | renderStruct->lastBuffer = &this->lastBuffer; 126 | for (unsigned int i = 0; i < params.size(); i++) { 127 | this->params[i]->UpdateShader(&(this->shader), renderStruct); 128 | } 129 | 130 | this->renderBuffer.draw(0, 0); 131 | this->shader.end(); 132 | this->buffer.end(); 133 | 134 | if (wantsLastBuffer) { 135 | this->lastBuffer.begin(); 136 | this->buffer.draw(0,0); 137 | this->lastBuffer.end(); 138 | } 139 | } 140 | 141 | void ShaderPass::SetInputTexture(ofFbo *buffer) { 142 | this->shader.setUniformTexture("_MainTexture", buffer->getTexture(), 1); 143 | } 144 | 145 | void ShaderPass::UpdateTime(float time) { 146 | this->shader.setUniform1f("_Time", time); 147 | } 148 | 149 | void ShaderPass::startOfflineRender() { 150 | for (unsigned int i = 0; i < this->params.size(); i++) { 151 | this->params[i]->startOfflineRender(); 152 | } 153 | } 154 | 155 | void ShaderPass::stopOfflineRender() { 156 | for (unsigned int i = 0; i < this->params.size(); i++) { 157 | this->params[i]->stopOfflineRender(); 158 | } 159 | } 160 | 161 | void ShaderPass::LoadJsonParametersFromLoadedShader() { 162 | 163 | ofFile textFile(filePath + ".frag"); 164 | ofBuffer buffer(textFile, 1024); 165 | std::string shaderSource = buffer.getText(); 166 | 167 | std::size_t startJsonIndex = shaderSource.find("/*"); 168 | std::size_t endJsonIndex = shaderSource.find("*/"); 169 | 170 | if (startJsonIndex != std::string::npos && endJsonIndex != std::string::npos) { 171 | string jsonString = shaderSource.substr(startJsonIndex+2, endJsonIndex-2); 172 | json.parse(jsonString); 173 | LoadParametersFromJson(json); 174 | } 175 | } 176 | 177 | void ShaderPass::LoadParametersFromJson(Json::Value &json) { 178 | 179 | for (unsigned int j = 0; j < json["parameters"].size(); j++) 180 | { 181 | string type = json["parameters"][j]["type"].asString(); 182 | 183 | // floats 184 | if (type == "float") { 185 | float val = json["parameters"][j]["value"].asFloat(); 186 | std::string name = json["parameters"][j]["name"].asString(); 187 | float x = json["parameters"][j]["range"]["x"].asFloat(); 188 | float y = json["parameters"][j]["range"]["y"].asFloat(); 189 | bool show = json["parameters"][j]["show"].asBool(); 190 | int midi = -1; 191 | if (json["parameters"][j].isMember("midi")) { 192 | midi = json["parameters"][j]["midi"].asInt(); 193 | } 194 | 195 | AddFloatParameter(name, val, glm::vec2(x, y), show, midi); 196 | } 197 | // vec3s 198 | else if (type == "vec3") { 199 | float valx = json["parameters"][j]["value"]["x"].asFloat(); 200 | float valy = json["parameters"][j]["value"]["y"].asFloat(); 201 | float valz = json["parameters"][j]["value"]["z"].asFloat(); 202 | 203 | std::string name = json["parameters"][j]["name"].asString(); 204 | float x = json["parameters"][j]["range"]["x"].asFloat(); 205 | float y = json["parameters"][j]["range"]["y"].asFloat(); 206 | bool show = json["parameters"][j]["show"].asBool(); 207 | 208 | int midi[] = {-1, -1, -1}; 209 | 210 | if (json["parameters"][j].isMember("midi")) { 211 | midi[0] = json["parameters"][j]["midi"]["x"].asInt(); 212 | midi[1] = json["parameters"][j]["midi"]["y"].asInt(); 213 | midi[2] = json["parameters"][j]["midi"]["z"].asInt(); 214 | } 215 | AddVector3Parameter(name, glm::vec3(valx, valy, valz), show, glm::vec2(x, y), midi); 216 | } 217 | // textures 218 | else if (type == "texture") { 219 | string name = json["parameters"][j]["name"].asString(); 220 | string path = json["parameters"][j]["filePath"].asString(); 221 | bool show = json["parameters"][j]["show"].asBool(); 222 | int index = json["parameters"][j]["textureIndex"].asInt(); 223 | string texType = json["parameters"][j]["textype"].asString(); 224 | string targetBufferName = ""; 225 | 226 | if (texType == "Last") { 227 | wantsLastBuffer = true; 228 | } 229 | 230 | if (texType == "Buffer") { 231 | targetBufferName = json["parameters"][j]["targetBufferName"].asString(); 232 | } 233 | 234 | AddTextureParameter(name, path, index, show, texType, targetBufferName); 235 | } 236 | // colors 237 | else if (type == "color") { 238 | float r = json["parameters"][j]["value"]["r"].asFloat(); 239 | float g = json["parameters"][j]["value"]["g"].asFloat(); 240 | float b = json["parameters"][j]["value"]["b"].asFloat(); 241 | float a = json["parameters"][j]["value"]["a"].asFloat(); 242 | std::string name = json["parameters"][j]["name"].asString(); 243 | bool show = json["parameters"][j]["show"].asBool(); 244 | 245 | int midi[] = {-1, -1, -1, -1}; 246 | 247 | AddColorParameter(name, r, g, b, a, show, midi); 248 | } // vec2s 249 | else if (type == "vec2") { 250 | float valx = json["parameters"][j]["value"]["x"].asFloat(); 251 | float valy = json["parameters"][j]["value"]["y"].asFloat(); 252 | 253 | std::string name = json["parameters"][j]["name"].asString(); 254 | float x = json["parameters"][j]["range"]["x"].asFloat(); 255 | float y = json["parameters"][j]["range"]["y"].asFloat(); 256 | bool show = json["parameters"][j]["show"].asBool(); 257 | 258 | int midi[] = {-1, -1}; 259 | 260 | if (json["parameters"][j].isMember("midi")) { 261 | midi[0] = json["parameters"][j]["midi"]["x"].asInt(); 262 | midi[1] = json["parameters"][j]["midi"]["y"].asInt(); 263 | } 264 | AddVector2Parameter(name, glm::vec2(valx, valy), show, glm::vec2(x, y), midi); 265 | } 266 | else if (type == "vec4") { 267 | float valx = json["parameters"][j]["value"]["x"].asFloat(); 268 | float valy = json["parameters"][j]["value"]["y"].asFloat(); 269 | float valz = json["parameters"][j]["value"]["z"].asFloat(); 270 | float valw = json["parameters"][j]["value"]["w"].asFloat(); 271 | 272 | std::string name = json["parameters"][j]["name"].asString(); 273 | float x = json["parameters"][j]["range"]["x"].asFloat(); 274 | float y = json["parameters"][j]["range"]["y"].asFloat(); 275 | bool show = json["parameters"][j]["show"].asBool(); 276 | 277 | int midi[] = {-1, -1, -1, -1}; 278 | 279 | if (json["parameters"][j].isMember("midi")) { 280 | midi[0] = json["parameters"][j]["midi"]["x"].asInt(); 281 | midi[1] = json["parameters"][j]["midi"]["y"].asInt(); 282 | midi[2] = json["parameters"][j]["midi"]["z"].asInt(); 283 | midi[2] = json["parameters"][j]["midi"]["w"].asInt(); 284 | } 285 | AddVector4Parameter(name, glm::vec4(valx, valy, valz, valw), show, glm::vec2(x, y), midi); 286 | } 287 | else if (type == "int") { 288 | int val = json["parameters"][j]["value"].asInt(); 289 | 290 | std::string name = json["parameters"][j]["name"].asString(); 291 | float x = json["parameters"][j]["range"]["x"].asFloat(); 292 | float y = json["parameters"][j]["range"]["y"].asFloat(); 293 | bool show = json["parameters"][j]["show"].asBool(); 294 | 295 | int midi = -1; 296 | 297 | AddIntParameter(name, val, glm::vec2(x, y), show, midi); 298 | } else if (type == "bool") { 299 | bool val = json["parameters"][j]["value"].asBool(); 300 | std::string name = json["parameters"][j]["name"].asString(); 301 | bool show = json["parameters"][j]["show"].asBool(); 302 | 303 | int midi = -1; 304 | 305 | AddBoolParameter(name, val, show, midi); 306 | } else if (type == "camera") { 307 | float xPos = json["parameters"][j]["value"]["pos"]["x"].asFloat(); 308 | float yPos = json["parameters"][j]["value"]["pos"]["y"].asFloat(); 309 | float zPos = json["parameters"][j]["value"]["pos"]["z"].asFloat(); 310 | cout << "ypos " << yPos << endl; 311 | 312 | glm::vec3 pos = glm::vec3(xPos, yPos, zPos); 313 | 314 | float xRot = json["parameters"][j]["value"]["rot"]["x"].asFloat(); 315 | float yRot = json["parameters"][j]["value"]["rot"]["y"].asFloat(); 316 | float zRot = json["parameters"][j]["value"]["rot"]["z"].asFloat(); 317 | 318 | glm::vec3 rot = glm::vec3(xRot, yRot, zRot); 319 | 320 | addCameraParameter(pos, rot); 321 | } else if (type == "audioFloat") { 322 | float val = json["parameters"][j]["value"].asFloat(); 323 | std::string name = json["parameters"][j]["name"].asString(); 324 | cout << "loading audio float " << name << " with " << val << endl; 325 | float x = json["parameters"][j]["range"]["x"].asFloat(); 326 | float y = json["parameters"][j]["range"]["y"].asFloat(); 327 | float fx = json["parameters"][j]["frequencyRange"]["x"].asFloat(); 328 | float fy = json["parameters"][j]["frequencyRange"]["y"].asFloat(); 329 | float scaleFactor = 1, expFactor = 1; 330 | bool accumulate = true; 331 | if(json["parameters"][j].isMember("scaleFactor")) { 332 | scaleFactor = json["parameters"][j]["scaleFactor"].asFloat(); 333 | } 334 | if(json["parameters"][j].isMember("expFactor")) { 335 | expFactor = json["parameters"][j]["expFactor"].asFloat(); 336 | } 337 | if(json["parameters"][j].isMember("accumulate")) { 338 | accumulate = json["parameters"][j]["accumulate"].asBool(); 339 | } 340 | bool show = json["parameters"][j]["show"].asBool(); 341 | int midi = -1; 342 | if (json["parameters"][j].isMember("midi")) { 343 | midi = json["parameters"][j]["midi"].asInt(); 344 | } 345 | 346 | AddAudioFloatParameter(name, val, glm::vec2(x, y), glm::vec2(fx, fy), scaleFactor, expFactor, accumulate, show, midi); 347 | } 348 | } 349 | 350 | if (wantsLastBuffer) { 351 | this->lastBuffer.allocate(targetResolution.x, targetResolution.y, GL_RGBA32F); 352 | } 353 | } 354 | 355 | void ShaderPass::LoadFromJson(Json::Value &json, float width, float height) { 356 | std::string shaderName = json["shaderName"].asString(); 357 | Load(shaderName, glm::vec2(width, height)); 358 | LoadParametersFromJson(json); 359 | } 360 | 361 | void ShaderPass::AddToGui(ofxGuiContainer *gui, TextureInputSelectionView *selectionView) { 362 | 363 | parameterGroup = gui->addGroup(); 364 | parameterGroup->setName(displayName); 365 | 366 | for (unsigned int i = 0; i < this->params.size(); i++) { 367 | params[i]->selectionView = selectionView; 368 | params[i]->AddToGui(parameterGroup); 369 | } 370 | } 371 | 372 | void ShaderPass::updateShaderJson() { 373 | ofFile textFile(filePath + ".frag", ofFile::ReadWrite); 374 | ofBuffer buffer(textFile, 1024); 375 | std::string shaderSource = buffer.getText(); 376 | 377 | std::size_t startJsonIndex = shaderSource.find("/*"); 378 | std::size_t endJsonIndex = shaderSource.find("*/"); 379 | 380 | if (startJsonIndex != std::string::npos && endJsonIndex != std::string::npos) { 381 | Json::Value content(Json::arrayValue); 382 | 383 | for(Json::Value::ArrayIndex j=0; jparams[(int)j]->getDict(); 385 | } 386 | 387 | json["parameters"] = content; 388 | 389 | shaderSource.replace(startJsonIndex+2, endJsonIndex+1, "\n" + json.getRawString() + "*/\n"); 390 | buffer.set(shaderSource.c_str(), shaderSource.size()); 391 | textFile.close(); 392 | bool fileWritten = ofBufferToFile(filePath + ".frag", buffer); 393 | } 394 | else { 395 | cout << "Couldn't locate shader json" << endl; 396 | } 397 | 398 | } 399 | --------------------------------------------------------------------------------