├── NShader.vsix ├── README.md ├── ReadMe.txt ├── Run.bat ├── VSColorOutput.vsix ├── bin ├── bass.dll ├── freeglut.dll ├── glew32.dll ├── libconfig.dll ├── liveCodingGlslCompiler.exe └── liveCodingPreview.exe ├── config.cfg ├── package.bat ├── shaders ├── compiler │ ├── glslOfflineCompiler.props │ ├── glslOfflineCompiler.targets │ ├── glslOfflineCompiler.xml │ ├── shaders.sln │ └── shaders.vcxproj ├── empty.glsl ├── fft_midi_test.glsl ├── fft_test.glsl ├── sampleShader.glsl └── splashScreen.glsl ├── sine.wav ├── src ├── liveCodingGlslCompiler.sln ├── liveCodingGlslCompiler │ ├── liveCodingGlslCompiler.vcxproj │ ├── main.cpp │ ├── stdafx.cpp │ ├── stdafx.h │ └── targetver.h ├── liveCodingPreview.sln └── liveCodingPreview │ ├── liveCoding.cpp │ ├── liveCoding.h │ ├── liveCodingPreview.vcxproj │ ├── liveCoding_inputs.cpp │ ├── midi.cpp │ ├── midi.h │ ├── stdafx.cpp │ ├── stdafx.h │ ├── targetver.h │ ├── util.cpp │ └── util.h ├── textures ├── checker.png ├── noise.png ├── splashScreen.png ├── tex1.png ├── tex2.png ├── tex3.png └── tex4.png └── wilhelm.wav /NShader.vsix: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bonzajplc/LiveCodingFramework/001b78efa3179eb0d94b57a77b74beb3405daabb/NShader.vsix -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # LiveCodingFramework 2 | Live Coding Framework used at WeCan 2014 demoscene party. Githubbed for archive purposes only. Made by Michal Szymczyk (misz/plastic) 3 | 4 | ------------------------------------------ 5 | 6 | Live Coding Framework by misz/plastic 7 | 8 | ------------------------------------------ 9 | 10 | v0.91 11 | 12 | - added FFT integration and smoothing 13 | - added FFT history 14 | - extra options in config file - window dimensions and always on top option 15 | 16 | ------------------------------------------ 17 | 18 | v0.9 19 | 20 | ------------------------------------------ 21 | 22 | Some basic info about the tool 23 | 24 | It consists of two elements: 25 | * liveCodingPreview - opengl window showing fullscreen quad with our fancy shader 26 | * liveCodingGlslCompiler - custom, offline glsl compiler, that can be plugged into visual studio build system 27 | 28 | First, we start liveCodingPreview. Then we open shaders/compiler/shaders.sln in visual studio. This is a solution with one project that has build chain customized with our liveCodingGlslCompiler. All files with extension *.glsl will be handled by our custom compiler. Every time coder hits compile button (or Ctrl-F7) shader will be recompiled, and if compilation succeeds, our compiler will send compiled binary to the instance of liveCodingPreview. liveCodingPreview will reload shader and we will see changes. 29 | 30 | Try using Run.bat macro. It will start both, liveCodingPreview.exe and Visual Studio with our solution. You may need to tweak path to devenv.exe to start it (Is there any envvar showing where devenv.exe sits?) 31 | 32 | liveCodingPreview.exe expects one input argument, path to where whole 'liveCoding tool' file structure is located. Depending on how you run (debugger, bin/liveCodingPreview.exe, bat), it may require different setting. 33 | 34 | There are two solutions for visual studio. One for each executable. This makes debugging comunication between two easier... 35 | 36 | There are also two optional visual studio extensions that are very useful: 37 | * NShader - for syntax higlighting 38 | * VSColorOutput - for coloring text within output window (build system errors, warnings, etc...) 39 | 40 | Whole liveCodingPreview has very simple setup, based on freeglut. OpenGL 4.3 at least required. There isn't much error checking, but I don't expect anyone to have problems with debugging it. 41 | 42 | If you want to add other textures, place them in liveCodingRoot/textures directory and register them in liveCoding::setupShaderInputs function. There's also liveCoding::setShaderInputs for setting custom shader parameters. 43 | 44 | One word about performance. When shaders get big (and we found that people don't care about writing optimal code during compo), compile times stop beeing negliable. That's why we decided to compile "on demand" instead of compiling "while typing". User will hit Ctrl-F7 eventually to check if shader is correct. We use that moment to reload preview. liveCodingGlslCompiler creates fake opengl contex to compile shader and then sends binary to liveCodingPreview to avoid extra compilation. 45 | 46 | F2 toggles between windowed/fullscreen modes. In case you have multi monitor setup, drag window over desired display and then hit F2. It will go fullscreen on that particular monitor. 47 | 48 | liveCodingPreview launches with 'splashScreen' shader that displays texture file "textures/splashScreen.png". 49 | 50 | Only 24/32-bit png images are supported. 51 | 52 | There's a config file 'config.cfg' located in root directory that remembers window position and fullscreen state from last session. Delete the file to restore defaults. There's special variable for selecting BASS input device called 'bassRecordDevice'. Set it to 0, 1, 2 (or -1 to let BASS decide). Default value for 'bassRecordDevice' is -1 in case it's not declared in config.cfg. liveCodingPreview lists all available recording devices on startup. 53 | 54 | To exit, press Alt-F4 or click 'x' in right-top corner of the window. ESC is ignored to prevent closing application when someone hits it accidentaly while coding. 55 | 56 | Enjoy! 57 | -------------------------------------------------------------------------------- /ReadMe.txt: -------------------------------------------------------------------------------- 1 | Live Coding Framework by misz/plastic 2 | 3 | ------------------------------------------ 4 | 5 | v0.91 6 | 7 | - added FFT integration and smoothing 8 | - added FFT history 9 | - extra options in config file - window dimensions and always on top option 10 | 11 | ------------------------------------------ 12 | 13 | v0.9 14 | 15 | ------------------------------------------ 16 | 17 | Some basic info about the tool 18 | 19 | It consists of two elements: 20 | * liveCodingPreview - opengl window showing fullscreen quad with our fancy shader 21 | * liveCodingGlslCompiler - custom, offline glsl compiler, that can be plugged into visual studio build system 22 | 23 | First, we start liveCodingPreview. Then we open shaders/compiler/shaders.sln in visual studio. This is a solution with one project that has build chain customized with our liveCodingGlslCompiler. All files with extension *.glsl will be handled by our custom compiler. Every time coder hits compile button (or Ctrl-F7) shader will be recompiled, and if compilation succeeds, our compiler will send compiled binary to the instance of liveCodingPreview. liveCodingPreview will reload shader and we will see changes. 24 | 25 | Try using Run.bat macro. It will start both, liveCodingPreview.exe and Visual Studio with our solution. You may need to tweak path to devenv.exe to start it (Is there any envvar showing where devenv.exe sits?) 26 | 27 | liveCodingPreview.exe expects one input argument, path to where whole 'liveCoding tool' file structure is located. Depending on how you run (debugger, bin/liveCodingPreview.exe, bat), it may require different setting. 28 | 29 | There are two solutions for visual studio. One for each executable. This makes debugging comunication between two easier... 30 | 31 | There are also two optional visual studio extensions that are very useful: 32 | * NShader - for syntax higlighting 33 | * VSColorOutput - for coloring text within output window (build system errors, warnings, etc...) 34 | 35 | Whole liveCodingPreview has very simple setup, based on freeglut. OpenGL 4.3 at least required. There isn't much error checking, but I don't expect anyone to have problems with debugging it. 36 | 37 | If you want to add other textures, place them in liveCodingRoot/textures directory and register them in liveCoding::setupShaderInputs function. There's also liveCoding::setShaderInputs for setting custom shader parameters. 38 | 39 | One word about performance. When shaders get big (and we found that people don't care about writing optimal code during compo), compile times stop beeing negliable. That's why we decided to compile "on demand" instead of compiling "while typing". User will hit Ctrl-F7 eventually to check if shader is correct. We use that moment to reload preview. liveCodingGlslCompiler creates fake opengl contex to compile shader and then sends binary to liveCodingPreview to avoid extra compilation. 40 | 41 | F2 toggles between windowed/fullscreen modes. In case you have multi monitor setup, drag window over desired display and then hit F2. It will go fullscreen on that particular monitor. 42 | 43 | liveCodingPreview launches with 'splashScreen' shader that displays texture file "textures/splashScreen.png". 44 | 45 | Only 24/32-bit png images are supported. 46 | 47 | There's a config file 'config.cfg' located in root directory that remembers window position and fullscreen state from last session. Delete the file to restore defaults. There's special variable for selecting BASS input device called 'bassRecordDevice'. Set it to 0, 1, 2 (or -1 to let BASS decide). Default value for 'bassRecordDevice' is -1 in case it's not declared in config.cfg. liveCodingPreview lists all available recording devices on startup. 48 | 49 | To exit, press Alt-F4 or click 'x' in right-top corner of the window. ESC is ignored to prevent closing application when someone hits it accidentaly while coding. 50 | 51 | Enjoy! 52 | -------------------------------------------------------------------------------- /Run.bat: -------------------------------------------------------------------------------- 1 | start bin/liveCodingPreview.exe ./ 2 | start "c:\Program Files (x86)\Microsoft Visual Studio 10.0\Common7\IDE\devenv.exe" shaders/compiler/shaders.sln 3 | pause -------------------------------------------------------------------------------- /VSColorOutput.vsix: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bonzajplc/LiveCodingFramework/001b78efa3179eb0d94b57a77b74beb3405daabb/VSColorOutput.vsix -------------------------------------------------------------------------------- /bin/bass.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bonzajplc/LiveCodingFramework/001b78efa3179eb0d94b57a77b74beb3405daabb/bin/bass.dll -------------------------------------------------------------------------------- /bin/freeglut.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bonzajplc/LiveCodingFramework/001b78efa3179eb0d94b57a77b74beb3405daabb/bin/freeglut.dll -------------------------------------------------------------------------------- /bin/glew32.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bonzajplc/LiveCodingFramework/001b78efa3179eb0d94b57a77b74beb3405daabb/bin/glew32.dll -------------------------------------------------------------------------------- /bin/libconfig.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bonzajplc/LiveCodingFramework/001b78efa3179eb0d94b57a77b74beb3405daabb/bin/libconfig.dll -------------------------------------------------------------------------------- /bin/liveCodingGlslCompiler.exe: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bonzajplc/LiveCodingFramework/001b78efa3179eb0d94b57a77b74beb3405daabb/bin/liveCodingGlslCompiler.exe -------------------------------------------------------------------------------- /bin/liveCodingPreview.exe: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bonzajplc/LiveCodingFramework/001b78efa3179eb0d94b57a77b74beb3405daabb/bin/liveCodingPreview.exe -------------------------------------------------------------------------------- /config.cfg: -------------------------------------------------------------------------------- 1 | windowPosX = 540; 2 | windowPosY = 243; 3 | fullscreen = false; 4 | windowW = 1280; 5 | windowH = 720; 6 | -------------------------------------------------------------------------------- /package.bat: -------------------------------------------------------------------------------- 1 | "C:\Program Files\7-Zip\7z.exe" -pliveCoding -mhe -mx3 a -t7z liveCoding.7z .\* -xr!?svn* -xr!*build\* -xr!*.sdf -xr!*.pdb -xr!*.ilk -xr!*.suo -xr!*.hlslc -xr!*.ipch -xr!*.user -------------------------------------------------------------------------------- /shaders/compiler/glslOfflineCompiler.props: -------------------------------------------------------------------------------- 1 |  2 | 3 | 5 | Midl 6 | CustomBuild 7 | 8 | 9 | _SelectedFiles;$(glslCompilerDependsOn) 11 | 12 | 13 | 14 | $(IntDir)%(Filename).fxo 15 | "..\..\bin\liveCodingGlslCompiler.exe" [inputs] 16 | %(ObjectFileName) 17 | %(Identity) 18 | 19 | 20 | 21 | -------------------------------------------------------------------------------- /shaders/compiler/glslOfflineCompiler.targets: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 6 | 8 | GlslOfflineCompiler 9 | 10 | 11 | 15 | $(MSBuildThisFileDirectory)$(MSBuildThisFileName).xml 16 | 17 | 25 | 27 | 30 | 31 | 32 | 35 | @(glslCompiler, '|') 36 | 37 | 38 | 41 | 45 | 51 | 52 | 53 | 54 | $(ComputeLinkInputsTargets); 55 | ComputeglslCompilerOutput; 56 | 57 | 58 | $(ComputeLibInputsTargets); 59 | ComputeglslCompilerOutput; 60 | 61 | 62 | 65 | 66 | 69 | 72 | 75 | 78 | 79 | 81 | 82 | 83 | -------------------------------------------------------------------------------- /shaders/compiler/glslOfflineCompiler.xml: -------------------------------------------------------------------------------- 1 |  2 | 3 | 8 | 9 | 12 | 13 | 14 | 16 | 17 | General 18 | 19 | 20 | 23 | 24 | Command Line 25 | 26 | 27 | 28 | 33 | 34 | 38 | 39 | 40 | 47 | 52 | 57 | 58 | Execute Before 59 | 60 | 61 | Specifies the targets for the build customization to run before. 62 | 63 | 64 | 67 | 68 | 69 | 72 | 73 | 74 | 79 | 80 | Execute After 81 | 82 | 83 | Specifies the targets for the build customization to run after. 84 | 85 | 86 | 89 | 90 | 91 | 95 | 96 | 97 | 102 | 107 | 112 | 116 | 117 | Additional Options 118 | 119 | 120 | Additional Options 121 | 122 | 123 | 124 | 127 | 130 | 134 | 135 | -------------------------------------------------------------------------------- /shaders/compiler/shaders.sln: -------------------------------------------------------------------------------- 1 |  2 | Microsoft Visual Studio Solution File, Format Version 11.00 3 | # Visual Studio 2010 4 | Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "shaders", "shaders.vcxproj", "{CC45AD60-64BD-4E1C-A19B-4CE5EC5875BC}" 5 | EndProject 6 | Global 7 | GlobalSection(SolutionConfigurationPlatforms) = preSolution 8 | Release|x64 = Release|x64 9 | EndGlobalSection 10 | GlobalSection(ProjectConfigurationPlatforms) = postSolution 11 | {CC45AD60-64BD-4E1C-A19B-4CE5EC5875BC}.Release|x64.ActiveCfg = Release|x64 12 | {CC45AD60-64BD-4E1C-A19B-4CE5EC5875BC}.Release|x64.Build.0 = Release|x64 13 | {4D76EE1A-C6D1-4302-894F-9F9A2D1EB7A5}.Release|x64.ActiveCfg = Release|x64 14 | {4D76EE1A-C6D1-4302-894F-9F9A2D1EB7A5}.Release|x64.Build.0 = Release|x64 15 | {FADDFD73-116A-4C1E-A8A8-EAF17F58A428}.Release|x64.ActiveCfg = Release|x64 16 | {FADDFD73-116A-4C1E-A8A8-EAF17F58A428}.Release|x64.Build.0 = Release|x64 17 | EndGlobalSection 18 | GlobalSection(SolutionProperties) = preSolution 19 | HideSolutionNode = FALSE 20 | EndGlobalSection 21 | EndGlobal 22 | -------------------------------------------------------------------------------- /shaders/compiler/shaders.vcxproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | Release 6 | x64 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | {CC45AD60-64BD-4E1C-A19B-4CE5EC5875BC} 18 | Win32Proj 19 | 20 | 21 | 22 | Utility 23 | 24 | 25 | 26 | 27 | 28 | 29 | <_ProjectFileVersion>10.0.40219.1 30 | $(SolutionDir)..\..\build\$(ProjectName)\$(Configuration)\$(Platform)\ 31 | $(SolutionDir)..\..\build\$(ProjectName)\$(Configuration)\$(Platform)\ 32 | 33 | 34 | 35 | 36 | 37 | -------------------------------------------------------------------------------- /shaders/empty.glsl: -------------------------------------------------------------------------------- 1 | /////////////////////////////////////////////////////////////////////////////// 2 | // shader inputs/outputs 3 | /////////////////////////////////////////////////////////////////////////////// 4 | uniform float iGlobalTime; // in seconds 5 | uniform vec2 iResolution; // viewport resolution (in pixels) (1080p or 720p) 6 | uniform mat4 iMidiPad; // 16 buttons of midi controller 7 | uniform float iMidiPadValue; // sum of all elements in iMidiPad/16 8 | 9 | uniform float iFFT[8]; 10 | uniform float iFFTi[8]; 11 | uniform float iFFTs[8]; 12 | uniform float iFFTsi[8]; 13 | 14 | 15 | // all samplers have linear filtering applied, wraping set to repeat 16 | // 17 | uniform sampler1D iFFTTexture; // 1024 18 | uniform sampler2D iNoise; // 512x512 noise 19 | // predefined textures 20 | // 21 | uniform sampler2D iTex1; 22 | uniform sampler2D iTex2; 23 | uniform sampler2D iTex3; 24 | uniform sampler2D iTex4; 25 | 26 | // out_color must be written in order to see anything 27 | // 28 | layout(location = 0) out vec4 out_color; 29 | /////////////////////////////////////////////////////////////////////////////// 30 | /////////////////////////////////////////////////////////////////////////////// 31 | 32 | void main(void) 33 | { 34 | vec2 uv = vec2( gl_FragCoord.xy + vec2(iGlobalTime*10) ) / iResolution; 35 | vec4 t = texture( iTex1, uv ); 36 | out_color = t; 37 | } 38 | -------------------------------------------------------------------------------- /shaders/fft_midi_test.glsl: -------------------------------------------------------------------------------- 1 | /////////////////////////////////////////////////////////////////////////////// 2 | // shader inputs/outputs 3 | /////////////////////////////////////////////////////////////////////////////// 4 | uniform float iGlobalTime; // in seconds 5 | uniform vec2 iResolution; // viewport resolution (in pixels) (1080p or 720p) 6 | uniform mat4 iMidiPad; // 16 buttons of midi controller 7 | uniform float iMidiPadValue; // sum of all elements in iMidiPad/16 8 | 9 | uniform float iFFT[8]; 10 | uniform float iFFTs[8]; 11 | 12 | // all samplers have linear filtering applied, wraping set to repeat 13 | // 14 | uniform sampler1D iFFTTexture; // 1024 15 | // predefined textures 16 | // 17 | uniform sampler2D iSplashScreen; 18 | uniform sampler2D iNoise; // 512x512 noise 19 | 20 | // out_color must be written in order to see anything 21 | // 22 | layout(location = 0) out vec4 out_color; 23 | /////////////////////////////////////////////////////////////////////////////// 24 | /////////////////////////////////////////////////////////////////////////////// 25 | 26 | void main(void) 27 | { 28 | float x = ( gl_FragCoord.x + 0.5 ) / iResolution.x; 29 | //float fft = sqrt( texture( iFFTTexture, x ).x ) * 1000; 30 | int xb = int( gl_FragCoord.x / 80 ) % 8; 31 | float fftb = iFFTs[xb] * 1000; 32 | 33 | float t = 1; 34 | if ( fftb < gl_FragCoord.y ) 35 | t = 0; 36 | 37 | if ( x < 0.5 ) 38 | { 39 | out_color = float4( t, t, t, 1 ); 40 | } 41 | else 42 | { 43 | out_color = float4( iMidiPad[0][0], iMidiPad[0][1], iMidiPad[0][2], 1 ); 44 | } 45 | } 46 | -------------------------------------------------------------------------------- /shaders/fft_test.glsl: -------------------------------------------------------------------------------- 1 | /////////////////////////////////////////////////////////////////////////////// 2 | // shader inputs 3 | /////////////////////////////////////////////////////////////////////////////// 4 | 5 | // all samplers have linear filtering applied, wraping set to repeat 6 | // 7 | 8 | uniform float iGlobalTime; // in seconds 9 | uniform vec2 iResolution; // viewport resolution (in pixels) (1080p or 720p) 10 | uniform mat4 iMidiPad; // 16 buttons of midi controller 11 | uniform float iMidiPadValue; // sum of all elements in iMidiPad/16 12 | 13 | uniform float iFFT[8]; // latest frame 14 | uniform float iFFTs[8]; // smoothed latest frame 15 | uniform sampler2D iFFTsHistory; // smoothed fft history, 8x1024, x coord = bin, y coord n-frames earlier, y=0 is latest frame 16 | uniform sampler1D iFFTTexture; // 1024 17 | // predefined textures 18 | // 19 | uniform sampler2D iSplashScreen; 20 | uniform sampler2D iNoise; // 512x512 noise 21 | 22 | // out_color must be written in order to see anything 23 | // 24 | layout(location = 0) out vec4 out_color; 25 | /////////////////////////////////////////////////////////////////////////////// 26 | /////////////////////////////////////////////////////////////////////////////// 27 | 28 | void main(void) 29 | { 30 | int xb = int( gl_FragCoord.x / 160 ) % 8; 31 | 32 | int xScreen = xb * 160 + 80; 33 | 34 | //// 1 35 | //// 36 | //float fft = texelFetch( iFFTsHistory, ivec2(xb, 0), 0 ) * 1000; 37 | //float t = 1; 38 | //if ( fft < gl_FragCoord.y || abs((xb*160+80)-gl_FragCoord.x) > 40 ) 39 | // t = 0; 40 | 41 | //// 2, the same as 1 42 | //// 43 | //float fft = iFFTs[xb] * 1000; 44 | //float t = 1; 45 | //if ( fft < gl_FragCoord.y || abs((xb*160+80)-gl_FragCoord.x) > 40 ) 46 | // t = 0; 47 | 48 | // 3, history 49 | // 50 | float fft = texture( iFFTsHistory, gl_FragCoord.xy / iResolution ) * 50; 51 | float t = 0; 52 | if ( abs(xScreen-gl_FragCoord.x) < fft /*&& abs(yScreen-gl_FragCoord.y) < scale*/ ) 53 | t = 1; 54 | 55 | out_color = float4( t, t, t, 1 ) * texture( iNoise, gl_FragCoord.xy / iResolution ); 56 | } 57 | -------------------------------------------------------------------------------- /shaders/sampleShader.glsl: -------------------------------------------------------------------------------- 1 | /////////////////////////////////////////////////////////////////////////////// 2 | // shader inputs/outputs 3 | /////////////////////////////////////////////////////////////////////////////// 4 | uniform float iGlobalTime; // in seconds 5 | uniform vec2 iResolution; // viewport resolution (in pixels) (1080p or 720p) 6 | uniform mat4 iMidiPad; // 16 buttons of midi controller 7 | uniform float iMidiPadValue; // sum of all elements in iMidiPad/16 8 | 9 | // all samplers have linear filtering applied, wraping set to repeat 10 | // 11 | uniform sampler1D iFFTTexture; // 1024 12 | // copies of following textures for preview are located on desktop 13 | // 14 | uniform sampler2D iSplashScreen; 15 | uniform sampler2D iChecker; 16 | uniform sampler2D iTex1; 17 | uniform sampler2D iTex2; 18 | uniform sampler2D iTex3; 19 | uniform sampler2D iTex4; 20 | 21 | // out_color must be written in order to see anything 22 | // 23 | layout(location = 0) out vec4 out_color; 24 | /////////////////////////////////////////////////////////////////////////////// 25 | /////////////////////////////////////////////////////////////////////////////// 26 | 27 | void main(void) 28 | { 29 | vec2 uv = float2(gl_FragCoord.xy+float2(0.5,0.5)) / float2(iResolution); 30 | //vec4 t = texture( iSplashScreen, uv ); 31 | //out_color = t; 32 | 33 | //out_color = float4( iMidiPad[0][0], iMidiPad[0][1], iMidiPad[0][2], 1 ); 34 | out_color = float4( iMidiPadValue, iMidiPadValue, iMidiPadValue, 1 ); 35 | 36 | float fft = sqrt(texture( iFFTTexture, uv.x ).x) * 1000; 37 | float t = 1; 38 | if ( fft < gl_FragCoord.y ) 39 | t = 0; 40 | 41 | out_color *= float4( t, t, t, 1 ); 42 | 43 | //const float BANDS = 20; 44 | //float x = gl_FragCoord.x / (iResolution.x/BANDS); 45 | ////x /= BANDS; 46 | //int b0 = int( pow( 2, max(x-1, 0) * 10.0/(BANDS-1) ) ); 47 | //int b1 = int( pow( 2, x * 10.0/(BANDS-1) ) ); 48 | //b1 = min( b1, 1024 ); 49 | ////int b0 = 0; 50 | //b1 = max( b1, b0 + 1 ); 51 | 52 | //float peak = 0; 53 | //for ( ; b0 < b1; ++b0 ) 54 | //{ 55 | // float t = texture( iFFTTexture, b0 * (1.0/1024.0) ).x; 56 | // peak = max( peak, t ); 57 | //} 58 | 59 | //float t = 1; 60 | //if ( peak*1000 < gl_FragCoord.y ) 61 | // t = 0; 62 | //out_color = float4( t, t, t, 1 ); 63 | 64 | //out_color = float4( x, x, x, 1 ); 65 | 66 | //out_color = float4( iMidiPad[0][0], iMidiPad[0][1], iMidiPad[0][2], 1 ); 67 | } 68 | -------------------------------------------------------------------------------- /shaders/splashScreen.glsl: -------------------------------------------------------------------------------- 1 | /////////////////////////////////////////////////////////////////////////////// 2 | // shader inputs/outputs 3 | /////////////////////////////////////////////////////////////////////////////// 4 | uniform float iGlobalTime; // in seconds 5 | uniform vec2 iResolution; // viewport resolution (in pixels) (1080p or 720p) 6 | uniform mat4 iMidiPad; // 16 buttons of midi controller 7 | uniform float iMidiPadValue; // sum of all elements in iMidiPad/16 8 | 9 | // all samplers have linear filtering applied, wraping set to repeat 10 | // 11 | uniform sampler1D iFFTTexture; // 1024 12 | // predefined textures 13 | // 14 | uniform sampler2D iSplashScreen; 15 | 16 | // out_color must be written in order to see anything 17 | // 18 | layout(location = 0) out vec4 out_color; 19 | /////////////////////////////////////////////////////////////////////////////// 20 | /////////////////////////////////////////////////////////////////////////////// 21 | 22 | void main(void) 23 | { 24 | vec2 uv = vec2(gl_FragCoord.xy) / iResolution; 25 | vec4 t = texture( iSplashScreen, uv ); 26 | out_color = t; 27 | } 28 | -------------------------------------------------------------------------------- /sine.wav: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bonzajplc/LiveCodingFramework/001b78efa3179eb0d94b57a77b74beb3405daabb/sine.wav -------------------------------------------------------------------------------- /src/liveCodingGlslCompiler.sln: -------------------------------------------------------------------------------- 1 |  2 | Microsoft Visual Studio Solution File, Format Version 11.00 3 | # Visual Studio 2010 4 | Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "liveCodingGlslCompiler", "liveCodingGlslCompiler\liveCodingGlslCompiler.vcxproj", "{840A6B61-5766-4F90-A8B5-41FE2363F2C7}" 5 | EndProject 6 | Global 7 | GlobalSection(SolutionConfigurationPlatforms) = preSolution 8 | Debug|x64 = Debug|x64 9 | Release|x64 = Release|x64 10 | EndGlobalSection 11 | GlobalSection(ProjectConfigurationPlatforms) = postSolution 12 | {FD4D8A71-25B7-4B0E-86E3-154FD2384F86}.Debug|x64.ActiveCfg = Debug|x64 13 | {FD4D8A71-25B7-4B0E-86E3-154FD2384F86}.Debug|x64.Build.0 = Debug|x64 14 | {FD4D8A71-25B7-4B0E-86E3-154FD2384F86}.Release|x64.ActiveCfg = Release|x64 15 | {FD4D8A71-25B7-4B0E-86E3-154FD2384F86}.Release|x64.Build.0 = Release|x64 16 | {840A6B61-5766-4F90-A8B5-41FE2363F2C7}.Debug|x64.ActiveCfg = Debug|x64 17 | {840A6B61-5766-4F90-A8B5-41FE2363F2C7}.Debug|x64.Build.0 = Debug|x64 18 | {840A6B61-5766-4F90-A8B5-41FE2363F2C7}.Release|x64.ActiveCfg = Release|x64 19 | {840A6B61-5766-4F90-A8B5-41FE2363F2C7}.Release|x64.Build.0 = Release|x64 20 | EndGlobalSection 21 | GlobalSection(SolutionProperties) = preSolution 22 | HideSolutionNode = FALSE 23 | EndGlobalSection 24 | EndGlobal 25 | -------------------------------------------------------------------------------- /src/liveCodingGlslCompiler/liveCodingGlslCompiler.vcxproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | Debug 6 | x64 7 | 8 | 9 | Release 10 | x64 11 | 12 | 13 | 14 | {840A6B61-5766-4F90-A8B5-41FE2363F2C7} 15 | Win32Proj 16 | liveCodingGlslCompiler 17 | 18 | 19 | 20 | Application 21 | true 22 | NotSet 23 | 24 | 25 | Application 26 | false 27 | true 28 | NotSet 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | true 42 | $(SolutionDir)..\bin\ 43 | $(SolutionDir)..\build\$(ProjectName)\$(Configuration)\$(Platform)\ 44 | 45 | 46 | false 47 | $(SolutionDir)..\build\$(ProjectName)\$(Configuration)\$(Platform)\ 48 | $(SolutionDir)..\bin\ 49 | 50 | 51 | 52 | Use 53 | Level3 54 | Disabled 55 | WIN32;_DEBUG;_CONSOLE;_CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions) 56 | 57 | 58 | Console 59 | true 60 | ../../external/freeglut/lib/x64/freeglut.lib;../../external/glew/lib/Release/x64/glew32.lib;../../external/libpng/libpng_x64_release.lib;../../external/libpng/ZLib_x64_release.lib;opengl32.lib;%(AdditionalDependencies) 61 | 62 | 63 | 64 | 65 | Level3 66 | Use 67 | MaxSpeed 68 | true 69 | true 70 | WIN32;NDEBUG;_CONSOLE;_CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions) 71 | 72 | 73 | Console 74 | true 75 | true 76 | true 77 | ../../external/freeglut/lib/x64/freeglut.lib;../../external/glew/lib/Release/x64/glew32.lib;../../external/libpng/libpng_x64_release.lib;../../external/libpng/ZLib_x64_release.lib;opengl32.lib;%(AdditionalDependencies) 78 | 79 | 80 | 81 | 82 | 83 | 84 | 85 | 86 | 87 | Create 88 | Create 89 | 90 | 91 | 92 | 93 | 94 | -------------------------------------------------------------------------------- /src/liveCodingGlslCompiler/main.cpp: -------------------------------------------------------------------------------- 1 | /******************************************************************************* 2 | * 2005-2014, plastic demoscene group 3 | * authors: misz, bonzaj 4 | *******************************************************************************/ 5 | #include "stdafx.h" 6 | 7 | HGLRC hglrc; 8 | HDC hdc; 9 | HWND hPFwnd; 10 | HINSTANCE hInst; 11 | 12 | bool extraLogMessages = false; 13 | 14 | std::string gVendor; 15 | 16 | static int _StartUpOpenGL(int args, char** argv) 17 | { 18 | // fake window 19 | // 20 | PIXELFORMATDESCRIPTOR pfd = { 21 | sizeof (PIXELFORMATDESCRIPTOR), 1, 22 | PFD_DRAW_TO_WINDOW | PFD_SUPPORT_OPENGL | PFD_DOUBLEBUFFER | PFD_SWAP_EXCHANGE, 23 | PFD_TYPE_RGBA, 24 | (BYTE)32, 25 | 0, 0, 0, 0, 0, 0, 0, 0, (BYTE)0, 0, 0, 0, 0, 26 | (BYTE)0, (BYTE)0, 27 | 0, PFD_MAIN_PLANE, 0, 0, 0, 0 28 | }; 29 | 30 | hInst = GetModuleHandle(NULL); 31 | WNDCLASS wincl; 32 | wincl.hInstance = hInst; 33 | wincl.lpszClassName = "PFrmt"; 34 | wincl.lpfnWndProc = DefWindowProc; 35 | wincl.style = 0; 36 | wincl.hIcon = NULL; 37 | wincl.hCursor = NULL; 38 | wincl.lpszMenuName = NULL; 39 | wincl.cbClsExtra = 0; 40 | wincl.cbWndExtra = 0; 41 | wincl.hbrBackground = NULL; 42 | RegisterClass(&wincl); 43 | 44 | // Create a dummy window to get our extension entry points 45 | hPFwnd = CreateWindow("PFrmt", "PFormat", WS_POPUP | WS_CLIPCHILDREN | WS_CLIPSIBLINGS, 0, 0, 8, 8, HWND_DESKTOP, NULL, hInst, NULL); 46 | 47 | hdc = GetDC(hPFwnd); 48 | SetPixelFormat(hdc,ChoosePixelFormat(hdc,&pfd), &pfd); 49 | hglrc = wglCreateContext(hdc); 50 | 51 | if( ! hglrc ) 52 | { 53 | //free( fileMem ); 54 | std::cerr << argv[0] << "Error while creating opengl context!" << std::endl; 55 | 56 | UnregisterClass( "PFrmt", hInst ); 57 | DestroyWindow( hPFwnd ); 58 | 59 | return 101; 60 | } 61 | 62 | wglMakeCurrent(hdc,hglrc); 63 | 64 | const GLubyte* renderer = glGetString( GL_RENDERER ); 65 | const GLubyte* vendor = glGetString( GL_VENDOR ); 66 | GLint majorVer = 1; 67 | glGetIntegerv( GL_MAJOR_VERSION, &majorVer ); 68 | GLint minorVer = 0; 69 | glGetIntegerv( GL_MINOR_VERSION, &minorVer ); 70 | 71 | GLenum err = glewInit(); 72 | if (GLEW_OK != err) 73 | { 74 | /* Problem: glewInit failed, something is seriously wrong. */ 75 | fprintf(stderr, "Error: %s\n", glewGetErrorString(err)); 76 | exit( -1 ); 77 | } 78 | 79 | 80 | std::string rendererVendorInfo = (const char*)glGetString(GL_VENDOR); 81 | std::string rendererVendorInfoLowerCase = rendererVendorInfo; 82 | std::transform( rendererVendorInfo.begin(), rendererVendorInfo.end(), rendererVendorInfoLowerCase.begin(), std::tolower ); 83 | 84 | if ( strstr(rendererVendorInfoLowerCase.c_str(), "nvidia") ) 85 | gVendor = "nvidia"; 86 | else if ( strstr(rendererVendorInfoLowerCase.c_str(), "ati") ) 87 | gVendor = "amd"; 88 | else if ( strstr(rendererVendorInfoLowerCase.c_str(), "amd") ) 89 | gVendor = "amd"; 90 | else 91 | { 92 | std::cerr << argv[0] << ": Unknown OpenGL vendor!" << std::endl; 93 | } 94 | 95 | return 0; 96 | } 97 | 98 | static void _ShutDownOpenGL() 99 | { 100 | // restore previous context 101 | // 102 | wglMakeCurrent( NULL, NULL ); 103 | 104 | // delete fake one 105 | // 106 | wglDeleteContext( hglrc ); 107 | ReleaseDC( hPFwnd, hdc ); 108 | 109 | SendMessage(hPFwnd,WM_CLOSE, 0, 0); 110 | UnregisterClass( "PFrmt", hInst ); 111 | } 112 | 113 | int loadFile( const char* filename, char** dstBuf, size_t* dstBufSize ) 114 | { 115 | FILE* f = fopen( filename, "rb" ); 116 | if ( !f ) 117 | { 118 | fprintf( stderr, "fopen failed! (%s)", filename ); 119 | return -1; 120 | } 121 | 122 | fseek( f, 0, SEEK_END ); 123 | size_t sizeInBytes = ftell( f ); 124 | fseek( f, 0, SEEK_SET ); 125 | 126 | char* buf = new char[sizeInBytes+1]; 127 | size_t readBytes = fread( buf, 1, sizeInBytes, f ); 128 | (void)readBytes; 129 | assert( readBytes == sizeInBytes ); 130 | int ret = fclose( f ); 131 | (void)ret; 132 | assert( ret != EOF ); 133 | 134 | buf[sizeInBytes] = NULL; 135 | 136 | *dstBuf = buf; 137 | *dstBufSize = sizeInBytes; 138 | 139 | return 0; 140 | } 141 | 142 | 143 | GLuint createGLSLShaderFromBuf( const char* filename, const char* buf, size_t bufSize, GLenum profile ) 144 | { 145 | std::stringstream ssLine0; 146 | ssLine0 << 147 | "#version 430 core" << std::endl << 148 | "#define float2 vec2" << std::endl << 149 | "#define float3 vec3" << std::endl << 150 | "#define float4 vec4" << std::endl << 151 | "#define half2 vec2" << std::endl << 152 | "#define half3 vec3" << std::endl << 153 | "#define half4 vec4" << std::endl << 154 | "#define int2 ivec2" << std::endl << 155 | "#define int3 ivec3" << std::endl << 156 | "#define int4 ivec4" << std::endl << 157 | "#define bool4 bvec4" << std::endl << 158 | 159 | "#define float4x4 mat4" << std::endl << 160 | "#define float3x3 mat3" << std::endl << 161 | 162 | "#define lerp mix" << std::endl << 163 | "#define saturate(x) clamp(x, 0, 1)" << std::endl << 164 | "#define mul(mtxLeft, vecRight) (mtxLeft * vecRight)" << std::endl 165 | 166 | << buf << std::endl; 167 | ; 168 | 169 | std::string line0 = ssLine0.str(); 170 | 171 | GLuint glsh = glCreateShader( profile ); 172 | const GLchar* lines[1] = { line0.c_str() }; 173 | glShaderSource( glsh, 1, lines, NULL ); 174 | glCompileShader( glsh ); 175 | 176 | GLint result = GL_FALSE; 177 | glGetShaderiv( glsh, GL_COMPILE_STATUS, &result ); 178 | 179 | if ( result == GL_FALSE ) 180 | { 181 | if ( extraLogMessages ) 182 | fprintf( stderr, "glsl shader compilation failed!\n" ); 183 | 184 | int infoLogLength; 185 | glGetShaderiv( glsh, GL_INFO_LOG_LENGTH, &infoLogLength ); 186 | 187 | if ( infoLogLength ) 188 | { 189 | std::string errString; 190 | errString.resize( infoLogLength ); 191 | glGetShaderInfoLog( glsh, infoLogLength, NULL, &errString[0] ); 192 | const char* text = reinterpret_cast( &errString[0] ); 193 | 194 | std::stringstream src; 195 | src.str( errString ); 196 | 197 | std::string line; 198 | 199 | int nExtraLines = 16; 200 | 201 | while ( getline(src, line) ) 202 | { 203 | if ( gVendor == "nvidia" ) 204 | { 205 | std::string::size_type errPos = line.find( ") : error" ); 206 | if ( errPos != std::string::npos ) 207 | { 208 | std::string::size_type nextBracket = errPos; 209 | if ( nextBracket != std::string::npos ) 210 | { 211 | std::string lineNoStr = line.substr( 2, nextBracket-2 ); 212 | int lineNo = atoi( lineNoStr.c_str() ); 213 | lineNo -= (int)nExtraLines; 214 | 215 | std::string errText = line.substr( errPos + 1 ); 216 | fprintf( stderr, "%s(%d)%s\n", filename ? filename : "unknown", lineNo, errText.c_str() ); 217 | } 218 | } 219 | } 220 | else if ( gVendor == "amd" ) 221 | { 222 | const char* token = "ERROR: 0:"; 223 | std::string::size_type tokenPos = line.find( token ); 224 | if ( tokenPos != std::string::npos ) 225 | { 226 | std::string::size_type colonPos = tokenPos + strlen(token); 227 | std::string::size_type nextColonPos = line.find( ':', colonPos + 1 ); 228 | 229 | if ( nextColonPos != std::string::npos ) 230 | { 231 | std::string lineNoStr = line.substr( colonPos, nextColonPos-colonPos ); 232 | int lineNo = atoi( lineNoStr.c_str() ); 233 | lineNo -= (int)nExtraLines; 234 | 235 | std::string errText = line.substr( nextColonPos + 1 ); 236 | fprintf( stderr, "%s(%d):%s\n", filename ? filename : "unknown", lineNo, errText.c_str() ); 237 | } 238 | } 239 | else 240 | { 241 | fprintf( stderr, "%s\n", line.c_str() ); 242 | } 243 | } 244 | else 245 | { 246 | fprintf( stderr, "%s\n", line.c_str() ); 247 | } 248 | } 249 | } 250 | 251 | fprintf( stderr, "\n\n" ); 252 | 253 | GLenum err = glGetError(); 254 | while ( err ) 255 | { 256 | err = glGetError(); 257 | } 258 | 259 | return 0; 260 | } 261 | 262 | return glsh; 263 | } 264 | 265 | HANDLE _OpenPipe() 266 | { 267 | HANDLE hPipe = CreateFile( 268 | "\\\\.\\pipe\\LiveCodingShaderPipe", // pipe name 269 | /*GENERIC_READ |*/ // read and write access 270 | GENERIC_WRITE, 271 | 0, // no sharing 272 | NULL, // default security attributes 273 | OPEN_EXISTING, // opens existing pipe 274 | 0, // default attributes 275 | NULL); // no template file 276 | 277 | if ( hPipe != INVALID_HANDLE_VALUE ) 278 | { 279 | return hPipe; 280 | } 281 | 282 | return 0; 283 | } 284 | 285 | void _ClosePipe( HANDLE h ) 286 | { 287 | BOOL bres = FlushFileBuffers( h ); 288 | (void)bres; 289 | assert( bres ); 290 | CloseHandle( h ); 291 | } 292 | 293 | void sendProgramSource( const char* sourceCode, size_t sourceCodeLen ) 294 | { 295 | HANDLE hPipe = _OpenPipe(); 296 | if ( ! hPipe ) 297 | { 298 | fprintf( stderr, "_OpenPipe failed! Shader compilation succeeded but new program wasn't sent for preview. liveCodingGlslCompiler and liveCodingPreview are intended to be used together.\n" ); 299 | return; 300 | } 301 | 302 | const char* message = "srcCode"; 303 | const size_t messageLen = strlen( message ); 304 | 305 | size_t bufSize = messageLen + 1 + sourceCodeLen + 1; 306 | char* buf = new char[bufSize]; 307 | char* tmpBuf = buf; 308 | memcpy( tmpBuf, message, messageLen + 1 ); 309 | tmpBuf += messageLen + 1; 310 | memcpy( tmpBuf, sourceCode, sourceCodeLen + 1 ); 311 | tmpBuf += sourceCodeLen + 1; 312 | 313 | DWORD cbWritten = 0; 314 | 315 | BOOL fSuccess = WriteFile( 316 | hPipe, // pipe handle 317 | buf, // message 318 | (DWORD)bufSize, // message length 319 | &cbWritten, // bytes written 320 | NULL); // not overlapped 321 | 322 | delete[] buf; 323 | 324 | if ( ! fSuccess) 325 | { 326 | fprintf( stderr, "WriteFile to pipe failed. Err=%d\n", GetLastError() ); 327 | } 328 | 329 | //Sleep( 1000 ); 330 | 331 | _ClosePipe( hPipe ); 332 | } 333 | 334 | void sendProgramBinary( GLuint glprog ) 335 | { 336 | GLint programBinaryLength = 0; 337 | glGetProgramiv( glprog, GL_PROGRAM_BINARY_LENGTH, &programBinaryLength ); 338 | 339 | const char* message = "programBinary"; 340 | const size_t messageLen = strlen( message ); 341 | 342 | size_t bufSize = messageLen + 1 + 8 + programBinaryLength; 343 | u8* buf = new u8[bufSize]; 344 | 345 | GLenum binaryFormat = 0; 346 | glGetProgramBinary( glprog, programBinaryLength, NULL, &binaryFormat, buf + messageLen + 1 + 8 ); 347 | 348 | u8* tmpBuf = buf; 349 | memcpy( tmpBuf, message, messageLen + 1 ); 350 | tmpBuf += messageLen + 1; 351 | memcpy( tmpBuf, &programBinaryLength, 4 ); 352 | tmpBuf += 4; 353 | memcpy( tmpBuf, &binaryFormat, 4 ); 354 | tmpBuf += 4; 355 | 356 | HANDLE hPipe = _OpenPipe(); 357 | if ( ! hPipe ) 358 | { 359 | delete[] buf; 360 | fprintf( stderr, "_OpenPipe failed! Shader compilation succeeded but new program wasn't sent for preview. liveCodingGlslCompiler and liveCodingPreview are intended to be used together.\n" ); 361 | return; 362 | } 363 | 364 | DWORD cbWritten = 0; 365 | 366 | BOOL fSuccess = WriteFile( 367 | hPipe, // pipe handle 368 | buf, // message 369 | (DWORD)bufSize, // message length 370 | &cbWritten, // bytes written 371 | NULL); // not overlapped 372 | 373 | delete[] buf; 374 | 375 | if ( ! fSuccess) 376 | { 377 | fprintf( stderr, "WriteFile to pipe failed. Err=%d\n", GetLastError() ); 378 | } 379 | 380 | //Sleep( 1000 ); 381 | 382 | _ClosePipe( hPipe ); 383 | } 384 | 385 | int doFile( const std::string& srcFile ) 386 | { 387 | if ( extraLogMessages ) 388 | fprintf( stderr, "doFile: %s\n", srcFile.c_str() ); 389 | 390 | // create default vertex shader 391 | // 392 | const char* vp = 393 | "in float4 position;\n" \ 394 | "void main()\n" \ 395 | "{\n" \ 396 | " gl_Position = position;\n" \ 397 | "}\n" 398 | ; 399 | 400 | GLuint vertexShader_ = createGLSLShaderFromBuf( NULL, vp, strlen(vp), GL_VERTEX_SHADER ); 401 | if ( ! vertexShader_ ) 402 | { 403 | return -10; 404 | } 405 | 406 | char cwd[MAX_PATH]; 407 | _getcwd( cwd, MAX_PATH ); 408 | 409 | char* buf = NULL; 410 | size_t bufSize = 0; 411 | int ires = loadFile( srcFile.c_str(), &buf, &bufSize ); 412 | if ( ires ) 413 | return ires; 414 | 415 | GLuint fragmentShader_ = createGLSLShaderFromBuf( srcFile.c_str(), buf, bufSize, GL_FRAGMENT_SHADER ); 416 | if ( ! fragmentShader_ ) 417 | { 418 | delete[] buf; 419 | return -11; 420 | } 421 | 422 | GLuint program_ = glCreateProgram(); 423 | glProgramParameteri( program_, GL_PROGRAM_BINARY_RETRIEVABLE_HINT, GL_TRUE ); 424 | 425 | glAttachShader( program_, vertexShader_ ); 426 | glAttachShader( program_, fragmentShader_ ); 427 | 428 | glLinkProgram( program_ ); 429 | 430 | GLint result = GL_FALSE; 431 | glGetProgramiv( program_, GL_LINK_STATUS, &result ); 432 | 433 | if ( result == GL_FALSE ) 434 | { 435 | // error during link 436 | // 437 | 438 | int infoLogLength = 0; 439 | glGetProgramiv( program_, GL_INFO_LOG_LENGTH, &infoLogLength ); 440 | 441 | if ( infoLogLength ) 442 | { 443 | std::string errString; 444 | errString.resize( infoLogLength ); 445 | glGetProgramInfoLog( program_, infoLogLength, NULL, &errString[0] ); 446 | const char* text = errString.c_str(); 447 | fprintf( stderr, "glLinkProgram failed: Info log:\n%s", text ); 448 | } 449 | 450 | GLenum err = glGetError(); 451 | while ( err ) 452 | { 453 | err = glGetError(); 454 | } 455 | 456 | glDeleteProgram( program_ ); 457 | glDeleteShader( fragmentShader_ ); 458 | glDeleteShader( vertexShader_ ); 459 | 460 | delete[] buf; 461 | return -20; 462 | } 463 | 464 | sendProgramBinary( program_ ); 465 | 466 | glDeleteProgram( program_ ); 467 | glDeleteShader( fragmentShader_ ); 468 | glDeleteShader( vertexShader_ ); 469 | 470 | return 0; 471 | } 472 | 473 | int main(int argc, char* argv[]) 474 | { 475 | if ( argc < 2 ) 476 | { 477 | std::cerr << argv[0] << ": Expecting source file as first parameter." << std::endl; 478 | return -1; 479 | } 480 | 481 | if ( extraLogMessages ) 482 | fprintf( stderr, "glslOfflineCompiler: %s\n", argv[1] ); 483 | 484 | int ires = _StartUpOpenGL( argc, argv ); 485 | if ( ires ) 486 | return 0; 487 | 488 | std::string srcFile = argv[1]; 489 | ires = doFile( srcFile ); 490 | if ( ires ) 491 | { 492 | return ires; 493 | } 494 | 495 | _ShutDownOpenGL(); 496 | 497 | return 0; 498 | } 499 | -------------------------------------------------------------------------------- /src/liveCodingGlslCompiler/stdafx.cpp: -------------------------------------------------------------------------------- 1 | /******************************************************************************* 2 | * 2005-2014, plastic demoscene group 3 | * authors: misz, bonzaj 4 | *******************************************************************************/ 5 | 6 | #include "stdafx.h" 7 | -------------------------------------------------------------------------------- /src/liveCodingGlslCompiler/stdafx.h: -------------------------------------------------------------------------------- 1 | /******************************************************************************* 2 | * 2005-2014, plastic demoscene group 3 | * authors: misz, bonzaj 4 | *******************************************************************************/ 5 | 6 | #pragma once 7 | 8 | #include "targetver.h" 9 | 10 | #include 11 | #include 12 | #include 13 | #include 14 | #include 15 | #include 16 | #include 17 | 18 | #include "../../external/glew/include/GL/glew.h" 19 | #include "../../external/glew/include/GL/wglew.h" 20 | 21 | #include 22 | typedef uint8_t u8; 23 | typedef uint16_t u16; 24 | typedef uint32_t u32; 25 | typedef uint64_t u64; 26 | typedef int8_t s8; 27 | typedef int16_t s16; 28 | typedef int32_t s32; 29 | typedef int64_t s64; 30 | typedef int8_t i8; 31 | typedef int16_t i16; 32 | typedef int32_t i32; 33 | typedef int64_t i64; 34 | -------------------------------------------------------------------------------- /src/liveCodingGlslCompiler/targetver.h: -------------------------------------------------------------------------------- 1 | /******************************************************************************* 2 | * 2005-2014, plastic demoscene group 3 | * authors: misz, bonzaj 4 | *******************************************************************************/ 5 | 6 | #pragma once 7 | 8 | // Including SDKDDKVer.h defines the highest available Windows platform. 9 | 10 | // If you wish to build your application for a previous Windows platform, include WinSDKVer.h and 11 | // set the _WIN32_WINNT macro to the platform you wish to support before including SDKDDKVer.h. 12 | 13 | #include 14 | -------------------------------------------------------------------------------- /src/liveCodingPreview.sln: -------------------------------------------------------------------------------- 1 |  2 | Microsoft Visual Studio Solution File, Format Version 11.00 3 | # Visual Studio 2010 4 | Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "liveCodingPreview", "liveCodingPreview\liveCodingPreview.vcxproj", "{FD4D8A71-25B7-4B0E-86E3-154FD2384F86}" 5 | EndProject 6 | Global 7 | GlobalSection(SolutionConfigurationPlatforms) = preSolution 8 | Debug|x64 = Debug|x64 9 | Release|x64 = Release|x64 10 | EndGlobalSection 11 | GlobalSection(ProjectConfigurationPlatforms) = postSolution 12 | {FD4D8A71-25B7-4B0E-86E3-154FD2384F86}.Debug|x64.ActiveCfg = Debug|x64 13 | {FD4D8A71-25B7-4B0E-86E3-154FD2384F86}.Debug|x64.Build.0 = Debug|x64 14 | {FD4D8A71-25B7-4B0E-86E3-154FD2384F86}.Release|x64.ActiveCfg = Release|x64 15 | {FD4D8A71-25B7-4B0E-86E3-154FD2384F86}.Release|x64.Build.0 = Release|x64 16 | {840A6B61-5766-4F90-A8B5-41FE2363F2C7}.Debug|x64.ActiveCfg = Debug|x64 17 | {840A6B61-5766-4F90-A8B5-41FE2363F2C7}.Debug|x64.Build.0 = Debug|x64 18 | {840A6B61-5766-4F90-A8B5-41FE2363F2C7}.Release|x64.ActiveCfg = Release|x64 19 | {840A6B61-5766-4F90-A8B5-41FE2363F2C7}.Release|x64.Build.0 = Release|x64 20 | EndGlobalSection 21 | GlobalSection(SolutionProperties) = preSolution 22 | HideSolutionNode = FALSE 23 | EndGlobalSection 24 | EndGlobal 25 | -------------------------------------------------------------------------------- /src/liveCodingPreview/liveCoding.cpp: -------------------------------------------------------------------------------- 1 | /******************************************************************************* 2 | * 2005-2014, plastic demoscene group 3 | * authors: misz, bonzaj 4 | *******************************************************************************/ 5 | 6 | #include "stdafx.h" 7 | #include "liveCoding.h" 8 | 9 | #ifdef _DEBUG 10 | #define new _DEBUG_NEW 11 | #endif 12 | 13 | liveCoding* g; 14 | 15 | //u32 prevMS = 0; 16 | 17 | // Display func for main window 18 | void displayFunc() 19 | { 20 | glClearColor(0.0, 1.0, 0.0, 0.0); 21 | glClear(GL_COLOR_BUFFER_BIT); 22 | 23 | g->draw(); 24 | 25 | HDC hdc = wglGetCurrentDC(); 26 | HWND hwnd = WindowFromDC( hdc ); 27 | 28 | RECT wr; 29 | BOOL bres = GetWindowRect( hwnd, &wr ); 30 | if ( bres ) 31 | { 32 | g->windowPosX_ = wr.left; 33 | g->windowPosY_ = wr.top; 34 | } 35 | 36 | //u32 curMS = getTimeMS(); 37 | //if ( curMS < prevMS ) 38 | // curMS = prevMS; 39 | 40 | //u32 deltaMS = curMS - prevMS; 41 | //prevMS = curMS; 42 | 43 | // float fps = 1.0f / (deltaMS * 0.001f); 44 | // printf( "FPS: %3.1f\n", fps ); 45 | 46 | glutSwapBuffers(); 47 | } 48 | 49 | void idleFunc() 50 | { 51 | glutPostRedisplay(); 52 | } 53 | 54 | void reshapeFunc(int w1,int h1) { 55 | 56 | if(h1 == 0) 57 | h1 = 1; 58 | 59 | printf( "reshapeFunc(%d, %d)\n", w1, h1 ); 60 | 61 | glMatrixMode(GL_PROJECTION); 62 | glLoadIdentity(); 63 | glOrtho( 0, w1, 0, h1, 0.1f, 1 ); 64 | 65 | glViewport(0, 0, w1, h1); 66 | 67 | glMatrixMode(GL_MODELVIEW); 68 | 69 | g->windowW_ = w1; 70 | g->windowH_ = h1; 71 | } 72 | 73 | void keyboardFunc(unsigned char /*key*/, int /*x*/, int /*y*/) 74 | { 75 | //if ( key == 27 ) 76 | //{ 77 | // glutLeaveMainLoop(); 78 | // return; 79 | //} 80 | 81 | //glutPostRedisplay(); 82 | } 83 | 84 | void specialFunc(int key, int /*x*/, int /*y*/) 85 | { 86 | if ( key == GLUT_KEY_F4 ) 87 | { 88 | int mod = glutGetModifiers(); 89 | if ( mod & GLUT_ACTIVE_ALT ) 90 | { 91 | glutLeaveMainLoop(); 92 | return; 93 | } 94 | } 95 | else if ( key == GLUT_KEY_F2 ) 96 | { 97 | g->fullscreen_ = !g->fullscreen_; 98 | glutFullScreenToggle(); 99 | //glutGameModeString("1920x1080:32@60"); 100 | //glutEnterGameMode(); 101 | } 102 | } 103 | 104 | //void popupMenuFunc( int val ) 105 | //{ 106 | // if ( val == 1 ) 107 | // { 108 | // glutFullScreenToggle(); 109 | // } 110 | //}; 111 | 112 | int main(int argc, char* argv[]) 113 | { 114 | #ifdef _DEBUG 115 | int flag = _CrtSetDbgFlag(_CRTDBG_REPORT_FLAG); 116 | flag |= _CRTDBG_LEAK_CHECK_DF; 117 | flag |= _CRTDBG_ALLOC_MEM_DF; 118 | flag &= ~_CRTDBG_CHECK_ALWAYS_DF; 119 | _CrtSetDbgFlag(flag); 120 | #endif 121 | 122 | // init GLUT and create main window 123 | glutInit(&argc, argv); 124 | glutSetOption( GLUT_ACTION_ON_WINDOW_CLOSE, GLUT_ACTION_GLUTMAINLOOP_RETURNS ); 125 | glutInitDisplayMode(/*GLUT_DEPTH |*/ GLUT_DOUBLE | GLUT_RGBA); 126 | glutInitWindowPosition(0,0); 127 | glutInitWindowSize(1280,720); 128 | glutCreateWindow("Live Coding Preview"); 129 | 130 | //glutCreateMenu( popupMenuFunc ); 131 | //glutAddMenuEntry( "Toggle Fullscreen", 1 ); 132 | //glutAttachMenu( GLUT_RIGHT_BUTTON ); 133 | 134 | GLenum err = glewInit(); 135 | if (GLEW_OK != err) 136 | { 137 | /* Problem: glewInit failed, something is seriously wrong. */ 138 | fprintf(stderr, "Error: %s\n", glewGetErrorString(err)); 139 | exit( -1 ); 140 | } 141 | 142 | const char* glRenderer = reinterpret_cast( glGetString(GL_RENDERER) ); 143 | const char* glVendor = reinterpret_cast( glGetString(GL_VENDOR) ); 144 | GLint majorVer = 1; 145 | glGetIntegerv( GL_MAJOR_VERSION, &majorVer ); 146 | GLint minorVer = 0; 147 | glGetIntegerv( GL_MINOR_VERSION, &minorVer ); 148 | 149 | printf( "GL_RENDERER: %s\nGL_VENDOR: %s\nGL version: %d.%d\n\n", glRenderer, glVendor, majorVer, minorVer ); 150 | 151 | glEnable( GL_FRAMEBUFFER_SRGB ); 152 | wglSwapIntervalEXT( 1 ); 153 | 154 | // callbacks for main window 155 | glutDisplayFunc(displayFunc); 156 | glutReshapeFunc(reshapeFunc); 157 | glutKeyboardFunc(keyboardFunc); 158 | glutSpecialFunc(specialFunc); 159 | glutIdleFunc(idleFunc); 160 | 161 | g = new liveCoding(); 162 | int ires = g->startUp( argc, argv ); 163 | if ( ires ) 164 | { 165 | fprintf( stderr, "liveCoding::startUp failed! Err=%d\n", ires ); 166 | g->shutDown(); 167 | delete g; 168 | return -1; 169 | } 170 | 171 | // enter GLUT event processing cycle 172 | glutMainLoop(); 173 | 174 | g->shutDown(); 175 | delete g; 176 | g = NULL; 177 | 178 | return 0; 179 | } 180 | 181 | 182 | int liveCoding::startUp( int argc, char* argv[] ) 183 | { 184 | if ( argc < 2 ) 185 | { 186 | fprintf( stderr, "expecting path to data directory as a first parameter!" ); 187 | return -30; 188 | } 189 | 190 | liveCodingDir_ = argv[1]; 191 | if ( liveCodingDir_.back() != '\\' && liveCodingDir_.back() != '/' ) 192 | liveCodingDir_.append( 1, '/' ); 193 | 194 | char cwd[MAX_PATH]; 195 | _getcwd( cwd, MAX_PATH ); 196 | printf( "CWD: %s\n\n", cwd ); 197 | 198 | config_init( &config_ ); 199 | readConfig(); 200 | 201 | { 202 | HDC hdc = wglGetCurrentDC(); 203 | HWND hwnd = WindowFromDC( hdc ); 204 | 205 | LONG style = GetWindowLong( hwnd, GWL_STYLE ); 206 | 207 | RECT cr; 208 | cr.left = windowPosX_; 209 | cr.right = windowPosX_ + windowW_; 210 | cr.top = windowPosY_; 211 | cr.bottom = windowPosY_ + windowH_; 212 | 213 | BOOL bres = AdjustWindowRect( &cr, style, false ); 214 | if ( bres ) 215 | { 216 | int w = cr.right - cr.left; 217 | int h = cr.bottom - cr.top; 218 | SetWindowPos( hwnd, HWND_TOPMOST, windowPosX_, windowPosY_, w, h, 0 ); 219 | 220 | if ( fullscreen_ ) 221 | { 222 | glutFullScreenToggle(); 223 | } 224 | } 225 | } 226 | 227 | // create default vertex shader 228 | // 229 | const char* vp = 230 | "in float4 position;\n" \ 231 | "void main()\n" \ 232 | "{\n" \ 233 | " gl_Position = position;\n" \ 234 | "}\n" 235 | ; 236 | 237 | vertexShader_ = createGLSLShaderFromBuf( vp, strlen(vp), GL_VERTEX_SHADER ); 238 | if ( ! vertexShader_ ) 239 | { 240 | return -10; 241 | } 242 | 243 | const char* fp = 244 | "layout(location = 0) out float4 out_color;\n" \ 245 | "void main()\n" \ 246 | "{\n" \ 247 | " out_color = float4( 1, 0, 0, 1 );\n" \ 248 | "}\n" 249 | ; 250 | 251 | reloadShaderSource( fp, strlen(fp) ); 252 | 253 | { 254 | glGenTextures( 1, &iFFTTexture_ ); 255 | glBindTexture( GL_TEXTURE_1D, iFFTTexture_ ); 256 | 257 | glTexParameteri( GL_TEXTURE_1D, GL_TEXTURE_WRAP_S, GL_REPEAT ); 258 | glTexParameteri( GL_TEXTURE_1D, GL_TEXTURE_MIN_FILTER, GL_LINEAR ); 259 | glTexParameteri( GL_TEXTURE_1D, GL_TEXTURE_MAG_FILTER, GL_LINEAR ); 260 | 261 | float fftData[FFT_SIZE]; 262 | for ( int i = 0; i < FFT_SIZE; ++i ) 263 | fftData[i] = 1.0f; 264 | 265 | glTexImage1D( GL_TEXTURE_1D, 0, GL_R32F, FFT_SIZE, 0, GL_RED, GL_FLOAT, fftData ); 266 | glBindTexture( GL_TEXTURE_1D, 0 ); 267 | } 268 | 269 | { 270 | glGenTextures( 1, &iFFTsHistoryTexture_ ); 271 | glBindTexture( GL_TEXTURE_2D, iFFTsHistoryTexture_ ); 272 | 273 | glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT ); 274 | glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT ); 275 | glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR ); 276 | glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR ); 277 | 278 | iFFTsHistoryData_ = (float*)_aligned_malloc( 4 * FFT_BINS * FFT_HISTORY_LENGTH, 64 ); 279 | memset( iFFTsHistoryData_, 0, 4 * FFT_BINS * FFT_HISTORY_LENGTH ); 280 | 281 | glTexImage2D( GL_TEXTURE_2D, 0, GL_R32F, FFT_BINS, FFT_HISTORY_LENGTH, 0, GL_RED, GL_FLOAT, iFFTsHistoryData_ ); 282 | glBindTexture( GL_TEXTURE_2D, 0 ); 283 | } 284 | 285 | setupShaderInputs(); 286 | 287 | const size_t nTextures = textures_.size(); 288 | for ( size_t itex = 0; itex < nTextures; ++itex ) 289 | { 290 | Tex& t = textures_[itex]; 291 | if ( ! t.filename_.empty() ) 292 | { 293 | t.glTexID_ = readTexture( (liveCodingDir_ + t.filename_).c_str() ); 294 | if ( ! t.glTexID_ ) 295 | { 296 | fprintf( stderr, "readTexture(%s) failed!\n", t.filename_.c_str() ); 297 | } 298 | } 299 | } 300 | 301 | startTimeMS_ = getTimeMS(); 302 | 303 | memset( &pipeMutex_, 0, sizeof(pipeMutex_) ); 304 | InitializeCriticalSection( &pipeMutex_ ); 305 | 306 | int ires = startUpPipe(); 307 | if ( ires ) 308 | { 309 | fprintf( stderr, "startUpPipe failed. Err=%d", ires ); 310 | return ires; 311 | } 312 | 313 | ires = bass_startUp(); 314 | if ( ires ) 315 | { 316 | fprintf( stderr, "bass_startUp failed. Err=%d", ires ); 317 | //return ires; 318 | } 319 | 320 | if ( ! ires ) 321 | bass_startCapture(); 322 | 323 | // midi 324 | // 325 | { 326 | midiController_CME_U2MIDI* mc = new midiController_CME_U2MIDI(); 327 | ires = mc->startUp(); 328 | if ( ires ) 329 | { 330 | delete mc; 331 | } 332 | else 333 | midiController_ = mc; 334 | } 335 | 336 | //if ( ! midiController_ ) 337 | //{ 338 | // midiController_Akai_MPD26* mc = new midiController_Akai_MPD26(); 339 | // ires = mc->startUp(); 340 | // if ( ires ) 341 | // { 342 | // delete mc; 343 | // } 344 | // else 345 | // midiController_ = mc; 346 | //} 347 | 348 | return 0; 349 | } 350 | 351 | void liveCoding::shutDown() 352 | { 353 | if ( midiController_ ) 354 | { 355 | midiController_->shutDown(); 356 | delete midiController_; 357 | midiController_ = NULL; 358 | } 359 | 360 | bass_stopCapture(); 361 | bass_shutDown(); 362 | 363 | shutDownPipe(); 364 | 365 | delete[] freshBinary_; 366 | freshBinary_ = NULL; 367 | freshBinarySize_ = 0; 368 | freshBinaryFormat_ = 0; 369 | 370 | delete[] freshSourceCode_; 371 | freshSourceCode_ = NULL; 372 | freshSourceCodeSize_ = 0; 373 | 374 | _aligned_free( iFFTsHistoryData_ ); 375 | iFFTsHistoryData_ = NULL; 376 | 377 | if ( iFFTsHistoryTexture_ ) 378 | { 379 | glDeleteTextures( 1, &iFFTsHistoryTexture_ ); 380 | iFFTsHistoryTexture_ = 0; 381 | } 382 | 383 | if ( iFFTTexture_ ) 384 | { 385 | glDeleteTextures( 1, &iFFTTexture_ ); 386 | iFFTTexture_ = 0; 387 | } 388 | 389 | const size_t nTextures = textures_.size(); 390 | for ( size_t itex = 0; itex < nTextures; ++itex ) 391 | { 392 | Tex& t = textures_[itex]; 393 | if ( t.glTexID_ ) 394 | { 395 | glDeleteTextures( 1, &t.glTexID_ ); 396 | } 397 | } 398 | 399 | textures_.clear(); 400 | 401 | writeConfig(); 402 | config_destroy( &config_ ); 403 | } 404 | 405 | void liveCoding::readConfig() 406 | { 407 | std::string filename = liveCodingDir_ + "config.cfg"; 408 | int ires = config_read_file( &config_, filename.c_str() ); 409 | if ( ! ires ) 410 | { 411 | fprintf( stderr, "config_read_file '%s' failed. Creating default one.\n", filename.c_str() ); 412 | } 413 | 414 | setupDefaultConfig(); 415 | 416 | config_lookup_int( &config_, "windowPosX", &windowPosX_ ); 417 | config_lookup_int( &config_, "windowPosY", &windowPosY_ ); 418 | config_lookup_int( &config_, "windowW", &windowW_ ); 419 | config_lookup_int( &config_, "windowH", &windowH_ ); 420 | config_lookup_bool( &config_, "fullscreen", &fullscreen_ ); 421 | } 422 | 423 | void liveCoding::writeConfig() 424 | { 425 | { 426 | // store current window pos and fullscreen state 427 | // 428 | config_setting_set_int( config_lookup( &config_, "windowPosX" ), windowPosX_ ); 429 | config_setting_set_int( config_lookup( &config_, "windowPosY" ), windowPosY_ ); 430 | config_setting_set_int( config_lookup( &config_, "windowW" ), windowW_ ); 431 | config_setting_set_int( config_lookup( &config_, "windowH" ), windowH_ ); 432 | config_setting_set_bool( config_lookup( &config_, "fullscreen" ), fullscreen_ ); 433 | } 434 | 435 | std::string filename = liveCodingDir_ + "config.cfg"; 436 | 437 | int ires = config_write_file( &config_, filename.c_str() ); 438 | if ( ! ires ) 439 | { 440 | fprintf( stderr, "config_write_file '%s' failed.\n", filename.c_str() ); 441 | } 442 | } 443 | 444 | void liveCoding::setupDefaultConfig() 445 | { 446 | // fill missing settings 447 | // 448 | { 449 | config_setting_t* s = config_lookup( &config_, "windowPosX" ); 450 | if ( ! s ) 451 | { 452 | s = config_setting_add( config_root_setting( &config_ ), "windowPosX", CONFIG_TYPE_INT ); 453 | config_setting_set_int( s, 0 ); 454 | } 455 | } 456 | { 457 | config_setting_t* s = config_lookup( &config_, "windowPosY" ); 458 | if ( ! s ) 459 | { 460 | s = config_setting_add( config_root_setting( &config_ ), "windowPosY", CONFIG_TYPE_INT ); 461 | config_setting_set_int( s, 0 ); 462 | } 463 | } 464 | { 465 | config_setting_t* s = config_lookup( &config_, "windowW" ); 466 | if ( ! s ) 467 | { 468 | s = config_setting_add( config_root_setting( &config_ ), "windowW", CONFIG_TYPE_INT ); 469 | config_setting_set_int( s, 800 ); 470 | } 471 | } 472 | { 473 | config_setting_t* s = config_lookup( &config_, "windowH" ); 474 | if ( ! s ) 475 | { 476 | s = config_setting_add( config_root_setting( &config_ ), "windowH", CONFIG_TYPE_INT ); 477 | config_setting_set_int( s, 600 ); 478 | } 479 | } 480 | { 481 | config_setting_t* s = config_lookup( &config_, "fullscreen" ); 482 | if ( ! s ) 483 | { 484 | s = config_setting_add( config_root_setting( &config_ ), "fullscreen", CONFIG_TYPE_BOOL ); 485 | config_setting_set_bool( s, false ); 486 | } 487 | } 488 | } 489 | 490 | void liveCoding::draw() 491 | { 492 | reloadShader(); 493 | 494 | float midiPad[midiController::ePadCount]; 495 | memset( midiPad, 0, sizeof(midiPad) ); 496 | if ( midiController_ ) 497 | { 498 | midiController_->update(); 499 | midiController_->getData( midiPad ); 500 | } 501 | 502 | if ( program_ ) 503 | { 504 | { 505 | GLint location = glGetUniformLocation( program_, "iMidiPad" ); 506 | if ( location != -1 ) 507 | { 508 | glProgramUniformMatrix4fv( program_, location, 1, false, midiPad ); 509 | } 510 | } 511 | 512 | { 513 | GLint location = glGetUniformLocation( program_, "iMidiPadValue" ); 514 | if ( location != -1 ) 515 | { 516 | float sum = 0; 517 | for ( int i = 0; i < midiController::ePadCount; ++i ) 518 | sum += midiPad[i]; 519 | 520 | sum /= midiController::ePadCount; 521 | 522 | glProgramUniform1f( program_, location, sum ); 523 | } 524 | } 525 | 526 | if ( hRecord_ ) 527 | { 528 | unsigned len = 0; 529 | 530 | switch( FFT_SIZE*2 ) // for 256 fft, only 128 values will contain DC in our case 531 | { 532 | case 256: 533 | len = BASS_DATA_FFT256; 534 | break; 535 | case 512: 536 | len = BASS_DATA_FFT512; 537 | break; 538 | case 1024: 539 | len = BASS_DATA_FFT1024; 540 | break; 541 | case 2048: 542 | len = BASS_DATA_FFT2048; 543 | break; 544 | case 4096: 545 | len = BASS_DATA_FFT4096; 546 | break; 547 | case 8192: 548 | len = BASS_DATA_FFT8192; 549 | break; 550 | case 16384: 551 | len = BASS_DATA_FFT16384; 552 | break; 553 | default: 554 | fprintf( stderr, "BASS invalid fft window size\n" ); 555 | break; 556 | } 557 | 558 | if ( len ) 559 | { 560 | //memset( fftBuf, 0, sizeof(fftBuf) ); 561 | 562 | const int numBytes = BASS_ChannelGetData( hRecord_, fftBassBuf_, len | BASS_DATA_FFT_REMOVEDC ); 563 | if( numBytes == -1 ) 564 | { 565 | fprintf( stderr, "BASS_ChannelGetData failed. Err=%d\n", BASS_ErrorGetCode() ); 566 | } 567 | else if ( numBytes > 0 ) 568 | { 569 | memset( fft_, 0, sizeof(fft_) ); 570 | 571 | int b0=0; 572 | 573 | for (int x=0;x FFT_SIZE-1 ) 578 | b1 = FFT_SIZE-1; 579 | 580 | if ( b1 <= b0 ) 581 | b1 = b0 + 1; // make sure it uses at least 1 FFT bin 582 | 583 | float sum = 0; 584 | 585 | for ( ; b0 < b1; b0++ ) 586 | { 587 | if (peak < fftBassBuf_[1+b0]) 588 | peak = fftBassBuf_[1+b0]; 589 | sum += /*(1.0f / FFT_SIZE) **/ fftBassBuf_[1+b0]; 590 | } 591 | 592 | fft_[x] = peak; 593 | //fft_[x] = sum; 594 | } 595 | 596 | const float t = 0.9f; 597 | for ( int i = 0; i < FFT_BINS; ++i ) 598 | { 599 | ffts_[i] = ffts_[i]*t + (1 - t)*fft_[i]; 600 | ffti_[i] += fft_[i]; 601 | fftsi_[i] += ffts_[i]; 602 | } 603 | 604 | for ( int h = FFT_HISTORY_LENGTH-1; h > 0; --h ) 605 | { 606 | float* srcRow = iFFTsHistoryData_ + (h-1) * FFT_BINS; 607 | float* dstRow = srcRow + FFT_BINS; 608 | memcpy( dstRow, srcRow, 4 * FFT_BINS ); 609 | } 610 | 611 | memcpy( iFFTsHistoryData_, ffts_, 4 * FFT_BINS ); 612 | 613 | if ( iFFTTextureUnit_ >= 0 ) 614 | { 615 | glActiveTexture( GL_TEXTURE0 + iFFTTextureUnit_ ); 616 | glBindTexture( GL_TEXTURE_1D, iFFTTexture_ ); 617 | glTexSubImage1D( GL_TEXTURE_1D, 0, 0, FFT_SIZE, GL_RED, GL_FLOAT, fftBassBuf_ ); 618 | } 619 | 620 | if ( iFFTsHistoryTextureUnit_ >= 0 ) 621 | { 622 | glActiveTexture( GL_TEXTURE0 + iFFTsHistoryTextureUnit_ ); 623 | glBindTexture( GL_TEXTURE_2D, iFFTsHistoryTexture_ ); 624 | glTexSubImage2D( GL_TEXTURE_2D, 0, 0, 0, FFT_BINS, FFT_HISTORY_LENGTH, GL_RED, GL_FLOAT, iFFTsHistoryData_ ); 625 | } 626 | 627 | GLint location; 628 | 629 | location = glGetUniformLocation( program_, "iFFT" ); 630 | if ( location != -1 ) 631 | glProgramUniform1fv( program_, location, FFT_BINS, fft_ ); 632 | 633 | location = glGetUniformLocation( program_, "iFFTi" ); 634 | if ( location != -1 ) 635 | glProgramUniform1fv( program_, location, FFT_BINS, ffti_ ); 636 | 637 | location = glGetUniformLocation( program_, "iFFTs" ); 638 | if ( location != -1 ) 639 | glProgramUniform1fv( program_, location, FFT_BINS, ffts_ ); 640 | 641 | location = glGetUniformLocation( program_, "iFFTsi" ); 642 | if ( location != -1 ) 643 | glProgramUniform1fv( program_, location, FFT_BINS, fftsi_ ); 644 | } 645 | } 646 | } 647 | 648 | { 649 | GLint location = glGetUniformLocation( program_, "iGlobalTime" ); 650 | if ( location != -1 ) 651 | { 652 | u32 deltaTimeMS = getTimeMS() - startTimeMS_; 653 | float t = deltaTimeMS * 0.001f; 654 | glProgramUniform1f( program_, location, t ); 655 | } 656 | } 657 | 658 | { 659 | GLint location = glGetUniformLocation( program_, "iResolution" ); 660 | if ( location != -1 ) 661 | { 662 | glProgramUniform2f( program_, location, (float)windowW_, (float)windowH_ ); 663 | } 664 | } 665 | 666 | setShaderInputs(); 667 | 668 | glUseProgram( program_ ); 669 | 670 | glBegin( GL_TRIANGLES ); 671 | 672 | glVertex2f( -1, -1 ); 673 | glVertex2f( 3, -1 ); 674 | glVertex2f( -1, 3 ); 675 | 676 | glEnd(); 677 | } 678 | } 679 | 680 | void liveCoding::reloadShader() 681 | { 682 | EnterCriticalSection( &pipeMutex_ ); 683 | 684 | if ( ! reloadShaderRequested_ ) 685 | { 686 | LeaveCriticalSection( &pipeMutex_ ); 687 | return; 688 | } 689 | 690 | reloadShaderRequested_ = false; 691 | 692 | if ( freshBinary_ ) 693 | { 694 | u8* buf = freshBinary_; 695 | size_t bufSize = freshBinarySize_; 696 | GLenum format = freshBinaryFormat_; 697 | freshBinary_ = NULL; 698 | freshBinarySize_ = 0; 699 | freshBinaryFormat_ = 0; 700 | 701 | LeaveCriticalSection( &pipeMutex_ ); 702 | 703 | reloadShaderBinary( buf, bufSize, format ); 704 | 705 | delete[] buf; 706 | } 707 | else 708 | { 709 | char* buf = NULL; 710 | size_t bufSize = 0; 711 | 712 | if ( freshSourceCode_ ) 713 | { 714 | buf = freshSourceCode_; 715 | bufSize = freshSourceCodeSize_; 716 | freshSourceCode_ = NULL; 717 | freshSourceCodeSize_ = 0; 718 | 719 | LeaveCriticalSection( &pipeMutex_ ); 720 | } 721 | else 722 | { 723 | LeaveCriticalSection( &pipeMutex_ ); 724 | 725 | //int ires = loadFile( (liveCodingDir_ + "shaders/splashScreen.glsl").c_str(), &buf, &bufSize ); 726 | int ires = loadFile( (liveCodingDir_ + "shaders/fft_test.glsl").c_str(), &buf, &bufSize ); 727 | if ( ires ) 728 | { 729 | return; 730 | } 731 | } 732 | 733 | reloadShaderSource( buf, bufSize ); 734 | 735 | delete[] buf; 736 | } 737 | 738 | const size_t nTextures = textures_.size(); 739 | int unit = 1; // use unit 0 for management/creation 740 | for ( size_t itex = 0; itex < nTextures; ++itex ) 741 | { 742 | const Tex& t = textures_[itex]; 743 | if ( ! t.glTexID_ ) 744 | continue; 745 | 746 | GLint location = glGetUniformLocation( program_, t.samplerName_.c_str() ); 747 | if ( location != -1 ) 748 | { 749 | glProgramUniform1i( program_, location, unit ); 750 | glActiveTexture( GL_TEXTURE0 + unit ); 751 | glBindTexture( GL_TEXTURE_2D, t.glTexID_ ); 752 | ++ unit; 753 | } 754 | } 755 | 756 | { 757 | GLint location = glGetUniformLocation( program_, "iFFTTexture" ); 758 | if ( location != -1 ) 759 | { 760 | glProgramUniform1i( program_, location, unit ); 761 | glActiveTexture( GL_TEXTURE0 + unit ); 762 | glBindTexture( GL_TEXTURE_1D, iFFTTexture_ ); 763 | iFFTTextureUnit_ = unit; 764 | ++ unit; 765 | } 766 | else 767 | { 768 | iFFTTextureUnit_ = -1; 769 | } 770 | } 771 | 772 | { 773 | GLint location = glGetUniformLocation( program_, "iFFTsHistory" ); 774 | if ( location != -1 ) 775 | { 776 | glProgramUniform1i( program_, location, unit ); 777 | glActiveTexture( GL_TEXTURE0 + unit ); 778 | glBindTexture( GL_TEXTURE_2D, iFFTsHistoryTexture_ ); 779 | iFFTsHistoryTextureUnit_ = unit; 780 | ++ unit; 781 | } 782 | else 783 | { 784 | iFFTsHistoryTextureUnit_ = -1; 785 | } 786 | } 787 | } 788 | 789 | int liveCoding::reloadShaderSource( const char* buf, size_t bufSize ) 790 | { 791 | GLuint newFragmentShader = createGLSLShaderFromBuf( buf, bufSize, GL_FRAGMENT_SHADER ); 792 | if ( ! newFragmentShader ) 793 | { 794 | return -1; 795 | } 796 | 797 | GLuint newProgram = glCreateProgram(); 798 | glAttachShader( newProgram, vertexShader_ ); 799 | glAttachShader( newProgram, newFragmentShader ); 800 | 801 | glLinkProgram( newProgram ); 802 | 803 | GLint result = GL_FALSE; 804 | glGetProgramiv( newProgram, GL_LINK_STATUS, &result ); 805 | 806 | if ( result == GL_FALSE ) 807 | { 808 | // error during link 809 | // 810 | 811 | int infoLogLength = 0; 812 | glGetProgramiv( newProgram, GL_INFO_LOG_LENGTH, &infoLogLength ); 813 | 814 | if ( infoLogLength ) 815 | { 816 | std::string errString; 817 | errString.resize( infoLogLength ); 818 | glGetProgramInfoLog( newProgram, infoLogLength, NULL, &errString[0] ); 819 | const char* text = errString.c_str(); 820 | fprintf( stderr, "glLinkProgram failed: Info log:\n%s\n", text ); 821 | } 822 | 823 | GLenum err = glGetError(); 824 | while ( err ) 825 | { 826 | err = glGetError(); 827 | } 828 | 829 | glDeleteProgram( newProgram ); 830 | glDeleteShader( newFragmentShader ); 831 | 832 | return -20; 833 | } 834 | 835 | if ( program_ ) 836 | { 837 | glDeleteProgram( program_ ); 838 | } 839 | 840 | if ( fragmentShader_ ) 841 | { 842 | glDeleteShader( fragmentShader_ ); 843 | } 844 | 845 | program_ = newProgram; 846 | fragmentShader_ = newFragmentShader; 847 | 848 | return 0; 849 | } 850 | 851 | int liveCoding::reloadShaderBinary( const u8* buf, size_t bufSize, GLenum format ) 852 | { 853 | GLuint newProgram = glCreateProgram(); 854 | glProgramBinary( newProgram, format, buf, (GLsizei)bufSize ); 855 | 856 | GLint result = GL_FALSE; 857 | glGetProgramiv( newProgram, GL_LINK_STATUS, &result ); 858 | 859 | if ( result == GL_FALSE ) 860 | { 861 | int infoLogLength = 0; 862 | glGetProgramiv( newProgram, GL_INFO_LOG_LENGTH, &infoLogLength ); 863 | 864 | if ( infoLogLength ) 865 | { 866 | std::string errString; 867 | errString.resize( infoLogLength ); 868 | glGetProgramInfoLog( newProgram, infoLogLength, NULL, &errString[0] ); 869 | const char* text = errString.c_str(); 870 | fprintf( stderr, "glProgramBinary failed: Info log:\n%s\n", text ); 871 | } 872 | 873 | GLenum err = glGetError(); 874 | while ( err ) 875 | { 876 | err = glGetError(); 877 | } 878 | 879 | glDeleteProgram( newProgram ); 880 | 881 | return -20; 882 | } 883 | 884 | if ( program_ ) 885 | { 886 | glDeleteProgram( program_ ); 887 | } 888 | 889 | if ( fragmentShader_ ) 890 | { 891 | glDeleteShader( fragmentShader_ ); 892 | } 893 | 894 | program_ = newProgram; 895 | fragmentShader_ = NULL; 896 | 897 | return 0; 898 | } 899 | 900 | GLuint liveCoding::createGLSLShaderFromBuf( const char* buf, size_t /*bufSize*/, GLenum profile ) 901 | { 902 | std::stringstream ssLine0; 903 | ssLine0 << 904 | "#version 430 core" << std::endl << 905 | 906 | "#define float2 vec2" << std::endl << 907 | "#define float3 vec3" << std::endl << 908 | "#define float4 vec4" << std::endl << 909 | "#define half2 vec2" << std::endl << 910 | "#define half3 vec3" << std::endl << 911 | "#define half4 vec4" << std::endl << 912 | "#define int2 ivec2" << std::endl << 913 | "#define int3 ivec3" << std::endl << 914 | "#define int4 ivec4" << std::endl << 915 | "#define bool4 bvec4" << std::endl << 916 | 917 | "#define float4x4 mat4" << std::endl << 918 | "#define float3x3 mat3" << std::endl << 919 | 920 | "#define lerp mix" << std::endl << 921 | "#define saturate(x) clamp(x, 0, 1)" << std::endl << 922 | "#define mul(mtxLeft, vecRight) (mtxLeft * vecRight)" << std::endl 923 | 924 | << buf << std::endl; 925 | ; 926 | 927 | std::string line0 = ssLine0.str(); 928 | 929 | GLuint glsh = glCreateShader( profile ); 930 | const GLchar* lines[1] = { line0.c_str() }; 931 | glShaderSource( glsh, 1, lines, NULL ); 932 | glCompileShader( glsh ); 933 | 934 | GLint result = GL_FALSE; 935 | glGetShaderiv( glsh, GL_COMPILE_STATUS, &result ); 936 | 937 | if ( result == GL_FALSE ) 938 | { 939 | fprintf( stderr, "glsl shader compilation failed!\n" ); 940 | 941 | int infoLogLength; 942 | glGetShaderiv( glsh, GL_INFO_LOG_LENGTH, &infoLogLength ); 943 | 944 | if ( infoLogLength ) 945 | { 946 | std::string errString; 947 | errString.resize( infoLogLength ); 948 | glGetShaderInfoLog( glsh, infoLogLength, NULL, &errString[0] ); 949 | const char* text = reinterpret_cast( &errString[0] ); 950 | 951 | fprintf( stderr, "glsl error:\n%s\n", text ); 952 | } 953 | 954 | GLenum err = glGetError(); 955 | while ( err ) 956 | { 957 | err = glGetError(); 958 | } 959 | 960 | return 0; 961 | } 962 | 963 | return glsh; 964 | } 965 | 966 | int liveCoding::startUpPipe() 967 | { 968 | threadHandle_ = _beginthreadex( NULL, 0, &thread_funcStatic, this, 0, &threadId_ ); 969 | if ( ! threadHandle_ ) 970 | { 971 | fprintf( stderr, "Couldn't start thread for pipe!" ); 972 | return -1; 973 | } 974 | 975 | return 0; 976 | } 977 | 978 | void liveCoding::shutDownPipe() 979 | { 980 | if ( threadHandle_ ) 981 | { 982 | { 983 | EnterCriticalSection( &pipeMutex_ ); 984 | shutDownThread_ = true; 985 | LeaveCriticalSection( &pipeMutex_ ); 986 | } 987 | 988 | WaitForSingleObject( (HANDLE)threadHandle_, INFINITE ); 989 | CloseHandle( (HANDLE)threadHandle_ ); 990 | 991 | threadHandle_ = NULL; 992 | threadId_ = 0; 993 | } 994 | } 995 | 996 | BOOL liveCoding::tryConnect() 997 | { 998 | OVERLAPPED ol; 999 | memset( &ol, 0, sizeof(ol) ); 1000 | BOOL ret = 0; 1001 | 1002 | for ( ; ; ) 1003 | { 1004 | { 1005 | EnterCriticalSection( &pipeMutex_ ); 1006 | if ( shutDownThread_ ) 1007 | { 1008 | LeaveCriticalSection( &pipeMutex_ ); 1009 | return FALSE; 1010 | } 1011 | LeaveCriticalSection( &pipeMutex_ ); 1012 | } 1013 | 1014 | // Wait for the client to connect; if it succeeds, 1015 | // the function returns a nonzero value. If the function 1016 | // returns zero, GetLastError returns ERROR_PIPE_CONNECTED. 1017 | 1018 | ol.hEvent = CreateEvent(NULL, TRUE, FALSE, NULL); 1019 | 1020 | BOOL fConnected = ConnectNamedPipe( hPipe_, &ol ); 1021 | 1022 | if ( fConnected ) 1023 | { 1024 | printf( "Shader pipe connected\n" ); 1025 | return TRUE; 1026 | } 1027 | else 1028 | { 1029 | DWORD err = GetLastError(); 1030 | 1031 | if ( err == ERROR_PIPE_CONNECTED ) 1032 | { 1033 | CloseHandle( ol.hEvent ); 1034 | return TRUE; 1035 | } 1036 | else if ( err == ERROR_PIPE_LISTENING ) 1037 | { 1038 | Sleep( 100 ); 1039 | } 1040 | else if ( err == ERROR_IO_PENDING ) 1041 | { 1042 | if( WaitForSingleObject( ol.hEvent, 1000 ) == WAIT_OBJECT_0 ) 1043 | { 1044 | DWORD dwIgnore; 1045 | ret = GetOverlappedResult( hPipe_, &ol, &dwIgnore, FALSE ); 1046 | if ( ret ) 1047 | { 1048 | CloseHandle( ol.hEvent ); 1049 | return TRUE; 1050 | } 1051 | 1052 | } else 1053 | { 1054 | CancelIo( hPipe_ ); 1055 | } 1056 | } 1057 | else 1058 | { 1059 | fprintf( stderr, "ConnectNamedPipe failed! Err=%d\n", err ); 1060 | break; 1061 | } 1062 | } 1063 | } 1064 | 1065 | return FALSE; 1066 | } 1067 | 1068 | void liveCoding::handlePipe() 1069 | { 1070 | BOOL fSuccess = FALSE; 1071 | 1072 | u8* inBuffer = new u8[ e_PipeBUFSIZE ]; 1073 | 1074 | for ( ; ; ) 1075 | { 1076 | { 1077 | EnterCriticalSection( &pipeMutex_ ); 1078 | if ( shutDownThread_ ) 1079 | { 1080 | LeaveCriticalSection( &pipeMutex_ ); 1081 | break; 1082 | } 1083 | LeaveCriticalSection( &pipeMutex_ ); 1084 | } 1085 | 1086 | DWORD cbBytesRead = 0; 1087 | 1088 | memset( inBuffer, 0, e_PipeBUFSIZE ); 1089 | 1090 | fSuccess = ReadFile( 1091 | hPipe_, // handle to pipe 1092 | inBuffer, // buffer to receive data 1093 | e_PipeBUFSIZE-1, // size of buffer 1094 | &cbBytesRead, // number of bytes read 1095 | NULL); // not overlapped I/O 1096 | 1097 | if ( !fSuccess || cbBytesRead == 0 ) 1098 | { 1099 | DWORD err = GetLastError(); 1100 | 1101 | if ( err == ERROR_NO_DATA ) 1102 | { 1103 | Sleep( 100 ); 1104 | continue; 1105 | } 1106 | else if (err == ERROR_BROKEN_PIPE) 1107 | { 1108 | //fprintf( stderr, "ReadFile failed! Broken pipe\n" ); 1109 | break; 1110 | } 1111 | else 1112 | { 1113 | fprintf( stderr, "ReadFile failed!\n Err=%d", err ); 1114 | break; 1115 | } 1116 | } 1117 | 1118 | // process message 1119 | // 1120 | 1121 | const char* message = reinterpret_cast( inBuffer ); 1122 | const size_t messageLen = strlen(message); 1123 | 1124 | if ( messageLen >= strlen("srcCode") && !strcmp(message, "srcCode") ) 1125 | { 1126 | const char* payload = message + messageLen + 1; 1127 | 1128 | //printf( "newSourceCode:\n%s\n", payload ); 1129 | 1130 | size_t payLoadSize = strlen(payload); 1131 | char* src = new char[payLoadSize+1]; 1132 | 1133 | memcpy( src, payload, payLoadSize ); 1134 | src[payLoadSize] = 0; 1135 | 1136 | char* oldSourceCode = NULL; 1137 | size_t oldSourceCodeSize = 0; 1138 | 1139 | EnterCriticalSection( &pipeMutex_ ); 1140 | 1141 | reloadShaderRequested_ = true; 1142 | oldSourceCode = freshSourceCode_; 1143 | oldSourceCodeSize = freshSourceCodeSize_; 1144 | 1145 | freshSourceCode_ = src; 1146 | freshSourceCodeSize_ = payLoadSize; 1147 | 1148 | LeaveCriticalSection( &pipeMutex_ ); 1149 | 1150 | delete[] oldSourceCode; 1151 | } 1152 | else if ( messageLen >= strlen("programBinary") && !strcmp(message, "programBinary") ) 1153 | { 1154 | const char* payload = message + messageLen + 1; 1155 | u32 binaryLen = 0; 1156 | GLenum binaryFormat = 0; 1157 | memcpy( &binaryLen, payload, 4 ); 1158 | memcpy( &binaryFormat, payload + 4, 4 ); 1159 | 1160 | u8* bin = new u8[binaryLen]; 1161 | memcpy( bin, payload + 8, binaryLen ); 1162 | 1163 | u8* oldBinary = NULL; 1164 | 1165 | EnterCriticalSection( &pipeMutex_ ); 1166 | 1167 | reloadShaderRequested_ = true; 1168 | 1169 | oldBinary = freshBinary_; 1170 | 1171 | freshBinary_ = bin; 1172 | freshBinarySize_ = binaryLen; 1173 | freshBinaryFormat_ = binaryFormat; 1174 | 1175 | LeaveCriticalSection( &pipeMutex_ ); 1176 | 1177 | delete[] oldBinary; 1178 | } 1179 | } 1180 | 1181 | printf( " Shader pipe DISconnected\n" ); 1182 | 1183 | delete[] inBuffer; 1184 | 1185 | DisconnectNamedPipe( hPipe_ ); 1186 | } 1187 | 1188 | unsigned int __stdcall liveCoding::thread_funcStatic( void *arg ) 1189 | { 1190 | liveCoding* nod = reinterpret_cast( arg ); 1191 | return nod->thread_func( NULL ); 1192 | } 1193 | 1194 | unsigned int liveCoding::thread_func( void * /*arg*/ ) 1195 | { 1196 | hPipe_ = CreateNamedPipe( 1197 | "\\\\.\\pipe\\LiveCodingShaderPipe", // pipe name 1198 | FILE_FLAG_OVERLAPPED | 1199 | PIPE_ACCESS_INBOUND, // read/write access 1200 | PIPE_TYPE_MESSAGE | // message type pipe 1201 | PIPE_READMODE_MESSAGE | // message-read mode 1202 | PIPE_WAIT, // blocking mode 1203 | 1, // max. instances 1204 | 0, // output buffer size 1205 | e_PipeBUFSIZE, // input buffer size 1206 | 1000, // client time-out 1207 | NULL ); // default security attribute 1208 | 1209 | if ( hPipe_ == INVALID_HANDLE_VALUE ) 1210 | { 1211 | fprintf( stderr, "Couldn't open named pipe! Err=%u\n", GetLastError() ); 1212 | return 1; 1213 | } 1214 | 1215 | BOOL fConnected = FALSE; 1216 | 1217 | for ( ; ; ) 1218 | { 1219 | { 1220 | EnterCriticalSection( &pipeMutex_ ); 1221 | if ( shutDownThread_ ) 1222 | { 1223 | LeaveCriticalSection( &pipeMutex_ ); 1224 | break; 1225 | } 1226 | LeaveCriticalSection( &pipeMutex_ ); 1227 | } 1228 | 1229 | fConnected = tryConnect(); 1230 | 1231 | if ( fConnected ) 1232 | { 1233 | handlePipe(); 1234 | } 1235 | } 1236 | 1237 | if ( hPipe_ != INVALID_HANDLE_VALUE ) 1238 | { 1239 | CloseHandle( hPipe_ ); 1240 | hPipe_ = 0; 1241 | } 1242 | 1243 | return 0; 1244 | } 1245 | 1246 | int liveCoding::bass_startUp() 1247 | { 1248 | int device = -1; 1249 | config_lookup_int( &config_, "bassRecordDevice", &device ); 1250 | 1251 | const int freq = 44100; 1252 | 1253 | int ires = 0; 1254 | ires = BASS_Init( device, freq, 0, 0, 0 ); 1255 | if( !ires ) 1256 | { 1257 | fprintf( stderr, "BASS_Init failed! Err=%d\n", BASS_ErrorGetCode() ); 1258 | return -1; 1259 | } 1260 | 1261 | int a, count = 0; 1262 | BASS_DEVICEINFO allInfo[16]; 1263 | memset( allInfo, 0, sizeof(allInfo) ); 1264 | BASS_DEVICEINFO info; 1265 | for ( a = 0; BASS_RecordGetDeviceInfo(a, &info); a++ ) 1266 | { 1267 | if ( info.flags & BASS_DEVICE_ENABLED ) // device is enabled 1268 | { 1269 | printf( "BASS_RecordDevice: %d : %s\n", count, info.name ); 1270 | 1271 | if ( count < 16 ) 1272 | allInfo[count] = info; 1273 | 1274 | count++; // count it 1275 | } 1276 | } 1277 | 1278 | //printf( "n", count, info.name ); 1279 | 1280 | ires = BASS_RecordInit( device ); 1281 | if( !ires ) 1282 | { 1283 | fprintf( stderr, "BASS_RecordInit failed! Err=%d\n", BASS_ErrorGetCode() ); 1284 | return -2; 1285 | } 1286 | 1287 | DWORD usedDevice = BASS_RecordGetDevice(); 1288 | (void)usedDevice; 1289 | 1290 | return 0; 1291 | } 1292 | 1293 | void liveCoding::bass_shutDown() 1294 | { 1295 | BASS_RecordFree(); 1296 | BASS_Free(); 1297 | } 1298 | 1299 | void liveCoding::bass_startCapture() 1300 | { 1301 | bass_stopCapture(); 1302 | 1303 | //const int freq = 44100; 1304 | //const int channels = 2; 1305 | 1306 | //hRecord_ = BASS_RecordStart( freq, channels, BASS_SAMPLE_8BITS, 0, 0 ); 1307 | //if( !hRecord_ ) 1308 | //{ 1309 | // fprintf( stderr, "BASS_RecordStart failed! Err=%d\n", BASS_ErrorGetCode() ); 1310 | //} 1311 | 1312 | //std::string file = liveCodingDir_ + "sine.wav"; 1313 | //std::string file = liveCodingDir_ + "catzilla.ogg"; 1314 | std::string file = liveCodingDir_ + "wilhelm.wav"; 1315 | 1316 | if ( ! (hRecord_ = BASS_StreamCreateFile(FALSE,file.c_str(),0,0,BASS_SAMPLE_LOOP)) 1317 | && ! ( hRecord_ = BASS_MusicLoad(FALSE,file.c_str(),0,0,BASS_MUSIC_RAMP|BASS_SAMPLE_LOOP,1))) 1318 | { 1319 | assert( false ); 1320 | return; 1321 | } 1322 | 1323 | BASS_ChannelPlay(hRecord_,FALSE); 1324 | } 1325 | 1326 | void liveCoding::bass_stopCapture() 1327 | { 1328 | if ( hRecord_ ) 1329 | { 1330 | BASS_ChannelStop( hRecord_ ); 1331 | hRecord_ = 0; 1332 | } 1333 | } 1334 | -------------------------------------------------------------------------------- /src/liveCodingPreview/liveCoding.h: -------------------------------------------------------------------------------- 1 | /******************************************************************************* 2 | * 2005-2014, plastic demoscene group 3 | * authors: misz, bonzaj 4 | *******************************************************************************/ 5 | 6 | #pragma once 7 | 8 | #include "util.h" 9 | #include "midi.h" 10 | 11 | #define FFT_SIZE 1024 12 | #define FFT_BINS 8 13 | #define FFT_HISTORY_LENGTH 1024 14 | 15 | struct liveCoding 16 | { 17 | liveCoding() 18 | : startTimeMS_( 0 ) 19 | , windowPosX_( 0 ) 20 | , windowPosY_( 0 ) 21 | , windowW_( 800 ) 22 | , windowH_( 600 ) 23 | , fullscreen_( 0 ) 24 | , reloadShaderRequested_( true ) 25 | , freshSourceCode_( NULL ) 26 | , freshSourceCodeSize_( 0 ) 27 | 28 | , freshBinary_( NULL ) 29 | , freshBinarySize_( 0 ) 30 | , freshBinaryFormat_( 0 ) 31 | 32 | , iFFTTexture_( 0 ) 33 | , iFFTTextureUnit_( -1 ) 34 | , iFFTsHistoryTexture_( 0 ) 35 | , iFFTsHistoryTextureUnit_( -1 ) 36 | , iFFTsHistoryData_( NULL ) 37 | 38 | , hPipe_( NULL ) 39 | , threadHandle_( NULL ) 40 | , threadId_( 0 ) 41 | , shutDownThread_( false ) 42 | 43 | // bass 44 | // 45 | , hRecord_( NULL ) 46 | 47 | // midi 48 | // 49 | , midiController_( NULL ) 50 | { 51 | memset( fftBassBuf_, 0, sizeof(fftBassBuf_) ); 52 | memset( fft_, 0, sizeof(fft_) ); 53 | memset( ffts_, 0, sizeof(ffts_) ); 54 | memset( ffti_, 0, sizeof(ffti_) ); 55 | memset( fftsi_, 0, sizeof(fftsi_) ); 56 | } 57 | 58 | int startUp( int argc, char* argv[] ); 59 | void shutDown(); 60 | void readConfig(); 61 | void writeConfig(); 62 | void setupDefaultConfig(); 63 | 64 | void draw(); 65 | void setupShaderInputs(); 66 | void setShaderInputs(); 67 | 68 | void reloadShader(); 69 | int reloadShaderSource( const char* buf, size_t bufSize ); 70 | int reloadShaderBinary( const u8* buf, size_t bufSize, GLenum format ); 71 | GLuint createGLSLShaderFromBuf( const char* buf, size_t bufSize, GLenum profile ); 72 | 73 | // pipes 74 | // 75 | int startUpPipe(); 76 | void shutDownPipe(); 77 | 78 | BOOL tryConnect(); 79 | void handlePipe(); 80 | 81 | static unsigned int __stdcall thread_funcStatic( void *arg ); 82 | unsigned int thread_func( void *arg ); 83 | 84 | // bass 85 | // 86 | int bass_startUp(); 87 | void bass_shutDown(); 88 | void bass_startCapture(); 89 | void bass_stopCapture(); 90 | 91 | struct Tex 92 | { 93 | Tex() 94 | : glTexID_( 0 ) 95 | { } 96 | 97 | Tex( const char* samplerName, const char* filename ) 98 | : samplerName_( samplerName ) 99 | , filename_( filename ) 100 | { } 101 | 102 | std::string samplerName_; 103 | std::string filename_; 104 | GLuint glTexID_; 105 | }; 106 | 107 | config_t config_; 108 | 109 | std::string liveCodingDir_; 110 | int windowPosX_; 111 | int windowPosY_; 112 | int windowW_; 113 | int windowH_; 114 | int fullscreen_; 115 | u32 startTimeMS_; 116 | 117 | GLuint vertexShader_; 118 | GLuint fragmentShader_; 119 | GLuint program_; 120 | 121 | bool reloadShaderRequested_; 122 | char* freshSourceCode_; 123 | size_t freshSourceCodeSize_; 124 | 125 | u8* freshBinary_; 126 | size_t freshBinarySize_; 127 | GLenum freshBinaryFormat_; 128 | 129 | std::vector textures_; 130 | GLuint iFFTTexture_; 131 | int iFFTTextureUnit_; 132 | GLuint iFFTsHistoryTexture_; 133 | int iFFTsHistoryTextureUnit_; 134 | float* iFFTsHistoryData_; 135 | 136 | // pipes 137 | // 138 | enum { e_PipeBUFSIZE = 256 * 1024 }; 139 | 140 | HANDLE hPipe_; 141 | uintptr_t threadHandle_; 142 | unsigned int threadId_; 143 | 144 | CRITICAL_SECTION pipeMutex_; 145 | bool shutDownThread_; 146 | 147 | // bass 148 | // 149 | HRECORD hRecord_; 150 | float fftBassBuf_[FFT_SIZE]; 151 | float fft_[FFT_BINS]; 152 | float ffts_[FFT_BINS]; 153 | float ffti_[FFT_BINS]; 154 | float fftsi_[FFT_BINS]; 155 | 156 | // midi 157 | // 158 | midiController* midiController_; 159 | }; -------------------------------------------------------------------------------- /src/liveCodingPreview/liveCodingPreview.vcxproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | Debug 6 | x64 7 | 8 | 9 | Release 10 | x64 11 | 12 | 13 | 14 | {FD4D8A71-25B7-4B0E-86E3-154FD2384F86} 15 | Win32Proj 16 | liveCodingPreview 17 | 18 | 19 | 20 | Application 21 | true 22 | NotSet 23 | 24 | 25 | Application 26 | false 27 | true 28 | NotSet 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | true 42 | $(SolutionDir)..\bin\ 43 | $(SolutionDir)..\build\$(ProjectName)\$(Configuration)\$(Platform)\ 44 | 45 | 46 | false 47 | $(SolutionDir)..\bin\ 48 | $(SolutionDir)..\build\$(ProjectName)\$(Configuration)\$(Platform)\ 49 | 50 | 51 | 52 | Use 53 | Level3 54 | Disabled 55 | WIN32;_DEBUG;_CONSOLE;_CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions) 56 | 57 | 58 | Console 59 | true 60 | ../../external/freeglut/lib/x64/freeglut.lib;../../external/glew/lib/Release/x64/glew32.lib;../../external/libpng/libpng_x64_release.lib;../../external/libpng/ZLib_x64_release.lib;../../external/libconfig/Release/x64/libconfig.lib;../../external/bass/c/x64/bass.lib;%(AdditionalDependencies) 61 | 62 | 63 | 64 | 65 | Level4 66 | Use 67 | MaxSpeed 68 | true 69 | true 70 | WIN32;NDEBUG;_CONSOLE;_CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions) 71 | 72 | 73 | Console 74 | true 75 | true 76 | true 77 | ../../external/freeglut/lib/x64/freeglut.lib;../../external/glew/lib/Release/x64/glew32.lib;../../external/libpng/libpng_x64_release.lib;../../external/libpng/ZLib_x64_release.lib;../../external/libconfig/Release/x64/libconfig.lib;../../external/bass/c/x64/bass.lib;%(AdditionalDependencies) 78 | 79 | 80 | 81 | 82 | 83 | 84 | 85 | 86 | 87 | 88 | 89 | 90 | 91 | 92 | Create 93 | Create 94 | 95 | 96 | 97 | 98 | 99 | 100 | -------------------------------------------------------------------------------- /src/liveCodingPreview/liveCoding_inputs.cpp: -------------------------------------------------------------------------------- 1 | /******************************************************************************* 2 | * 2005-2014, plastic demoscene group 3 | * authors: misz, bonzaj 4 | *******************************************************************************/ 5 | 6 | #include "stdafx.h" 7 | #include "liveCoding.h" 8 | 9 | void liveCoding::setupShaderInputs() 10 | { 11 | textures_.push_back( Tex( "iSplashScreen", "textures/splashScreen.png" ) ); 12 | textures_.push_back( Tex( "iChecker", "textures/checker.png" ) ); 13 | textures_.push_back( Tex( "iNoise", "textures/noise.png" ) ); 14 | textures_.push_back( Tex( "iTex1", "textures/tex1.png" ) ); 15 | textures_.push_back( Tex( "iTex2", "textures/tex2.png" ) ); 16 | textures_.push_back( Tex( "iTex3", "textures/tex3.png" ) ); 17 | textures_.push_back( Tex( "iTex4", "textures/tex4.png" ) ); 18 | } 19 | 20 | void liveCoding::setShaderInputs() 21 | { 22 | } 23 | -------------------------------------------------------------------------------- /src/liveCodingPreview/midi.cpp: -------------------------------------------------------------------------------- 1 | /******************************************************************************* 2 | * 2005-2014, plastic demoscene group 3 | * authors: misz, bonzaj 4 | *******************************************************************************/ 5 | 6 | #include "stdafx.h" 7 | #include "midi.h" 8 | 9 | #ifdef _DEBUG 10 | #define new _DEBUG_NEW 11 | #endif 12 | 13 | void CALLBACK MidiInProcWin( HMIDIIN hMidiIn, UINT wMsg, DWORD_PTR dwInstance, DWORD_PTR dwParam1, DWORD_PTR dwParam2 ) 14 | { 15 | (void)dwParam2; 16 | (void)hMidiIn; 17 | if( wMsg == MIM_DATA ) 18 | { 19 | midiDevice* dev = (midiDevice*)dwInstance; 20 | dev->addData( (u32)dwParam1 ); 21 | } 22 | } 23 | 24 | 25 | int midiDevice::startUp( const char* deviceName ) 26 | { 27 | unsigned deviceId = ~0u; 28 | 29 | const unsigned numDevices = midiInGetNumDevs(); 30 | for( unsigned i = 0; i < numDevices; ++i ) 31 | { 32 | MIDIINCAPS capabilities; 33 | MMRESULT res = midiInGetDevCaps(i, &capabilities, sizeof(MIDIINCAPS)); 34 | if ( res != MMSYSERR_NOERROR ) 35 | { 36 | fprintf( stderr, "midiInGetDevCaps failed! Err=%d", res ); 37 | return -1; 38 | } 39 | 40 | if( !strcmp( capabilities.szPname, deviceName ) ) 41 | { 42 | deviceId = i; 43 | break; 44 | } 45 | } 46 | 47 | if( deviceId == ~0u ) 48 | { 49 | fprintf( stderr, "Can not open MIDI device '%s': device not found\n", deviceName ); 50 | printf( "Available '%d' devices:\n", numDevices ); 51 | for( unsigned i = 0; i < numDevices; ++i ) 52 | { 53 | MIDIINCAPS capabilities; 54 | MMRESULT res = midiInGetDevCaps(deviceId, &capabilities, sizeof(MIDIINCAPS)); 55 | if ( res != MMSYSERR_NOERROR ) 56 | { 57 | printf( "%s\n", capabilities.szPname ); 58 | } 59 | } 60 | 61 | return -1; 62 | } 63 | 64 | csValid_ = true; 65 | InitializeCriticalSection( &cs_ ); 66 | 67 | MMRESULT result = midiInOpen( &device_, deviceId, (DWORD_PTR)(MidiInProcWin), (DWORD)(this), CALLBACK_FUNCTION ); 68 | if (result != MMSYSERR_NOERROR) 69 | { 70 | fprintf( stderr, "midiInOpen failed! Err=%d\n", result ); 71 | return -1; 72 | } 73 | 74 | result = midiInStart(device_); 75 | if (result != MMSYSERR_NOERROR) 76 | { 77 | fprintf( stderr, "midiInOpen failed! Err=%d\n", result ); 78 | return -1; 79 | } 80 | 81 | deviceId_ = deviceId; 82 | 83 | return 0; 84 | } 85 | 86 | void midiDevice::shutDown() 87 | { 88 | if ( device_ ) 89 | { 90 | midiInStop( device_ ); 91 | midiInClose( device_ ); 92 | device_ = NULL; 93 | } 94 | 95 | midiData_.clear(); 96 | 97 | if ( csValid_ ) 98 | { 99 | csValid_ = false; 100 | DeleteCriticalSection( &cs_ ); 101 | } 102 | } 103 | 104 | void midiDevice::addData( u32 data ) 105 | { 106 | EnterCriticalSection( &cs_ ); 107 | midiData_.push_back( data ); 108 | LeaveCriticalSection( &cs_ ); 109 | } 110 | 111 | int midiDevice::poll( midiEvent* events, int capacity ) 112 | { 113 | int size = 0; 114 | 115 | union Helper 116 | { 117 | u32 dword; 118 | struct Bytes 119 | { 120 | u8 _0; 121 | u8 _1; 122 | u8 _2; 123 | u8 _3; 124 | } bytes; 125 | } helper; 126 | 127 | EnterCriticalSection( &cs_ ); 128 | 129 | const size_t nData = midiData_.size(); 130 | for ( size_t i = 0; i < nData; ++i ) 131 | { 132 | if( size >= capacity ) 133 | break; 134 | 135 | u32 data = midiData_.front(); 136 | midiData_.pop_front(); 137 | 138 | helper.dword = data; 139 | midiEvent& e = events[size]; 140 | e.type = helper.bytes._0; 141 | e.channel = helper.bytes._1; 142 | e.value = helper.bytes._2; 143 | ++ size; 144 | } 145 | 146 | LeaveCriticalSection( &cs_ ); 147 | 148 | return size; 149 | 150 | } 151 | 152 | 153 | 154 | 155 | midiController::midiController( const char* name ) 156 | : deviceName_( name ) 157 | { 158 | memset( padData_, 0, sizeof(padData_) ); 159 | } 160 | 161 | void midiController::update() 162 | { 163 | const float normalizationFactor127 = 1.f / 127; 164 | const int MAX_EVENTS = 128; 165 | midiEvent events[MAX_EVENTS]; 166 | const int numEvents = device_.poll( events, MAX_EVENTS ); 167 | 168 | for( int i = 0; i < numEvents; ++i ) 169 | { 170 | const midiEvent& e = events[i]; 171 | _Map( e ); 172 | } 173 | } 174 | 175 | int midiController::startUp() 176 | { 177 | int ires = device_.startUp( deviceName_.c_str() ); 178 | if ( ires ) 179 | { 180 | device_.shutDown(); 181 | return ires; 182 | } 183 | 184 | return 0; 185 | } 186 | 187 | void midiController::shutDown() 188 | { 189 | device_.shutDown(); 190 | } 191 | 192 | midiController_CME_U2MIDI::midiController_CME_U2MIDI() 193 | : midiController( "CME U2MIDI" ) 194 | { 195 | memset( mapping_, ePadCount, sizeof(mapping_) ); 196 | 197 | mapping_[36] = ePad0; 198 | mapping_[37] = ePad1; 199 | mapping_[38] = ePad2; 200 | mapping_[39] = ePad3; 201 | mapping_[40] = ePad4; 202 | mapping_[41] = ePad5; 203 | mapping_[42] = ePad6; 204 | mapping_[43] = ePad7; 205 | mapping_[44] = ePad8; 206 | mapping_[45] = ePad9; 207 | 208 | mapping_[46] = ePad10; 209 | mapping_[47] = ePad11; 210 | mapping_[48] = ePad12; 211 | mapping_[49] = ePad13; 212 | mapping_[50] = ePad14; 213 | mapping_[51] = ePad15; 214 | } 215 | 216 | void midiController_CME_U2MIDI::_Map( const midiEvent& e ) 217 | { 218 | const float normalizationFactor127 = 1.f / 127; 219 | 220 | u8 channelModified = 0xFF; 221 | if( (e.type & 0xF0) == 0x90 ) // note on 222 | { 223 | _SetValue( e.channel, e.value * normalizationFactor127 ); 224 | channelModified = e.channel; 225 | } 226 | else if( (e.type & 0xF0) == 0x80 ) 227 | { 228 | _SetValue( e.channel, 0.f ); 229 | channelModified = e.channel; 230 | } 231 | } 232 | 233 | void midiController_CME_U2MIDI::_SetValue( int channel, float value ) 234 | { 235 | //printf( "channel: %d\n", channel ); 236 | 237 | if ( channel >= 0 && channel < 128 ) 238 | { 239 | int index = mapping_[channel]; 240 | if( index >= 0 && index < ePadCount ) 241 | { 242 | if ( value > 0 ) 243 | padData_[index] = 1; 244 | else 245 | padData_[index] = 0; 246 | } 247 | } 248 | } 249 | 250 | //midiController_Akai_MPD26::midiController_Akai_MPD26() 251 | // : midiController( "Akai MPD26" ) 252 | //{ 253 | // memset( mapping_, ePadCount, sizeof(mapping_) ); 254 | // 255 | // mapping_[36] = ePad0; 256 | // mapping_[37] = ePad1; 257 | // mapping_[38] = ePad2; 258 | // mapping_[39] = ePad3; 259 | // mapping_[40] = ePad4; 260 | // mapping_[41] = ePad5; 261 | // mapping_[42] = ePad6; 262 | // mapping_[43] = ePad7; 263 | // mapping_[44] = ePad8; 264 | // mapping_[45] = ePad9; 265 | // 266 | // mapping_[46] = ePad10; 267 | // mapping_[47] = ePad11; 268 | // mapping_[48] = ePad12; 269 | // mapping_[49] = ePad13; 270 | // mapping_[50] = ePad14; 271 | // mapping_[51] = ePad15; 272 | //} 273 | // 274 | //void midiController_Akai_MPD26::_Map( const midiEvent& e ) 275 | //{ 276 | // const float normalizationFactor127 = 1.f / 127; 277 | // 278 | // u8 channelModified = 0xFF; 279 | // if( (e.type & 0xF0) == 0x90 ) // note on 280 | // { 281 | // _SetValue( e.channel, e.value * normalizationFactor127 ); 282 | // channelModified = e.channel; 283 | // } 284 | // else if( (e.type & 0xF0) == 0x80 ) 285 | // { 286 | // _SetValue( e.channel, 0.f ); 287 | // channelModified = e.channel; 288 | // } 289 | //} 290 | // 291 | //void midiController_Akai_MPD26::_SetValue( int channel, float value ) 292 | //{ 293 | // printf( "channel: %d\n", channel ); 294 | // 295 | // if ( channel >= 0 && channel < 128 ) 296 | // { 297 | // int index = mapping_[channel]; 298 | // if( index >= 0 && index < ePadCount ) 299 | // { 300 | // if ( value > 0 ) 301 | // padData_[index] = 1; 302 | // else 303 | // padData_[index] = 0; 304 | // } 305 | // } 306 | //} 307 | -------------------------------------------------------------------------------- /src/liveCodingPreview/midi.h: -------------------------------------------------------------------------------- 1 | /******************************************************************************* 2 | * 2005-2014, plastic demoscene group 3 | * authors: misz, bonzaj 4 | *******************************************************************************/ 5 | 6 | #pragma once 7 | #include 8 | 9 | struct midiEvent 10 | { 11 | u8 type; 12 | u8 channel; 13 | u8 value; 14 | u8 padd0__[1]; 15 | }; 16 | 17 | class midiDevice 18 | { 19 | public: 20 | midiDevice() 21 | : deviceId_( ~0U ) 22 | , device_( NULL ) 23 | , csValid_( false ) 24 | { 25 | memset( &cs_, 0, sizeof(cs_) ); 26 | } 27 | ~midiDevice() {} 28 | 29 | int startUp( const char* deviceName ); 30 | void shutDown(); 31 | 32 | int poll( midiEvent* events, int capacity ); 33 | //bool opened() const; 34 | //bool connected() const; 35 | 36 | void addData( u32 data ); 37 | 38 | protected: 39 | unsigned _GetDeviceCount(); 40 | void _GetDeviceName( char* dstName, int dstNameCapacity, unsigned deviceId ); 41 | 42 | //int _OpenImpl( unsigned deviceId ); 43 | //void _CloseImpl(); 44 | //int _PollImpl( midiEvent* events, int capacity ); 45 | 46 | u32 deviceId_; 47 | HMIDIIN device_; 48 | 49 | std::list midiData_; 50 | CRITICAL_SECTION cs_; 51 | bool csValid_; 52 | }; 53 | 54 | class midiController 55 | { 56 | public: 57 | enum 58 | { 59 | ePad0, 60 | ePad1, 61 | ePad2, 62 | ePad3, 63 | ePad4, 64 | ePad5, 65 | ePad6, 66 | ePad7, 67 | ePad8, 68 | ePad9, 69 | ePad10, 70 | ePad11, 71 | ePad12, 72 | ePad13, 73 | ePad14, 74 | ePad15, 75 | ePadCount, 76 | }; 77 | 78 | midiController( const char* name ); 79 | virtual ~midiController() {} 80 | 81 | int startUp(); 82 | void shutDown(); 83 | 84 | void update(); 85 | 86 | void getData( float dst[ePadCount] ) const 87 | { 88 | memcpy( dst, padData_, sizeof(padData_) ); 89 | } 90 | 91 | protected: 92 | virtual void _Map( const midiEvent& e ) = 0; 93 | 94 | protected: 95 | std::string deviceName_; 96 | midiDevice device_; 97 | float padData_[ePadCount]; 98 | }; 99 | 100 | class midiController_CME_U2MIDI : public midiController 101 | { 102 | public: 103 | midiController_CME_U2MIDI(); 104 | 105 | protected: 106 | void _Map( const midiEvent& e ); 107 | void _SetValue( int channel, float value ); 108 | 109 | u8 mapping_[128]; 110 | }; 111 | 112 | //class midiController_Akai_MPD26 : public midiController 113 | //{ 114 | //public: 115 | // midiController_Akai_MPD26(); 116 | // 117 | //protected: 118 | // void _Map( const midiEvent& e ); 119 | // void _SetValue( int channel, float value ); 120 | // 121 | // u8 mapping_[128]; 122 | //}; 123 | -------------------------------------------------------------------------------- /src/liveCodingPreview/stdafx.cpp: -------------------------------------------------------------------------------- 1 | /******************************************************************************* 2 | * 2005-2014, plastic demoscene group 3 | * authors: misz, bonzaj 4 | *******************************************************************************/ 5 | 6 | #include "stdafx.h" 7 | -------------------------------------------------------------------------------- /src/liveCodingPreview/stdafx.h: -------------------------------------------------------------------------------- 1 | /******************************************************************************* 2 | * 2005-2014, plastic demoscene group 3 | * authors: misz, bonzaj 4 | *******************************************************************************/ 5 | 6 | #pragma once 7 | 8 | #include "targetver.h" 9 | 10 | #if defined(_MSC_VER) && defined(_DEBUG) 11 | #define _CRTDBG_MAP_ALLOC 12 | #include 13 | #include 14 | #else 15 | #include 16 | #endif 17 | 18 | #include 19 | #include 20 | #include 21 | #include 22 | #include 23 | #include 24 | #include 25 | 26 | #include "../../external/glew/include/GL/glew.h" 27 | #include "../../external/glew/include/GL/wglew.h" 28 | #include "../../external/freeglut/include/GL/freeglut.h" 29 | #include "../../external/libpng/png.h" 30 | #include "../../external/libconfig/lib/libconfig.h" 31 | #include "../../external/bass/c/bass.h" 32 | 33 | #include 34 | typedef uint8_t u8; 35 | typedef uint16_t u16; 36 | typedef uint32_t u32; 37 | typedef uint64_t u64; 38 | typedef int8_t s8; 39 | typedef int16_t s16; 40 | typedef int32_t s32; 41 | typedef int64_t s64; 42 | typedef int8_t i8; 43 | typedef int16_t i16; 44 | typedef int32_t i32; 45 | typedef int64_t i64; 46 | 47 | #if defined(_MSC_VER) && defined(_DEBUG) 48 | /** 49 | * Be aware to add: 50 | * #if defined(_MSC_VER) && defined(_DEBUG) 51 | * #define new _DEBUG_NEW 52 | * #endif 53 | * at the beginning of a file that uses 'new' operator. Only then overloaded versions for tracking allocation 54 | * will work!!! 55 | */ 56 | #define _DEBUG_NEW new(_NORMAL_BLOCK, __FILE__, __LINE__) 57 | #else 58 | #define _DEBUG_NEW 59 | #endif // 60 | -------------------------------------------------------------------------------- /src/liveCodingPreview/targetver.h: -------------------------------------------------------------------------------- 1 | /******************************************************************************* 2 | * 2005-2014, plastic demoscene group 3 | * authors: misz, bonzaj 4 | *******************************************************************************/ 5 | 6 | #pragma once 7 | 8 | // Including SDKDDKVer.h defines the highest available Windows platform. 9 | 10 | // If you wish to build your application for a previous Windows platform, include WinSDKVer.h and 11 | // set the _WIN32_WINNT macro to the platform you wish to support before including SDKDDKVer.h. 12 | 13 | #include 14 | -------------------------------------------------------------------------------- /src/liveCodingPreview/util.cpp: -------------------------------------------------------------------------------- 1 | /******************************************************************************* 2 | * 2005-2014, plastic demoscene group 3 | * authors: misz, bonzaj 4 | *******************************************************************************/ 5 | 6 | #include "stdafx.h" 7 | #include "util.h" 8 | 9 | static unsigned __int64 getHz() 10 | { 11 | LARGE_INTEGER tf; 12 | QueryPerformanceFrequency(&tf); 13 | return tf.QuadPart; 14 | } 15 | 16 | static unsigned __int64 _gQPF = getHz(); 17 | 18 | unsigned int getTimeMS() 19 | { 20 | LARGE_INTEGER ct; 21 | QueryPerformanceCounter( &ct ); 22 | 23 | unsigned int val = (unsigned int)( (ct.QuadPart * 1000) / _gQPF ); 24 | return val; 25 | } 26 | 27 | int loadFile( const char* filename, char** dstBuf, size_t* dstBufSize ) 28 | { 29 | FILE* f = fopen( filename, "rb" ); 30 | if ( !f ) 31 | { 32 | fprintf( stderr, "fopen failed! (%s)", filename ); 33 | return -1; 34 | } 35 | 36 | fseek( f, 0, SEEK_END ); 37 | size_t sizeInBytes = ftell( f ); 38 | fseek( f, 0, SEEK_SET ); 39 | 40 | char* buf = new char[sizeInBytes+1]; 41 | size_t readBytes = fread( buf, 1, sizeInBytes, f ); 42 | (void)readBytes; 43 | assert( readBytes == sizeInBytes ); 44 | int ret = fclose( f ); 45 | (void)ret; 46 | assert( ret != EOF ); 47 | 48 | buf[sizeInBytes] = NULL; 49 | 50 | *dstBuf = buf; 51 | *dstBufSize = sizeInBytes; 52 | 53 | return 0; 54 | } 55 | 56 | GLuint readTexture( const char* filename ) 57 | { 58 | png_structp png_ptr; 59 | png_infop info_ptr; 60 | unsigned int sig_read = 0; 61 | FILE *fp; 62 | 63 | if ((fp = fopen(filename, "rb")) == NULL) 64 | return 0; 65 | 66 | /* Create and initialize the png_struct with the desired error handler 67 | * functions. If you want to use the default stderr and longjump method, 68 | * you can supply NULL for the last three parameters. We also supply the 69 | * the compiler header file version, so that we know if the application 70 | * was compiled with a compatible version of the library. REQUIRED 71 | */ 72 | png_ptr = png_create_read_struct(PNG_LIBPNG_VER_STRING, NULL, NULL, NULL ); 73 | //png_voidp user_error_ptr, user_error_fn, user_warning_fn); 74 | 75 | if (png_ptr == NULL) 76 | { 77 | fclose(fp); 78 | return 0; 79 | } 80 | 81 | /* Allocate/initialize the memory for image information. REQUIRED. */ 82 | info_ptr = png_create_info_struct(png_ptr); 83 | if (info_ptr == NULL) 84 | { 85 | fclose(fp); 86 | png_destroy_read_struct(&png_ptr, NULL, NULL); 87 | return 0; 88 | } 89 | 90 | /* Set error handling if you are using the setjmp/longjmp method (this is 91 | * the normal method of doing things with libpng). REQUIRED unless you 92 | * set up your own error handlers in the png_create_read_struct() earlier. 93 | */ 94 | 95 | if (setjmp(png_jmpbuf(png_ptr))) 96 | { 97 | /* Free all of the memory associated with the png_ptr and info_ptr */ 98 | png_destroy_read_struct(&png_ptr, &info_ptr, NULL); 99 | fclose(fp); 100 | /* If we get here, we had a problem reading the file */ 101 | return 0; 102 | } 103 | 104 | /* Set up the input control if you are using standard C streams */ 105 | png_init_io(png_ptr, fp); 106 | 107 | 108 | /* If we have already read some of the signature */ 109 | png_set_sig_bytes(png_ptr, sig_read); 110 | 111 | /* 112 | * If you have enough memory to read in the entire image at once, 113 | * and you need to specify only transforms that can be controlled 114 | * with one of the PNG_TRANSFORM_* bits (this presently excludes 115 | * dithering, filling, setting background, and doing gamma 116 | * adjustment), then you can read the entire image (including 117 | * pixels) into the info structure with this call: 118 | */ 119 | png_read_png(png_ptr, info_ptr, NULL, NULL); 120 | 121 | //png_read_image(png_ptr, row_pointers); 122 | 123 | GLenum internalFormat = GL_SRGB8_ALPHA8; 124 | GLenum srcFormat = 0; 125 | 126 | if( info_ptr->bit_depth == 8 ) 127 | { 128 | 129 | } 130 | else 131 | { 132 | /* Free all of the memory associated with the png_ptr and info_ptr */ 133 | png_destroy_read_struct(&png_ptr, &info_ptr, NULL); 134 | fclose(fp); 135 | /* If we get here, we had a problem reading the file */ 136 | return 0; 137 | } 138 | 139 | if ( info_ptr->channels == 3 ) 140 | { 141 | srcFormat = GL_RGB; 142 | } 143 | else if ( info_ptr->channels == 4 ) 144 | { 145 | srcFormat = GL_RGBA; 146 | } 147 | else 148 | { 149 | /* Free all of the memory associated with the png_ptr and info_ptr */ 150 | png_destroy_read_struct(&png_ptr, &info_ptr, NULL); 151 | fclose(fp); 152 | /* If we get here, we had a problem reading the file */ 153 | return 0; 154 | } 155 | 156 | const unsigned pixelSize = info_ptr->channels; 157 | const unsigned rowSize = info_ptr->width * pixelSize; 158 | const unsigned size = rowSize * info_ptr->height; 159 | 160 | unsigned char* pixels = new unsigned char[size]; 161 | unsigned char* tmpPixels = pixels; 162 | 163 | for (int y = info_ptr->height-1; y >= 0; --y) 164 | { 165 | memcpy( tmpPixels, info_ptr->row_pointers[y], rowSize ); 166 | tmpPixels += rowSize; 167 | } 168 | 169 | GLuint glTexId = 0; 170 | glGenTextures( 1, &glTexId ); 171 | glBindTexture( GL_TEXTURE_2D, glTexId ); 172 | 173 | glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT ); 174 | glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT ); 175 | glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR ); 176 | glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR ); 177 | 178 | glTexImage2D( GL_TEXTURE_2D, 0, internalFormat, info_ptr->width, info_ptr->height, 0, srcFormat, GL_UNSIGNED_BYTE, pixels ); 179 | 180 | glBindTexture( GL_TEXTURE_2D, 0 ); 181 | 182 | delete[] pixels; 183 | 184 | png_destroy_read_struct(&png_ptr, &info_ptr, NULL); 185 | fclose( fp ); 186 | 187 | return glTexId; 188 | } 189 | -------------------------------------------------------------------------------- /src/liveCodingPreview/util.h: -------------------------------------------------------------------------------- 1 | /******************************************************************************* 2 | * 2005-2014, plastic demoscene group 3 | * authors: misz, bonzaj 4 | *******************************************************************************/ 5 | 6 | #pragma once 7 | 8 | unsigned int getTimeMS(); 9 | 10 | int loadFile( const char* filename, char** dstBuf, size_t* dstBufSize ); 11 | GLuint readTexture( const char* filename ); 12 | -------------------------------------------------------------------------------- /textures/checker.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bonzajplc/LiveCodingFramework/001b78efa3179eb0d94b57a77b74beb3405daabb/textures/checker.png -------------------------------------------------------------------------------- /textures/noise.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bonzajplc/LiveCodingFramework/001b78efa3179eb0d94b57a77b74beb3405daabb/textures/noise.png -------------------------------------------------------------------------------- /textures/splashScreen.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bonzajplc/LiveCodingFramework/001b78efa3179eb0d94b57a77b74beb3405daabb/textures/splashScreen.png -------------------------------------------------------------------------------- /textures/tex1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bonzajplc/LiveCodingFramework/001b78efa3179eb0d94b57a77b74beb3405daabb/textures/tex1.png -------------------------------------------------------------------------------- /textures/tex2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bonzajplc/LiveCodingFramework/001b78efa3179eb0d94b57a77b74beb3405daabb/textures/tex2.png -------------------------------------------------------------------------------- /textures/tex3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bonzajplc/LiveCodingFramework/001b78efa3179eb0d94b57a77b74beb3405daabb/textures/tex3.png -------------------------------------------------------------------------------- /textures/tex4.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bonzajplc/LiveCodingFramework/001b78efa3179eb0d94b57a77b74beb3405daabb/textures/tex4.png -------------------------------------------------------------------------------- /wilhelm.wav: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bonzajplc/LiveCodingFramework/001b78efa3179eb0d94b57a77b74beb3405daabb/wilhelm.wav --------------------------------------------------------------------------------