mirror of
https://github.com/projectM-visualizer/projectm.git
synced 2026-02-05 16:05:47 +00:00
Use Mesh class in User Sprites
This commit is contained in:
@ -1,5 +1,6 @@
|
||||
#include "UserSprites/MilkdropSprite.hpp"
|
||||
|
||||
#include "SpriteException.hpp"
|
||||
#include "SpriteShaders.hpp"
|
||||
|
||||
#include <Preset.hpp>
|
||||
@ -24,19 +25,9 @@ namespace libprojectM {
|
||||
namespace UserSprites {
|
||||
|
||||
MilkdropSprite::MilkdropSprite()
|
||||
: m_mesh(Renderer::VertexBufferUsage::DynamicDraw, false, true)
|
||||
{
|
||||
RenderItem::Init();
|
||||
}
|
||||
|
||||
void MilkdropSprite::InitVertexAttrib()
|
||||
{
|
||||
glEnableVertexAttribArray(0);
|
||||
glDisableVertexAttribArray(1);
|
||||
glEnableVertexAttribArray(2);
|
||||
|
||||
glVertexAttribPointer(0, 2, GL_FLOAT, GL_FALSE, sizeof(TexturedPoint), reinterpret_cast<void*>(offsetof(TexturedPoint, x))); // Position
|
||||
// Color (index 1) is passed as a 4-float constant vertex attribute.
|
||||
glVertexAttribPointer(2, 2, GL_FLOAT, GL_FALSE, sizeof(TexturedPoint), reinterpret_cast<void*>(offsetof(TexturedPoint, u))); // Texture coordinate
|
||||
m_mesh.SetVertexCount(4);
|
||||
}
|
||||
|
||||
void MilkdropSprite::Init(const std::string& spriteData, const Renderer::RenderContext& renderContext)
|
||||
@ -119,7 +110,7 @@ void MilkdropSprite::Draw(const Audio::FrameAudioData& audioData,
|
||||
m_spriteDone = *m_codeContext.done != 0.0;
|
||||
bool burnIn = *m_codeContext.burn != 0.0;
|
||||
|
||||
Quad vertices{};
|
||||
auto& vertices = m_mesh.Vertices().Get();
|
||||
|
||||
// Get values from expression code and clamp them where necessary.
|
||||
float x = std::min(1000.0f, std::max(-1000.0f, static_cast<float>(*m_codeContext.x) * 2.0f - 1.0f));
|
||||
@ -139,14 +130,14 @@ void MilkdropSprite::Draw(const Audio::FrameAudioData& audioData,
|
||||
float a = std::min(1.0f, std::max(0.0f, (static_cast<float>(*m_codeContext.a))));
|
||||
|
||||
// ToDo: Move all translations to vertex shader
|
||||
vertices[0 + flipx].x = -sx;
|
||||
vertices[1 - flipx].x = sx;
|
||||
vertices[2 + flipx].x = -sx;
|
||||
vertices[3 - flipx].x = sx;
|
||||
vertices[0 + flipy * 2].y = -sy;
|
||||
vertices[1 + flipy * 2].y = -sy;
|
||||
vertices[2 - flipy * 2].y = sy;
|
||||
vertices[3 - flipy * 2].y = sy;
|
||||
vertices[0 + flipx].SetX(-sx);
|
||||
vertices[1 - flipx].SetX(sx);
|
||||
vertices[2 + flipx].SetX(-sx);
|
||||
vertices[3 - flipx].SetX(sx);
|
||||
vertices[0 + flipy * 2].SetY(-sy);
|
||||
vertices[1 + flipy * 2].SetY(-sy);
|
||||
vertices[2 - flipy * 2].SetY(sy);
|
||||
vertices[3 - flipy * 2].SetY(sy);
|
||||
|
||||
// First aspect ratio: adjust for non-1:1 images
|
||||
{
|
||||
@ -157,7 +148,7 @@ void MilkdropSprite::Draw(const Audio::FrameAudioData& audioData,
|
||||
// Landscape image
|
||||
for (auto& vertex : vertices)
|
||||
{
|
||||
vertex.y *= aspect;
|
||||
vertex.SetY(vertex.Y() * aspect);
|
||||
}
|
||||
}
|
||||
else
|
||||
@ -165,7 +156,7 @@ void MilkdropSprite::Draw(const Audio::FrameAudioData& audioData,
|
||||
// Portrait image
|
||||
for (auto& vertex : vertices)
|
||||
{
|
||||
vertex.x /= aspect;
|
||||
vertex.SetX(vertex.X() / aspect);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -177,18 +168,17 @@ void MilkdropSprite::Draw(const Audio::FrameAudioData& audioData,
|
||||
|
||||
for (auto& vertex : vertices)
|
||||
{
|
||||
float rotX = vertex.x * cos_rot - vertex.y * sin_rot;
|
||||
float rotY = vertex.x * sin_rot + vertex.y * cos_rot;
|
||||
vertex.x = rotX;
|
||||
vertex.y = rotY;
|
||||
float rotX = vertex.X() * cos_rot - vertex.Y() * sin_rot;
|
||||
float rotY = vertex.X() * sin_rot + vertex.Y() * cos_rot;
|
||||
vertex = {rotX, rotY};
|
||||
}
|
||||
}
|
||||
|
||||
// Translation
|
||||
for (auto& vertex : vertices)
|
||||
{
|
||||
vertex.x += x;
|
||||
vertex.y += y;
|
||||
vertex.SetX(vertex.X() + x);
|
||||
vertex.SetY(vertex.Y() + y);
|
||||
}
|
||||
|
||||
// Second aspect ratio: normalize to width of screen
|
||||
@ -199,14 +189,14 @@ void MilkdropSprite::Draw(const Audio::FrameAudioData& audioData,
|
||||
{
|
||||
for (auto& vertex : vertices)
|
||||
{
|
||||
vertex.y *= aspect;
|
||||
vertex.SetY(vertex.Y() * aspect);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
for (auto& vertex : vertices)
|
||||
{
|
||||
vertex.x /= aspect;
|
||||
vertex.SetX(vertex.X() / aspect);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -219,19 +209,15 @@ void MilkdropSprite::Draw(const Audio::FrameAudioData& audioData,
|
||||
float dtu = 0.5f;
|
||||
float dtv = 0.5f;
|
||||
|
||||
vertices[0].u = -dtu;
|
||||
vertices[1].u = dtu;
|
||||
vertices[2].u = -dtu;
|
||||
vertices[3].u = dtu;
|
||||
vertices[0].v = -dtv;
|
||||
vertices[1].v = -dtv;
|
||||
vertices[2].v = dtv;
|
||||
vertices[3].v = dtv;
|
||||
m_mesh.UVs().Set({{-dtu, -dtv},
|
||||
{dtu, -dtv},
|
||||
{-dtu, dtv},
|
||||
{dtu, dtv}});
|
||||
|
||||
for (auto& vertex : vertices)
|
||||
for (auto& uv : m_mesh.UVs().Get())
|
||||
{
|
||||
vertex.u = (vertex.u - 0.0f) * repeatx + 0.5f;
|
||||
vertex.v = (vertex.v - 0.0f) * repeaty + 0.5f;
|
||||
uv = {(uv.U() - 0.0f) * repeatx + 0.5f,
|
||||
(uv.V() - 0.0f) * repeaty + 0.5f};
|
||||
}
|
||||
}
|
||||
|
||||
@ -243,9 +229,7 @@ void MilkdropSprite::Draw(const Audio::FrameAudioData& audioData,
|
||||
m_texture->Bind(0);
|
||||
m_sampler.Bind(0);
|
||||
|
||||
glBindVertexArray(m_vaoID);
|
||||
glBindBuffer(GL_ARRAY_BUFFER, m_vboID);
|
||||
glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices.data(), GL_DYNAMIC_DRAW);
|
||||
m_mesh.Update();
|
||||
|
||||
glVertexAttrib4f(1, r, g, b, a);
|
||||
|
||||
@ -275,7 +259,7 @@ void MilkdropSprite::Draw(const Audio::FrameAudioData& audioData,
|
||||
}
|
||||
|
||||
// Draw to current output buffer
|
||||
glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
|
||||
m_mesh.Draw();
|
||||
|
||||
if (burnIn)
|
||||
{
|
||||
@ -288,7 +272,7 @@ void MilkdropSprite::Draw(const Audio::FrameAudioData& audioData,
|
||||
}
|
||||
|
||||
preset.get()->BindFramebuffer();
|
||||
glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
|
||||
m_mesh.Draw();
|
||||
}
|
||||
|
||||
// Reset to original FBO
|
||||
@ -300,6 +284,7 @@ void MilkdropSprite::Draw(const Audio::FrameAudioData& audioData,
|
||||
glBindBuffer(GL_ARRAY_BUFFER, 0);
|
||||
glBindVertexArray(0);
|
||||
m_texture->Unbind(0);
|
||||
Renderer::Mesh::Unbind();
|
||||
Renderer::Shader::Unbind();
|
||||
}
|
||||
|
||||
|
||||
@ -2,6 +2,7 @@
|
||||
|
||||
#include "UserSprites/Sprite.hpp"
|
||||
|
||||
#include <Renderer/Mesh.hpp>
|
||||
#include <Renderer/Texture.hpp>
|
||||
#include <Renderer/TextureSamplerDescriptor.hpp>
|
||||
|
||||
@ -17,8 +18,6 @@ public:
|
||||
|
||||
~MilkdropSprite() override = default;
|
||||
|
||||
void InitVertexAttrib() override;
|
||||
|
||||
void Init(const std::string& spriteData, const Renderer::RenderContext& renderContext) override;
|
||||
|
||||
void Draw(const Audio::FrameAudioData& audioData,
|
||||
@ -26,16 +25,13 @@ public:
|
||||
uint32_t outputFramebufferObject,
|
||||
PresetList presets) override;
|
||||
|
||||
auto Done() const-> bool override;
|
||||
auto Done() const -> bool override;
|
||||
|
||||
private:
|
||||
using Quad = std::array<TexturedPoint, 4>;
|
||||
|
||||
/**
|
||||
* @brief Context for the init and per-frame code.
|
||||
*/
|
||||
struct CodeContext
|
||||
{
|
||||
struct CodeContext {
|
||||
CodeContext();
|
||||
|
||||
~CodeContext();
|
||||
@ -61,46 +57,45 @@ private:
|
||||
const Renderer::RenderContext& renderContext);
|
||||
|
||||
projectm_eval_context* spriteCodeContext{nullptr}; //!< The code runtime context, holds memory buffers and variables.
|
||||
projectm_eval_code* perFrameCodeHandle{nullptr}; //!< The compiled per-frame code handle.
|
||||
projectm_eval_code* perFrameCodeHandle{nullptr}; //!< The compiled per-frame code handle.
|
||||
|
||||
// Input variables
|
||||
PRJM_EVAL_F* time{}; //!< Time passed since program start. Also available in init code.
|
||||
PRJM_EVAL_F* frame{}; //!< Total frames rendered so far. Also available in init code.
|
||||
PRJM_EVAL_F* fps{}; //!< Current (or, if not available, target) frames per second value.
|
||||
PRJM_EVAL_F* time{}; //!< Time passed since program start. Also available in init code.
|
||||
PRJM_EVAL_F* frame{}; //!< Total frames rendered so far. Also available in init code.
|
||||
PRJM_EVAL_F* fps{}; //!< Current (or, if not available, target) frames per second value.
|
||||
PRJM_EVAL_F* progress{}; //!< Preset blending progress (only if blending).
|
||||
PRJM_EVAL_F* bass{}; //!< Bass frequency loudness, median of 1.0, range of ~0.7 to ~1.3 in most cases.
|
||||
PRJM_EVAL_F* mid{}; //!< Middle frequency loudness, median of 1.0, range of ~0.7 to ~1.3 in most cases.
|
||||
PRJM_EVAL_F* treb{}; //!< Treble frequency loudness, median of 1.0, range of ~0.7 to ~1.3 in most cases.
|
||||
PRJM_EVAL_F* bass{}; //!< Bass frequency loudness, median of 1.0, range of ~0.7 to ~1.3 in most cases.
|
||||
PRJM_EVAL_F* mid{}; //!< Middle frequency loudness, median of 1.0, range of ~0.7 to ~1.3 in most cases.
|
||||
PRJM_EVAL_F* treb{}; //!< Treble frequency loudness, median of 1.0, range of ~0.7 to ~1.3 in most cases.
|
||||
PRJM_EVAL_F* bass_att{}; //!< More attenuated/smoothed value of bass.
|
||||
PRJM_EVAL_F* mid_att{}; //!< More attenuated/smoothed value of mid.
|
||||
PRJM_EVAL_F* mid_att{}; //!< More attenuated/smoothed value of mid.
|
||||
PRJM_EVAL_F* treb_att{}; //!< More attenuated/smoothed value of treb.
|
||||
|
||||
// Output variables
|
||||
PRJM_EVAL_F* done{}; //!< If this becomes non-zero, the sprite is deleted. Default: 0.0
|
||||
PRJM_EVAL_F* burn{}; //!< If non-zero, the sprite will be "burned" into currently rendered presets when done is also true, effectively "dissolving" the sprite in the preset. Default: 1.0
|
||||
PRJM_EVAL_F* x{}; //!< Sprite x position (position of the image center). Range from -1000 to 1000. Default: 0.5
|
||||
PRJM_EVAL_F* y{}; //!< Sprite y position (position of the image center). Range from -1000 to 1000. Default: 0.5
|
||||
PRJM_EVAL_F* sx{}; //!< Sprite x scaling factor. Range from -1000 to 1000. Default: 1.0
|
||||
PRJM_EVAL_F* sy{}; //!< Sprite y scaling factor. Range from -1000 to 1000. Default: 1.0
|
||||
PRJM_EVAL_F* rot{}; //!< Sprite rotation in radians (2*PI equals one full rotation). Default: 0.0
|
||||
PRJM_EVAL_F* flipx{}; //!< If flag is non-zero, the sprite is flipped on the x axis. Default: 0.0
|
||||
PRJM_EVAL_F* flipy{}; //!< If flag is non-zero, the sprite is flipped on the y axis. Default: 0.0
|
||||
PRJM_EVAL_F* repeatx{}; //!< Repeat count of the image on the sprite quad on the x axis. Fractional values allowed. Range from 0.01 to 100.0. Default: 1.0
|
||||
PRJM_EVAL_F* repeaty{}; //!< Repeat count of the image on the sprite quad on the y axis. Fractional values allowed. Range from 0.01 to 100.0. Default: 1.0
|
||||
PRJM_EVAL_F* done{}; //!< If this becomes non-zero, the sprite is deleted. Default: 0.0
|
||||
PRJM_EVAL_F* burn{}; //!< If non-zero, the sprite will be "burned" into currently rendered presets when done is also true, effectively "dissolving" the sprite in the preset. Default: 1.0
|
||||
PRJM_EVAL_F* x{}; //!< Sprite x position (position of the image center). Range from -1000 to 1000. Default: 0.5
|
||||
PRJM_EVAL_F* y{}; //!< Sprite y position (position of the image center). Range from -1000 to 1000. Default: 0.5
|
||||
PRJM_EVAL_F* sx{}; //!< Sprite x scaling factor. Range from -1000 to 1000. Default: 1.0
|
||||
PRJM_EVAL_F* sy{}; //!< Sprite y scaling factor. Range from -1000 to 1000. Default: 1.0
|
||||
PRJM_EVAL_F* rot{}; //!< Sprite rotation in radians (2*PI equals one full rotation). Default: 0.0
|
||||
PRJM_EVAL_F* flipx{}; //!< If flag is non-zero, the sprite is flipped on the x axis. Default: 0.0
|
||||
PRJM_EVAL_F* flipy{}; //!< If flag is non-zero, the sprite is flipped on the y axis. Default: 0.0
|
||||
PRJM_EVAL_F* repeatx{}; //!< Repeat count of the image on the sprite quad on the x axis. Fractional values allowed. Range from 0.01 to 100.0. Default: 1.0
|
||||
PRJM_EVAL_F* repeaty{}; //!< Repeat count of the image on the sprite quad on the y axis. Fractional values allowed. Range from 0.01 to 100.0. Default: 1.0
|
||||
PRJM_EVAL_F* blendmode{}; //!< Image blending mode. 0 = Alpha blending (default), 1 = Decal mode (no transparency), 2 = Additive blending, 3 = Source color blending, 4 = Color key blending. Default: 0
|
||||
PRJM_EVAL_F* r{}; //!< Modulation color used in some blending modes. Default: 1.0
|
||||
PRJM_EVAL_F* g{}; //!< Modulation color used in some blending modes. Default: 1.0
|
||||
PRJM_EVAL_F* b{}; //!< Modulation color used in some blending modes. Default: 1.0
|
||||
PRJM_EVAL_F* a{}; //!< Modulation color used in some blending modes. Default: 1.0
|
||||
|
||||
PRJM_EVAL_F* r{}; //!< Modulation color used in some blending modes. Default: 1.0
|
||||
PRJM_EVAL_F* g{}; //!< Modulation color used in some blending modes. Default: 1.0
|
||||
PRJM_EVAL_F* b{}; //!< Modulation color used in some blending modes. Default: 1.0
|
||||
PRJM_EVAL_F* a{}; //!< Modulation color used in some blending modes. Default: 1.0
|
||||
};
|
||||
|
||||
CodeContext m_codeContext; //!< Sprite init and per-frame code.
|
||||
std::shared_ptr<Renderer::Texture> m_texture; //!< The sprite image, loaded via a name like other textures in Milkdrop presets.
|
||||
CodeContext m_codeContext; //!< Sprite init and per-frame code.
|
||||
std::shared_ptr<Renderer::Texture> m_texture; //!< The sprite image, loaded via a name like other textures in Milkdrop presets.
|
||||
Renderer::Sampler m_sampler{GL_REPEAT, GL_LINEAR}; //!< Texture sampler settings
|
||||
std::weak_ptr<Renderer::Shader> m_spriteShader; //!< The shader used to draw the user sprite.
|
||||
bool m_spriteDone{false}; //!< If true, the sprite will be removed from the list.
|
||||
|
||||
std::weak_ptr<Renderer::Shader> m_spriteShader; //!< The shader used to draw the user sprite.
|
||||
Renderer::Mesh m_mesh; //!< A simple quad.
|
||||
bool m_spriteDone{false}; //!< If true, the sprite will be removed from the list.
|
||||
};
|
||||
|
||||
} // namespace UserSprites
|
||||
|
||||
@ -1,13 +1,10 @@
|
||||
#pragma once
|
||||
|
||||
#include "UserSprites/SpriteException.hpp"
|
||||
|
||||
#include <Preset.hpp>
|
||||
|
||||
#include <Audio/FrameAudioData.hpp>
|
||||
|
||||
#include <Renderer/RenderContext.hpp>
|
||||
#include <Renderer/RenderItem.hpp>
|
||||
|
||||
#include <cstdint>
|
||||
#include <functional>
|
||||
@ -18,12 +15,14 @@
|
||||
namespace libprojectM {
|
||||
namespace UserSprites {
|
||||
|
||||
class Sprite : public Renderer::RenderItem
|
||||
class Sprite
|
||||
{
|
||||
public:
|
||||
using Ptr = std::unique_ptr<Sprite>;
|
||||
using PresetList = std::vector<std::reference_wrapper<const std::unique_ptr<Preset>>>;
|
||||
|
||||
virtual ~Sprite() = default;
|
||||
|
||||
/**
|
||||
* @brief Initializes the sprite instance for rendering.
|
||||
* @param spriteData The data for the sprite type.
|
||||
|
||||
@ -1,6 +1,7 @@
|
||||
#include "UserSprites/SpriteManager.hpp"
|
||||
|
||||
#include "UserSprites/Factory.hpp"
|
||||
#include "UserSprites/SpriteException.hpp"
|
||||
|
||||
#include <Renderer/Shader.hpp>
|
||||
|
||||
@ -106,7 +107,8 @@ auto SpriteManager::ActiveSpriteCount() const -> uint32_t
|
||||
auto SpriteManager::ActiveSpriteIdentifiers() const -> std::vector<SpriteIdentifier>
|
||||
{
|
||||
std::vector<SpriteIdentifier> identifierList;
|
||||
for (auto& idAndSprite : m_sprites) {
|
||||
for (auto& idAndSprite : m_sprites)
|
||||
{
|
||||
identifierList.emplace_back(idAndSprite.first);
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user