Vital
Loading...
Searching...
No Matches
bar_renderer.cpp
Go to the documentation of this file.
1#include "bar_renderer.h"
2
3#include "skin.h"
4#include "shaders.h"
5#include "utils.h"
6
8BarRenderer::BarRenderer(int num_points, bool vertical) :
9 shader_(nullptr), vertical_(vertical), additive_blending_(true), display_scale_(1.0f), power_scale_(false),
10 square_scale_(false), dirty_(false), num_points_(num_points), total_points_(num_points) {
11 addRoundedCorners(); // Presumably a call from a base class or utility to add cornering.
12
13 scale_ = 1.0f;
14 offset_ = 0.0f;
15 bar_data_ = std::make_unique<float[]>(kFloatsPerBar * total_points_);
16 bar_indices_ = std::make_unique<int[]>(kTriangleIndicesPerBar * total_points_);
17 bar_corner_data_ = std::make_unique<float[]>(kCornerFloatsPerBar * total_points_);
18 bar_buffer_ = 0;
21 bar_width_ = 1.0f;
22
23 // Initialize bar geometry and indices.
24 for (int i = 0; i < total_points_; ++i) {
25 float t = i / (total_points_ * 1.0f);
26 int index = i * kFloatsPerBar;
27
28 for (int v = 0; v < kVerticesPerBar; ++v) {
29 int vertex_index = v * kFloatsPerVertex + index;
30 bar_data_[vertex_index] = 2.0f * t - 1.0f;
31 bar_data_[vertex_index + 1] = -1.0f;
32 }
33
34 int bar_index = i * kTriangleIndicesPerBar;
35 int bar_vertex_index = i * kVerticesPerBar;
36 bar_indices_[bar_index] = bar_vertex_index;
37 bar_indices_[bar_index + 1] = bar_vertex_index + 1;
38 bar_indices_[bar_index + 2] = bar_vertex_index + 2;
39 bar_indices_[bar_index + 3] = bar_vertex_index + 1;
40 bar_indices_[bar_index + 4] = bar_vertex_index + 2;
41 bar_indices_[bar_index + 5] = bar_vertex_index + 3;
42
43 int corner_index = i * kCornerFloatsPerBar;
44 bar_corner_data_[corner_index] = 0.0f;
45 bar_corner_data_[corner_index + 1] = 1.0f;
46 bar_corner_data_[corner_index + 2] = 1.0f;
47 bar_corner_data_[corner_index + 3] = 1.0f;
48 bar_corner_data_[corner_index + 4] = 0.0f;
49 bar_corner_data_[corner_index + 5] = 0.0f;
50 bar_corner_data_[corner_index + 6] = 1.0f;
51 bar_corner_data_[corner_index + 7] = 0.0f;
52 }
53}
54
56
58 OpenGlComponent::init(open_gl);
59
60 open_gl.context.extensions.glGenBuffers(1, &bar_buffer_);
61 open_gl.context.extensions.glBindBuffer(GL_ARRAY_BUFFER, bar_buffer_);
62
63 GLsizeiptr vert_size = static_cast<GLsizeiptr>(kFloatsPerBar * total_points_ * sizeof(float));
64 open_gl.context.extensions.glBufferData(GL_ARRAY_BUFFER, vert_size, bar_data_.get(), GL_STATIC_DRAW);
65
66 open_gl.context.extensions.glGenBuffers(1, &bar_corner_buffer_);
67 open_gl.context.extensions.glBindBuffer(GL_ARRAY_BUFFER, bar_corner_buffer_);
68
69 GLsizeiptr corner_size = static_cast<GLsizeiptr>(kCornerFloatsPerBar * total_points_ * sizeof(float));
70 open_gl.context.extensions.glBufferData(GL_ARRAY_BUFFER, corner_size, bar_corner_data_.get(), GL_STATIC_DRAW);
71
72 open_gl.context.extensions.glGenBuffers(1, &bar_indices_buffer_);
73 open_gl.context.extensions.glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, bar_indices_buffer_);
74
75 GLsizeiptr bar_size = static_cast<GLsizeiptr>(kTriangleIndicesPerBar * total_points_ * sizeof(int));
76 open_gl.context.extensions.glBufferData(GL_ELEMENT_ARRAY_BUFFER, bar_size, bar_indices_.get(), GL_STATIC_DRAW);
77
78 if (vertical_)
80 else
82
83 shader_->use();
84 color_uniform_ = getUniform(open_gl, *shader_, "color");
85 dimensions_uniform_ = getUniform(open_gl, *shader_, "dimensions");
86 offset_uniform_ = getUniform(open_gl, *shader_, "offset");
87 scale_uniform_ = getUniform(open_gl, *shader_, "scale");
88 width_percent_uniform_ = getUniform(open_gl, *shader_, "width_percent");
89 position_ = getAttribute(open_gl, *shader_, "position");
90 corner_ = getAttribute(open_gl, *shader_, "corner");
91}
92
94 if (!setViewPort(open_gl))
95 return;
96
97 if (shader_ == nullptr)
98 init(open_gl);
99
100 glEnable(GL_BLEND);
101 glEnable(GL_SCISSOR_TEST);
103 glBlendFunc(GL_SRC_ALPHA, GL_ONE);
104 else
105 glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
106
107 // Update buffer data if bars have changed.
108 if (dirty_) {
109 dirty_ = false;
110 setBarSizes();
111 open_gl.context.extensions.glBindBuffer(GL_ARRAY_BUFFER, bar_buffer_);
112
113 GLsizeiptr vert_size = static_cast<GLsizeiptr>(kFloatsPerBar * total_points_ * sizeof(float));
114 open_gl.context.extensions.glBufferData(GL_ARRAY_BUFFER, vert_size, bar_data_.get(), GL_STATIC_DRAW);
115 open_gl.context.extensions.glBindBuffer(GL_ARRAY_BUFFER, 0);
116 }
117
118 shader_->use();
119
120 color_uniform_->set(color_.getFloatRed(), color_.getFloatGreen(),
121 color_.getFloatBlue(), color_.getFloatAlpha());
122 dimensions_uniform_->set(getWidth(), getHeight());
125
126 float min_width = 4.0f / getWidth();
127 width_percent_uniform_->set(std::max(min_width, bar_width_ * scale_ * 2.0f / num_points_));
128 open_gl.context.extensions.glBindBuffer(GL_ARRAY_BUFFER, bar_buffer_);
129 open_gl.context.extensions.glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, bar_indices_buffer_);
130
131 open_gl.context.extensions.glVertexAttribPointer(position_->attributeID, kFloatsPerVertex, GL_FLOAT,
132 GL_FALSE, kFloatsPerVertex * sizeof(float), nullptr);
133 open_gl.context.extensions.glEnableVertexAttribArray(position_->attributeID);
134
135 open_gl.context.extensions.glBindBuffer(GL_ARRAY_BUFFER, bar_corner_buffer_);
136 open_gl.context.extensions.glVertexAttribPointer(corner_->attributeID, kCornerFloatsPerVertex, GL_FLOAT,
137 GL_FALSE, kCornerFloatsPerVertex * sizeof(float), nullptr);
138 open_gl.context.extensions.glEnableVertexAttribArray(corner_->attributeID);
139
140 glDrawElements(GL_TRIANGLES, kTriangleIndicesPerBar * total_points_, GL_UNSIGNED_INT, nullptr);
141
142 open_gl.context.extensions.glDisableVertexAttribArray(position_->attributeID);
143 open_gl.context.extensions.glBindBuffer(GL_ARRAY_BUFFER, 0);
144 open_gl.context.extensions.glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
145 glDisable(GL_BLEND);
146 glDisable(GL_SCISSOR_TEST);
147}
148
149void BarRenderer::render(OpenGlWrapper& open_gl, bool animate) {
150 drawBars(open_gl);
151}
152
155
156 shader_ = nullptr;
157 position_ = nullptr;
158 corner_ = nullptr;
159 color_uniform_ = nullptr;
160 dimensions_uniform_ = nullptr;
161 offset_uniform_ = nullptr;
162 scale_uniform_ = nullptr;
163 width_percent_uniform_ = nullptr;
164 open_gl.context.extensions.glDeleteBuffers(1, &bar_buffer_);
165 open_gl.context.extensions.glDeleteBuffers(1, &bar_indices_buffer_);
166
167 bar_buffer_ = 0;
169}
170
172 // Adjust the third coordinate to represent either width or height depending on orientation.
173 if (vertical_) {
174 for (int i = 0; i < total_points_; ++i) {
175 int index = i * kFloatsPerBar;
176 float height = fabsf(yAt(i) - bottomAt(i)) * 0.5f * display_scale_;
177
178 bar_data_[index + 2] = height;
179 bar_data_[index + kFloatsPerVertex + 2] = height;
180 bar_data_[index + 2 * kFloatsPerVertex + 2] = height;
181 bar_data_[index + 3 * kFloatsPerVertex + 2] = height;
182 }
183 }
184 else {
185 for (int i = 0; i < total_points_; ++i) {
186 int index = i * kFloatsPerBar;
187 float width = fabsf(xAt(i) - rightAt(i)) * 0.5f * display_scale_;
188
189 bar_data_[index + 2] = width;
190 bar_data_[index + kFloatsPerVertex + 2] = width;
191 bar_data_[index + 2 * kFloatsPerVertex + 2] = width;
192 bar_data_[index + 3 * kFloatsPerVertex + 2] = width;
193 }
194 }
195}
196
197void BarRenderer::setPowerScale(bool power_scale) {
198 if (power_scale == power_scale_)
199 return;
200
201 bool old_power_scale = power_scale_;
202 for (int i = 1; i < num_points_; ++i) {
203 power_scale_ = old_power_scale;
204 float old_y = scaledYAt(i);
205 power_scale_ = power_scale;
206 setScaledY(i, old_y);
207 }
208
209 dirty_ = true;
210}
211
212void BarRenderer::setSquareScale(bool square_scale) {
213 if (square_scale == square_scale_)
214 return;
215
216 bool old_square_scale = square_scale_;
217 for (int i = 0; i < num_points_; ++i) {
218 square_scale_ = old_square_scale;
219 float old_y = scaledYAt(i);
220 square_scale_ = square_scale;
221 setScaledY(i, old_y);
222 }
223
224 dirty_ = true;
225}
bool additive_blending_
If true, uses additive blending for rendering.
Definition bar_renderer.h:274
void setPowerScale(bool scale)
Enables or disables power scaling of bar heights.
Definition bar_renderer.cpp:197
float bottomAt(int index)
Gets the y-position of the bottom-left vertex of the given bar.
Definition bar_renderer.h:134
BarRenderer(int num_points, bool vertical=true)
Constructs a BarRenderer.
Definition bar_renderer.cpp:8
float yAt(int index)
Gets the y-position of the top-left vertex of the given bar.
Definition bar_renderer.h:127
std::unique_ptr< OpenGLShaderProgram::Attribute > position_
Attribute for vertex position.
Definition bar_renderer.h:266
std::unique_ptr< OpenGLShaderProgram::Uniform > dimensions_uniform_
Uniform for viewport dimensions.
Definition bar_renderer.h:262
force_inline float scaledYAt(int index)
Gets the scaled y-value of a bar at a given index.
Definition bar_renderer.h:218
float bar_width_
Relative width of each bar.
Definition bar_renderer.h:273
std::unique_ptr< float[]> bar_corner_data_
Bar corner coordinate data.
Definition bar_renderer.h:283
Colour color_
Current color of the bars.
Definition bar_renderer.h:269
float rightAt(int index)
Gets the x-position of the top-right vertex of the given bar.
Definition bar_renderer.h:120
OpenGLShaderProgram * shader_
The shader program used for rendering.
Definition bar_renderer.h:260
bool power_scale_
True if power scaling is applied to bar heights.
Definition bar_renderer.h:277
std::unique_ptr< float[]> bar_data_
Raw bar vertex position data.
Definition bar_renderer.h:282
static constexpr int kCornerFloatsPerVertex
Number of corner floats per vertex (used to determine corner coordinates).
Definition bar_renderer.h:36
void setSquareScale(bool scale)
Enables or disables square scaling of bar heights.
Definition bar_renderer.cpp:212
std::unique_ptr< int[]> bar_indices_
Triangle index data for bars.
Definition bar_renderer.h:284
force_inline void setScaledY(int index, float val)
Sets the scaled y-value at a specific index.
Definition bar_renderer.h:236
std::unique_ptr< OpenGLShaderProgram::Uniform > width_percent_uniform_
Uniform for bar width factor.
Definition bar_renderer.h:265
static constexpr int kFloatsPerBar
Number of floats per bar (4 vertices * 3 floats each).
Definition bar_renderer.h:30
float display_scale_
Additional scaling factor applied to bar sizes.
Definition bar_renderer.h:275
float offset_
Offset applied to bar positions.
Definition bar_renderer.h:272
void setBarSizes()
Updates the bar sizes based on their positions and scaling.
Definition bar_renderer.cpp:171
virtual void destroy(OpenGlWrapper &open_gl) override
Destroys any allocated OpenGL resources.
Definition bar_renderer.cpp:153
std::unique_ptr< OpenGLShaderProgram::Uniform > scale_uniform_
Uniform for scaling factor.
Definition bar_renderer.h:264
static constexpr int kCornerFloatsPerBar
Number of corner floats per bar.
Definition bar_renderer.h:39
bool vertical_
True if bars are rendered vertically.
Definition bar_renderer.h:270
virtual void init(OpenGlWrapper &open_gl) override
Initializes the renderer with an OpenGL context.
Definition bar_renderer.cpp:57
int num_points_
Number of bars to render.
Definition bar_renderer.h:280
float xAt(int index)
Gets the x-position of the top-left vertex of the given bar.
Definition bar_renderer.h:113
virtual void render(OpenGlWrapper &open_gl, bool animate) override
Renders the bars using the current OpenGL context.
Definition bar_renderer.cpp:149
static constexpr int kTriangleIndicesPerBar
Number of triangle indices per bar (each bar represented as two triangles).
Definition bar_renderer.h:33
bool dirty_
True if bar data needs to be re-uploaded to the GPU.
Definition bar_renderer.h:279
std::unique_ptr< OpenGLShaderProgram::Uniform > offset_uniform_
Uniform for position offset.
Definition bar_renderer.h:263
float scale_
Scale factor for bar dimensions.
Definition bar_renderer.h:271
void drawBars(OpenGlWrapper &open_gl)
Draws the bars to the currently active OpenGL context.
Definition bar_renderer.cpp:93
std::unique_ptr< OpenGLShaderProgram::Uniform > color_uniform_
Uniform for bar color.
Definition bar_renderer.h:261
std::unique_ptr< OpenGLShaderProgram::Attribute > corner_
Attribute for corner coordinates.
Definition bar_renderer.h:267
virtual ~BarRenderer()
Destructor.
Definition bar_renderer.cpp:55
GLuint bar_indices_buffer_
OpenGL buffer object for bar indices.
Definition bar_renderer.h:287
int total_points_
Total number of allocated points (bars).
Definition bar_renderer.h:281
static constexpr int kFloatsPerVertex
Number of float values per vertex (x, y, [and potentially other attributes]).
Definition bar_renderer.h:24
GLuint bar_corner_buffer_
OpenGL buffer object for bar corners.
Definition bar_renderer.h:286
bool square_scale_
True if square scaling is applied to bar heights.
Definition bar_renderer.h:278
static constexpr int kVerticesPerBar
Number of vertices per bar.
Definition bar_renderer.h:27
GLuint bar_buffer_
OpenGL buffer object for bar positions.
Definition bar_renderer.h:285
static bool setViewPort(Component *component, Rectangle< int > bounds, OpenGlWrapper &open_gl)
Sets the OpenGL viewport to match a specified rectangle within a component.
Definition open_gl_component.cpp:42
void addRoundedCorners()
Adds rounded corners to the component's edges.
Definition open_gl_component.cpp:138
static std::unique_ptr< OpenGLShaderProgram::Attribute > getAttribute(const OpenGlWrapper &open_gl, const OpenGLShaderProgram &program, const char *name)
Retrieves an attribute from the shader program if it exists.
Definition open_gl_component.h:79
virtual void destroy(OpenGlWrapper &open_gl)
Destroys any OpenGL-specific resources allocated by this component.
Definition open_gl_component.cpp:168
static std::unique_ptr< OpenGLShaderProgram::Uniform > getUniform(const OpenGlWrapper &open_gl, const OpenGLShaderProgram &program, const char *name)
Retrieves a uniform from the shader program if it exists.
Definition open_gl_component.h:64
virtual void init(OpenGlWrapper &open_gl)
Initializes any OpenGL-specific resources needed by the component.
Definition open_gl_component.cpp:148
@ kBarVerticalVertex
Definition shaders.h:48
@ kBarHorizontalVertex
Definition shaders.h:47
@ kBarFragment
Definition shaders.h:79
OpenGLShaderProgram * getShaderProgram(VertexShader vertex_shader, FragmentShader fragment_shader, const GLchar **varyings=nullptr)
Retrieves or creates an OpenGLShaderProgram from a given vertex and fragment shader pair.
Definition shaders.cpp:953
A helper struct containing references to OpenGL context, shaders, and display scale.
Definition shaders.h:174
OpenGLContext & context
The OpenGLContext for current rendering.
Definition shaders.h:181
Shaders * shaders
Pointer to the Shaders instance providing compiled shaders.
Definition shaders.h:182
Provides various utility functions, classes, and constants for audio, math, and general-purpose opera...