Mimic Milkdrop code when handling RGBA values outside [0.0, 1.0]

This commit is contained in:
Dane Wagner
2024-02-13 15:22:57 -06:00
committed by Kai Blaschke
parent db89e54109
commit 0c27e8164a
3 changed files with 61 additions and 12 deletions

View File

@ -3,6 +3,7 @@
#include "PresetFileParser.hpp"
#include <Renderer/TextureManager.hpp>
#include <Renderer/RenderItem.hpp>
#include <vector>
@ -155,15 +156,21 @@ void CustomShape::Draw()
vertexData[0].u = 0.5f;
vertexData[0].v = 0.5f;
vertexData[0].r = static_cast<float>(*m_perFrameContext.r);
vertexData[0].g = static_cast<float>(*m_perFrameContext.g);
vertexData[0].b = static_cast<float>(*m_perFrameContext.b);
vertexData[0].a = static_cast<float>(*m_perFrameContext.a);
// x = f*255.0 & 0xFF = (f*255.0) % 256
// f' = x/255.0 = f % (256/255)
// 1.0 -> 255 (0xFF)
// 2.0 -> 254 (0xFE)
// -1.0 -> 0x01
vertexData[1].r = static_cast<float>(*m_perFrameContext.r2);
vertexData[1].g = static_cast<float>(*m_perFrameContext.g2);
vertexData[1].b = static_cast<float>(*m_perFrameContext.b2);
vertexData[1].a = static_cast<float>(*m_perFrameContext.a2);
vertexData[0].r = Renderer::color_modulo(*m_perFrameContext.r);
vertexData[0].g = Renderer::color_modulo(*m_perFrameContext.g);
vertexData[0].b = Renderer::color_modulo(*m_perFrameContext.b);
vertexData[0].a = Renderer::color_modulo(*m_perFrameContext.a);
vertexData[1].r = Renderer::color_modulo(*m_perFrameContext.r2);
vertexData[1].g = Renderer::color_modulo(*m_perFrameContext.g2);
vertexData[1].b = Renderer::color_modulo(*m_perFrameContext.b2);
vertexData[1].a = Renderer::color_modulo(*m_perFrameContext.a2);
for (int i = 1; i < sides + 1; i++)
{

View File

@ -157,10 +157,10 @@ void CustomWaveform::Draw(const PerFrameContext& presetPerFrameContext)
pointsTransformed[sample].x = static_cast<float>((*m_perPointContext.x * 2.0 - 1.0) * m_presetState.renderContext.invAspectX);
pointsTransformed[sample].y = static_cast<float>((*m_perPointContext.y * -2.0 + 1.0) * m_presetState.renderContext.invAspectY);
pointsTransformed[sample].r = static_cast<float>(*m_perPointContext.r);
pointsTransformed[sample].g = static_cast<float>(*m_perPointContext.g);
pointsTransformed[sample].b = static_cast<float>(*m_perPointContext.b);
pointsTransformed[sample].a = static_cast<float>(*m_perPointContext.a);
pointsTransformed[sample].r = Renderer::color_modulo(*m_perPointContext.r);
pointsTransformed[sample].g = Renderer::color_modulo(*m_perPointContext.g);
pointsTransformed[sample].b = Renderer::color_modulo(*m_perPointContext.b);
pointsTransformed[sample].a = Renderer::color_modulo(*m_perPointContext.a);
}
std::vector<ColoredPoint> pointsSmoothed(sampleCount * 2);

View File

@ -1,10 +1,52 @@
#pragma once
#include <projectM-opengl.h>
#include <cmath>
namespace libprojectM {
namespace Renderer {
/**
* @brief Computes the modulus to wrap float values into the range of [0.0, 1.0].
*
* This code mimics the following equations used by the original Milkdrop code:
*
* v[0].Diffuse =
* ((((int)(*pState->m_shape[i].var_pf_a * 255 * alpha_mult)) & 0xFF) << 24) |
* ((((int)(*pState->m_shape[i].var_pf_r * 255)) & 0xFF) << 16) |
* ((((int)(*pState->m_shape[i].var_pf_g * 255)) & 0xFF) << 8) |
* ((((int)(*pState->m_shape[i].var_pf_b * 255)) & 0xFF) );
*
* In projectM, we use float values when drawing primitives or configuring vertices.
* Converting the above back to a float looks like this:
*
* d = (f * 255.0) & 0xFF = int((f * 255.0) % 256.0); *
* f' = float(d)/255.0;
*
* * Here % represents the Euclidean modulus, not the traditional (signed) fractional
* remainder.
*
* To avoid limiting ourselves to 8 bits, we combine the above equations into one that
* does not discard any information:
*
* f' = ((f * 255.0) % 256.0) / 255.0;
* = f % (256.0/255.0);
*
* Since we're using the Euclidean modulus we need to generate it from the fractional
* remainder using a standard equation.
*/
inline float color_modulo(float x)
{
const float m = 256.0f / 255.0f;
return std::fmod(std::fmod(x, m) + m, m);
}
inline float color_modulo(double x)
{
// Convert the input to float before performing the computation.
return color_modulo(static_cast<float>(x));
}
/**
* @brief Base class for render meshes.
* Also defines a few standard vertex attribute structures for use with the shaders.