mirror of
https://github.com/projectM-visualizer/projectm.git
synced 2026-02-05 01:25:28 +00:00
Fixed more UV coordinate issues in the warp shader.
Main issue was a wrong -, replaced with + in the rotation calculation. Plus we shouldn't negate the Y pos, as this may mess up UV calculations done in HLSL.
This commit is contained in:
@ -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);
|
||||
|
||||
@ -139,6 +139,9 @@ void FinalComposite::InitializeMesh(const PresetState& presetState)
|
||||
return;
|
||||
}
|
||||
|
||||
float const halfTexelWidth = 0.5f / static_cast<float>(presetState.renderContext.viewportSizeX);
|
||||
float const halfTexelHeight = 0.5f / static_cast<float>(presetState.renderContext.viewportSizeY);
|
||||
|
||||
float const dividedByX = 1.0f / static_cast<float>(compositeGridWidth - 2);
|
||||
float const dividedByY = 1.0f / static_cast<float>(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<int>(leftHalf) + static_cast<int>(topHalf) + static_cast<int>(center4)) % 2 == 1)
|
||||
{
|
||||
|
||||
@ -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.
|
||||
|
||||
@ -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
|
||||
|
||||
|
||||
@ -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(),
|
||||
|
||||
@ -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<float>(*presetPerFrameContext.mv_l));
|
||||
m_motionVectorShader.SetUniformFloat("minimum_length", minimumLength);
|
||||
|
||||
|
||||
@ -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<void*>(offsetof(MeshVertex, x))); // Position, radius & angle
|
||||
glVertexAttribPointer(1, 4, GL_FLOAT, GL_FALSE, sizeof(MeshVertex), reinterpret_cast<void*>(offsetof(MeshVertex, zoom))); // zoom, zoom exponent, rotation & warp
|
||||
glVertexAttribPointer(2, 2, GL_FLOAT, GL_FALSE, sizeof(MeshVertex), reinterpret_cast<void*>(offsetof(MeshVertex, centerX))); // Center coord
|
||||
glVertexAttribPointer(3, 2, GL_FLOAT, GL_FALSE, sizeof(MeshVertex), reinterpret_cast<void*>(offsetof(MeshVertex, distanceX))); // Distance
|
||||
glVertexAttribPointer(4, 2, GL_FLOAT, GL_FALSE, sizeof(MeshVertex), reinterpret_cast<void*>(offsetof(MeshVertex, stretchX))); // Stretch
|
||||
glVertexAttribPointer(0, 2, GL_FLOAT, GL_FALSE, sizeof(MeshVertex), reinterpret_cast<void*>(offsetof(MeshVertex, x))); // Position, radius & angle
|
||||
glVertexAttribPointer(1, 2, GL_FLOAT, GL_FALSE, sizeof(MeshVertex), reinterpret_cast<void*>(offsetof(MeshVertex, radius))); // Position, radius & angle
|
||||
glVertexAttribPointer(2, 4, GL_FLOAT, GL_FALSE, sizeof(MeshVertex), reinterpret_cast<void*>(offsetof(MeshVertex, zoom))); // zoom, zoom exponent, rotation & warp
|
||||
glVertexAttribPointer(3, 2, GL_FLOAT, GL_FALSE, sizeof(MeshVertex), reinterpret_cast<void*>(offsetof(MeshVertex, centerX))); // Center coord
|
||||
glVertexAttribPointer(4, 2, GL_FLOAT, GL_FALSE, sizeof(MeshVertex), reinterpret_cast<void*>(offsetof(MeshVertex, distanceX))); // Distance
|
||||
glVertexAttribPointer(5, 2, GL_FLOAT, GL_FALSE, sizeof(MeshVertex), reinterpret_cast<void*>(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<float>(presetState.renderContext.aspectX);
|
||||
float aspectY = static_cast<float>(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<float>(gridY) / static_cast<float>(m_gridSizeY) * 2.0f - 1.0f;
|
||||
|
||||
// Milkdrop uses sqrtf, but hypotf is probably safer.
|
||||
vertex.radius = hypotf(vertex.x * static_cast<float>(presetState.renderContext.aspectX),
|
||||
vertex.y * static_cast<float>(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<float>(presetState.renderContext.aspectY),
|
||||
vertex.x * static_cast<float>(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);
|
||||
|
||||
@ -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<int> m_listIndices; //!< List of vertex indices to render.
|
||||
VertexList m_drawVertices; //!< Temp data buffer for the vertices to be drawn.
|
||||
std::vector<int> 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<MilkdropShader> 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.
|
||||
};
|
||||
|
||||
@ -7,6 +7,7 @@
|
||||
#include <random>
|
||||
|
||||
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);
|
||||
|
||||
@ -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<int, TextureSamplerDescriptor> 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.
|
||||
};
|
||||
|
||||
@ -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);
|
||||
|
||||
@ -72,10 +72,6 @@ void Waveform::Draw(const PerFrameContext& presetPerFrameContext)
|
||||
const auto smoothedSamples = SmoothWave(waveVertices, smoothedWave.data());
|
||||
|
||||
m_tempAlpha = static_cast<float>(*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<float>(*presetPerFrameContext.wave_r)};
|
||||
float waveG{static_cast<float>(*presetPerFrameContext.wave_g)};
|
||||
float waveB{static_cast<float>(*presetPerFrameContext.wave_b)};
|
||||
|
||||
if (*presetPerFrameContext.wave_brighten > 0)
|
||||
{
|
||||
constexpr float fMaximizeWaveColorAmount = 1.0f;
|
||||
float cr{static_cast<float>(*presetPerFrameContext.wave_r)};
|
||||
float cg{static_cast<float>(*presetPerFrameContext.wave_g)};
|
||||
float cb{static_cast<float>(*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<float>(*presetPerFrameContext.wave_r),
|
||||
static_cast<float>(*presetPerFrameContext.wave_g),
|
||||
static_cast<float>(*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;
|
||||
|
||||
|
||||
@ -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.
|
||||
|
||||
@ -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;
|
||||
}
|
||||
)";
|
||||
|
||||
|
||||
Reference in New Issue
Block a user