Skip to content

Commit 4e9fe28

Browse files
committed
Use Mesh class in Custom Wave effect
1 parent bdebafb commit 4e9fe28

File tree

2 files changed

+64
-74
lines changed

2 files changed

+64
-74
lines changed

src/libprojectM/MilkdropPreset/CustomWaveform.cpp

Lines changed: 55 additions & 60 deletions
Original file line numberDiff line numberDiff line change
@@ -9,40 +9,29 @@
99
namespace libprojectM {
1010
namespace MilkdropPreset {
1111

12-
static constexpr int CustomWaveformMaxSamples = std::max(libprojectM::Audio::WaveformSamples, libprojectM::Audio::SpectrumSamples);
12+
static constexpr int CustomWaveformMaxSamples = std::max(Audio::WaveformSamples, Audio::SpectrumSamples);
1313

1414
CustomWaveform::CustomWaveform(PresetState& presetState)
15-
: RenderItem()
16-
, m_presetState(presetState)
15+
: m_presetState(presetState)
1716
, m_perFrameContext(presetState.globalMemory, &presetState.globalRegisters)
1817
, m_perPointContext(presetState.globalMemory, &presetState.globalRegisters)
18+
, m_mesh(Renderer::VertexBufferUsage::StreamDraw, true, false)
1919
{
20-
RenderItem::Init();
21-
2220
m_perFrameContext.RegisterBuiltinVariables();
2321
m_perPointContext.RegisterBuiltinVariables();
24-
}
25-
26-
void CustomWaveform::InitVertexAttrib()
27-
{
28-
glEnableVertexAttribArray(0);
29-
glEnableVertexAttribArray(1);
3022

31-
glVertexAttribPointer(0, 2, GL_FLOAT, GL_FALSE, sizeof(ColoredPoint), nullptr); // points
32-
glVertexAttribPointer(1, 4, GL_FLOAT, GL_FALSE, sizeof(ColoredPoint), reinterpret_cast<void*>(sizeof(float) * 2)); // colors
33-
34-
std::vector<ColoredPoint> vertexData;
35-
vertexData.resize(std::max(libprojectM::Audio::SpectrumSamples, libprojectM::Audio::WaveformSamples) * 2 + 2);
36-
glBufferData(GL_ARRAY_BUFFER, sizeof(ColoredPoint) * vertexData.size(), vertexData.data(), GL_STREAM_DRAW);
23+
// Allocate space for max number of vertices possible, so we won't have to resize the vertex
24+
// buffers, which may change on each frame.
25+
m_mesh.SetVertexCount(std::max(Audio::SpectrumSamples, Audio::WaveformSamples) * 2 + 2);
3726
}
3827

39-
void CustomWaveform::Initialize(::libprojectM::PresetFileParser& parsedFile, int index)
28+
void CustomWaveform::Initialize(PresetFileParser& parsedFile, int index)
4029
{
4130
std::string const wavecodePrefix = "wavecode_" + std::to_string(index) + "_";
4231
std::string const wavePrefix = "wave_" + std::to_string(index) + "_";
4332

4433
m_index = index;
45-
m_enabled = parsedFile.GetInt(wavecodePrefix + "enabled", m_enabled);
34+
m_enabled = parsedFile.GetBool(wavecodePrefix + "enabled", m_enabled);
4635
m_samples = parsedFile.GetInt(wavecodePrefix + "samples", m_samples);
4736
m_sep = parsedFile.GetInt(wavecodePrefix + "sep", m_sep);
4837
m_spectrum = parsedFile.GetBool(wavecodePrefix + "bSpectrum", m_spectrum);
@@ -56,6 +45,7 @@ void CustomWaveform::Initialize(::libprojectM::PresetFileParser& parsedFile, int
5645
m_b = parsedFile.GetFloat(wavecodePrefix + "b", m_b);
5746
m_a = parsedFile.GetFloat(wavecodePrefix + "a", m_a);
5847

48+
m_mesh.SetRenderPrimitiveType(m_useDots ? Renderer::Mesh::PrimitiveType::Points : Renderer::Mesh::PrimitiveType::LineStrip);
5949
}
6050

6151
void CustomWaveform::CompileCodeAndRunInitExpressions(const PerFrameContext& presetPerFrameContext)
@@ -74,15 +64,15 @@ void CustomWaveform::CompileCodeAndRunInitExpressions(const PerFrameContext& pre
7464

7565
void CustomWaveform::Draw(const PerFrameContext& presetPerFrameContext)
7666
{
77-
static_assert(libprojectM::Audio::WaveformSamples <= WaveformMaxPoints, "WaveformMaxPoints is larger than WaveformSamples");
78-
static_assert(libprojectM::Audio::SpectrumSamples <= WaveformMaxPoints, "WaveformMaxPoints is larger than SpectrumSamples");
67+
static_assert(Audio::WaveformSamples <= WaveformMaxPoints, "WaveformMaxPoints is larger than WaveformSamples");
68+
static_assert(Audio::SpectrumSamples <= WaveformMaxPoints, "WaveformMaxPoints is larger than SpectrumSamples");
7969

8070
if (!m_enabled)
8171
{
8272
return;
8373
}
8474

85-
int const maxSampleCount{m_spectrum ? libprojectM::Audio::SpectrumSamples : libprojectM::Audio::WaveformSamples};
75+
int const maxSampleCount{m_spectrum ? Audio::SpectrumSamples : Audio::WaveformSamples};
8676

8777
// Initialize and execute per-frame code
8878
LoadPerFrameEvaluationVariables(presetPerFrameContext);
@@ -108,7 +98,6 @@ void CustomWaveform::Draw(const PerFrameContext& presetPerFrameContext)
10898
: m_presetState.audioData.waveformRight.data();
10999

110100
const float mult = m_scaling * m_presetState.waveScale * (m_spectrum ? 0.15f : 0.004f);
111-
//const float mult = m_scaling * m_presetState.waveScale * (m_spectrum ? 0.05f : 1.0f);
112101

113102
// PCM data smoothing
114103
const int offset1 = m_spectrum ? 0 : (maxSampleCount - sampleCount) / 2 - m_sep / 2;
@@ -144,7 +133,8 @@ void CustomWaveform::Draw(const PerFrameContext& presetPerFrameContext)
144133
sampleDataR[sample] *= mult;
145134
}
146135

147-
std::vector<ColoredPoint> pointsTransformed(sampleCount);
136+
std::vector<Renderer::Point> points(sampleCount);
137+
std::vector<Renderer::Color> colors(sampleCount);
148138

149139
float const sampleMultiplicator = sampleCount > 1 ? 1.0f / static_cast<float>(sampleCount - 1) : 0.0f;
150140
for (int sample = 0; sample < sampleCount; sample++)
@@ -154,17 +144,16 @@ void CustomWaveform::Draw(const PerFrameContext& presetPerFrameContext)
154144

155145
m_perPointContext.ExecutePerPointCode();
156146

157-
pointsTransformed[sample].x = static_cast<float>((*m_perPointContext.x * 2.0 - 1.0) * m_presetState.renderContext.invAspectX);
158-
pointsTransformed[sample].y = static_cast<float>((*m_perPointContext.y * -2.0 + 1.0) * m_presetState.renderContext.invAspectY);
147+
points[sample] = Renderer::Point(static_cast<float>((*m_perPointContext.x * 2.0 - 1.0) * m_presetState.renderContext.invAspectX),
148+
static_cast<float>((*m_perPointContext.y * -2.0 + 1.0) * m_presetState.renderContext.invAspectY));
159149

160-
pointsTransformed[sample].r = Renderer::color_modulo(*m_perPointContext.r);
161-
pointsTransformed[sample].g = Renderer::color_modulo(*m_perPointContext.g);
162-
pointsTransformed[sample].b = Renderer::color_modulo(*m_perPointContext.b);
163-
pointsTransformed[sample].a = Renderer::color_modulo(*m_perPointContext.a);
150+
colors[sample] = Renderer::Color::Modulo(Renderer::Color(static_cast<float>(*m_perPointContext.r),
151+
static_cast<float>(*m_perPointContext.g),
152+
static_cast<float>(*m_perPointContext.b),
153+
static_cast<float>(*m_perPointContext.a)));
164154
}
165155

166-
std::vector<ColoredPoint> pointsSmoothed(sampleCount * 2);
167-
auto smoothedVertexCount = SmoothWave(pointsTransformed.data(), sampleCount, pointsSmoothed.data());
156+
SmoothWave(points, colors);
168157

169158
#ifndef USE_GLES
170159
glDisable(GL_LINE_SMOOTH);
@@ -192,10 +181,9 @@ void CustomWaveform::Draw(const PerFrameContext& presetPerFrameContext)
192181
auto incrementX = 1.0f / static_cast<float>(m_presetState.renderContext.viewportSizeX);
193182
auto incrementY = 1.0f / static_cast<float>(m_presetState.renderContext.viewportSizeX);
194183

195-
GLuint drawType = m_useDots ? GL_POINTS : GL_LINE_STRIP;
184+
size_t smoothedVertexCount = m_mesh.Indices().Size();
196185

197-
glBindVertexArray(m_vaoID);
198-
glBindBuffer(GL_ARRAY_BUFFER, m_vboID);
186+
auto& vertices = m_mesh.Vertices();
199187

200188
// If thick outline is used, draw the shape four times with slight offsets
201189
// (top left, top right, bottom right, bottom left).
@@ -208,34 +196,32 @@ void CustomWaveform::Draw(const PerFrameContext& presetPerFrameContext)
208196
break;
209197

210198
case 1:
211-
for (auto j = 0; j < smoothedVertexCount; j++)
199+
for (size_t j = 0; j < smoothedVertexCount; j++)
212200
{
213-
pointsSmoothed[j].x += incrementX;
201+
vertices[j].SetX(vertices[j].X() + incrementX);
214202
}
215203
break;
216204

217205
case 2:
218-
for (auto j = 0; j < smoothedVertexCount; j++)
206+
for (size_t j = 0; j < smoothedVertexCount; j++)
219207
{
220-
pointsSmoothed[j].y += incrementY;
208+
vertices[j].SetY(vertices[j].Y() + incrementY);
221209
}
222210
break;
223211

224212
case 3:
225-
for (auto j = 0; j < smoothedVertexCount; j++)
213+
for (size_t j = 0; j < smoothedVertexCount; j++)
226214
{
227-
pointsSmoothed[j].x -= incrementX;
215+
vertices[j].SetX(vertices[j].X() - incrementX);
228216
}
229217
break;
230218
}
231219

232-
glBufferSubData(GL_ARRAY_BUFFER, 0, sizeof(ColoredPoint) * smoothedVertexCount, pointsSmoothed.data());
233-
glDrawArrays(drawType, 0, smoothedVertexCount);
220+
m_mesh.Update();
221+
m_mesh.Draw();
234222
}
235223

236-
glBindBuffer(GL_ARRAY_BUFFER, 0);
237-
glBindVertexArray(0);
238-
224+
m_mesh.Unbind();
239225
Renderer::Shader::Unbind();
240226

241227
glDisable(GL_BLEND);
@@ -272,35 +258,44 @@ void CustomWaveform::LoadPerPointEvaluationVariables(float sample, float value1,
272258
*m_perPointContext.a = *m_perFrameContext.a;
273259
}
274260

275-
int CustomWaveform::SmoothWave(const CustomWaveform::ColoredPoint* inputVertices,
276-
int vertexCount,
277-
CustomWaveform::ColoredPoint* outputVertices)
261+
void CustomWaveform::SmoothWave(const std::vector<Renderer::Point>& points, const std::vector<Renderer::Color>& colors)
278262
{
279263
constexpr float c1{-0.15f};
280264
constexpr float c2{1.15f};
281265
constexpr float c3{1.15f};
282266
constexpr float c4{-0.15f};
283267
constexpr float inverseSum{1.0f / (c1 + c2 + c3 + c4)};
284268

285-
int outputIndex = 0;
286-
int iBelow = 0;
287-
int iAbove2 = 1;
269+
size_t outputIndex = 0;
270+
size_t iBelow = 0;
271+
size_t iAbove2 = 1;
272+
273+
size_t vertexCount = points.size();
274+
275+
auto& outVertices = m_mesh.Vertices();
276+
auto& outColors = m_mesh.Colors();
288277

289-
for (auto inputIndex = 0; inputIndex < vertexCount - 1; inputIndex++)
278+
for (size_t inputIndex = 0; inputIndex < vertexCount - 1; inputIndex++)
290279
{
291-
int const iAbove = iAbove2;
280+
size_t const iAbove = iAbove2;
292281
iAbove2 = std::min(vertexCount - 1, inputIndex + 2);
293-
outputVertices[outputIndex] = inputVertices[inputIndex];
294-
outputVertices[outputIndex + 1] = inputVertices[inputIndex];
295-
outputVertices[outputIndex + 1].x = (c1 * inputVertices[iBelow].x + c2 * inputVertices[inputIndex].x + c3 * inputVertices[iAbove].x + c4 * inputVertices[iAbove2].x) * inverseSum;
296-
outputVertices[outputIndex + 1].y = (c1 * inputVertices[iBelow].y + c2 * inputVertices[inputIndex].y + c3 * inputVertices[iAbove].y + c4 * inputVertices[iAbove2].y) * inverseSum;
282+
outVertices[outputIndex] = points[inputIndex];
283+
outColors[outputIndex] = colors[inputIndex];
284+
outColors[outputIndex + 1] = colors[inputIndex];
285+
auto& smoothedPoint = outVertices[outputIndex + 1];
286+
smoothedPoint = points[inputIndex];
287+
smoothedPoint.SetX((c1 * points[iBelow].X() + c2 * points[inputIndex].X() + c3 * points[iAbove].X() + c4 * points[iAbove2].X()) * inverseSum);
288+
smoothedPoint.SetY((c1 * points[iBelow].Y() + c2 * points[inputIndex].Y() + c3 * points[iAbove].Y() + c4 * points[iAbove2].Y()) * inverseSum);
297289
iBelow = inputIndex;
298290
outputIndex += 2;
299291
}
300292

301-
outputVertices[outputIndex] = inputVertices[vertexCount - 1];
293+
outVertices[outputIndex] = points[vertexCount - 1];
294+
outColors[outputIndex] = colors[vertexCount - 1];
302295

303-
return outputIndex + 1;
296+
auto& indices = m_mesh.Indices();
297+
indices.Resize(outputIndex + 1);
298+
indices.MakeContinuous();
304299
}
305300

306301
} // namespace MilkdropPreset

