diff --git a/msvc/projectMSDL.vcxproj b/msvc/projectMSDL.vcxproj
index 1e19a28ae..dcce504f9 100644
--- a/msvc/projectMSDL.vcxproj
+++ b/msvc/projectMSDL.vcxproj
@@ -53,7 +53,7 @@
- $(MSBuildThisFileDirectory)../src\libprojectM;$(MSBuildThisFileDirectory);$(MSBuildThisFileDirectory)../src\libprojectM\Renderer;$(MSBuildThisFileDirectory)../vendor;%(AdditionalIncludeDirectories)
+ $(MSBuildThisFileDirectory)../src\libprojectM;$(MSBuildThisFileDirectory);$(MSBuildThisFileDirectory)../src\libprojectM\Renderer\hlslparser\src;$(MSBuildThisFileDirectory)../src\libprojectM\Renderer;$(MSBuildThisFileDirectory)../vendor;%(AdditionalIncludeDirectories)
Debug/
EnableFastChecks
CompileAsCpp
@@ -97,7 +97,7 @@
- $(MSBuildThisFileDirectory)../src\libprojectM;$(MSBuildThisFileDirectory);$(MSBuildThisFileDirectory)../src\libprojectM\Renderer;$(MSBuildThisFileDirectory)../vendor;%(AdditionalIncludeDirectories)
+ $(MSBuildThisFileDirectory)../src\libprojectM;$(MSBuildThisFileDirectory);$(MSBuildThisFileDirectory)../src\libprojectM\Renderer\hlslparser\src;$(MSBuildThisFileDirectory)../src\libprojectM\Renderer;$(MSBuildThisFileDirectory)../vendor;%(AdditionalIncludeDirectories)
Release/
CompileAsCpp
Sync
diff --git a/src/EyeTune/EyeTune.Shared/EyeTune.Shared.vcxitems b/src/EyeTune/EyeTune.Shared/EyeTune.Shared.vcxitems
index 760e7d02c..8661f3f47 100644
--- a/src/EyeTune/EyeTune.Shared/EyeTune.Shared.vcxitems
+++ b/src/EyeTune/EyeTune.Shared/EyeTune.Shared.vcxitems
@@ -66,6 +66,7 @@
+
CompileAsC
diff --git a/src/libprojectM/Renderer/Makefile.am b/src/libprojectM/Renderer/Makefile.am
index 60a2c2820..982ea4917 100644
--- a/src/libprojectM/Renderer/Makefile.am
+++ b/src/libprojectM/Renderer/Makefile.am
@@ -11,6 +11,7 @@ libRenderer_la_SOURCES = \
Pipeline.cpp \
Renderer.cpp \
ShaderEngine.cpp \
+ StaticGlShaders.cpp \
Texture.cpp \
Waveform.cpp \
Filters.cpp \
@@ -39,6 +40,7 @@ libRenderer_la_SOURCES = \
SOIL2/pvr_helper.h SOIL2/stbi_pkm_c.h\
SOIL2/stb_image.h SOIL2/stbi_pvr.h\
SOIL2/stb_image_write.h SOIL2/stbi_pvr_c.h\
+ StaticGlShaders.h\
hlslparser/src/CodeWriter.cpp hlslparser/src/Engine.h \
hlslparser/src/HLSLParser.h hlslparser/src/HLSLTree.cpp \
hlslparser/src/CodeWriter.h hlslparser/src/GLSLGenerator.cpp \
diff --git a/src/libprojectM/Renderer/ShaderEngine.cpp b/src/libprojectM/Renderer/ShaderEngine.cpp
index ab35a9577..9b461e044 100644
--- a/src/libprojectM/Renderer/ShaderEngine.cpp
+++ b/src/libprojectM/Renderer/ShaderEngine.cpp
@@ -11,398 +11,32 @@
#include "Texture.hpp"
#include "HLSLParser.h"
#include "GLSLGenerator.h"
+#include "StaticGlShaders.h"
#include // glm::mat4
#include // glm::translate, glm::rotate, glm::scale, glm::perspective
#include
#include
#include
-#ifdef USE_GLES
- #define GLSL_VERSION "300 es"
- #define SHADER_VERSION M4::GLSLGenerator::Version_300_ES
-#else
- #define GLSL_VERSION "330"
- #define SHADER_VERSION M4::GLSLGenerator::Version_330
-#endif
-
-
#define FRAND ((rand() % 7381)/7380.0f)
-
-std::string presetWarpVertexShader(
- "#version "
- GLSL_VERSION
- "\n"
- "layout(location = 0) in vec2 vertex_position;\n"
- "layout(location = 1) in vec4 vertex_color;\n"
- "layout(location = 2) in vec2 vertex_texture;\n"
- ""
- "uniform mat4 vertex_transformation;\n"
- ""
- "out vec4 frag_COLOR;\n"
- "out vec4 frag_TEXCOORD0;\n"
- "out vec2 frag_TEXCOORD1;\n"
- ""
- "void main(){\n"
- " vec4 position = vertex_transformation * vec4(vertex_position, 0.0, 1.0);\n"
- " gl_Position = position;\n"
- " frag_COLOR = vertex_color;\n"
- " frag_TEXCOORD0.xy = vertex_texture;\n"
- " frag_TEXCOORD0.zw = position.xy;\n"
- " frag_TEXCOORD1 = vec2(0.0, 0.0);\n"
- "}\n");
-
-std::string presetCompVertexShader(
- "#version "
- GLSL_VERSION
- "\n"
- "layout(location = 0) in vec2 vertex_position;\n"
- "layout(location = 1) in vec4 vertex_color;\n"
- "layout(location = 2) in vec2 vertex_texture;\n"
- "layout(location = 3) in vec2 vertex_rad_ang;\n"
- ""
- "out vec4 frag_COLOR;\n"
- "out vec2 frag_TEXCOORD0;\n"
- "out vec2 frag_TEXCOORD1;\n"
- ""
- "void main(){\n"
- " vec4 position = vec4(vertex_position, 0.0, 1.0);\n"
- " gl_Position = position;\n"
- " frag_COLOR = vertex_color;\n"
- " frag_TEXCOORD0 = vertex_texture;\n"
- " frag_TEXCOORD1 = vertex_rad_ang;\n"
- "}\n");
-
-
-const std::string ShaderEngine::v2f_c4f_vert(
- "#version "
- GLSL_VERSION
- "\n"
- ""
- "layout(location = 0) in vec2 vertex_position;\n"
- "layout(location = 1) in vec4 vertex_color;\n"
- ""
- "uniform mat4 vertex_transformation;\n"
- "uniform float vertex_point_size;\n"
- ""
- "out vec4 fragment_color;\n"
- ""
- "void main(){\n"
- " gl_Position = vertex_transformation * vec4(vertex_position, 0.0, 1.0);\n"
- " gl_PointSize = vertex_point_size;\n"
- " fragment_color = vertex_color;\n"
- "}\n");
-
-const std::string ShaderEngine::v2f_c4f_frag(
- "#version "
- GLSL_VERSION
- "\n"
- "precision mediump float;\n"
- ""
- "in vec4 fragment_color;\n"
- "out vec4 color;\n"
- ""
- "void main(){\n"
- " color = fragment_color;\n"
- "}\n");
-
-const std::string ShaderEngine::v2f_c4f_t2f_vert(
- "#version "
- GLSL_VERSION
- "\n"
- "layout(location = 0) in vec2 vertex_position;\n"
- "layout(location = 1) in vec4 vertex_color;\n"
- "layout(location = 2) in vec2 vertex_texture;\n"
- ""
- "uniform mat4 vertex_transformation;\n"
- ""
- "out vec4 fragment_color;\n"
- "out vec2 fragment_texture;\n"
- ""
- "void main(){\n"
- " gl_Position = vertex_transformation * vec4(vertex_position, 0.0, 1.0);\n"
- " fragment_color = vertex_color;\n"
- " fragment_texture = vertex_texture;\n"
- "}\n");
-
-const std::string ShaderEngine::v2f_c4f_t2f_frag(
- "#version "
- GLSL_VERSION
- "\n"
- "precision mediump float;\n"
- ""
- "in vec4 fragment_color;\n"
- "in vec2 fragment_texture;\n"
- ""
- "uniform sampler2D texture_sampler;\n"
- ""
- "out vec4 color;\n"
- ""
- "void main(){\n"
- " color = fragment_color * texture(texture_sampler, fragment_texture.st);\n"
- "}\n");
-
-
-std::string PresetShaderIncludes = ""
-"#define M_PI 3.14159265359\n"
-"#define M_PI_2 6.28318530718\n"
-"#define M_INV_PI_2 0.159154943091895\n"
-
-"uniform float4 rand_frame; // random float4, updated each frame\n"
-"uniform float4 rand_preset; // random float4, updated once per *preset*\n"
-"uniform float4 _c0; // .xy: multiplier to use on UV's to paste an image fullscreen, *aspect-aware*; .zw = inverse.\n"
-"uniform float4 _c1, _c2, _c3, _c4;\n"
-"uniform float4 _c5; //.xy = scale,bias for reading blur1; .zw = scale,bias for reading blur2; \n"
-"uniform float4 _c6; //.xy = scale,bias for reading blur3; .zw = blur1_min,blur1_max\n"
-"uniform float4 _c7; // .xy ~= float2(1024,768); .zw ~= float2(1/1024.0, 1/768.0)\n"
-"uniform float4 _c8; // .xyzw ~= 0.5 + 0.5*cos(time * float4(~0.3, ~1.3, ~5, ~20))\n"
-"uniform float4 _c9; // .xyzw ~= same, but using sin()\n"
-"uniform float4 _c10; // .xyzw ~= 0.5 + 0.5*cos(time * float4(~0.005, ~0.008, ~0.013, ~0.022))\n"
-"uniform float4 _c11; // .xyzw ~= same, but using sin()\n"
-"uniform float4 _c12; // .xyz = mip info for main image (.x=#across, .y=#down, .z=avg); .w = unused\n"
-"uniform float4 _c13; //.xy = blur2_min,blur2_max; .zw = blur3_min, blur3_max.\n"
-"uniform float4 _qa; // q vars bank 1 [q1-q4]\n"
-"uniform float4 _qb; // q vars bank 2 [q5-q8]\n"
-"uniform float4 _qc; // q vars ...\n"
-"uniform float4 _qd; // q vars\n"
-"uniform float4 _qe; // q vars\n"
-"uniform float4 _qf; // q vars\n"
-"uniform float4 _qg; // q vars\n"
-"uniform float4 _qh; // q vars bank 8 [q29-q32]\n"
-
-"// note: in general, don't use the current time w/the *dynamic* rotations!\n"
-"uniform float4x3 rot_s1; // four random, static rotations. randomized @ preset load time.\n"
-"uniform float4x3 rot_s2; // minor translation component (<1).\n"
-"uniform float4x3 rot_s3;\n"
-"uniform float4x3 rot_s4;\n"
-
-"uniform float4x3 rot_d1; // four random, slowly changing rotations.\n"
-"uniform float4x3 rot_d2; \n"
-"uniform float4x3 rot_d3;\n"
-"uniform float4x3 rot_d4;\n"
-"uniform float4x3 rot_f1; // faster-changing.\n"
-"uniform float4x3 rot_f2;\n"
-"uniform float4x3 rot_f3;\n"
-"uniform float4x3 rot_f4;\n"
-"uniform float4x3 rot_vf1; // very-fast-changing.\n"
-"uniform float4x3 rot_vf2;\n"
-"uniform float4x3 rot_vf3;\n"
-"uniform float4x3 rot_vf4;\n"
-"uniform float4x3 rot_uf1; // ultra-fast-changing.\n"
-"uniform float4x3 rot_uf2;\n"
-"uniform float4x3 rot_uf3;\n"
-"uniform float4x3 rot_uf4;\n"
-
-"uniform float4x3 rot_rand1; // random every frame\n"
-"uniform float4x3 rot_rand2;\n"
-"uniform float4x3 rot_rand3;\n"
-"uniform float4x3 rot_rand4;\n"
-
-"#define time _c2.x\n"
-"#define fps _c2.y\n"
-"#define frame _c2.z\n"
-"#define progress _c2.w\n"
-"#define bass _c3.x\n"
-"#define mid _c3.y\n"
-"#define treb _c3.z\n"
-"#define vol _c3.w\n"
-"#define bass_att _c4.x\n"
-"#define mid_att _c4.y\n"
-"#define treb_att _c4.z\n"
-"#define vol_att _c4.w\n"
-"#define q1 _qa.x\n"
-"#define q2 _qa.y\n"
-"#define q3 _qa.z\n"
-"#define q4 _qa.w\n"
-"#define q5 _qb.x\n"
-"#define q6 _qb.y\n"
-"#define q7 _qb.z\n"
-"#define q8 _qb.w\n"
-"#define q9 _qc.x\n"
-"#define q10 _qc.y\n"
-"#define q11 _qc.z\n"
-"#define q12 _qc.w\n"
-"#define q13 _qd.x\n"
-"#define q14 _qd.y\n"
-"#define q15 _qd.z\n"
-"#define q16 _qd.w\n"
-"#define q17 _qe.x\n"
-"#define q18 _qe.y\n"
-"#define q19 _qe.z\n"
-"#define q20 _qe.w\n"
-"#define q21 _qf.x\n"
-"#define q22 _qf.y\n"
-"#define q23 _qf.z\n"
-"#define q24 _qf.w\n"
-"#define q25 _qg.x\n"
-"#define q26 _qg.y\n"
-"#define q27 _qg.z\n"
-"#define q28 _qg.w\n"
-"#define q29 _qh.x\n"
-"#define q30 _qh.y\n"
-"#define q31 _qh.z\n"
-"#define q32 _qh.w\n"
-
-"#define aspect _c0\n"
-"#define texsize _c7 // .xy = (w,h); .zw = (1/(float)w, 1/(float)h)\n"
-"#define roam_cos _c8\n"
-"#define roam_sin _c9\n"
-"#define slow_roam_cos _c10\n"
-"#define slow_roam_sin _c11\n"
-"#define mip_x _c12.x\n"
-"#define mip_y _c12.y\n"
-"#define mip_xy _c12.xy\n"
-"#define mip_avg _c12.z\n"
-"#define blur1_min _c6.z\n"
-"#define blur1_max _c6.w\n"
-"#define blur2_min _c13.x\n"
-"#define blur2_max _c13.y\n"
-"#define blur3_min _c13.z\n"
-"#define blur3_max _c13.w\n"
-
-"#define sampler_FC_main sampler_fc_main\n"
-"#define sampler_PC_main sampler_pc_main\n"
-"#define sampler_FW_main sampler_fw_main\n"
-"#define sampler_PW_main sampler_pw_main\n"
-
-"#define GetMain(uv) (tex2D(sampler_main,uv).xyz)\n"
-"#define GetPixel(uv) (tex2D(sampler_main,uv).xyz)\n"
-"#define GetBlur1(uv) (tex2D(sampler_blur1,uv).xyz*_c5.x + _c5.y)\n"
-"#define GetBlur2(uv) (tex2D(sampler_blur2,uv).xyz*_c5.z + _c5.w)\n"
-"#define GetBlur3(uv) (tex2D(sampler_blur3,uv).xyz*_c6.x + _c6.y)\n"
-
-"#define lum(x) (dot(x,float3(0.32,0.49,0.29)))\n"
-"#define tex2d tex2D\n"
-"#define tex3d tex3D\n"
-;
-
-
-std::string blur_vert(
- "#version "
- GLSL_VERSION
- "\n"
- "layout(location = 0) in vec2 vertex_position;\n"
- "layout(location = 1) in vec2 vertex_texture;\n"
- ""
- "out vec2 fragment_texture;\n"
- ""
- "void main(){\n"
- " gl_Position = vec4(vertex_position, 0.0, 1.0);\n"
- " fragment_texture = vertex_texture;\n"
- "}\n");
-
-
-std::string blur1_frag(
- "#version "
- GLSL_VERSION
- "\n"
- "precision mediump float;\n"
- ""
- "in vec2 fragment_texture;\n"
- ""
- "uniform sampler2D texture_sampler;\n"
- "uniform vec4 _c0; // source texsize (.xy), and inverse (.zw)\n"
- "uniform vec4 _c1; // w1..w4\n"
- "uniform vec4 _c2; // d1..d4\n"
- "uniform vec4 _c3; // scale, bias, w_div\n"
- ""
- "out vec4 color;\n"
- ""
- "void main(){\n"
- ""
- " // LONG HORIZ. PASS 1:\n"
- " #define srctexsize _c0\n"
- " #define w1 _c1.x\n"
- " #define w2 _c1.y\n"
- " #define w3 _c1.z\n"
- " #define w4 _c1.w\n"
- " #define d1 _c2.x\n"
- " #define d2 _c2.y\n"
- " #define d3 _c2.z\n"
- " #define d4 _c2.w\n"
- " #define fscale _c3.x\n"
- " #define fbias _c3.y\n"
- " #define w_div _c3.z\n"
- ""
- " // note: if you just take one sample at exactly uv.xy, you get an avg of 4 pixels.\n"
- " vec2 uv2 = fragment_texture.xy + srctexsize.zw*vec2(1.0,1.0); // + moves blur UP, LEFT by 1-pixel increments\n"
- ""
- " vec3 blur = \n"
- " ( texture( texture_sampler, uv2 + vec2( d1*srctexsize.z,0) ).xyz\n"
- " + texture( texture_sampler, uv2 + vec2(-d1*srctexsize.z,0) ).xyz)*w1 +\n"
- " ( texture( texture_sampler, uv2 + vec2( d2*srctexsize.z,0) ).xyz\n"
- " + texture( texture_sampler, uv2 + vec2(-d2*srctexsize.z,0) ).xyz)*w2 +\n"
- " ( texture( texture_sampler, uv2 + vec2( d3*srctexsize.z,0) ).xyz\n"
- " + texture( texture_sampler, uv2 + vec2(-d3*srctexsize.z,0) ).xyz)*w3 +\n"
- " ( texture( texture_sampler, uv2 + vec2( d4*srctexsize.z,0) ).xyz\n"
- " + texture( texture_sampler, uv2 + vec2(-d4*srctexsize.z,0) ).xyz)*w4\n"
- " ;\n"
- " blur.xyz *= w_div;\n"
- ""
- " blur.xyz = blur.xyz*fscale + fbias;\n"
- ""
- " color.xyz = blur;\n"
- " color.w = 1.0;\n"
- "}\n");
-
-std::string blur2_frag(
- "#version "
- GLSL_VERSION
- "\n"
- "precision mediump float;\n"
- ""
- "in vec2 fragment_texture;\n"
- ""
- "uniform sampler2D texture_sampler;\n"
- "uniform vec4 _c0; // source texsize (.xy), and inverse (.zw)\n"
- "uniform vec4 _c5; // w1,w2,d1,d2\n"
- "uniform vec4 _c6; // w_div, edge_darken_c1, edge_darken_c2, edge_darken_c3\n"
- ""
- "out vec4 color;\n"
- ""
- "void main(){\n"
- ""
- " //SHORT VERTICAL PASS 2:\n"
- " #define srctexsize _c0\n"
- " #define w1 _c5.x\n"
- " #define w2 _c5.y\n"
- " #define d1 _c5.z\n"
- " #define d2 _c5.w\n"
- " #define edge_darken_c1 _c6.y\n"
- " #define edge_darken_c2 _c6.z\n"
- " #define edge_darken_c3 _c6.w\n"
- " #define w_div _c6.x\n"
- ""
- " // note: if you just take one sample at exactly uv.xy, you get an avg of 4 pixels.\n"
- " vec2 uv2 = fragment_texture.xy + srctexsize.zw*vec2(0,0); // + moves blur UP, LEFT by TWO-pixel increments! (since texture is 1/2 the size of blur1_ps)\n"
- ""
- " vec3 blur = \n"
- " ( texture( texture_sampler, uv2 + vec2(0, d1*srctexsize.w) ).xyz\n"
- " + texture( texture_sampler, uv2 + vec2(0,-d1*srctexsize.w) ).xyz)*w1 +\n"
- " ( texture( texture_sampler, uv2 + vec2(0, d2*srctexsize.w) ).xyz\n"
- " + texture( texture_sampler, uv2 + vec2(0,-d2*srctexsize.w) ).xyz)*w2\n"
- " ;\n"
- " blur.xyz *= w_div;\n"
- ""
- " // tone it down at the edges: (only happens on 1st X pass!)\n"
- " float t = min( min(fragment_texture.x, fragment_texture.y), 1.0-max(fragment_texture.x, fragment_texture.y) );\n"
- " t = sqrt(t);\n"
- " t = edge_darken_c1 + edge_darken_c2*clamp(t*edge_darken_c3, 0.0, 1.0);\n"
- " blur.xyz *= t;\n"
- ""
- " color.xyz = blur;\n"
- " color.w = 1.0;\n"
- "}\n");
-
-
-
ShaderEngine::ShaderEngine() : presetCompShaderLoaded(false), presetWarpShaderLoaded(false)
{
- programID_v2f_c4f = CompileShaderProgram(v2f_c4f_vert, v2f_c4f_frag, "v2f_c4f");
- programID_v2f_c4f_t2f = CompileShaderProgram(v2f_c4f_t2f_vert, v2f_c4f_t2f_frag, "v2f_c4f_t2f");
+ std::shared_ptr static_gl_shaders = StaticGlShaders::Get();
- programID_blur1 = CompileShaderProgram(blur_vert, blur1_frag, "blur1");
- programID_blur2 = CompileShaderProgram(blur_vert, blur2_frag, "blur2");
+ programID_v2f_c4f = CompileShaderProgram(
+ static_gl_shaders->GetV2fC4fVertexShader(),
+ static_gl_shaders->GetV2fC4fFragmentShader(), "v2f_c4f");
+ programID_v2f_c4f_t2f = CompileShaderProgram(
+ static_gl_shaders->GetV2fC4fT2fVertexShader(),
+ static_gl_shaders->GetV2fC4fT2fFragmentShader(), "v2f_c4f_t2f");
+
+ programID_blur1 = CompileShaderProgram(
+ static_gl_shaders->GetBlurVertexShader(),
+ static_gl_shaders->GetBlur1FragmentShader(), "blur1");
+ programID_blur2 = CompileShaderProgram(
+ static_gl_shaders->GetBlurVertexShader(),
+ static_gl_shaders->GetBlur2FragmentShader(), "blur2");
uniform_v2f_c4f_vertex_tranformation = glGetUniformLocation(programID_v2f_c4f, "vertex_transformation");
uniform_v2f_c4f_vertex_point_size = glGetUniformLocation(programID_v2f_c4f, "vertex_point_size");
@@ -642,7 +276,7 @@ GLuint ShaderEngine::compilePresetShader(const PresentShaderType shaderType, Sha
std::string fullSource;
// prepend our HLSL template to the actual program source
- fullSource.append(PresetShaderIncludes);
+ fullSource.append(StaticGlShaders::Get()->GetPresetShaderHeader());
if (shaderType == PresentWarpShader) {
fullSource.append( "#define rad _rad_ang.x\n"
@@ -743,7 +377,9 @@ GLuint ShaderEngine::compilePresetShader(const PresentShaderType shaderType, Sha
}
// generate GLSL
- if (!generator.Generate(&tree, M4::GLSLGenerator::Target_FragmentShader, SHADER_VERSION, "PS")) {
+ if (!generator.Generate(&tree, M4::GLSLGenerator::Target_FragmentShader,
+ StaticGlShaders::Get()->GetGlslGeneratorVersion(),
+ "PS")) {
std::cerr << "Failed to transpile HLSL(step3) " << shaderTypeString << " shader to GLSL" << std::endl;
#if !DUMP_SHADERS_ON_ERROR
std::cerr << "Source: " << std::endl << sourcePreprocessed << std::endl;
@@ -755,13 +391,18 @@ GLuint ShaderEngine::compilePresetShader(const PresentShaderType shaderType, Sha
return GL_FALSE;
}
- // now we have GLSL source for the preset shader program (hopefully it's valid!)
- // copmile the preset shader fragment shader with the standard vertex shader and cross our fingers
+ // now we have GLSL source for the preset shader program (hopefully it's
+ // valid!) copmile the preset shader fragment shader with the standard
+ // vertex shader and cross our fingers
GLuint ret = 0;
if (shaderType == PresentWarpShader) {
- ret = CompileShaderProgram(presetWarpVertexShader, generator.GetResult(), shaderTypeString); // returns new program
+ ret = CompileShaderProgram(
+ StaticGlShaders::Get()->GetPresetWarpVertexShader(),
+ generator.GetResult(), shaderTypeString);
} else {
- ret = CompileShaderProgram(presetCompVertexShader, generator.GetResult(), shaderTypeString); // returns new program
+ ret = CompileShaderProgram(
+ StaticGlShaders::Get()->GetPresetCompVertexShader(),
+ generator.GetResult(), shaderTypeString);
}
if (ret != GL_FALSE) {
diff --git a/src/libprojectM/Renderer/StaticGlShaders.cpp b/src/libprojectM/Renderer/StaticGlShaders.cpp
new file mode 100644
index 000000000..7402dcc0e
--- /dev/null
+++ b/src/libprojectM/Renderer/StaticGlShaders.cpp
@@ -0,0 +1,821 @@
+#include "StaticGlShaders.h"
+#include "projectM-opengl.h"
+
+namespace {
+// Variants of shaders for GLSL1.2
+const std::string kPresetWarpVertexShaderGlsl120 = R"(
+attribute vec2 vertex_position;
+attribute vec4 vertex_color;
+attribute vec2 vertex_texture;
+
+uniform mat4 vertex_transformation;
+
+varying vec4 frag_COLOR;
+varying vec4 frag_TEXCOORD0;
+varying vec2 frag_TEXCOORD1;
+
+void main(){
+ vec4 position = vertex_transformation * vec4(vertex_position, 0.0, 1.0);
+ gl_Position = position;
+ frag_COLOR = vertex_color;
+ frag_TEXCOORD0.xy = vertex_texture;
+ frag_TEXCOORD0.zw = position.xy;
+ frag_TEXCOORD1 = vec2(0.0, 0.0);
+}
+)";
+
+const std::string kPresetCompVertexShaderGlsl120 = R"(
+attribute vec2 vertex_position;
+attribute vec4 vertex_color;
+attribute vec2 vertex_texture;
+attribute vec2 vertex_rad_ang;
+
+varying vec4 frag_COLOR;
+varying vec2 frag_TEXCOORD0;
+varying vec2 frag_TEXCOORD1;
+
+void main(){
+ vec4 position = vec4(vertex_position, 0.0, 1.0);
+ gl_Position = position;
+ frag_COLOR = vertex_color;
+ frag_TEXCOORD0 = vertex_texture;
+ frag_TEXCOORD1 = vertex_rad_ang;
+}
+)";
+
+const std::string kV2fC4fVertexShaderGlsl120 = R"(
+attribute vec2 vertex_position;
+attribute vec4 vertex_color;
+
+uniform mat4 vertex_transformation;
+uniform float vertex_point_size;
+
+varying vec4 fragment_color;
+
+void main(){
+ gl_Position = vertex_transformation * vec4(vertex_position, 0.0, 1.0);
+ gl_PointSize = vertex_point_size;
+ fragment_color = vertex_color;
+}
+)";
+
+const std::string kV2fC4fFragmentShaderGlsl120 = R"(
+varying vec4 fragment_color;
+
+void main(){
+ gl_FragColor = fragment_color;
+}
+)";
+
+const std::string kV2fC4fT2fVertexShaderGlsl120 = R"(
+attribute vec2 vertex_position;
+attribute vec4 vertex_color;
+attribute vec2 vertex_texture;
+
+uniform mat4 vertex_transformation;
+
+varying vec4 fragment_color;
+varying vec2 fragment_texture;
+
+void main(){
+ gl_Position = vertex_transformation * vec4(vertex_position, 0.0, 1.0);
+ fragment_color = vertex_color;
+ fragment_texture = vertex_texture;
+}
+)";
+
+const std::string kV2fC4fT2fFragmentShaderGlsl120 = R"(
+varying vec4 fragment_color;
+varying vec2 fragment_texture;
+
+uniform sampler2D texture_sampler;
+
+varying vec4 color;
+
+void main(){
+ gl_FragColor = fragment_color * texture2D(texture_sampler,
+ fragment_texture.st);
+}
+)";
+
+const std::string kPresetShaderHeaderGlsl120 = R"(
+#define M_PI 3.14159265359
+#define M_PI_2 6.28318530718
+#define M_INV_PI_2 0.159154943091895
+
+uniform float4 rand_frame; // random float4, updated each frame
+uniform float4 rand_preset; // random float4, updated once per *preset*
+uniform float4 _c0; // .xy: multiplier to use on UV's to paste
+ // an image fullscreen, *aspect-aware*
+ // .zw = inverse.
+uniform float4 _c1, _c2, _c3, _c4;
+uniform float4 _c5; // .xy = scale, bias for reading blur1
+ // .zw = scale, bias for reading blur2
+uniform float4 _c6; // .xy = scale, bias for reading blur3
+ // .zw = blur1_min, blur1_max
+uniform float4 _c7; // .xy ~= float2(1024,768)
+ // .zw ~= float2(1/1024.0, 1/768.0)
+uniform float4 _c8; // .xyzw ~= 0.5 + 0.5 * cos(
+ // time * float4(~0.3, ~1.3, ~5, ~20))
+uniform float4 _c9; // .xyzw ~= same, but using sin()
+uniform float4 _c10; // .xyzw ~= 0.5 + 0.5 * cos(
+ // time * float4(~0.005, ~0.008, ~0.013,
+ // ~0.022))
+uniform float4 _c11; // .xyzw ~= same, but using sin()
+uniform float4 _c12; // .xyz = mip info for main image
+ // (.x=#across, .y=#down, .z=avg)
+ // .w = unused
+uniform float4 _c13; // .xy = blur2_min, blur2_max
+ // .zw = blur3_min, blur3_max
+uniform float4 _qa; // q vars bank 1 [q1-q4]
+uniform float4 _qb; // q vars bank 2 [q5-q8]
+uniform float4 _qc; // q vars ...
+uniform float4 _qd; // q vars
+uniform float4 _qe; // q vars
+uniform float4 _qf; // q vars
+uniform float4 _qg; // q vars
+uniform float4 _qh; // q vars bank 8 [q29-q32]
+
+// note: in general, don't use the current time w/the *dynamic* rotations!
+
+// four random, static rotations, randomized at preset load time.
+// minor translation component (<1).
+uniform float4x3 rot_s1;
+uniform float4x3 rot_s2;
+uniform float4x3 rot_s3;
+uniform float4x3 rot_s4;
+
+// four random, slowly changing rotations.
+uniform float4x3 rot_d1;
+uniform float4x3 rot_d2;
+uniform float4x3 rot_d3;
+uniform float4x3 rot_d4;
+
+// faster-changing.
+uniform float4x3 rot_f1;
+uniform float4x3 rot_f2;
+uniform float4x3 rot_f3;
+uniform float4x3 rot_f4;
+
+// very-fast-changing.
+uniform float4x3 rot_vf1;
+uniform float4x3 rot_vf2;
+uniform float4x3 rot_vf3;
+uniform float4x3 rot_vf4;
+
+// ultra-fast-changing.
+uniform float4x3 rot_uf1;
+uniform float4x3 rot_uf2;
+uniform float4x3 rot_uf3;
+uniform float4x3 rot_uf4;
+
+// Random every frame.
+uniform float4x3 rot_rand1;
+uniform float4x3 rot_rand2;
+uniform float4x3 rot_rand3;
+uniform float4x3 rot_rand4;
+
+#define time _c2.x
+#define fps _c2.y
+#define frame _c2.z
+#define progress _c2.w
+#define bass _c3.x
+#define mid _c3.y
+#define treb _c3.z
+#define vol _c3.w
+#define bass_att _c4.x
+#define mid_att _c4.y
+#define treb_att _c4.z
+#define vol_att _c4.w
+#define q1 _qa.x
+#define q2 _qa.y
+#define q3 _qa.z
+#define q4 _qa.w
+#define q5 _qb.x
+#define q6 _qb.y
+#define q7 _qb.z
+#define q8 _qb.w
+#define q9 _qc.x
+#define q10 _qc.y
+#define q11 _qc.z
+#define q12 _qc.w
+#define q13 _qd.x
+#define q14 _qd.y
+#define q15 _qd.z
+#define q16 _qd.w
+#define q17 _qe.x
+#define q18 _qe.y
+#define q19 _qe.z
+#define q20 _qe.w
+#define q21 _qf.x
+#define q22 _qf.y
+#define q23 _qf.z
+#define q24 _qf.w
+#define q25 _qg.x
+#define q26 _qg.y
+#define q27 _qg.z
+#define q28 _qg.w
+#define q29 _qh.x
+#define q30 _qh.y
+#define q31 _qh.z
+#define q32 _qh.w
+
+#define aspect _c0
+
+// .xy = (w,h); .zw = (1/(float)w, 1/(float)h)
+#define texsize _c7
+
+#define roam_cos _c8
+#define roam_sin _c9
+#define slow_roam_cos _c10
+#define slow_roam_sin _c11
+#define mip_x _c12.x
+#define mip_y _c12.y
+#define mip_xy _c12.xy
+#define mip_avg _c12.z
+#define blur1_min _c6.z
+#define blur1_max _c6.w
+#define blur2_min _c13.x
+#define blur2_max _c13.y
+#define blur3_min _c13.z
+#define blur3_max _c13.w
+
+#define sampler_FC_main sampler_fc_main
+#define sampler_PC_main sampler_pc_main
+#define sampler_FW_main sampler_fw_main
+#define sampler_PW_main sampler_pw_main
+
+#define GetMain(uv) (tex2D(sampler_main,uv).xyz)
+#define GetPixel(uv) (tex2D(sampler_main,uv).xyz)
+#define GetBlur1(uv) (tex2D(sampler_blur1,uv).xyz*_c5.x + _c5.y)
+#define GetBlur2(uv) (tex2D(sampler_blur2,uv).xyz*_c5.z + _c5.w)
+#define GetBlur3(uv) (tex2D(sampler_blur3,uv).xyz*_c6.x + _c6.y)
+
+#define lum(x) (dot(x,float3(0.32,0.49,0.29)))
+#define tex2d tex2D
+#define tex3d tex3D
+)";
+
+const std::string kBlurVertexShaderGlsl120 = R"(
+attribute vec2 vertex_position;
+attribute vec2 vertex_texture;
+
+varying vec2 fragment_texture;
+
+void main(){
+ gl_Position = vec4(vertex_position, 0.0, 1.0);
+ fragment_texture = vertex_texture;
+}
+)";
+
+std::string kBlur1FragmentShaderGlsl120 = R"(
+varying vec2 fragment_texture;
+
+uniform sampler2D texture_sampler;
+uniform vec4 _c0; // source texsize (.xy), and inverse (.zw)
+uniform vec4 _c1; // w1..w4
+uniform vec4 _c2; // d1..d4
+uniform vec4 _c3; // scale, bias, w_div
+
+void main(){
+ // LONG HORIZ. PASS 1:
+ #define srctexsize _c0
+ #define w1 _c1.x
+ #define w2 _c1.y
+ #define w3 _c1.z
+ #define w4 _c1.w
+ #define d1 _c2.x
+ #define d2 _c2.y
+ #define d3 _c2.z
+ #define d4 _c2.w
+ #define fscale _c3.x
+ #define fbias _c3.y
+ #define w_div _c3.z
+
+ // note: if you just take one sample at exactly uv.xy, you get an avg of 4
+ // pixels.
+
+ // + moves blur UP, LEFT by 1-pixel increments
+ vec2 uv2 = fragment_texture.xy + srctexsize.zw*vec2(1.0,1.0);
+
+ vec3 blur =
+ (texture2D(texture_sampler, uv2 + vec2(d1 * srctexsize.z, 0)).xyz +
+ texture2D(texture_sampler, uv2 + vec2(-d1 * srctexsize.z, 0)).xyz) *
+ w1 +
+ (texture2D(texture_sampler, uv2 + vec2(d2 * srctexsize.z, 0)).xyz +
+ texture2D(texture_sampler, uv2 + vec2(-d2 * srctexsize.z, 0)).xyz) *
+ w2 +
+ (texture2D(texture_sampler, uv2 + vec2(d3 * srctexsize.z, 0)).xyz +
+ texture2D(texture_sampler, uv2 + vec2(-d3 * srctexsize.z, 0)).xyz) *
+ w3 +
+ (texture2D(texture_sampler, uv2 + vec2(d4 * srctexsize.z, 0)).xyz +
+ texture2D(texture_sampler, uv2 + vec2(-d4 * srctexsize.z, 0)).xyz) *
+ w4;
+
+ blur.xyz *= w_div;
+
+ blur.xyz = blur.xyz*fscale + fbias;
+
+ gl_FragColor.xyz = blur;
+ gl_FragColor.w = 1.0;
+}
+)";
+
+std::string kBlur2FragmentShaderGlsl120 = R"(
+varying vec2 fragment_texture;
+
+uniform sampler2D texture_sampler;
+uniform vec4 _c0; // source texsize (.xy), and inverse (.zw)
+uniform vec4 _c5; // w1,w2,d1,d2
+uniform vec4 _c6; // w_div, edge_darken_c1, edge_darken_c2, edge_darken_c3
+
+void main(){
+ // SHORT VERTICAL PASS 2:
+ #define srctexsize _c0
+ #define w1 _c5.x
+ #define w2 _c5.y
+ #define d1 _c5.z
+ #define d2 _c5.w
+ #define edge_darken_c1 _c6.y
+ #define edge_darken_c2 _c6.z
+ #define edge_darken_c3 _c6.w
+ #define w_div _c6.x
+
+ // note: if you just take one sample at exactly uv.xy, you get an avg of 4
+ // pixels.
+
+ // + moves blur UP, LEFT by TWO-pixel increments! (since texture is 1/2 the
+ // size of blur1_ps)
+ vec2 uv2 = fragment_texture.xy + srctexsize.zw*vec2(0,0);
+
+ vec3 blur =
+ (texture2D(texture_sampler, uv2 + vec2(0, d1 * srctexsize.w)).xyz +
+ texture2D(texture_sampler, uv2 + vec2(0, -d1 * srctexsize.w)).xyz) *
+ w1 +
+ (texture2D(texture_sampler, uv2 + vec2(0, d2 * srctexsize.w)).xyz +
+ texture2D(texture_sampler, uv2 + vec2(0, -d2 * srctexsize.w)).xyz) *
+ w2;
+ blur.xyz *= w_div;
+
+ // tone it down at the edges (only happens on 1st X pass!)
+ float t = min(min(fragment_texture.x, fragment_texture.y),
+ 1.0 - max(fragment_texture.x, fragment_texture.y));
+ t = sqrt(t);
+ t = edge_darken_c1 + edge_darken_c2 * clamp(t * edge_darken_c3, 0.0, 1.0);
+ blur.xyz *= t;
+
+ gl_FragColor.xyz = blur;
+ gl_FragColor.w = 1.0;
+}
+)";
+
+// Variants of shaders for GLSL3.3
+const std::string kPresetWarpVertexShaderGlsl330 = R"(
+layout(location = 0) in vec2 vertex_position;
+layout(location = 1) in vec4 vertex_color;
+layout(location = 2) in vec2 vertex_texture;
+
+uniform mat4 vertex_transformation;
+
+out vec4 frag_COLOR;
+out vec4 frag_TEXCOORD0;
+out vec2 frag_TEXCOORD1;
+
+void main(){
+ vec4 position = vertex_transformation * vec4(vertex_position, 0.0, 1.0);
+ gl_Position = position;
+ frag_COLOR = vertex_color;
+ frag_TEXCOORD0.xy = vertex_texture;
+ frag_TEXCOORD0.zw = position.xy;
+ frag_TEXCOORD1 = vec2(0.0, 0.0);
+}
+)";
+
+const std::string kPresetCompVertexShaderGlsl330 = R"(
+layout(location = 0) in vec2 vertex_position;
+layout(location = 1) in vec4 vertex_color;
+layout(location = 2) in vec2 vertex_texture;
+layout(location = 3) in vec2 vertex_rad_ang;
+
+out vec4 frag_COLOR;
+out vec2 frag_TEXCOORD0;
+out vec2 frag_TEXCOORD1;
+
+void main(){
+ vec4 position = vec4(vertex_position, 0.0, 1.0);
+ gl_Position = position;
+ frag_COLOR = vertex_color;
+ frag_TEXCOORD0 = vertex_texture;
+ frag_TEXCOORD1 = vertex_rad_ang;
+}
+)";
+
+const std::string kV2fC4fVertexShaderGlsl330 = R"(
+layout(location = 0) in vec2 vertex_position;
+layout(location = 1) in vec4 vertex_color;
+
+uniform mat4 vertex_transformation;
+uniform float vertex_point_size;
+
+out vec4 fragment_color;
+
+void main(){
+ gl_Position = vertex_transformation * vec4(vertex_position, 0.0, 1.0);
+ gl_PointSize = vertex_point_size;
+ fragment_color = vertex_color;
+}
+)";
+
+const std::string kV2fC4fFragmentShaderGlsl330 = R"(
+precision mediump float;
+
+in vec4 fragment_color;
+out vec4 color;
+
+void main(){
+ color = fragment_color;
+}
+)";
+
+const std::string kV2fC4fT2fVertexShaderGlsl330 = R"(
+layout(location = 0) in vec2 vertex_position;
+layout(location = 1) in vec4 vertex_color;
+layout(location = 2) in vec2 vertex_texture;
+
+uniform mat4 vertex_transformation;
+
+out vec4 fragment_color;
+out vec2 fragment_texture;
+
+void main(){
+ gl_Position = vertex_transformation * vec4(vertex_position, 0.0, 1.0);
+ fragment_color = vertex_color;
+ fragment_texture = vertex_texture;
+}
+)";
+
+const std::string kV2fC4fT2fFragmentShaderGlsl330 = R"(
+precision mediump float;
+
+in vec4 fragment_color;
+in vec2 fragment_texture;
+
+uniform sampler2D texture_sampler;
+
+out vec4 color;
+
+void main(){
+ color = fragment_color * texture2D(texture_sampler, fragment_texture.st);
+}
+)";
+
+const std::string kPresetShaderHeaderGlsl330 = R"(
+#define M_PI 3.14159265359
+#define M_PI_2 6.28318530718
+#define M_INV_PI_2 0.159154943091895
+
+uniform float4 rand_frame; // random float4, updated each frame
+uniform float4 rand_preset; // random float4, updated once per *preset*
+uniform float4 _c0; // .xy: multiplier to use on UV's to paste
+ // an image fullscreen, *aspect-aware*
+ // .zw = inverse.
+uniform float4 _c1, _c2, _c3, _c4;
+uniform float4 _c5; // .xy = scale, bias for reading blur1
+ // .zw = scale, bias for reading blur2
+uniform float4 _c6; // .xy = scale, bias for reading blur3
+ // .zw = blur1_min, blur1_max
+uniform float4 _c7; // .xy ~= float2(1024,768)
+ // .zw ~= float2(1/1024.0, 1/768.0)
+uniform float4 _c8; // .xyzw ~= 0.5 + 0.5 * cos(
+ // time * float4(~0.3, ~1.3, ~5, ~20))
+uniform float4 _c9; // .xyzw ~= same, but using sin()
+uniform float4 _c10; // .xyzw ~= 0.5 + 0.5 * cos(
+ // time * float4(~0.005, ~0.008, ~0.013,
+ // ~0.022))
+uniform float4 _c11; // .xyzw ~= same, but using sin()
+uniform float4 _c12; // .xyz = mip info for main image
+ // (.x=#across, .y=#down, .z=avg)
+ // .w = unused
+uniform float4 _c13; // .xy = blur2_min, blur2_max
+ // .zw = blur3_min, blur3_max
+uniform float4 _qa; // q vars bank 1 [q1-q4]
+uniform float4 _qb; // q vars bank 2 [q5-q8]
+uniform float4 _qc; // q vars ...
+uniform float4 _qd; // q vars
+uniform float4 _qe; // q vars
+uniform float4 _qf; // q vars
+uniform float4 _qg; // q vars
+uniform float4 _qh; // q vars bank 8 [q29-q32]
+
+// note: in general, don't use the current time w/the *dynamic* rotations!
+
+// four random, static rotations, randomized at preset load time.
+// minor translation component (<1).
+uniform float4x3 rot_s1;
+uniform float4x3 rot_s2;
+uniform float4x3 rot_s3;
+uniform float4x3 rot_s4;
+
+// four random, slowly changing rotations.
+uniform float4x3 rot_d1;
+uniform float4x3 rot_d2;
+uniform float4x3 rot_d3;
+uniform float4x3 rot_d4;
+
+// faster-changing.
+uniform float4x3 rot_f1;
+uniform float4x3 rot_f2;
+uniform float4x3 rot_f3;
+uniform float4x3 rot_f4;
+
+// very-fast-changing.
+uniform float4x3 rot_vf1;
+uniform float4x3 rot_vf2;
+uniform float4x3 rot_vf3;
+uniform float4x3 rot_vf4;
+
+// ultra-fast-changing.
+uniform float4x3 rot_uf1;
+uniform float4x3 rot_uf2;
+uniform float4x3 rot_uf3;
+uniform float4x3 rot_uf4;
+
+// Random every frame.
+uniform float4x3 rot_rand1;
+uniform float4x3 rot_rand2;
+uniform float4x3 rot_rand3;
+uniform float4x3 rot_rand4;
+
+#define time _c2.x
+#define fps _c2.y
+#define frame _c2.z
+#define progress _c2.w
+#define bass _c3.x
+#define mid _c3.y
+#define treb _c3.z
+#define vol _c3.w
+#define bass_att _c4.x
+#define mid_att _c4.y
+#define treb_att _c4.z
+#define vol_att _c4.w
+#define q1 _qa.x
+#define q2 _qa.y
+#define q3 _qa.z
+#define q4 _qa.w
+#define q5 _qb.x
+#define q6 _qb.y
+#define q7 _qb.z
+#define q8 _qb.w
+#define q9 _qc.x
+#define q10 _qc.y
+#define q11 _qc.z
+#define q12 _qc.w
+#define q13 _qd.x
+#define q14 _qd.y
+#define q15 _qd.z
+#define q16 _qd.w
+#define q17 _qe.x
+#define q18 _qe.y
+#define q19 _qe.z
+#define q20 _qe.w
+#define q21 _qf.x
+#define q22 _qf.y
+#define q23 _qf.z
+#define q24 _qf.w
+#define q25 _qg.x
+#define q26 _qg.y
+#define q27 _qg.z
+#define q28 _qg.w
+#define q29 _qh.x
+#define q30 _qh.y
+#define q31 _qh.z
+#define q32 _qh.w
+
+#define aspect _c0
+
+// .xy = (w,h); .zw = (1/(float)w, 1/(float)h)
+#define texsize _c7
+
+#define roam_cos _c8
+#define roam_sin _c9
+#define slow_roam_cos _c10
+#define slow_roam_sin _c11
+#define mip_x _c12.x
+#define mip_y _c12.y
+#define mip_xy _c12.xy
+#define mip_avg _c12.z
+#define blur1_min _c6.z
+#define blur1_max _c6.w
+#define blur2_min _c13.x
+#define blur2_max _c13.y
+#define blur3_min _c13.z
+#define blur3_max _c13.w
+
+#define sampler_FC_main sampler_fc_main
+#define sampler_PC_main sampler_pc_main
+#define sampler_FW_main sampler_fw_main
+#define sampler_PW_main sampler_pw_main
+
+#define GetMain(uv) (tex2D(sampler_main,uv).xyz)
+#define GetPixel(uv) (tex2D(sampler_main,uv).xyz)
+#define GetBlur1(uv) (tex2D(sampler_blur1,uv).xyz*_c5.x + _c5.y)
+#define GetBlur2(uv) (tex2D(sampler_blur2,uv).xyz*_c5.z + _c5.w)
+#define GetBlur3(uv) (tex2D(sampler_blur3,uv).xyz*_c6.x + _c6.y)
+
+#define lum(x) (dot(x,float3(0.32,0.49,0.29)))
+#define tex2d tex2D
+#define tex3d tex3D
+)";
+
+const std::string kBlurVertexShaderGlsl330 = R"(
+layout(location = 0) in vec2 vertex_position;
+layout(location = 1) in vec2 vertex_texture;
+
+out vec2 fragment_texture;
+
+void main(){
+ gl_Position = vec4(vertex_position, 0.0, 1.0);
+ fragment_texture = vertex_texture;
+}
+)";
+
+std::string kBlur1FragmentShaderGlsl330 = R"(
+precision mediump float;
+
+in vec2 fragment_texture;
+
+uniform sampler2D texture_sampler;
+uniform vec4 _c0; // source texsize (.xy), and inverse (.zw)
+uniform vec4 _c1; // w1..w4
+uniform vec4 _c2; // d1..d4
+uniform vec4 _c3; // scale, bias, w_div
+
+out vec4 color;
+
+void main(){
+ // LONG HORIZ. PASS 1:
+ #define srctexsize _c0
+ #define w1 _c1.x
+ #define w2 _c1.y
+ #define w3 _c1.z
+ #define w4 _c1.w
+ #define d1 _c2.x
+ #define d2 _c2.y
+ #define d3 _c2.z
+ #define d4 _c2.w
+ #define fscale _c3.x
+ #define fbias _c3.y
+ #define w_div _c3.z
+
+ // note: if you just take one sample at exactly uv.xy, you get an avg of 4
+ // pixels.
+
+ // + moves blur UP, LEFT by 1-pixel increments
+ vec2 uv2 = fragment_texture.xy + srctexsize.zw*vec2(1.0,1.0);
+
+ vec3 blur =
+ (texture2D(texture_sampler, uv2 + vec2(d1 * srctexsize.z, 0)).xyz +
+ texture2D(texture_sampler, uv2 + vec2(-d1 * srctexsize.z, 0)).xyz) *
+ w1 +
+ (texture2D(texture_sampler, uv2 + vec2(d2 * srctexsize.z, 0)).xyz +
+ texture2D(texture_sampler, uv2 + vec2(-d2 * srctexsize.z, 0)).xyz) *
+ w2 +
+ (texture2D(texture_sampler, uv2 + vec2(d3 * srctexsize.z, 0)).xyz +
+ texture2D(texture_sampler, uv2 + vec2(-d3 * srctexsize.z, 0)).xyz) *
+ w3 +
+ (texture2D(texture_sampler, uv2 + vec2(d4 * srctexsize.z, 0)).xyz +
+ texture2D(texture_sampler, uv2 + vec2(-d4 * srctexsize.z, 0)).xyz) *
+ w4;
+
+ blur.xyz *= w_div;
+
+ blur.xyz = blur.xyz*fscale + fbias;
+
+ color.xyz = blur;
+ color.w = 1.0;
+}
+)";
+
+std::string kBlur2FragmentShaderGlsl330 = R"(
+precision mediump float;
+
+in vec2 fragment_texture;
+
+uniform sampler2D texture_sampler;
+uniform vec4 _c0; // source texsize (.xy), and inverse (.zw)
+uniform vec4 _c5; // w1,w2,d1,d2
+uniform vec4 _c6; // w_div, edge_darken_c1, edge_darken_c2, edge_darken_c3
+
+out vec4 color;
+
+void main(){
+ // SHORT VERTICAL PASS 2:
+ #define srctexsize _c0
+ #define w1 _c5.x
+ #define w2 _c5.y
+ #define d1 _c5.z
+ #define d2 _c5.w
+ #define edge_darken_c1 _c6.y
+ #define edge_darken_c2 _c6.z
+ #define edge_darken_c3 _c6.w
+ #define w_div _c6.x
+
+ // note: if you just take one sample at exactly uv.xy, you get an avg of 4
+ // pixels.
+
+ // + moves blur UP, LEFT by TWO-pixel increments! (since texture is 1/2 the
+ // size of blur1_ps)
+ vec2 uv2 = fragment_texture.xy + srctexsize.zw*vec2(0,0);
+
+ vec3 blur =
+ (texture2D(texture_sampler, uv2 + vec2(0, d1 * srctexsize.w)).xyz +
+ texture2D(texture_sampler, uv2 + vec2(0, -d1 * srctexsize.w)).xyz) *
+ w1 +
+ (texture2D(texture_sampler, uv2 + vec2(0, d2 * srctexsize.w)).xyz +
+ texture2D(texture_sampler, uv2 + vec2(0, -d2 * srctexsize.w)).xyz) *
+ w2;
+ blur.xyz *= w_div;
+
+ // tone it down at the edges (only happens on 1st X pass!)
+ float t = min(min(fragment_texture.x, fragment_texture.y),
+ 1.0 - max(fragment_texture.x, fragment_texture.y));
+ t = sqrt(t);
+ t = edge_darken_c1 + edge_darken_c2 * clamp(t * edge_darken_c3, 0.0, 1.0);
+ blur.xyz *= t;
+
+ color.xyz = blur;
+ color.w = 1.0;
+}
+)";
+
+} // namespace
+
+StaticGlShaders::StaticGlShaders(bool use_gles) : use_gles_(use_gles) {
+ version_ = QueryGlslVersion();
+
+ if (use_gles_) {
+ // If GLES is specified, override the version header.
+ version_header_ = "#version 300 es";
+ glsl_generator_version_ = M4::GLSLGenerator::Version::Version_300_ES;
+ } else {
+ if (version_.major < 3) {
+ // For all GLSL versions less than 3.*, use the GLSL1.2 shaders.
+ version_header_ = "#version 120";
+ glsl_generator_version_ = M4::GLSLGenerator::Version::Version_120;
+ } else {
+ version_header_ = "#version 330";
+ glsl_generator_version_ = M4::GLSLGenerator::Version::Version_330;
+ }
+ }
+}
+
+StaticGlShaders::GlslVersion StaticGlShaders::QueryGlslVersion() {
+ std::string glsl_version_string = reinterpret_cast(
+ glGetString(GL_SHADING_LANGUAGE_VERSION));
+ size_t dot_location = glsl_version_string.find('.');
+ size_t end_location = glsl_version_string.find(' ');
+ auto major_string = glsl_version_string.substr(0, dot_location);
+ auto minor_string = glsl_version_string.substr(dot_location + 1,
+ end_location - dot_location);
+ int major = std::stoi(major_string);
+ int minor = std::stoi(minor_string);
+
+ return GlslVersion{major, minor};
+}
+
+std::string StaticGlShaders::AddVersionHeader(std::string shader_text) {
+ return version_header_ + "\n" + shader_text;
+}
+
+#define DECLARE_SHADER_ACCESSOR(name) \
+ std::string StaticGlShaders::Get##name() { \
+ if (use_gles_) { \
+ return AddVersionHeader(k##name##Glsl330); \
+ } \
+ if (version_.major < 3) { \
+ return AddVersionHeader(k##name##Glsl120); \
+ } \
+ return AddVersionHeader(k##name##Glsl330); \
+ }
+
+#define DECLARE_SHADER_ACCESSOR_NO_HEADER(name) \
+ std::string StaticGlShaders::Get##name() { \
+ if (use_gles_) { \
+ return k##name##Glsl330; \
+ } \
+ if (version_.major < 3) { \
+ return k##name##Glsl120; \
+ } \
+ return k##name##Glsl330; \
+ }
+
+DECLARE_SHADER_ACCESSOR(PresetWarpVertexShader);
+DECLARE_SHADER_ACCESSOR(PresetCompVertexShader);
+DECLARE_SHADER_ACCESSOR(V2fC4fVertexShader);
+DECLARE_SHADER_ACCESSOR(V2fC4fFragmentShader);
+DECLARE_SHADER_ACCESSOR(V2fC4fT2fVertexShader);
+DECLARE_SHADER_ACCESSOR(V2fC4fT2fFragmentShader);
+DECLARE_SHADER_ACCESSOR(BlurVertexShader);
+DECLARE_SHADER_ACCESSOR(Blur1FragmentShader);
+DECLARE_SHADER_ACCESSOR(Blur2FragmentShader);
+DECLARE_SHADER_ACCESSOR_NO_HEADER(PresetShaderHeader);
diff --git a/src/libprojectM/Renderer/StaticGlShaders.h b/src/libprojectM/Renderer/StaticGlShaders.h
new file mode 100644
index 000000000..8500dce8a
--- /dev/null
+++ b/src/libprojectM/Renderer/StaticGlShaders.h
@@ -0,0 +1,72 @@
+#include
+
+#include "GLSLGenerator.h"
+
+// Singleton manager for static resource GL shaders. The manager provides
+// shaders through its accessor methods, and selects the appropriate shader
+// version to be compatible with the system GLSL version.
+class StaticGlShaders {
+ public:
+ // Returns the singleton StaticGlShaders instance.
+ static std::shared_ptr Get() {
+ bool use_gles = false;
+#ifdef USE_GLES
+ use_gles = true;
+#endif
+
+ static std::shared_ptr instance(
+ new StaticGlShaders(use_gles));
+
+ return instance;
+ }
+
+ // Returns the GLSLGenerator version enum value corresponding to the queried
+ // OpenGL shader version.
+ M4::GLSLGenerator::Version GetGlslGeneratorVersion() {
+ return glsl_generator_version_;
+ }
+
+ // Returns the named static GL shader resource.
+ std::string GetPresetWarpVertexShader();
+ std::string GetPresetCompVertexShader();
+ std::string GetV2fC4fVertexShader();
+ std::string GetV2fC4fFragmentShader();
+ std::string GetV2fC4fT2fVertexShader();
+ std::string GetV2fC4fT2fFragmentShader();
+ std::string GetBlurVertexShader();
+ std::string GetBlur1FragmentShader();
+ std::string GetBlur2FragmentShader();
+ std::string GetPresetShaderHeader();
+
+ private:
+ // POD struct to store parsed GLSL version numbers.
+ struct GlslVersion {
+ int major, minor;
+ };
+
+ // Constructs a StaticGlShaders, overriding the version to GLES3 if
+ // `use_gles` is true.
+ StaticGlShaders(bool use_gles);
+
+ // Queries the system GLSL version using
+ // `glGetString(GL_SHADING_LANGUAGE_VERSION)` and returns the major and
+ // minor numbers.
+ GlslVersion QueryGlslVersion();
+
+ // Prepends a string of the form "#version \n" to the provided
+ // shader text, where is derived from the queried GLSL version (or
+ // overridden when the manager was constructed with `use_gles` = true).
+ std::string AddVersionHeader(std::string shader_text);
+
+ // Whether or not to use GLES shaders.
+ bool use_gles_;
+
+ // The queried GLSL version.
+ GlslVersion version_;
+
+ // The version header to prepended by AddVersionHeader.
+ std::string version_header_;
+
+ // The GLSL generator version to pass to the hlslparser generator.
+ M4::GLSLGenerator::Version glsl_generator_version_;
+};
diff --git a/src/libprojectM/Renderer/hlslparser/src/GLSLGenerator.cpp b/src/libprojectM/Renderer/hlslparser/src/GLSLGenerator.cpp
index aa55b8434..3e6b3e3bc 100755
--- a/src/libprojectM/Renderer/hlslparser/src/GLSLGenerator.cpp
+++ b/src/libprojectM/Renderer/hlslparser/src/GLSLGenerator.cpp
@@ -133,6 +133,7 @@ GLSLGenerator::GLSLGenerator() :
m_scalarSwizzle4Function[0] = 0;
m_sinCosFunction[0] = 0;
m_bvecTernary[ 0 ] = 0;
+ m_modfFunction[0] = 0;
m_outputPosition = false;
m_outputTargets = 0;
}
@@ -144,7 +145,7 @@ bool GLSLGenerator::Generate(HLSLTree* tree, Target target, Version version, con
m_entryName = entryName;
m_target = target;
m_version = version;
- m_versionLegacy = (version == Version_110 || version == Version_100_ES);
+ m_versionLegacy = (version == Version_110 || version == Version_120 || version == Version_100_ES);
m_options = options;
globalVarsAssignments.clear();
@@ -159,6 +160,7 @@ bool GLSLGenerator::Generate(HLSLTree* tree, Target target, Version version, con
ChooseUniqueName("tex3Dlod", m_tex3DlodFunction, sizeof(m_tex3DlodFunction));
ChooseUniqueName("texCUBEbias", m_texCUBEbiasFunction, sizeof(m_texCUBEbiasFunction));
ChooseUniqueName( "texCUBElod", m_texCUBElodFunction, sizeof( m_texCUBElodFunction ) );
+ ChooseUniqueName( "modf", m_modfFunction, sizeof( m_modfFunction ) );
for (int i = 0; i < s_numReservedWords; ++i)
{
@@ -201,6 +203,10 @@ bool GLSLGenerator::Generate(HLSLTree* tree, Target target, Version version, con
{
m_writer.WriteLine(0, "#version 110");
}
+ if (m_version == Version_120)
+ {
+ m_writer.WriteLine(0, "#version 120");
+ }
else if (m_version == Version_140)
{
m_writer.WriteLine(0, "#version 140");
@@ -244,7 +250,7 @@ bool GLSLGenerator::Generate(HLSLTree* tree, Target target, Version version, con
m_writer.WriteLine(0, "vec4 %s(mat4 m, int i) { return vec4( m[0][i], m[1][i], m[2][i], m[3][i] ); }", m_matrixRowFunction);
// Output the special function used to do matrix cast for OpenGL 2.0
- if (m_version == Version_110)
+ if (m_versionLegacy)
{
m_writer.WriteLine(0, "mat3 %s(mat4 m) { return mat3(m[0][0], m[0][1], m[0][2], m[1][0], m[1][1], m[1][2], m[2][0], m[2][1], m[2][2]); }", m_matrixCtorFunction);
}
@@ -276,7 +282,7 @@ bool GLSLGenerator::Generate(HLSLTree* tree, Target target, Version version, con
{
const char* function = "textureLod";
- if (m_version == Version_110)
+ if (m_versionLegacy)
{
m_writer.WriteLine(0, "#extension GL_ARB_shader_texture_lod : require");
function = "texture2DLod";
@@ -295,7 +301,7 @@ bool GLSLGenerator::Generate(HLSLTree* tree, Target target, Version version, con
{
const char* function = "textureGrad";
- if (m_version == Version_110)
+ if (m_versionLegacy)
{
m_writer.WriteLine(0, "#extension GL_ARB_shader_texture_lod : require");
function = "texture2DGradARB";
@@ -356,7 +362,7 @@ bool GLSLGenerator::Generate(HLSLTree* tree, Target target, Version version, con
{
const char* function = "textureLod";
- if (m_version == Version_110)
+ if (m_version == Version_110 || m_version == Version_120)
{
m_writer.WriteLine(0, "#extension GL_ARB_shader_texture_lod : require");
function = "textureCubeLod";
@@ -370,6 +376,16 @@ bool GLSLGenerator::Generate(HLSLTree* tree, Target target, Version version, con
m_writer.WriteLine( 0, "vec4 %s(samplerCube samp, vec4 texCoord) { return %s(samp, texCoord.xyz, texCoord.w); }", m_texCUBElodFunction, function);
}
+ if (m_tree->NeedsFunction("modf"))
+ {
+ if (m_version == Version_110 || m_version == Version_120 || m_version == Version_100_ES)
+ {
+ m_writer.WriteLine(0, "float %s(float x, out int ip) { ip = int(x); return x - ip; }", m_modfFunction);
+ } else {
+ m_writer.WriteLine(0, "float %s(float x, out int ip) { return modf(x, ip); }", m_modfFunction);
+ }
+ }
+
m_writer.WriteLine(0, "vec2 %s(float x) { return vec2(x, x); }", m_scalarSwizzle2Function);
m_writer.WriteLine(0, "ivec2 %s(int x) { return ivec2(x, x); }", m_scalarSwizzle2Function);
@@ -676,11 +692,19 @@ void GLSLGenerator::OutputExpression(HLSLExpression* expression, const HLSLType*
default:
ASSERT(0);
}
- m_writer.Write("(");
- OutputExpression(binaryExpression->expression1, dstType1);
- m_writer.Write("%s", op);
- OutputExpression(binaryExpression->expression2, dstType2);
- m_writer.Write(")");
+ if ((m_version == Version_110 || m_version == Version_120 || m_version == Version_100_ES) && binaryExpression->binaryOp == HLSLBinaryOp_Mod) {
+ m_writer.Write("(int(mod(");
+ OutputExpression(binaryExpression->expression1, dstType1);
+ m_writer.Write(",");
+ OutputExpression(binaryExpression->expression2, dstType2);
+ m_writer.Write(")))");
+ } else {
+ m_writer.Write("(");
+ OutputExpression(binaryExpression->expression1, dstType1);
+ m_writer.Write("%s", op);
+ OutputExpression(binaryExpression->expression2, dstType2);
+ m_writer.Write(")");
+ }
}
}
else if (expression->nodeType == HLSLNodeType_ConditionalExpression)
@@ -997,6 +1021,10 @@ void GLSLGenerator::OutputIdentifier(const char* name)
{
name = "dFdy";
}
+ else if (String_Equal(name, "modf"))
+ {
+ name = m_modfFunction;
+ }
else
{
// The identifier could be a GLSL reserved word (if it's not also a HLSL reserved word).
@@ -1958,7 +1986,7 @@ void GLSLGenerator::OutputDeclarationBody( const HLSLType& type, const char* nam
void GLSLGenerator::OutputCast(const HLSLType& type)
{
- if (m_version == Version_110 && type.baseType == HLSLBaseType_Float3x3)
+ if ((m_version == Version_110 || m_version == Version_120) && type.baseType == HLSLBaseType_Float3x3)
m_writer.Write("%s", m_matrixCtorFunction);
else
OutputDeclaration(type, "");
diff --git a/src/libprojectM/Renderer/hlslparser/src/GLSLGenerator.h b/src/libprojectM/Renderer/hlslparser/src/GLSLGenerator.h
index 098425231..6ae5e0007 100755
--- a/src/libprojectM/Renderer/hlslparser/src/GLSLGenerator.h
+++ b/src/libprojectM/Renderer/hlslparser/src/GLSLGenerator.h
@@ -29,6 +29,7 @@ public:
enum Version
{
Version_110, // OpenGL 2.0
+ Version_120, // OpenGL 2.1
Version_140, // OpenGL 3.1
Version_150, // OpenGL 3.2
Version_330, // OpenGL 3.3
@@ -156,6 +157,7 @@ private:
char m_scalarSwizzle4Function[64];
char m_sinCosFunction[64];
char m_bvecTernary[ 64 ];
+ char m_modfFunction[64];
bool m_error;
diff --git a/src/projectM-sdl/Makefile.am b/src/projectM-sdl/Makefile.am
index 976b0aaac..b681c3039 100644
--- a/src/projectM-sdl/Makefile.am
+++ b/src/projectM-sdl/Makefile.am
@@ -3,6 +3,7 @@ ${my_CFLAGS} \
-include $(top_builddir)/config.h \
-DSYSCONFDIR=\""$(sysconfdir)"\" \
-I${top_srcdir}/src/libprojectM \
+-I$(top_srcdir)/src/libprojectM/Renderer/hlslparser/src \
-I${top_srcdir}/src/libprojectM/Renderer \
${SDL_CFLAGS}
diff --git a/src/projectM-sdl/pmSDL.cpp b/src/projectM-sdl/pmSDL.cpp
index 39d09e3b2..b1ebac789 100644
--- a/src/projectM-sdl/pmSDL.cpp
+++ b/src/projectM-sdl/pmSDL.cpp
@@ -32,6 +32,7 @@
#include
#include
#include "Renderer/ShaderEngine.hpp"
+#include "Renderer/StaticGlShaders.h"
void projectMSDL::audioInputCallbackF32(void *userdata, unsigned char *stream, int len) {
@@ -591,7 +592,9 @@ void projectMSDL::init(SDL_Window *window, SDL_GLContext *_glCtx, const bool _re
// are we rendering to a texture?
renderToTexture = _renderToTexture;
if (renderToTexture) {
- programID = ShaderEngine::CompileShaderProgram(ShaderEngine::v2f_c4f_t2f_vert, ShaderEngine::v2f_c4f_t2f_frag, "v2f_c4f_t2f");
+ programID = ShaderEngine::CompileShaderProgram(
+ StaticGlShaders::Get()->GetV2fC4fT2fVertexShader(),
+ StaticGlShaders::Get()->GetV2fC4fT2fFragmentShader(), "v2f_c4f_t2f");
textureID = projectM::initRenderToTexture();
float points[16] = {
diff --git a/src/projectM-sdl/projectM_SDL_main.cpp b/src/projectM-sdl/projectM_SDL_main.cpp
index a3e19941a..3101e7102 100644
--- a/src/projectM-sdl/projectM_SDL_main.cpp
+++ b/src/projectM-sdl/projectM_SDL_main.cpp
@@ -304,8 +304,8 @@ srand((int)(time(NULL)));
#else
// Disabling compatibility profile
- SDL_GL_SetAttribute(SDL_GL_CONTEXT_MAJOR_VERSION, 3);
- SDL_GL_SetAttribute(SDL_GL_CONTEXT_MINOR_VERSION, 2);
+ SDL_GL_SetAttribute(SDL_GL_CONTEXT_MAJOR_VERSION, 2);
+ SDL_GL_SetAttribute(SDL_GL_CONTEXT_MINOR_VERSION, 1);
SDL_GL_SetAttribute(SDL_GL_CONTEXT_PROFILE_MASK, SDL_GL_CONTEXT_PROFILE_CORE);
#endif