diff --git a/src/libprojectM/MilkdropPreset/CustomShape.cpp b/src/libprojectM/MilkdropPreset/CustomShape.cpp index 9664e7191..640cb97a2 100644 --- a/src/libprojectM/MilkdropPreset/CustomShape.cpp +++ b/src/libprojectM/MilkdropPreset/CustomShape.cpp @@ -75,20 +75,20 @@ void CustomShape::Initialize(FileParser& parsedFile, int index) m_thickOutline = parsedFile.GetInt(shapecodePrefix + "thickOutline", m_thickOutline); m_textured = parsedFile.GetInt(shapecodePrefix + "textured", m_textured); m_instances = parsedFile.GetInt(shapecodePrefix + "num_inst", m_instances); - m_x = parsedFile.GetBool(shapecodePrefix + "x", m_x); - m_y = parsedFile.GetBool(shapecodePrefix + "y", m_y); - m_radius = parsedFile.GetBool(shapecodePrefix + "rad", m_radius); - m_angle = parsedFile.GetBool(shapecodePrefix + "ang", m_angle); - m_tex_ang = parsedFile.GetBool(shapecodePrefix + "tex_ang", m_tex_ang); - m_tex_zoom = parsedFile.GetBool(shapecodePrefix + "tex_zoom", m_tex_zoom); + m_x = parsedFile.GetFloat(shapecodePrefix + "x", m_x); + m_y = parsedFile.GetFloat(shapecodePrefix + "y", m_y); + m_radius = parsedFile.GetFloat(shapecodePrefix + "rad", m_radius); + m_angle = parsedFile.GetFloat(shapecodePrefix + "ang", m_angle); + m_tex_ang = parsedFile.GetFloat(shapecodePrefix + "tex_ang", m_tex_ang); + m_tex_zoom = parsedFile.GetFloat(shapecodePrefix + "tex_zoom", m_tex_zoom); m_r = parsedFile.GetFloat(shapecodePrefix + "r", m_r); m_g = parsedFile.GetFloat(shapecodePrefix + "g", m_g); m_b = parsedFile.GetFloat(shapecodePrefix + "b", m_b); m_a = parsedFile.GetFloat(shapecodePrefix + "a", m_a); - m_r2 = parsedFile.GetBool(shapecodePrefix + "r2", m_r2); - m_g2 = parsedFile.GetBool(shapecodePrefix + "g2", m_g2); - m_b2 = parsedFile.GetBool(shapecodePrefix + "b2", m_b2); - m_a2 = parsedFile.GetBool(shapecodePrefix + "a2", m_a2); + m_r2 = parsedFile.GetFloat(shapecodePrefix + "r2", m_r2); + m_g2 = parsedFile.GetFloat(shapecodePrefix + "g2", m_g2); + m_b2 = parsedFile.GetFloat(shapecodePrefix + "b2", m_b2); + m_a2 = parsedFile.GetFloat(shapecodePrefix + "a2", m_a2); m_border_r = parsedFile.GetFloat(shapecodePrefix + "border_r", m_border_r); m_border_g = parsedFile.GetFloat(shapecodePrefix + "border_g", m_border_g); m_border_b = parsedFile.GetFloat(shapecodePrefix + "border_b", m_border_b); diff --git a/src/libprojectM/MilkdropPreset/MilkdropPreset.hpp b/src/libprojectM/MilkdropPreset/MilkdropPreset.hpp index 0ddb04390..eb2d80b4f 100644 --- a/src/libprojectM/MilkdropPreset/MilkdropPreset.hpp +++ b/src/libprojectM/MilkdropPreset/MilkdropPreset.hpp @@ -23,13 +23,6 @@ */ #pragma once -#ifdef DEBUG -/* 0 for no debugging, 1 for normal, 2 for insane */ -#define MILKDROP_PRESET_DEBUG 1 -#else -#define MILKDROP_PRESET_DEBUG 0 -#endif - #include "CustomShape.hpp" #include "CustomWaveform.hpp" #include "PerFrameContext.hpp" @@ -51,14 +44,14 @@ class MilkdropPreset : public Preset public: /** - * @brief Load a MilkdropPreset by filename with input and output buffers specified. + * @brief LoadCode a MilkdropPreset by filename with input and output buffers specified. * @param factory The factory class that created this preset instance. * @param absoluteFilePath the absolute file path of a MilkdropPreset to load from the file system */ MilkdropPreset(MilkdropPresetFactory* factory, const std::string& absoluteFilePath); /** - * @brief Load a MilkdropPreset from an input stream with input and output buffers specified. + * @brief LoadCode a MilkdropPreset from an input stream with input and output buffers specified. * @param presetData an already initialized input stream to read the MilkdropPreset file from * @param presetOutputs initialized and filled with data parsed from a MilkdropPreset */ diff --git a/src/libprojectM/MilkdropPreset/MilkdropPresetFactory.cpp b/src/libprojectM/MilkdropPreset/MilkdropPresetFactory.cpp index 7912af44a..9ed499ec0 100644 --- a/src/libprojectM/MilkdropPreset/MilkdropPresetFactory.cpp +++ b/src/libprojectM/MilkdropPreset/MilkdropPresetFactory.cpp @@ -11,225 +11,32 @@ // // #include "MilkdropPresetFactory.hpp" + #include "MilkdropPreset.hpp" #include "IdlePreset.hpp" -#include "PresetFrameIO.hpp" MilkdropPresetFactory::MilkdropPresetFactory(int meshX, int meshY) : m_meshX(meshX) , m_meshY(meshY) { - /* Initializes the builtin function database */ - BuiltinFuncs::init_builtin_func_db(); - - /* Initializes all infix operators */ - Eval::init_infix_ops(); } MilkdropPresetFactory::~MilkdropPresetFactory() { - Eval::destroy_infix_ops(); - BuiltinFuncs::destroy_builtin_func_db(); } -/* Reinitializes the engine variables to a default (conservative and sane) value */ -void MilkdropPresetFactory::ResetPresetOutputs(PresetOutputs* presetOutputs) -{ - if (presetOutputs == nullptr) - { - return; - } - - presetOutputs->zoom = 1.0; - presetOutputs->zoomexp = 1.0; - presetOutputs->rot = 0.0; - presetOutputs->warp = 0.0; - - presetOutputs->sx = 1.0; - presetOutputs->sy = 1.0; - presetOutputs->dx = 0.0; - presetOutputs->dy = 0.0; - presetOutputs->cx = 0.5; - presetOutputs->cy = 0.5; - - presetOutputs->screenDecay = .98; - - presetOutputs->wave.r = 1.0; - presetOutputs->wave.g = 0.2; - presetOutputs->wave.b = 0.0; - presetOutputs->wave.x = 0.5; - presetOutputs->wave.y = 0.5; - presetOutputs->wave.mystery = 0.0; - - presetOutputs->border.outer_size = 0.0; - presetOutputs->border.outer_r = 0.0; - presetOutputs->border.outer_g = 0.0; - presetOutputs->border.outer_b = 0.0; - presetOutputs->border.outer_a = 0.0; - - presetOutputs->border.inner_size = 0.0; - presetOutputs->border.inner_r = 0.0; - presetOutputs->border.inner_g = 0.0; - presetOutputs->border.inner_b = 0.0; - presetOutputs->border.inner_a = 0.0; - - presetOutputs->mv.a = 0.0; - presetOutputs->mv.r = 0.0; - presetOutputs->mv.g = 0.0; - presetOutputs->mv.b = 0.0; - presetOutputs->mv.length = 1.0; - presetOutputs->mv.x_num = 16.0; - presetOutputs->mv.y_num = 12.0; - presetOutputs->mv.x_offset = 0.02; - presetOutputs->mv.y_offset = 0.02; - - - /* PER_FRAME CONSTANTS END */ - presetOutputs->fRating = 0; - presetOutputs->fGammaAdj = 1.0; - presetOutputs->videoEcho.zoom = 1.0; - presetOutputs->videoEcho.a = 0; - presetOutputs->videoEcho.orientation = Normal; - - presetOutputs->wave.additive = false; - presetOutputs->wave.dots = false; - presetOutputs->wave.thick = false; - presetOutputs->wave.modulateAlphaByVolume = 0; - presetOutputs->wave.maximizeColors = 0; - presetOutputs->textureWrap = 0; - presetOutputs->bDarkenCenter = 0; - presetOutputs->bRedBlueStereo = 0; - presetOutputs->bBrighten = 0; - presetOutputs->bDarken = 0; - presetOutputs->bSolarize = 0; - presetOutputs->bInvert = 0; - presetOutputs->bMotionVectorsOn = 1; - - presetOutputs->wave.a = 1.0; - presetOutputs->wave.scale = 1.0; - presetOutputs->wave.smoothing = 0; - presetOutputs->wave.mystery = 0; - presetOutputs->wave.modOpacityEnd = 0; - presetOutputs->wave.modOpacityStart = 0; - presetOutputs->fWarpAnimSpeed = 0; - presetOutputs->fWarpScale = 0; - presetOutputs->fShader = 0; - - /* PER_PIXEL CONSTANT END */ - /* Q VARIABLES START */ - - for (int i = 0; i < 32; i++) - { - presetOutputs->q[i] = 0; - } - -// for ( std::vector::iterator pos = presetOutputs->customWaves.begin(); -// pos != presetOutputs->customWaves.end(); ++pos ) -// if ( *pos != 0 ) delete ( *pos ); - -// for ( std::vector::iterator pos = presetOutputs->customShapes.begin(); -// pos != presetOutputs->customShapes.end(); ++pos ) -// if ( *pos != 0 ) delete ( *pos ); - - presetOutputs->customWaves.clear(); - presetOutputs->customShapes.clear(); - - /* Q VARIABLES END */ - -} - - -/* Reinitializes the engine variables to a default (conservative and sane) value */ -void MilkdropPresetFactory::reset() -{ - if (m_presetOutputsCache) - { - ResetPresetOutputs(m_presetOutputsCache); - } -} - -PresetOutputs* MilkdropPresetFactory::CreatePresetOutputs(int meshX, int meshY) -{ - auto* presetOutputs = new PresetOutputs(); - - presetOutputs->Initialize(meshX, meshY); - - /* PER FRAME CONSTANTS BEGIN */ - presetOutputs->zoom = 1.0; - presetOutputs->zoomexp = 1.0; - presetOutputs->rot = 0.0; - presetOutputs->warp = 0.0; - - presetOutputs->sx = 1.0; - presetOutputs->sy = 1.0; - presetOutputs->dx = 0.0; - presetOutputs->dy = 0.0; - presetOutputs->cx = 0.5; - presetOutputs->cy = 0.5; - - presetOutputs->screenDecay = 0.98f; - - /* PER_FRAME CONSTANTS END */ - presetOutputs->fRating = 0.0f; - presetOutputs->fGammaAdj = 1.0f; - presetOutputs->videoEcho.zoom = 1.0f; - presetOutputs->videoEcho.a = 0.0f; - presetOutputs->videoEcho.orientation = Orientation::Normal; - - presetOutputs->textureWrap = false; - presetOutputs->bDarkenCenter = false; - presetOutputs->bRedBlueStereo = false; - presetOutputs->bBrighten = false; - presetOutputs->bDarken = false; - presetOutputs->bSolarize = false; - presetOutputs->bInvert = false; - presetOutputs->bMotionVectorsOn = true; - presetOutputs->fWarpAnimSpeed = 0.0f; - presetOutputs->fWarpScale = 0.0f; - presetOutputs->fShader = 0.0f; - - /* PER_PIXEL CONSTANTS BEGIN */ - - /* PER_PIXEL CONSTANT END */ - - /* Q AND T VARIABLES START */ - - for (unsigned int i = 0; i < numQVariables; i++) - { - presetOutputs->q[i] = 0; - } - - /* Q AND T VARIABLES END */ - return presetOutputs; -} - - std::unique_ptr MilkdropPresetFactory::LoadPresetFromFile(const std::string& filename) { - PresetOutputs* presetOutputs; - // use cached PresetOutputs if there is one, otherwise allocate - if (m_presetOutputsCache) - { - presetOutputs = m_presetOutputsCache; - m_presetOutputsCache = nullptr; - } - else - { - presetOutputs = CreatePresetOutputs(m_meshX, m_meshY); - } - - ResetPresetOutputs(presetOutputs); - std::string path; auto protocol = PresetFactory::Protocol(filename, path); if (protocol == PresetFactory::IDLE_PRESET_PROTOCOL) { - return IdlePresets::allocate(this, presetOutputs); + return IdlePresets::allocate(this); } else if (protocol == "" || protocol == "file") { - return std::make_unique(this, path, presetOutputs); + return std::make_unique(this, path); } else { @@ -240,42 +47,5 @@ MilkdropPresetFactory::LoadPresetFromFile(const std::string& filename) std::unique_ptr MilkdropPresetFactory::LoadPresetFromStream(std::istream& data) { - - PresetOutputs* presetOutputs; - // use cached PresetOutputs if there is one, otherwise allocate - if (m_presetOutputsCache) - { - presetOutputs = m_presetOutputsCache; - m_presetOutputsCache = nullptr; - } - else - { - presetOutputs = CreatePresetOutputs(m_meshX, m_meshY); - } - - ResetPresetOutputs(presetOutputs); - - return std::make_unique(this, data, presetOutputs); + return std::make_unique(this, data); } - -// this gives the preset a way to return the PresetOutput w/o dependency on class projectM behavior -void MilkdropPresetFactory::releasePreset(Preset* preset) -{ - auto milkdropPreset = dynamic_cast(preset); - - if (!milkdropPreset || !milkdropPreset->_presetOutputs) - { - // Instance is not a MilkdropPreset or has no PresetOutput object. - return; - } - - // return PresetOutputs to the cache - if (!m_presetOutputsCache) - { - m_presetOutputsCache = milkdropPreset->_presetOutputs; - } - else - { - delete milkdropPreset->_presetOutputs; - } -} \ No newline at end of file diff --git a/src/libprojectM/MilkdropPreset/MilkdropShader.cpp b/src/libprojectM/MilkdropPreset/MilkdropShader.cpp index f598bf4e0..379ffb1e5 100644 --- a/src/libprojectM/MilkdropPreset/MilkdropShader.cpp +++ b/src/libprojectM/MilkdropPreset/MilkdropShader.cpp @@ -1 +1,164 @@ #include "MilkdropShader.hpp" + +#include + +MilkdropShader::MilkdropShader(ShaderType type) + : m_type(type) +{ +} + + +void MilkdropShader::LoadCode(std::string presetShaderCode) +{ + m_presetShaderCode = std::move(presetShaderCode); + + std::string program = m_presetShaderCode; + PreprocessPresetShader(program); + +} + +void MilkdropShader::LoadTextures(TextureManager& textureManager) +{ + // Add Milkdrop built-in textures + m_shader.SetUniformTexture("main", textureManager.getTexture("main", GL_REPEAT, GL_LINEAR)); + m_shader.SetUniformTexture("main", textureManager->getTexture("main", GL_REPEAT, GL_LINEAR)); + m_shader.SetUniformTexture("fc_main", textureManager->getTexture("main", GL_CLAMP_TO_EDGE, GL_LINEAR)); + m_shader.SetUniformTexture("pc_main", textureManager->getTexture("main", GL_CLAMP_TO_EDGE, GL_NEAREST)); + m_shader.SetUniformTexture("fw_main", textureManager->getTexture("main", GL_REPEAT, GL_LINEAR)); + m_shader.SetUniformTexture("pw_main", textureManager->getTexture("main", GL_REPEAT, GL_NEAREST)); + + m_shader.SetUniformTexture("noise_lq", textureManager->getTexture("noise_lq", GL_REPEAT, GL_LINEAR)); + m_shader.SetUniformTexture("noise_lq_lite", textureManager->getTexture("noise_lq_lite", GL_REPEAT, GL_LINEAR)); + m_shader.SetUniformTexture("noise_mq", textureManager->getTexture("noise_mq", GL_REPEAT, GL_LINEAR)); + m_shader.SetUniformTexture("noise_hq", textureManager->getTexture("noise_hq", GL_REPEAT, GL_LINEAR)); + m_shader.SetUniformTexture("noisevol_lq", textureManager->getTexture("noisevol_lq", GL_REPEAT, GL_LINEAR)); + m_shader.SetUniformTexture("noisevol_hq", textureManager->getTexture("noisevol_hq", GL_REPEAT, GL_LINEAR)); + +} + +void MilkdropShader::PreprocessPresetShader(std::string& program) +{ + + if (program.length() <= 0) + { + throw ShaderException("Preset shader is declared, but empty."); + } + + size_t found; + + // replace shader_body with entry point function + found = program.find("shader_body"); + if (found != std::string::npos) + { +#ifdef MILKDROP_PRESET_DEBUG + std::cerr << "[MilkdropShader] First 'shader_body' found at: " << int(found) << std::endl; +#endif + + if (m_type == ShaderType::WarpShader) + { + program.replace(int(found), 11, "void PS(float4 _vDiffuse : COLOR, float4 _uv : TEXCOORD0, float2 _rad_ang : TEXCOORD1, out float4 _return_value : COLOR)\n"); + } + else + { + program.replace(int(found), 11, "void PS(float4 _vDiffuse : COLOR, float2 _uv : TEXCOORD0, float2 _rad_ang : TEXCOORD1, out float4 _return_value : COLOR)\n"); + } + } + else + { + throw ShaderException("Preset shader is missing \"shader_body\" entry point."); + } + + // replace the "{" immediately following shader_body with some variable declarations + found = program.find('{', found); + if (found != std::string::npos) + { +#ifdef MILKDROP_PRESET_DEBUG + std::cerr << "[MilkdropShader] First '{' found at: " << int(found) << std::endl; +#endif + const char* progMain = + "{\n" + "float3 ret = 0;\n"; + program.replace(int(found), 1, progMain); + } + else + { + throw ShaderException("Preset shader has no opening braces."); + } + + // replace "}" with return statement (this can probably be optimized for the GLSL conversion...) + found = program.rfind('}'); + if (found != std::string::npos) + { +#ifdef MILKDROP_PRESET_DEBUG + std::cerr << "[MilkdropShader] Last '}' found at: " << int(found) << std::endl; +#endif + program.replace(int(found), 1, "_return_value = float4(ret.xyz, 1.0);\n" + "}\n"); + } + else + { + throw ShaderException("Preset shader has no closing brace."); + } + + // Find matching closing brace and cut off excess text after shader's main function + int bracesOpen = 1; + size_t pos = found + 1; + for (; pos < program.length() && bracesOpen > 0; ++pos) + { + switch (program.at(pos)) + { + case '/': + // Skip comments until EoL to prevent false counting + if (pos < program.length() - 1 && program.at(pos + 1) == '/') + { + for (; pos < program.length(); ++pos) + { + if (program.at(pos) == '\n') + { + break; + } + } + } + continue; + + case '{': + bracesOpen++; + continue; + + case '}': + bracesOpen--; + } + } + + if (pos < program.length() - 1) + { + program.resize(pos); + } + +} + +void MilkdropShader::GetReferencedSamplers(const std::string& program) +{ + // set up texture samplers for all samplers references in the shader program + auto found = program.find("sampler_", 0); + while (found != std::string::npos) + { + found += 8; + size_t end = program.find_first_of(" ;,\n\r)", found); + + if (end != std::string::npos) + { + std::string sampler = program.substr((int) found, (int) end - found); + std::string lowerCaseName(sampler); + std::transform(lowerCaseName.begin(), lowerCaseName.end(), lowerCaseName.begin(), tolower); + + m_samplerNames.push_back(lowerCaseName); + } + + found = program.find("sampler_", found); + } + + + found = program.find("GetBlur3"); + +} diff --git a/src/libprojectM/MilkdropPreset/MilkdropShader.hpp b/src/libprojectM/MilkdropPreset/MilkdropShader.hpp index 6bf216f47..83d53084a 100644 --- a/src/libprojectM/MilkdropPreset/MilkdropShader.hpp +++ b/src/libprojectM/MilkdropPreset/MilkdropShader.hpp @@ -4,6 +4,9 @@ */ #pragma once +#include "Renderer/Shader.hpp" +#include "Renderer/TextureManager.hpp" + /** * @brief Holds a warp or composite shader of Milkdrop presets. * Also does the required shader translation from HLSL to GLSL using hlslparser. @@ -11,7 +14,57 @@ class MilkdropShader { public: + enum class ShaderType + { + WarpShader, //!< Warp shader + CompositeShader //!< Composite shader + }; + + /** + * Maximum main texture blur level used in the shader + */ + enum class BlurLevel : int + { + None, //!< No blur used. + Blur1, //!< First blur level (2 passes) + Blur2, //!< Second blur level (4 passes) + Blur3 //!< Third blur level (6 passes) + }; + + /** + * constructor. + * @param type The preset shader type. + */ + explicit MilkdropShader(ShaderType type); + + /** + * @brief Translates and compiles the shader code. + * @param presetShaderCode The preset shader code. + */ + void LoadCode(std::string presetShaderCode); + + /** + * @brief Loads the required texture references into the shader. + */ + void LoadTextures(TextureManager& textureManager); private: + /** + * @brief Prepares the shader code to be translated into GLSL. + * @param program The program code to work on. + */ + void PreprocessPresetShader(std::string& program); + /** + * @brief Searches for sampler references in the program and stores them in m_samplerNames. + * @param program The program code to work on. + */ + void GetReferencedSamplers(const std::string& program); + + ShaderType m_type{ShaderType::WarpShader}; //!< Type of this shader. + std::string m_presetShaderCode; //!< The original preset shader code. + + std::vector m_samplerNames; //!< Names of all referenced samplers in the shader code. + + Shader m_shader; }; diff --git a/src/libprojectM/MilkdropPreset/PresetFrameIO.hpp b/src/libprojectM/MilkdropPreset/PresetFrameIO.hpp index 22ac54a4c..91196efc0 100644 --- a/src/libprojectM/MilkdropPreset/PresetFrameIO.hpp +++ b/src/libprojectM/MilkdropPreset/PresetFrameIO.hpp @@ -12,149 +12,3 @@ #include "Waveform.hpp" #include - -/// Container for all *read only* engine variables a preset requires to -/// evaluate milkdrop equations. Every preset object needs a reference to one of these. -class PresetInputs : public PipelineContext { - -public: - /* PER_PIXEL VARIBLES BEGIN */ - - float x_per_pixel; - float y_per_pixel; - float rad_per_pixel; - float ang_per_pixel; - - /* PER_PIXEL VARIBLES END */ - - float bass; - float mid; - float treb; - float bass_att; - float mid_att; - float treb_att; - - /* variables were added in milkdrop 1.04 */ - int gx, gy; - - float **x_mesh; - float **y_mesh; - - int pixelsx; - int pixelsy; - - float aspectx; - float aspecty; - - float **rad_mesh; - float **theta_mesh; - - float **origtheta; //grid containing interpolated mesh reference values - float **origrad; - float **origx; //original mesh - float **origy; - - void resetMesh(); - - ~PresetInputs(); - PresetInputs(); - - /// Initializes this preset inputs given a mesh size. - /// \param gx the width of the mesh - /// \param gy the height of the mesh - /// \note This must be called before reading values from this class - void Initialize(int _gx, int _gy); - - /// Updates this preset inputs with the latest values from the - /// the pipeline context and beat detection unit - void update (const BeatDetect & music, const PipelineContext & context); - - private: -}; - - -/// Container class for all preset writeable engine variables. This is the important glue -/// between the presets and renderer to facilitate smooth preset switching -/// Every preset object needs a reference to one of these. -class PresetOutputs : public Pipeline { -public: - typedef std::vector cwave_container; - typedef std::vector cshape_container; - - cwave_container customWaves; - cshape_container customShapes; - - void Initialize(int _gx, int _gy); - PresetOutputs(); - ~PresetOutputs(); - virtual void Render(const BeatDetect &music, const PipelineContext &context); - void PerPixelMath( const PipelineContext &context); - /* PER FRAME VARIABLES BEGIN */ - - float zoom; - float zoomexp; - float rot; - float warp; - - float sx; - float sy; - float dx; - float dy; - float cx; - float cy; - - VideoEcho videoEcho; - - Waveform wave; - Border border; - MotionVectors mv; - DarkenCenter darkenCenter; - - Brighten brighten; - Darken darken; - Invert invert; - Solarize solarize; - - // ToDo: Check if redeclaration here is wanted, as the Pipeline base class also defines these. - int gy; - int gx; - - /* PER_FRAME VARIABLES END */ - - float fRating; - float fGammaAdj; - - bool bDarkenCenter; - bool bRedBlueStereo; - bool bBrighten; - bool bDarken; - bool bSolarize; - bool bInvert; - bool bMotionVectorsOn; - - float fWarpAnimSpeed; - float fWarpScale; - float fShader; - - float **zoom_mesh; - float **zoomexp_mesh; - float **rot_mesh; - - float **sx_mesh; - float **sy_mesh; - float **dx_mesh; - float **dy_mesh; - float **cx_mesh; - float **cy_mesh; - float **warp_mesh; - - float **orig_x; //original mesh - float **orig_y; - float **rad_mesh; - -private: - void PerPixelMath_c( const PipelineContext &context); -#ifdef __SSE2__ - void PerPixelMath_sse( const PipelineContext &context); -#endif -}; diff --git a/src/libprojectM/PipelineMerger.cpp b/src/libprojectM/PipelineMerger.cpp index e76b3c0c8..ba8422c72 100644 --- a/src/libprojectM/PipelineMerger.cpp +++ b/src/libprojectM/PipelineMerger.cpp @@ -77,14 +77,10 @@ void PipelineMerger::mergePipelines(const Pipeline& a, const Pipeline& b, Pipeli { out.compositeShader = a.compositeShader; out.warpShader = a.warpShader; - out.warpShaderFilename = a.warpShaderFilename; - out.compositeShaderFilename = a.compositeShaderFilename; } else { out.compositeShader = b.compositeShader; out.warpShader = b.warpShader; - out.warpShaderFilename = b.warpShaderFilename; - out.compositeShaderFilename = b.compositeShaderFilename; } } diff --git a/src/libprojectM/ProjectM.hpp b/src/libprojectM/ProjectM.hpp index 834106559..2b48a52a7 100644 --- a/src/libprojectM/ProjectM.hpp +++ b/src/libprojectM/ProjectM.hpp @@ -48,7 +48,11 @@ class BackgroundWorkerSync; +namespace libprojectM { +namespace Audio { class BeatDetect; +} +} // namespace libprojectM class Pcm; @@ -240,7 +244,7 @@ private: #endif - class Pcm m_pcm; //!< Audio data buffer and analyzer instance. + class libprojectM::Audio::PCM m_pcm; //!< Audio data buffer and analyzer instance. size_t m_meshX{32}; //!< Per-point mesh horizontal resolution. size_t m_meshY{24}; //!< Per-point mesh vertical resolution. @@ -269,11 +273,11 @@ private: std::unique_ptr m_pipelineContext; //!< Pipeline context for the first/current preset. std::unique_ptr m_pipelineContext2; //!< Pipeline context for the next/transitioning preset. - std::unique_ptr m_renderer; //!< The Preset renderer. - std::unique_ptr m_beatDetect; //!< The beat detection class. - std::unique_ptr m_activePreset; //!< Currently loaded preset. - std::unique_ptr m_transitioningPreset; //!< Destination preset when smooth preset switching. - std::unique_ptr m_timeKeeper; //!< Keeps the different timers used to render and switch presets. + std::unique_ptr m_renderer; //!< The Preset renderer. + std::unique_ptr m_beatDetect; //!< The beat detection class. + std::unique_ptr m_activePreset; //!< Currently loaded preset. + std::unique_ptr m_transitioningPreset; //!< Destination preset when smooth preset switching. + std::unique_ptr m_timeKeeper; //!< Keeps the different timers used to render and switch presets. #if PROJECTM_USE_THREADS mutable std::recursive_mutex m_presetSwitchMutex; //!< Mutex for locking preset switching while rendering and vice versa. diff --git a/src/libprojectM/Renderer/Pipeline.hpp b/src/libprojectM/Renderer/Pipeline.hpp index 2a87f5294..0fc7b5e7f 100644 --- a/src/libprojectM/Renderer/Pipeline.hpp +++ b/src/libprojectM/Renderer/Pipeline.hpp @@ -41,9 +41,7 @@ public: float blur1ed; Shader warpShader; - std::string warpShaderFilename; Shader compositeShader; - std::string compositeShaderFilename; std::vector drawables; std::vector compositeDrawables; diff --git a/src/libprojectM/Renderer/Renderer.cpp b/src/libprojectM/Renderer/Renderer.cpp index 29da1957c..b7f7b0fc7 100644 --- a/src/libprojectM/Renderer/Renderer.cpp +++ b/src/libprojectM/Renderer/Renderer.cpp @@ -174,7 +174,6 @@ void Renderer::RenderItems(const Pipeline& pipeline, const PipelineContext& pipe m_renderContext.invAspectX = m_fInvAspectX; m_renderContext.invAspectY = m_fInvAspectY; m_renderContext.textureManager = m_textureManager.get(); - m_renderContext.beatDetect = m_beatDetect; for (std::vector::const_iterator pos = pipeline.drawables.begin(); pos != pipeline.drawables.end(); ++pos) { diff --git a/src/libprojectM/Renderer/Renderer.hpp b/src/libprojectM/Renderer/Renderer.hpp index d5f90b28f..eece2d2a4 100644 --- a/src/libprojectM/Renderer/Renderer.hpp +++ b/src/libprojectM/Renderer/Renderer.hpp @@ -1,5 +1,4 @@ -#ifndef Renderer_HPP -#define Renderer_HPP +#pragma once #include "Audio/BeatDetect.hpp" #include "Pipeline.hpp" @@ -174,5 +173,3 @@ private: float m_fInvAspectX{1.0}; float m_fInvAspectY{1.0}; }; - -#endif diff --git a/src/libprojectM/Renderer/Shader.cpp b/src/libprojectM/Renderer/Shader.cpp index 9bea3bba4..0b812d9f9 100644 --- a/src/libprojectM/Renderer/Shader.cpp +++ b/src/libprojectM/Renderer/Shader.cpp @@ -1,10 +1,219 @@ -/* - * Shader.cpp - * - * Created on: Jun 29, 2008 - * Author: pete - */ - #include "Shader.hpp" -Shader::Shader() {} +#include + +Shader::Shader() + : m_shaderProgram(glCreateProgram()) +{ +} + +Shader::~Shader() +{ + if (m_shaderProgram) + { + glDeleteProgram(m_shaderProgram); + } +} + +void Shader::CompileProgram(const std::string& vertexShaderSource, std::string& fragmentShaderSource) +{ + auto vertexShader = CompileShader(vertexShaderSource, GL_VERTEX_SHADER); + auto fragmentShader = CompileShader(fragmentShaderSource, GL_FRAGMENT_SHADER); + + glAttachShader(m_shaderProgram, vertexShader); + glAttachShader(m_shaderProgram, fragmentShader); + + glLinkProgram(m_shaderProgram); + + // Shader objects are no longer needed after linking, free the memory. + glDetachShader(m_shaderProgram, vertexShader); + glDetachShader(m_shaderProgram, fragmentShader); + glDeleteShader(vertexShader); + glDeleteShader(fragmentShader); + + GLint programLinked; + glGetProgramiv(m_shaderProgram, GL_LINK_STATUS, &programLinked); + if (programLinked == GL_TRUE) + { + return; + } + + GLint infoLogLength{}; + glGetProgramiv(m_shaderProgram, GL_INFO_LOG_LENGTH, &infoLogLength); + std::vector message(infoLogLength + 1); + glGetProgramInfoLog(m_shaderProgram, infoLogLength, nullptr, message.data()); + + throw ShaderException("Error compiling shader: " + std::string(message.data())); +} + +bool Shader::Validate(std::string& validationMessage) const +{ + GLint result{GL_FALSE}; + int infoLogLength; + + glValidateProgram(m_shaderProgram); + + glGetProgramiv(m_shaderProgram, GL_VALIDATE_STATUS, &result); + glGetProgramiv(m_shaderProgram, GL_INFO_LOG_LENGTH, &infoLogLength); + if (infoLogLength > 0) + { + std::vector validationErrorMessage(infoLogLength + 1); + glGetProgramInfoLog(m_shaderProgram, infoLogLength, nullptr, validationErrorMessage.data()); + validationMessage = std::string(validationErrorMessage.data()); + } + + return result; +} + +void Shader::Bind() +{ + if (m_shaderProgram > 0) + { + glUseProgram(m_shaderProgram); + } +} + +void Shader::Unbind() +{ + glUseProgram(0); +} + +void Shader::BindTextures() +{ + int texNum{0}; + std::map texSizes; + + // Set samplers + for (const auto& samplerIt : m_textures) + { + std::string const texName = samplerIt.first; + Texture* texture = samplerIt.second.first; + Sampler* sampler = samplerIt.second.second; + + std::string const samplerName = "sampler_" + texName; + + texSizes[texName] = texture; + texSizes[texture->name] = texture; + + // https://www.khronos.org/opengl/wiki/Sampler_(GLSL)#Binding_textures_to_samplers + glActiveTexture(GL_TEXTURE0 + texNum); + glBindTexture(texture->type, texture->texID); + glBindSampler(texNum, sampler->samplerID); + + SetUniformInt(samplerName.c_str(), texNum); + + texNum++; + } + + // Set texture size uniforms + for (const auto& texSize : texSizes) + { + Texture* texture = texSize.second; + + std::string const texSizeName = "texsize_" + texSize.first; + + SetUniformFloat4(texSizeName.c_str(), {texture->width, + texture->height, + 1 / (float) texture->width, + 1 / (float) texture->height}); + } +} + +void Shader::SetUniformTexture(const char* uniform, TextureSamplerDesc texture) +{ +} + +void Shader::SetUniformFloat(const char* uniform, float value) +{ + auto location = glGetUniformLocation(m_shaderProgram, uniform); + if (location < 0) + { + return; + } + glUniform1fv(location, 1, &value); +} + +void Shader::SetUniformInt(const char* uniform, int value) +{ + auto location = glGetUniformLocation(m_shaderProgram, uniform); + if (location < 0) + { + return; + } + glUniform1iv(location, 1, &value); +} + +void Shader::SetUniformFloat2(const char* uniform, const glm::vec2& values) +{ + auto location = glGetUniformLocation(m_shaderProgram, uniform); + if (location < 0) + { + return; + } + glUniform2fv(location, 1, glm::value_ptr(values)); +} + +void Shader::SetUniformFloat3(const char* uniform, const glm::vec3& values) +{ + auto location = glGetUniformLocation(m_shaderProgram, uniform); + if (location < 0) + { + return; + } + glUniform3fv(location, 1, glm::value_ptr(values)); +} + +void Shader::SetUniformFloat4(const char* uniform, const glm::vec4& values) +{ + auto location = glGetUniformLocation(m_shaderProgram, uniform); + if (location < 0) + { + return; + } + glUniform4fv(location, 1, glm::value_ptr(values)); +} + +void Shader::SetUniformMat3x4(const char* uniform, const glm::mat3x4& values) +{ + auto location = glGetUniformLocation(m_shaderProgram, uniform); + if (location < 0) + { + return; + } + glUniformMatrix3x4fv(location, 1, GL_FALSE, glm::value_ptr(values)); +} + +void Shader::SetUniformMat4x4(const char* uniform, const glm::mat4x4& values) +{ + auto location = glGetUniformLocation(m_shaderProgram, uniform); + if (location < 0) + { + return; + } + glUniformMatrix4fv(location, 1, GL_FALSE, glm::value_ptr(values)); +} + +GLuint Shader::CompileShader(const std::string& source, GLenum type) +{ + GLint shaderCompiled{}; + + auto shader = glCreateShader(type); + const auto *shaderSourceCStr = source.c_str(); + glShaderSource(shader, 1, &shaderSourceCStr, nullptr); + + glCompileShader(shader); + + glGetShaderiv(shader, GL_COMPILE_STATUS, &shaderCompiled); + if (shaderCompiled == GL_TRUE) + { + return shader; + } + + GLint infoLogLength{}; + glGetShaderiv(shader, GL_INFO_LOG_LENGTH, &infoLogLength); + std::vector message(infoLogLength + 1); + glGetShaderInfoLog(shader, infoLogLength, nullptr, message.data()); + glDeleteShader(shader); + + throw ShaderException("Error compiling shader: " + std::string(message.data())); +} diff --git a/src/libprojectM/Renderer/Shader.hpp b/src/libprojectM/Renderer/Shader.hpp index bccf5ecfc..0acf108d8 100644 --- a/src/libprojectM/Renderer/Shader.hpp +++ b/src/libprojectM/Renderer/Shader.hpp @@ -1,27 +1,160 @@ -/* - * Shader.hpp - * - * Created on: Jun 29, 2008 - * Author: pete +/** + * @file Shader.hpp + * @brief Implements an interface to a single shader program instance. */ +#pragma once -#ifndef SHADER_HPP_ -#define SHADER_HPP_ - -#include -#include #include "Texture.hpp" +#include +#include +#include +#include +#include + +#include +#include + +/** + * @brief Shader compilation exception. + */ +class ShaderException : public std::exception +{ +public: + inline ShaderException(std::string message) + : m_message(std::move(message)) + { + } + + virtual ~ShaderException() = default; + + const std::string& message() const + { + return m_message; + } + +private: + std::string m_message; +}; + + +/** + * @brief Base class containing a shader program, consisting of a vertex and fragment shader. + */ class Shader { public: + /** + * Creates a new shader. + */ + Shader(); - std::map textures; + /** + * Destructor. + */ + ~Shader(); - std::string programSource; - std::string presetPath; + /** + * @brief Compiles a vertex and fragment shader into a program. + * @throws ShaderException Thrown if compilation of a shader or program linking failed. + * @param vertexShaderSource The vertex shader source. + * @param fragmentShaderSource The fragment shader source. + */ + void CompileProgram(const std::string& vertexShaderSource, std::string& fragmentShaderSource); - Shader(); + /** + * @brief Validates that the program can run in the current state. + * @param validationMessage The error message if validation failed. + * @return true if the shader program is valid and can run, false if it broken. + */ + bool Validate(std::string& validationMessage) const; + + /** + * Binds the program into the current context. + */ + void Bind(); + + /** + * Unbinds the program. + */ + static void Unbind(); + + /** + * @brief Binds the registered textures to the current program context. + * The program must be bound before calling this method! + */ + void BindTextures(); + + void SetUniformTexture(const char* uniform, TextureSamplerDesc texture); + + /** + * @brief Sets a single float uniform. + * The program must be bound before calling this method! + * @param uniform The uniform name + * @param value The value to set. + */ + void SetUniformFloat(const char* uniform, float value); + + /** + * @brief Sets a single integer uniform. + * The program must be bound before calling this method! + * @param uniform The uniform name + * @param value The value to set. + */ + void SetUniformInt(const char* uniform, int value); + + /** + * @brief Sets a float vec2 uniform. + * The program must be bound before calling this method! + * @param uniform The uniform name + * @param values The values to set. + */ + void SetUniformFloat2(const char* uniform, const glm::vec2& values); + + /** + * @brief Sets a float vec3 uniform. + * The program must be bound before calling this method! + * @param uniform The uniform name + * @param values The values to set. + */ + void SetUniformFloat3(const char* uniform, const glm::vec3& values); + + /** + * @brief Sets a float vec4 uniform. + * The program must be bound before calling this method! + * @param uniform The uniform name + * @param values The values to set. + */ + void SetUniformFloat4(const char* uniform, const glm::vec4& values); + + /** + * @brief Sets a float 3x4 matrix uniform. + * The program must be bound before calling this method! + * @param uniform The uniform name + * @param values The matrix to set. + */ + void SetUniformMat3x4(const char* uniform, const glm::mat3x4& values); + + /** + * @brief Sets a float 4x4 matrix uniform. + * The program must be bound before calling this method! + * @param uniform The uniform name + * @param values The matrix to set. + */ + void SetUniformMat4x4(const char* uniform, const glm::mat4x4& values); + + +private: + /** + * @brief Compiles a single shader. + * @throws ShaderException Thrown if compilation of the shader failed. + * @param source The shader source. + * @param type The shader type, e.g. GL_VERTEX_SHADER. + * @return The shader ID. + */ + auto CompileShader(const std::string& source, GLenum type) -> GLuint; + + std::map m_textures; //!< Textures used in this program. + + GLuint m_shaderProgram{}; //!< The program ID. }; - -#endif /* SHADER_HPP_ */ diff --git a/src/libprojectM/Renderer/ShaderEngine.cpp b/src/libprojectM/Renderer/ShaderEngine.cpp index 832968cf6..2ae3c0b21 100644 --- a/src/libprojectM/Renderer/ShaderEngine.cpp +++ b/src/libprojectM/Renderer/ShaderEngine.cpp @@ -127,7 +127,7 @@ void ShaderEngine::setParams(int _texsizeX, int _texsizeY, // compile a user-defined shader from a preset. returns program ID if successful. GLuint ShaderEngine::compilePresetShader(const PresentShaderType shaderType, Shader &pmShader, const std::string &shaderFilename) { - std::string program = pmShader.programSource; + std::string program = pmShader.m_programSource; if (program.length() <= 0) { @@ -218,22 +218,22 @@ GLuint ShaderEngine::compilePresetShader(const PresentShaderType shaderType, Sha program.resize(pos); } - pmShader.textures.clear(); + pmShader.m_textures.clear(); // Add builtin textures - pmShader.textures["main"] = textureManager->getTexture("main", GL_REPEAT, GL_LINEAR); - pmShader.textures["fc_main"] = textureManager->getTexture("main", GL_CLAMP_TO_EDGE, GL_LINEAR); - pmShader.textures["pc_main"] = textureManager->getTexture("main", GL_CLAMP_TO_EDGE, GL_NEAREST); - pmShader.textures["fw_main"] = textureManager->getTexture("main", GL_REPEAT, GL_LINEAR); - pmShader.textures["pw_main"] = textureManager->getTexture("main", GL_REPEAT, GL_NEAREST); + pmShader.m_textures["main"] = textureManager->getTexture("main", GL_REPEAT, GL_LINEAR); + pmShader.m_textures["fc_main"] = textureManager->getTexture("main", GL_CLAMP_TO_EDGE, GL_LINEAR); + pmShader.m_textures["pc_main"] = textureManager->getTexture("main", GL_CLAMP_TO_EDGE, GL_NEAREST); + pmShader.m_textures["fw_main"] = textureManager->getTexture("main", GL_REPEAT, GL_LINEAR); + pmShader.m_textures["pw_main"] = textureManager->getTexture("main", GL_REPEAT, GL_NEAREST); - pmShader.textures["noise_lq"] = textureManager->getTexture("noise_lq", GL_REPEAT, GL_LINEAR); - pmShader.textures["noise_lq_lite"] = textureManager->getTexture("noise_lq_lite", GL_REPEAT, GL_LINEAR); - pmShader.textures["noise_mq"] = textureManager->getTexture("noise_mq", GL_REPEAT, GL_LINEAR); - pmShader.textures["noise_hq"] = textureManager->getTexture("noise_hq", GL_REPEAT, GL_LINEAR); - pmShader.textures["noisevol_lq"] = textureManager->getTexture("noisevol_lq", GL_REPEAT, GL_LINEAR); - pmShader.textures["noisevol_hq"] = textureManager->getTexture("noisevol_hq", GL_REPEAT, GL_LINEAR); + pmShader.m_textures["noise_lq"] = textureManager->getTexture("noise_lq", GL_REPEAT, GL_LINEAR); + pmShader.m_textures["noise_lq_lite"] = textureManager->getTexture("noise_lq_lite", GL_REPEAT, GL_LINEAR); + pmShader.m_textures["noise_mq"] = textureManager->getTexture("noise_mq", GL_REPEAT, GL_LINEAR); + pmShader.m_textures["noise_hq"] = textureManager->getTexture("noise_hq", GL_REPEAT, GL_LINEAR); + pmShader.m_textures["noisevol_lq"] = textureManager->getTexture("noisevol_lq", GL_REPEAT, GL_LINEAR); + pmShader.m_textures["noisevol_hq"] = textureManager->getTexture("noisevol_hq", GL_REPEAT, GL_LINEAR); @@ -272,15 +272,15 @@ GLuint ShaderEngine::compilePresetShader(const PresentShaderType shaderType, Sha } else { - std::map::const_iterator iter = pmShader.textures.cbegin(); - for ( ; iter != pmShader.textures.cend(); ++iter) + std::map::const_iterator iter = pmShader.m_textures.cbegin(); + for ( ; iter != pmShader.m_textures.cend(); ++iter) { if (iter->first == sampler) break; } - if (iter == pmShader.textures.cend()) - pmShader.textures[sampler] = texDesc; + if (iter == pmShader.m_textures.cend()) + pmShader.m_textures[sampler] = texDesc; } } @@ -293,9 +293,9 @@ GLuint ShaderEngine::compilePresetShader(const PresentShaderType shaderType, Sha if (found != std::string::npos) { blur1_enabled = blur2_enabled = blur3_enabled = true; - pmShader.textures["blur3"] = textureManager->getTexture("blur3", GL_REPEAT, GL_LINEAR); - pmShader.textures["blur2"] = textureManager->getTexture("blur2", GL_REPEAT, GL_LINEAR); - pmShader.textures["blur1"] = textureManager->getTexture("blur1", GL_REPEAT, GL_LINEAR); + pmShader.m_textures["blur3"] = textureManager->getTexture("blur3", GL_REPEAT, GL_LINEAR); + pmShader.m_textures["blur2"] = textureManager->getTexture("blur2", GL_REPEAT, GL_LINEAR); + pmShader.m_textures["blur1"] = textureManager->getTexture("blur1", GL_REPEAT, GL_LINEAR); } else { @@ -303,8 +303,8 @@ GLuint ShaderEngine::compilePresetShader(const PresentShaderType shaderType, Sha if (found != std::string::npos) { blur1_enabled = blur2_enabled = true; - pmShader.textures["blur2"] = textureManager->getTexture("blur2", GL_REPEAT, GL_LINEAR); - pmShader.textures["blur1"] = textureManager->getTexture("blur1", GL_REPEAT, GL_LINEAR); + pmShader.m_textures["blur2"] = textureManager->getTexture("blur2", GL_REPEAT, GL_LINEAR); + pmShader.m_textures["blur1"] = textureManager->getTexture("blur1", GL_REPEAT, GL_LINEAR); } else { @@ -312,7 +312,7 @@ GLuint ShaderEngine::compilePresetShader(const PresentShaderType shaderType, Sha if (found != std::string::npos) { blur1_enabled = true; - pmShader.textures["blur1"] = textureManager->getTexture("blur1", GL_REPEAT, GL_LINEAR); + pmShader.m_textures["blur1"] = textureManager->getTexture("blur1", GL_REPEAT, GL_LINEAR); } } } @@ -377,8 +377,8 @@ GLuint ShaderEngine::compilePresetShader(const PresentShaderType shaderType, Sha // Declare samplers std::set texsizes; - std::map::const_iterator iter_samplers = pmShader.textures.cbegin(); - for ( ; iter_samplers != pmShader.textures.cend(); ++iter_samplers) + std::map::const_iterator iter_samplers = pmShader.m_textures.cbegin(); + for ( ; iter_samplers != pmShader.m_textures.cend(); ++iter_samplers) { Texture * texture = iter_samplers->second.first; @@ -572,8 +572,8 @@ void ShaderEngine::SetupTextures(GLuint program, const Shader &shader) std::map texsizes; // Set samplers - for (std::map::const_iterator iter_samplers = shader.textures.begin(); iter_samplers - != shader.textures.end(); ++iter_samplers) + for (std::map::const_iterator iter_samplers = shader.m_textures.begin(); iter_samplers + != shader.m_textures.end(); ++iter_samplers) { std::string texName = iter_samplers->first; Texture * texture = iter_samplers->second.first; @@ -813,13 +813,13 @@ void ShaderEngine::loadPresetShaders(Pipeline &pipeline) programID_presetComp = GL_FALSE; // compile and link warp and composite shaders from pipeline - if (!pipeline.warpShader.programSource.empty()) { + if (!pipeline.warpShader.m_programSource.empty()) { programID_presetWarp = loadPresetShader(PresentWarpShader, pipeline.warpShader, pipeline.warpShaderFilename); uniform_vertex_transf_warp_shader = glGetUniformLocation(programID_presetWarp, "vertex_transformation"); presetWarpShaderLoaded = true; } - if (!pipeline.compositeShader.programSource.empty()) { + if (!pipeline.compositeShader.m_programSource.empty()) { programID_presetComp = loadPresetShader(PresentCompositeShader, pipeline.compositeShader, pipeline.compositeShaderFilename); presetCompShaderLoaded = true; } @@ -927,28 +927,14 @@ GLuint ShaderEngine::CompileShaderProgram(const std::string & VertexShaderCode, return linkOK ? programID : GL_FALSE; } -void ShaderEngine::validateProgram(const GLuint programID) { - GLint Result = GL_FALSE; - int InfoLogLength; - - glValidateProgram(programID); - - // Check the program - glGetProgramiv(programID, GL_VALIDATE_STATUS, &Result); - glGetProgramiv(programID, GL_INFO_LOG_LENGTH, &InfoLogLength); - if ( InfoLogLength > 0 ){ - std::vector ProgramErrorMessage(InfoLogLength+1); - glGetProgramInfoLog(programID, InfoLogLength, NULL, &ProgramErrorMessage[0]); - fprintf(stderr, "%s\n", &ProgramErrorMessage[0]); - } -} - // use the appropriate shader program for rendering the interpolation. // it will use the preset shader if available, otherwise the textured shader bool ShaderEngine::enableWarpShader(Shader &shader, const Pipeline &pipeline, const PipelineContext &pipelineContext, const glm::mat4 & mat_ortho) { if (presetWarpShaderLoaded) { glUseProgram(programID_presetWarp); + shader.Bind(); + shader.BindTextures(); SetupTextures(programID_presetWarp, shader); SetupShaderVariables(programID_presetWarp, pipeline, pipelineContext); diff --git a/src/libprojectM/Renderer/ShaderEngine.hpp b/src/libprojectM/Renderer/ShaderEngine.hpp index 6434e745c..9a0f20cbf 100644 --- a/src/libprojectM/Renderer/ShaderEngine.hpp +++ b/src/libprojectM/Renderer/ShaderEngine.hpp @@ -23,26 +23,6 @@ class ShaderEngine; #include "Shader.hpp" #include -class ShaderException : public std::exception -{ -public: - inline ShaderException(std::string message) - : m_message(std::move(message)) - { - } - - virtual ~ShaderException() = default; - - const std::string& message() const - { - return m_message; - } - -private: - std::string m_message; -}; - - class ShaderEngine { public: @@ -56,6 +36,7 @@ public: ShaderEngine(); virtual ~ShaderEngine(); + void loadPresetShaders(Pipeline &pipeline); bool enableWarpShader(Shader &shader, const Pipeline &pipeline, const PipelineContext &pipelineContext, const glm::mat4 & mat_ortho); bool enableCompositeShader(Shader &shader, const Pipeline &pipeline, const PipelineContext &pipelineContext); @@ -88,7 +69,6 @@ private: int texsizeY; float aspectX; float aspectY; - BeatDetect *beatDetect; TextureManager *textureManager; GLint uniform_vertex_transf_warp_shader; @@ -127,10 +107,6 @@ private: void disablePresetShaders(); GLuint loadPresetShader(const PresentShaderType shaderType, Shader &shader, std::string &shaderFilename); - void deletePresetShader(Shader &shader); - void validateProgram(const GLuint programID); - - // programs generated from preset shader code GLuint programID_presetComp, programID_presetWarp;