-
-
Notifications
You must be signed in to change notification settings - Fork 483
Expand file tree
/
Copy pathPerPixelMesh.hpp
More file actions
149 lines (126 loc) · 6.05 KB
/
Copy pathPerPixelMesh.hpp
File metadata and controls
149 lines (126 loc) · 6.05 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
#pragma once
#include <Renderer/Mesh.hpp>
#include <Renderer/Shader.hpp>
namespace libprojectM {
namespace MilkdropPreset {
class PresetState;
class PerFrameContext;
class PerPixelContext;
class MilkdropShader;
/**
* @brief The "per-pixel" transformation mesh.
*
* This mesh is responsible for most of the motion types in presets. Each mesh vertex
* is transposed (also scaled, from the center) or rotated to create a frame-by-frame motion.
* Fragment shader interpolation is then used to create smooth transitions in the space
* between the grid points.
*
* A higher resolution grid means better quality, especially for rotations, but also quickly
* increases the CPU usage as the per-pixel expression needs to be run for every grid point.
*
* The mesh size can be changed between frames, the class will reallocate the buffers if needed.
*/
class PerPixelMesh
{
public:
PerPixelMesh();
/**
* @brief Loads the warp shader, if the preset uses one.
* @param presetState The preset state to retrieve the shader from.
*/
void LoadWarpShader(const PresetState& presetState);
/**
* @brief Loads the required textures and compiles the warp shader.
* @param presetState The preset state to retrieve the configuration values from.
*/
void CompileWarpShader(PresetState& presetState);
/**
* True once the warp shader's deferred background compile (if any) has finished.
* Non-blocking.
*/
auto WarpShaderCompileReady() const -> bool;
/**
* Finalizes a deferred warp-shader compile, replaying CompileWarpShader's failure
* handling (drop the warp shader).
*/
void FinalizeWarpShaderCompile();
/**
* @brief Renders the transformation mesh.
* @param presetState The preset state to retrieve the configuration values from.
* @param presetPerFrameContext The per-frame context to retrieve the initial vars from.
* @param perPixelContext The per-pixel code context to use.
*/
void Draw(const PresetState& presetState,
const PerFrameContext& perFrameContext,
PerPixelContext& perPixelContext);
private:
/**
* Vertex attributes for radius and angle.
*/
struct RadiusAngle {
float radius{};
float angle{};
static void InitializeAttributePointer(uint32_t attributeIndex)
{
glVertexAttribPointer(attributeIndex, sizeof(RadiusAngle) / sizeof(float), GL_FLOAT, GL_FALSE, sizeof(RadiusAngle), nullptr);
}
};
/**
* Vertex attributes for zoom, zoom exponent, rotation and warp strength.
*/
struct ZoomRotWarp {
float zoom{};
float zoomExp{};
float rot{};
float warp{};
static void InitializeAttributePointer(uint32_t attributeIndex)
{
glVertexAttribPointer(attributeIndex, sizeof(ZoomRotWarp) / sizeof(float), GL_FLOAT, GL_FALSE, sizeof(ZoomRotWarp), nullptr);
}
};
/**
* @brief Initializes the vertex array and fills in static data if needed.
*
* The vertices will be reallocated if the grid size has changed. If either this happened,
* or the viewport size changed, the static values will be recalculated.
*
* @param presetState The preset state to retrieve the configuration values from.
*/
void InitializeMesh(const PresetState& presetState);
/**
* @brief Executes the per-pixel code and calculates the u/v coordinates.
* The x/y coordinates are either a static grid or computed by the per-vertex expression.
* @param presetState The preset state to retrieve the configuration values from.
* @param presetPerFrameContext The per-frame context to retrieve the initial vars from.
* @param perPixelContext The per-pixel code context to use.
*/
void CalculateMesh(const PresetState& presetState,
const PerFrameContext& perFrameContext,
PerPixelContext& perPixelContext);
/**
* @brief Draws the warp mesh with or without a warp shader.
* If the preset doesn't use a warp shader, a default textured shader is used.
*/
void WarpedBlit(const PresetState& presetState, const PerFrameContext& perFrameContext);
/**
* @brief Creates or retrieves the default warp shader.
* @param presetState The preset state to retrieve the rendering context from.
* @return A shared pointer to the default warp shader instance.
*/
auto GetDefaultWarpShader(const PresetState& presetState) -> std::shared_ptr<Renderer::Shader>;
int m_gridSizeX{}; //!< Warp mesh X resolution.
int m_gridSizeY{}; //!< Warp mesh Y resolution.
int m_viewportWidth{}; //!< Last known viewport width.
int m_viewportHeight{}; //!< Last known viewport height.
Renderer::Mesh m_warpMesh; //!< The Warp effect mesh
Renderer::VertexBuffer<RadiusAngle> m_radiusAngleBuffer{Renderer::VertexBufferUsage::StreamDraw}; //!< Vertex attribute buffer for radius and angle values.
Renderer::VertexBuffer<ZoomRotWarp> m_zoomRotWarpBuffer{Renderer::VertexBufferUsage::StreamDraw}; //!< Vertex attribute buffer for zoom, roation and warp values.
Renderer::VertexBuffer<Renderer::Point> m_centerBuffer{Renderer::VertexBufferUsage::StreamDraw}; //!< Vertex attribute buffer for center coordinate values.
Renderer::VertexBuffer<Renderer::Point> m_distanceBuffer{Renderer::VertexBufferUsage::StreamDraw}; //!< Vertex attribute buffer for distance values.
Renderer::VertexBuffer<Renderer::Point> m_stretchBuffer{Renderer::VertexBufferUsage::StreamDraw}; //!< Vertex attribute buffer for stretch values.
std::weak_ptr<Renderer::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.
Renderer::Sampler m_perPixelSampler{GL_CLAMP_TO_EDGE, GL_LINEAR}; //!< The main texture sampler.
};
} // namespace MilkdropPreset
} // namespace libprojectM