src/libprojectM/MilkdropPreset/CustomWaveform.hpp

Lines changed: 9 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,9 @@
33
#include "WaveformPerFrameContext.hpp"
44
#include "WaveformPerPointContext.hpp"
55

6-
#include <Renderer/RenderItem.hpp>
6+
#include <Renderer/Color.hpp>
7+
#include <Renderer/Mesh.hpp>
8+
#include "Renderer/Point.hpp"
79

810
#include <vector>
911

@@ -13,7 +15,7 @@ class PresetFileParser;
1315

1416
namespace MilkdropPreset {
1517

16-
class CustomWaveform : public Renderer::RenderItem
18+
class CustomWaveform
1719
{
1820
public:
1921

@@ -23,11 +25,6 @@ class CustomWaveform : public Renderer::RenderItem
2325
*/
2426
explicit CustomWaveform(PresetState& presetState);
2527

26-
/**
27-
* @brief Initializes the waveform's vertex buffer and attribute data.
28-
*/
29-
void InitVertexAttrib() override;
30-
3128
/**
3229
* @brief Loads the initial values and code from the preset file.
3330
* @param parsedFile The file parser with the preset data.
@@ -73,15 +70,13 @@ class CustomWaveform : public Renderer::RenderItem
7370
*
7471
* Roughly doubles the number of points.
7572
*
76-
* @param inputVertices Pointer to an array of vertices to be smoothed.
77-
* @param vertexCount Number of vertices/points in the input data.
78-
* @param outputVertices Pointer to a buffer that will receive the smoothed data. Must be able to hold 2 * vertexCount vertices.
79-
* @return The number of vertices in outputVertices after smoothing.
73+
* @param points A vector of points to be smoothed.
74+
* @param colors A vector of colors for the points.
8075
*/
81-
static int SmoothWave(const ColoredPoint* inputVertices, int vertexCount, ColoredPoint* outputVertices);
76+
void SmoothWave(const std::vector<Renderer::Point>& points, const std::vector<Renderer::Color>& colors);
8277

8378
int m_index{0}; //!< Custom waveform index in the preset.
84-
int m_enabled{0}; //!< Render waveform if non-zero.
79+
bool m_enabled{false}; //!< Render waveform if non-zero.
8580
int m_samples{WaveformMaxPoints}; //!< Number of samples/vertices in the waveform.
8681
int m_sep{0}; //!< Separation distance of dual waveforms.
8782
float m_scaling{1.0f}; //!< Scale factor of waveform.
@@ -103,7 +98,7 @@ class CustomWaveform : public Renderer::RenderItem
10398
WaveformPerFrameContext m_perFrameContext; //!< Holds the code execution context for per-frame expressions
10499
WaveformPerPointContext m_perPointContext; //!< Holds the code execution context for per-point expressions
105100

106-
std::vector<ColoredPoint> m_points; //!< Points in this waveform.
101+
Renderer::Mesh m_mesh; //!< Points in this waveform.
107102

108103
friend class WaveformPerFrameContext;
109104
friend class WaveformPerPointContext;

0 commit comments

Comments
 (0)