diff --git a/src/libprojectM/MilkdropPreset/Filters.cpp b/src/libprojectM/MilkdropPreset/Filters.cpp index 948421003..3d1a0e841 100644 --- a/src/libprojectM/MilkdropPreset/Filters.cpp +++ b/src/libprojectM/MilkdropPreset/Filters.cpp @@ -16,7 +16,7 @@ void Filters::Draw() glEnable(GL_BLEND); m_presetState.untexturedShader.Bind(); - m_presetState.untexturedShader.SetUniformMat4x4("vertex_transformation", PresetState::orthogonalProjection); + m_presetState.untexturedShader.SetUniformMat4x4("vertex_transformation", PresetState::orthogonalProjectionFlipped); glBindVertexArray(m_vaoID); glVertexAttrib4f(1, 1.0, 1.0, 1.0, 1.0); diff --git a/src/libprojectM/MilkdropPreset/FinalComposite.cpp b/src/libprojectM/MilkdropPreset/FinalComposite.cpp index eddd8dd9f..6c172c8a9 100644 --- a/src/libprojectM/MilkdropPreset/FinalComposite.cpp +++ b/src/libprojectM/MilkdropPreset/FinalComposite.cpp @@ -139,6 +139,9 @@ void FinalComposite::InitializeMesh(const PresetState& presetState) return; } + float const halfTexelWidth = 0.5f / static_cast(presetState.renderContext.viewportSizeX); + float const halfTexelHeight = 0.5f / static_cast(presetState.renderContext.viewportSizeY); + float const dividedByX = 1.0f / static_cast(compositeGridWidth - 2); float const dividedByY = 1.0f / static_cast(compositeGridHeight - 2); @@ -147,18 +150,19 @@ void FinalComposite::InitializeMesh(const PresetState& presetState) for (int gridY = 0; gridY < compositeGridHeight; gridY++) { int const gridY2 = gridY - gridY / (compositeGridHeight / 2); - float v = gridY2 * dividedByY; - v = SquishToCenter(v, 3.0f); - float sy = -((v) *2 - 1); + float const v = SquishToCenter(gridY2 * dividedByY, 3.0f); + float const sy = -((v - halfTexelHeight) * 2.0f - 1.0f); + for (int gridX = 0; gridX < compositeGridWidth; gridX++) { - int i2 = gridX - gridX / (compositeGridWidth / 2); - float u = i2 * dividedByX; - u = SquishToCenter(u, 3.0f); - float sx = (u) *2 - 1; - auto& pComp = m_vertices.at(gridX + gridY * compositeGridWidth); - pComp.x = sx; - pComp.y = sy; + int const gridX2 = gridX - gridX / (compositeGridWidth / 2); + float const u = SquishToCenter(gridX2 * dividedByX, 3.0f); + float const sx = (u - halfTexelWidth) * 2.0f - 1.0f; + + auto& vertex = m_vertices.at(gridX + gridY * compositeGridWidth); + + vertex.x = sx; + vertex.y = sy; float rad; float ang; @@ -227,11 +231,11 @@ void FinalComposite::InitializeMesh(const PresetState& presetState) ang = PI * 0.0f; } } - pComp.u = u; - pComp.v = 1.0f - v; + vertex.u = u; + vertex.v = v; - pComp.radius = rad; - pComp.angle = ang; + vertex.radius = rad; + vertex.angle = ang; } } @@ -254,8 +258,8 @@ void FinalComposite::InitializeMesh(const PresetState& presetState) bool const leftHalf = (gridX < compositeGridWidth / 2); bool const topHalf = (gridY < compositeGridHeight / 2); - bool const center4 = ((gridX == compositeGridWidth / 2 || gridX == compositeGridWidth / 2 - 1) && - (gridY == compositeGridHeight / 2 || gridY == compositeGridHeight / 2 - 1)); + bool const center4 = ((gridX == compositeGridWidth / 2) && + (gridY == compositeGridHeight / 2)); if ((static_cast(leftHalf) + static_cast(topHalf) + static_cast(center4)) % 2 == 1) { diff --git a/src/libprojectM/MilkdropPreset/MilkdropPreset.cpp b/src/libprojectM/MilkdropPreset/MilkdropPreset.cpp index 65079e28e..7b86acd95 100755 --- a/src/libprojectM/MilkdropPreset/MilkdropPreset.cpp +++ b/src/libprojectM/MilkdropPreset/MilkdropPreset.cpp @@ -81,16 +81,18 @@ void MilkdropPreset::RenderFrame(const libprojectM::Audio::FrameAudioData& audio { m_isFirstFrame = true; } + m_state.mainTexture = m_framebuffer.GetColorAttachmentTexture(m_previousFrameBuffer, 0); + m_framebuffer.MaskDrawBuffer(1, true); // First evaluate per-frame code PerFrameUpdate(); + m_framebuffer.Bind(m_previousFrameBuffer); // Motion vector field. Drawn to the previous frame texture before warping it. // Only do it after drawing one frame after init or resize. if (!m_isFirstFrame) { - m_framebuffer.Bind(m_previousFrameBuffer); m_motionVectors.Draw(m_perFrameContext, m_framebuffer.GetColorAttachmentTexture(m_previousFrameBuffer, 1)); } @@ -103,6 +105,7 @@ void MilkdropPreset::RenderFrame(const libprojectM::Audio::FrameAudioData& audio // Draw previous frame image warped via per-pixel mesh and warp shader m_perPixelMesh.Draw(m_state, m_perFrameContext, m_perPixelContext); + m_framebuffer.MaskDrawBuffer(1, true); // Update blur textures @@ -128,7 +131,7 @@ void MilkdropPreset::RenderFrame(const libprojectM::Audio::FrameAudioData& audio // Todo: Song title anim would go here - // We no longer need the previous frame image, as the composite shader reads from the current frame image. + // We no longer need the previous frame image, use it to render the final composite. m_framebuffer.BindRead(m_currentFrameBuffer); m_framebuffer.BindDraw(m_previousFrameBuffer); m_state.mainTexture = m_framebuffer.GetColorAttachmentTexture(m_currentFrameBuffer, 0); @@ -140,8 +143,10 @@ void MilkdropPreset::RenderFrame(const libprojectM::Audio::FrameAudioData& audio // TEST: Copy result to default framebuffer m_framebuffer.BindRead(m_previousFrameBuffer); glBindFramebuffer(GL_DRAW_FRAMEBUFFER, 0); + glReadBuffer(GL_COLOR_ATTACHMENT0); + glDrawBuffer(GL_COLOR_ATTACHMENT0); glBlitFramebuffer(0, 0, renderContext.viewportSizeX, renderContext.viewportSizeY, - renderContext.viewportSizeX, renderContext.viewportSizeY,0, 0, + 0, 0, renderContext.viewportSizeX, renderContext.viewportSizeY, GL_COLOR_BUFFER_BIT, GL_NEAREST); // Swap framebuffers for the next frame. @@ -211,9 +216,9 @@ void MilkdropPreset::Load(std::istream& stream) void MilkdropPreset::InitializePreset(PresetFileParser& parsedFile) { // Create the offscreen rendering surfaces. - m_framebuffer.CreateColorAttachment(0, 0); // Main image + m_framebuffer.CreateColorAttachment(0, 0); // Main image m_framebuffer.CreateColorAttachment(0, 1, GL_RG16F, GL_RG, GL_FLOAT); // Motion vector u/v - m_framebuffer.CreateColorAttachment(1, 0); // Main image + m_framebuffer.CreateColorAttachment(1, 0); // Main image m_framebuffer.CreateColorAttachment(1, 1, GL_RG16F, GL_RG, GL_FLOAT); // Motion vector u/v // Mask the motion vector buffer by default. diff --git a/src/libprojectM/MilkdropPreset/MilkdropPreset.hpp b/src/libprojectM/MilkdropPreset/MilkdropPreset.hpp index b9259cea9..5170fe27d 100644 --- a/src/libprojectM/MilkdropPreset/MilkdropPreset.hpp +++ b/src/libprojectM/MilkdropPreset/MilkdropPreset.hpp @@ -96,11 +96,6 @@ private: auto ParseFilename(const std::string& filename) -> std::string; - /** - * @brief Draws the composite shader quad to create the final output image. - */ - void ApplyCompositeShader(); - std::string m_absoluteFilePath; //!< The absolute file path of the MilkdropPreset std::string m_absolutePath; //!< The absolute path of the MilkdropPreset diff --git a/src/libprojectM/MilkdropPreset/MilkdropShader.cpp b/src/libprojectM/MilkdropPreset/MilkdropShader.cpp index 92c168c1a..310da3fd6 100644 --- a/src/libprojectM/MilkdropPreset/MilkdropShader.cpp +++ b/src/libprojectM/MilkdropPreset/MilkdropShader.cpp @@ -120,7 +120,7 @@ void MilkdropShader::LoadVariables(const PresetState& presetState, const PerFram m_shader.Bind(); - m_shader.SetUniformMat4x4("vertex_transformation", PresetState::orthogonalProjection); + m_shader.SetUniformMat4x4("vertex_transformation", PresetState::orthogonalProjectionFlipped); m_shader.SetUniformFloat4("rand_frame", {floatRand(), floatRand(), diff --git a/src/libprojectM/MilkdropPreset/MotionVectors.cpp b/src/libprojectM/MilkdropPreset/MotionVectors.cpp index 479b2aead..9f7eecf45 100644 --- a/src/libprojectM/MilkdropPreset/MotionVectors.cpp +++ b/src/libprojectM/MilkdropPreset/MotionVectors.cpp @@ -86,7 +86,7 @@ void MotionVectors::Draw(const PerFrameContext& presetPerFrameContext, std::shar glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); m_motionVectorShader.Bind(); - m_motionVectorShader.SetUniformMat4x4("vertex_transformation", m_presetState.orthogonalProjection); + m_motionVectorShader.SetUniformMat4x4("vertex_transformation", PresetState::orthogonalProjection); m_motionVectorShader.SetUniformFloat("length_multiplier", static_cast(*presetPerFrameContext.mv_l)); m_motionVectorShader.SetUniformFloat("minimum_length", minimumLength); diff --git a/src/libprojectM/MilkdropPreset/PerPixelMesh.cpp b/src/libprojectM/MilkdropPreset/PerPixelMesh.cpp index 604f9d7eb..e9de17fc2 100644 --- a/src/libprojectM/MilkdropPreset/PerPixelMesh.cpp +++ b/src/libprojectM/MilkdropPreset/PerPixelMesh.cpp @@ -33,13 +33,15 @@ void PerPixelMesh::InitVertexAttrib() glEnableVertexAttribArray(2); glEnableVertexAttribArray(3); glEnableVertexAttribArray(4); + glEnableVertexAttribArray(5); // Only position & texture coordinates are per-vertex, colors are equal all over the grid (used for decay). - glVertexAttribPointer(0, 4, GL_FLOAT, GL_FALSE, sizeof(MeshVertex), reinterpret_cast(offsetof(MeshVertex, x))); // Position, radius & angle - glVertexAttribPointer(1, 4, GL_FLOAT, GL_FALSE, sizeof(MeshVertex), reinterpret_cast(offsetof(MeshVertex, zoom))); // zoom, zoom exponent, rotation & warp - glVertexAttribPointer(2, 2, GL_FLOAT, GL_FALSE, sizeof(MeshVertex), reinterpret_cast(offsetof(MeshVertex, centerX))); // Center coord - glVertexAttribPointer(3, 2, GL_FLOAT, GL_FALSE, sizeof(MeshVertex), reinterpret_cast(offsetof(MeshVertex, distanceX))); // Distance - glVertexAttribPointer(4, 2, GL_FLOAT, GL_FALSE, sizeof(MeshVertex), reinterpret_cast(offsetof(MeshVertex, stretchX))); // Stretch + glVertexAttribPointer(0, 2, GL_FLOAT, GL_FALSE, sizeof(MeshVertex), reinterpret_cast(offsetof(MeshVertex, x))); // Position, radius & angle + glVertexAttribPointer(1, 2, GL_FLOAT, GL_FALSE, sizeof(MeshVertex), reinterpret_cast(offsetof(MeshVertex, radius))); // Position, radius & angle + glVertexAttribPointer(2, 4, GL_FLOAT, GL_FALSE, sizeof(MeshVertex), reinterpret_cast(offsetof(MeshVertex, zoom))); // zoom, zoom exponent, rotation & warp + glVertexAttribPointer(3, 2, GL_FLOAT, GL_FALSE, sizeof(MeshVertex), reinterpret_cast(offsetof(MeshVertex, centerX))); // Center coord + glVertexAttribPointer(4, 2, GL_FLOAT, GL_FALSE, sizeof(MeshVertex), reinterpret_cast(offsetof(MeshVertex, distanceX))); // Distance + glVertexAttribPointer(5, 2, GL_FLOAT, GL_FALSE, sizeof(MeshVertex), reinterpret_cast(offsetof(MeshVertex, stretchX))); // Stretch glBindVertexArray(0); glBindBuffer(GL_ARRAY_BUFFER, 0); @@ -134,6 +136,9 @@ void PerPixelMesh::InitializeMesh(const PresetState& presetState) return; } + float aspectX = static_cast(presetState.renderContext.aspectX); + float aspectY = static_cast(presetState.renderContext.aspectY); + // Either viewport size or mesh size changed, reinitialize the vertices. int vertexIndex{0}; for (int gridY = 0; gridY <= m_gridSizeY; gridY++) @@ -146,16 +151,14 @@ void PerPixelMesh::InitializeMesh(const PresetState& presetState) vertex.y = static_cast(gridY) / static_cast(m_gridSizeY) * 2.0f - 1.0f; // Milkdrop uses sqrtf, but hypotf is probably safer. - vertex.radius = hypotf(vertex.x * static_cast(presetState.renderContext.aspectX), - vertex.y * static_cast(presetState.renderContext.aspectY)); + vertex.radius = hypotf(vertex.x * aspectX, vertex.y * aspectY); if (gridY == m_gridSizeY / 2 && gridX == m_gridSizeX / 2) { vertex.angle = 0.0f; } else { - vertex.angle = atan2f(vertex.y * static_cast(presetState.renderContext.aspectY), - vertex.x * static_cast(presetState.renderContext.aspectX)); + vertex.angle = atan2f(vertex.y * aspectY, vertex.x * aspectX); } vertexIndex++; @@ -303,7 +306,7 @@ void PerPixelMesh::WarpedBlit(const PresetState& presetState, if (!m_warpShader) { m_perPixelMeshShader.Bind(); - m_perPixelMeshShader.SetUniformMat4x4("vertex_transformation", PresetState::orthogonalProjection); + m_perPixelMeshShader.SetUniformMat4x4("vertex_transformation", PresetState::orthogonalProjectionFlipped); m_perPixelMeshShader.SetUniformInt("texture_sampler", 0); m_perPixelMeshShader.SetUniformFloat4("aspect", {presetState.renderContext.aspectX, presetState.renderContext.aspectY, @@ -320,9 +323,9 @@ void PerPixelMesh::WarpedBlit(const PresetState& presetState, m_warpShader->LoadVariables(presetState, perFrameContext); auto& shader = m_warpShader->Shader(); shader.SetUniformFloat4("aspect", {presetState.renderContext.aspectX, - presetState.renderContext.aspectY, - presetState.renderContext.invAspectX, - presetState.renderContext.invAspectY}); + presetState.renderContext.aspectY, + presetState.renderContext.invAspectX, + presetState.renderContext.invAspectY}); shader.SetUniformFloat("warpTime", warpTime); shader.SetUniformFloat("warpScaleInverse", warpScaleInverse); shader.SetUniformFloat4("warpFactors", warpFactors); diff --git a/src/libprojectM/MilkdropPreset/PerPixelMesh.hpp b/src/libprojectM/MilkdropPreset/PerPixelMesh.hpp index 8247530b3..9f3b7638f 100644 --- a/src/libprojectM/MilkdropPreset/PerPixelMesh.hpp +++ b/src/libprojectM/MilkdropPreset/PerPixelMesh.hpp @@ -111,15 +111,15 @@ private: int m_gridSizeX{}; //!< Warp mesh X resolution. int m_gridSizeY{}; //!< Warp mesh Y resolution. - int m_viewportWidth{}; //!< Last known viewport width. + int m_viewportWidth{}; //!< Last known viewport width. int m_viewportHeight{}; //!< Last known viewport height. VertexList m_vertices; //!< The calculated mesh vertices. - std::vector m_listIndices; //!< List of vertex indices to render. - VertexList m_drawVertices; //!< Temp data buffer for the vertices to be drawn. + std::vector m_listIndices; //!< List of vertex indices to render. + VertexList m_drawVertices; //!< Temp data buffer for the vertices to be drawn. - Shader m_perPixelMeshShader; //!< Special shader which calculates the per-pixel UV coordinates. + Shader m_perPixelMeshShader; //!< Special shader which calculates the per-pixel UV coordinates. std::unique_ptr m_warpShader; //!< The warp shader. Either preset-defined or a default shader. Sampler m_perPixelSampler{GL_CLAMP_TO_EDGE, GL_LINEAR}; //!< The main texture sampler. }; diff --git a/src/libprojectM/MilkdropPreset/PresetState.cpp b/src/libprojectM/MilkdropPreset/PresetState.cpp index 2bead8ca2..68dea1108 100644 --- a/src/libprojectM/MilkdropPreset/PresetState.cpp +++ b/src/libprojectM/MilkdropPreset/PresetState.cpp @@ -7,6 +7,7 @@ #include const glm::mat4 PresetState::orthogonalProjection = glm::ortho(-1.0f, 1.0f, -1.0f, 1.0f, -40.0f, 40.0f); +const glm::mat4 PresetState::orthogonalProjectionFlipped = glm::ortho(-1.0f, 1.0f, 1.0f, -1.0f, -40.0f, 40.0f); PresetState::PresetState() : globalMemory(projectm_eval_memory_buffer_create()) @@ -81,7 +82,7 @@ void PresetState::Initialize(PresetFileParser& parsedFile) mvR = parsedFile.GetFloat("mv_r", mvR); mvG = parsedFile.GetFloat("mv_g", mvG); mvB = parsedFile.GetFloat("mv_b", mvB); - mvA = parsedFile.GetBool("bMotionVectorsOn", false) ? 0.0 : 1.0; // for backwards compatibility + mvA = parsedFile.GetBool("bMotionVectorsOn", false) ? 1.0 : 0.0; // for backwards compatibility mvA = parsedFile.GetFloat("mv_a", mvA); // Motion: @@ -99,6 +100,8 @@ void PresetState::Initialize(PresetFileParser& parsedFile) warpAnimSpeed = parsedFile.GetFloat("fWarpAnimSpeed", warpAnimSpeed); warpScale = parsedFile.GetFloat("fWarpScale", warpScale); zoomExponent = parsedFile.GetFloat("fZoomExponent", zoomExponent); + + // Borders: outerBorderSize = parsedFile.GetFloat("ob_size", outerBorderSize); outerBorderR = parsedFile.GetFloat("ob_r", outerBorderR); outerBorderG = parsedFile.GetFloat("ob_g", outerBorderG); diff --git a/src/libprojectM/MilkdropPreset/PresetState.hpp b/src/libprojectM/MilkdropPreset/PresetState.hpp index 1b7b17202..60c17f96f 100644 --- a/src/libprojectM/MilkdropPreset/PresetState.hpp +++ b/src/libprojectM/MilkdropPreset/PresetState.hpp @@ -110,7 +110,7 @@ public: BlendableFloat mvR{1.0f}; BlendableFloat mvG{1.0f}; BlendableFloat mvB{1.0f}; - BlendableFloat mvA{1.0f}; + BlendableFloat mvA{0.0f}; BlendableFloat blur1Min{0.0f}; BlendableFloat blur2Min{0.0f}; BlendableFloat blur3Min{0.0f}; @@ -160,4 +160,5 @@ public: std::map randomTextureDescriptors; //!< Descriptors for random texture IDs. Should be the same across both warp and comp shaders. static const glm::mat4 orthogonalProjection; //!< Projection matrix that transforms DirectX screen-space coordinates into the OpenGL coordinate frame. + static const glm::mat4 orthogonalProjectionFlipped; //!< Projection matrix that transforms DirectX screen-space coordinates into the OpenGL coordinate frame. }; diff --git a/src/libprojectM/MilkdropPreset/VideoEcho.cpp b/src/libprojectM/MilkdropPreset/VideoEcho.cpp index fee27a26a..5b53a33b4 100644 --- a/src/libprojectM/MilkdropPreset/VideoEcho.cpp +++ b/src/libprojectM/MilkdropPreset/VideoEcho.cpp @@ -69,7 +69,7 @@ void VideoEcho::Draw() } m_presetState.texturedShader.Bind(); - m_presetState.texturedShader.SetUniformMat4x4("vertex_transformation", PresetState::orthogonalProjection); + m_presetState.texturedShader.SetUniformMat4x4("vertex_transformation", PresetState::orthogonalProjectionFlipped); m_presetState.texturedShader.SetUniformInt("texture_sampler", 0); auto mainTexture = m_presetState.mainTexture.lock(); @@ -122,13 +122,13 @@ void VideoEcho::DrawVideoEcho() float const tempLow = 0.5f - 0.5f / zoom; float const temphigh = 0.5f + 0.5f / zoom; m_vertices[0].u = tempLow; - m_vertices[0].v = temphigh; + m_vertices[0].v = tempLow; m_vertices[1].u = temphigh; - m_vertices[1].v = temphigh; + m_vertices[1].v = tempLow; m_vertices[2].u = tempLow; - m_vertices[2].v = tempLow; + m_vertices[2].v = temphigh; m_vertices[3].u = temphigh; - m_vertices[3].v = tempLow; + m_vertices[3].v = temphigh; // Flipping if (pass == 1) @@ -197,13 +197,13 @@ void VideoEcho::DrawVideoEcho() void VideoEcho::DrawGammaAdjustment() { m_vertices[0].u = 0.0f; - m_vertices[0].v = 1.0f; + m_vertices[0].v = 0.0f; m_vertices[1].u = 1.0f; - m_vertices[1].v = 1.0f; + m_vertices[1].v = 0.0f; m_vertices[2].u = 0.0f; - m_vertices[2].v = 0.0f; + m_vertices[2].v = 1.0f; m_vertices[3].u = 1.0f; - m_vertices[3].v = 0.0f; + m_vertices[3].v = 1.0f; glDisable(GL_BLEND); glBlendFunc(GL_ONE, GL_ZERO); diff --git a/src/libprojectM/MilkdropPreset/Waveform.cpp b/src/libprojectM/MilkdropPreset/Waveform.cpp index 624e08a72..963672f5b 100644 --- a/src/libprojectM/MilkdropPreset/Waveform.cpp +++ b/src/libprojectM/MilkdropPreset/Waveform.cpp @@ -72,10 +72,6 @@ void Waveform::Draw(const PerFrameContext& presetPerFrameContext) const auto smoothedSamples = SmoothWave(waveVertices, smoothedWave.data()); m_tempAlpha = static_cast(*presetPerFrameContext.wave_a); - if (m_presetState.modWaveAlphaByvolume) - { - ModulateOpacityByVolume(presetPerFrameContext); - } MaximizeColors(presetPerFrameContext); // Always draw "thick" dots. @@ -159,8 +155,7 @@ void Waveform::MaximizeColors(const PerFrameContext& presetPerFrameContext) // the rest accordingly int texsize = std::max(m_presetState.renderContext.viewportSizeX, m_presetState.renderContext.viewportSizeY); - - if (m_mode == Mode::Blob2 || m_mode == Mode::ExplosiveHash) + if (m_mode == Mode::CenteredSpiro || m_mode == Mode::ExplosiveHash) { if (texsize <= 256) { @@ -184,7 +179,7 @@ void Waveform::MaximizeColors(const PerFrameContext& presetPerFrameContext) m_tempAlpha *= 0.15f; } } - else if (m_mode == Mode::Blob3) + else if (m_mode == Mode::CenteredSpiroVolume) { if (texsize <= 256) { @@ -211,6 +206,11 @@ void Waveform::MaximizeColors(const PerFrameContext& presetPerFrameContext) m_tempAlpha *= std::pow(m_presetState.audioData.treb, 2.0f); } + if (m_presetState.modWaveAlphaByvolume) + { + ModulateOpacityByVolume(presetPerFrameContext); + } + if (m_tempAlpha < 0.0f) { m_tempAlpha = 0.0f; @@ -221,39 +221,32 @@ void Waveform::MaximizeColors(const PerFrameContext& presetPerFrameContext) m_tempAlpha = 1.0f; } + float waveR{static_cast(*presetPerFrameContext.wave_r)}; + float waveG{static_cast(*presetPerFrameContext.wave_g)}; + float waveB{static_cast(*presetPerFrameContext.wave_b)}; + if (*presetPerFrameContext.wave_brighten > 0) { constexpr float fMaximizeWaveColorAmount = 1.0f; - float cr{static_cast(*presetPerFrameContext.wave_r)}; - float cg{static_cast(*presetPerFrameContext.wave_g)}; - float cb{static_cast(*presetPerFrameContext.wave_b)}; - float max = cr; - if (max < cg) + float max = waveR; + if (max < waveG) { - max = cg; + max = waveG; } - if (max < cb) + if (max < waveB) { - max = cb; + max = waveB; } if (max > 0.01f) { - cr = cr / max * fMaximizeWaveColorAmount + cr * (1.0f - fMaximizeWaveColorAmount); - cg = cg / max * fMaximizeWaveColorAmount + cg * (1.0f - fMaximizeWaveColorAmount); - cb = cb / max * fMaximizeWaveColorAmount + cb * (1.0f - fMaximizeWaveColorAmount); + waveR = waveR / max * fMaximizeWaveColorAmount + waveR * (1.0f - fMaximizeWaveColorAmount); + waveG = waveG / max * fMaximizeWaveColorAmount + waveG * (1.0f - fMaximizeWaveColorAmount); + waveB = waveB / max * fMaximizeWaveColorAmount + waveB * (1.0f - fMaximizeWaveColorAmount); } + } - glVertexAttrib4f(1, cr, cg, cb, m_tempAlpha); - } - else - { - glVertexAttrib4f(1, - static_cast(*presetPerFrameContext.wave_r), - static_cast(*presetPerFrameContext.wave_g), - static_cast(*presetPerFrameContext.wave_b), - m_tempAlpha); - } + glVertexAttrib4f(1, waveR, waveG, waveB, m_tempAlpha); } @@ -378,8 +371,8 @@ void Waveform::WaveformMath(const PerFrameContext& presetPerFrameContext) break; } - case Mode::Blob2: - case Mode::Blob3: { // Both "centered spiro" waveforms are identical. Only difference is the alpha value. + case Mode::CenteredSpiro: + case Mode::CenteredSpiroVolume: { // Both "centered spiro" waveforms are identical. Only difference is the alpha value. // Alpha calculation is handled in MaximizeColors(). m_samples = RenderWaveformSamples; diff --git a/src/libprojectM/MilkdropPreset/Waveform.hpp b/src/libprojectM/MilkdropPreset/Waveform.hpp index 67b5eca33..07b52eeea 100644 --- a/src/libprojectM/MilkdropPreset/Waveform.hpp +++ b/src/libprojectM/MilkdropPreset/Waveform.hpp @@ -15,8 +15,8 @@ public: { Circle = 0, //!< Circular wave. XYOscillationSpiral, //!< X-Y osc. that goes around in a spiral, in time. - Blob2, //!< Centered spiro (alpha constant). Aimed at not being so sound-responsive, but being very "nebula-like". - Blob3, //!< Centered spiro (alpha tied to volume). Aimed at having a strong audio-visual tie-in. + CenteredSpiro, //!< Centered spiro (alpha constant). Aimed at not being so sound-responsive, but being very "nebula-like". + CenteredSpiroVolume, //!< Centered spiro (alpha tied to volume). Aimed at having a strong audio-visual tie-in. DerivativeLine, //!< Horizontal "script", left channel. ExplosiveHash, //!< Weird explosive complex # thingy. Line, //!< Angle-adjustable left channel, with temporal wave alignment. diff --git a/src/libprojectM/Renderer/StaticGlShaders.cpp b/src/libprojectM/Renderer/StaticGlShaders.cpp index e2b10ed26..c3b2368f3 100644 --- a/src/libprojectM/Renderer/StaticGlShaders.cpp +++ b/src/libprojectM/Renderer/StaticGlShaders.cpp @@ -51,7 +51,11 @@ void main(){ // Initial texture coordinates, with built-in zoom factor vec2 uv = vec2(pos.x * aspectX * 0.5 * zoom2Inverse + 0.5, - -pos.y * aspectY * 0.5 * zoom2Inverse + 0.5); + pos.y * aspectY * 0.5 * zoom2Inverse + 0.5); + + // original UV coordinates + vec2 uv_original = vec2(pos.x * 0.5 + 0.5 + texelOffset.x, + pos.y * 0.5 + 0.5 + texelOffset.y); // Stretch on X, Y uv.x = (uv.x - center.x) / stretch.x + center.x; @@ -70,7 +74,7 @@ void main(){ float cosRotation = cos(rot); float sinRotation = sin(rot); uv.x = uv2.x * cosRotation - uv2.y * sinRotation + center.x; - uv.y = uv2.x * sinRotation - uv2.y * cosRotation + center.y; + uv.y = uv2.x * sinRotation + uv2.y * cosRotation + center.y; // Translation uv -= distance; @@ -85,7 +89,7 @@ void main(){ frag_COLOR = vec4(decay, decay, decay, 1.0); frag_TEXCOORD0.xy = uv; frag_TEXCOORD0.zw = gl_Position.xy; - frag_TEXCOORD1 = vertex_position.zw; + frag_TEXCOORD1 = uv_original; } )"; @@ -505,9 +509,9 @@ void main() { )"; const std::string kPresetWarpVertexShaderGlsl330 = R"( -#define pos vertex_position.xy -#define radius vertex_position.z -#define angle vertex_position.w +#define pos vertex_position +#define radius rad_ang.x +#define angle rad_ang.y #define zoom transforms.x #define zoomExp transforms.y #define rot transforms.z @@ -518,11 +522,12 @@ const std::string kPresetWarpVertexShaderGlsl330 = R"( #define invAspectX aspect.z #define invAspectY aspect.w -layout(location = 0) in vec4 vertex_position; -layout(location = 1) in vec4 transforms; -layout(location = 2) in vec2 center; -layout(location = 3) in vec2 distance; -layout(location = 4) in vec2 stretch; +layout(location = 0) in vec2 vertex_position; +layout(location = 1) in vec2 rad_ang; +layout(location = 2) in vec4 transforms; +layout(location = 3) in vec2 center; +layout(location = 4) in vec2 distance; +layout(location = 5) in vec2 stretch; uniform mat4 vertex_transformation; uniform vec4 aspect; @@ -537,52 +542,54 @@ out vec4 frag_TEXCOORD0; out vec2 frag_TEXCOORD1; void main() { - gl_Position = vertex_transformation * vec4(vec2(pos.x, -pos.y), 0.0, 1.0); + gl_Position = vertex_transformation * vec4(pos, 0.0, 1.0); float zoom2 = pow(zoom, pow(zoomExp, radius * 2.0 - 1.0)); float zoom2Inverse = 1.0 / zoom2; // Initial texture coordinates, with built-in zoom factor - vec2 uv = vec2(pos.x * aspectX * 0.5 * zoom2Inverse + 0.5, - pos.y * aspectY * 0.5 * zoom2Inverse + 0.5); + float u = pos.x * aspectX * 0.5 * zoom2Inverse + 0.5; + float v = -pos.y * aspectY * 0.5 * zoom2Inverse + 0.5; // original UV coordinates vec2 uv_original = vec2(pos.x * 0.5 + 0.5 + texelOffset.x, -pos.y * 0.5 + 0.5 + texelOffset.y); // Stretch on X, Y - uv.x = (uv.x - center.x) / stretch.x + center.x; - uv.y = (uv.y - center.y) / stretch.y + center.y; + u = (u - center.x) / stretch.x + center.x; + v = (v - center.y) / stretch.y + center.y; // Warping - uv.x += warp * 0.0035 * sin(warpTime * 0.333 + warpScaleInverse * (pos.x * warpFactors.x - pos.y * warpFactors.w)); - uv.y += warp * 0.0035 * cos(warpTime * 0.375 - warpScaleInverse * (pos.x * warpFactors.z + pos.y * warpFactors.y)); - uv.x += warp * 0.0035 * cos(warpTime * 0.753 - warpScaleInverse * (pos.x * warpFactors.y - pos.y * warpFactors.z)); - uv.y += warp * 0.0035 * sin(warpTime * 0.825 + warpScaleInverse * (pos.x * warpFactors.x + pos.y * warpFactors.w)); + u += warp * 0.0035 * sin(warpTime * 0.333 + warpScaleInverse * (pos.x * warpFactors.x - pos.y * warpFactors.w)); + v += warp * 0.0035 * cos(warpTime * 0.375 - warpScaleInverse * (pos.x * warpFactors.z + pos.y * warpFactors.y)); + u += warp * 0.0035 * cos(warpTime * 0.753 - warpScaleInverse * (pos.x * warpFactors.y - pos.y * warpFactors.z)); + v += warp * 0.0035 * sin(warpTime * 0.825 + warpScaleInverse * (pos.x * warpFactors.x + pos.y * warpFactors.w)); // Rotation - vec2 uv2 = vec2(uv.x - center.x, - uv.y - center.y); + float u2 = u - center.x; + float v2 = v - center.y; float cosRotation = cos(rot); float sinRotation = sin(rot); - uv.x = uv2.x * cosRotation - uv2.y * sinRotation + center.x; - uv.y = uv2.x * sinRotation - uv2.y * cosRotation + center.y; + u = u2 * cosRotation - v2 * sinRotation + center.x; + v = u2 * sinRotation + v2 * cosRotation + center.y; // Translation - uv -= distance; + u -= distance.x; + v -= distance.y; // Undo aspect ratio fix - uv.x = (uv.x - 0.5) * invAspectX + 0.5; - uv.y = (uv.y - 0.5) * invAspectY + 0.5; + u = (u - 0.5) * invAspectX + 0.5; + v = (v - 0.5) * invAspectY + 0.5; // Final half-texel translation - uv += texelOffset; + u += texelOffset.x; + v += texelOffset.y; frag_COLOR = vec4(decay, decay, decay, 1.0); - frag_TEXCOORD0.xy = uv; + frag_TEXCOORD0.xy = vec2(u, v); frag_TEXCOORD0.zw = uv_original; - frag_TEXCOORD1 = vertex_position.zw; + frag_TEXCOORD1 = rad_ang; } )";