Vital
Loading...
Searching...
No Matches
open_gl_multi_quad.cpp
Go to the documentation of this file.
2
3#include "common.h"
4#include "shaders.h"
5
7 target_component_(nullptr), scissor_component_(nullptr), fragment_shader_(shader),
8 max_quads_(max_quads), num_quads_(max_quads), draw_when_not_visible_(false),
9 active_(true), dirty_(false), max_arc_(2.0f), thumb_amount_(0.5f), start_pos_(0.0f),
10 current_alpha_mult_(1.0f), alpha_mult_(1.0f), additive_blending_(false),
11 current_thickness_(1.0f), thickness_(1.0f), rounding_(5.0f), shader_(nullptr) {
12 static const int triangles[] = {
13 0, 1, 2,
14 2, 3, 0
15 };
16
17 data_ = std::make_unique<float[]>(max_quads_ * kNumFloatsPerQuad);
18 indices_ = std::make_unique<int[]>(max_quads_ * kNumIndicesPerQuad);
21
22 mod_color_ = Colours::transparentBlack;
23
24 for (int i = 0; i < max_quads_; ++i) {
25 setCoordinates(i, -1.0f, -1.0f, 2.0f, 2.0f);
26 setShaderValue(i, 1.0f);
27
28 for (int j = 0; j < kNumIndicesPerQuad; ++j)
29 indices_[i * kNumIndicesPerQuad + j] = triangles[j] + i * kNumVertices;
30 }
31
32 setInterceptsMouseClicks(false, false);
33}
34
36
38 open_gl.context.extensions.glGenBuffers(1, &vertex_buffer_);
39 open_gl.context.extensions.glBindBuffer(GL_ARRAY_BUFFER, vertex_buffer_);
40
41 GLsizeiptr vert_size = static_cast<GLsizeiptr>(max_quads_ * kNumFloatsPerQuad * sizeof(float));
42 open_gl.context.extensions.glBufferData(GL_ARRAY_BUFFER, vert_size, data_.get(), GL_STATIC_DRAW);
43
44 open_gl.context.extensions.glGenBuffers(1, &indices_buffer_);
45 open_gl.context.extensions.glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, indices_buffer_);
46
47 GLsizeiptr bar_size = static_cast<GLsizeiptr>(max_quads_ * kNumIndicesPerQuad * sizeof(int));
48 open_gl.context.extensions.glBufferData(GL_ELEMENT_ARRAY_BUFFER, bar_size, indices_.get(), GL_STATIC_DRAW);
49
51 shader_->use();
52 color_uniform_ = getUniform(open_gl, *shader_, "color");
53 alt_color_uniform_ = getUniform(open_gl, *shader_, "alt_color");
54 mod_color_uniform_ = getUniform(open_gl, *shader_, "mod_color");
55 background_color_uniform_ = getUniform(open_gl, *shader_, "background_color");
56 thumb_color_uniform_ = getUniform(open_gl, *shader_, "thumb_color");
57 position_ = getAttribute(open_gl, *shader_, "position");
58 dimensions_ = getAttribute(open_gl, *shader_, "dimensions");
59 coordinates_ = getAttribute(open_gl, *shader_, "coordinates");
60 shader_values_ = getAttribute(open_gl, *shader_, "shader_values");
61 thickness_uniform_ = getUniform(open_gl, *shader_, "thickness");
62 rounding_uniform_ = getUniform(open_gl, *shader_, "rounding");
63 max_arc_uniform_ = getUniform(open_gl, *shader_, "max_arc");
64 thumb_amount_uniform_ = getUniform(open_gl, *shader_, "thumb_amount");
65 start_pos_uniform_ = getUniform(open_gl, *shader_, "start_pos");
66 alpha_mult_uniform_ = getUniform(open_gl, *shader_, "alpha_mult");
67}
68
70 shader_ = nullptr;
71 position_ = nullptr;
72 dimensions_ = nullptr;
73 coordinates_ = nullptr;
74 shader_values_ = nullptr;
75 color_uniform_ = nullptr;
76 alt_color_uniform_ = nullptr;
77 mod_color_uniform_ = nullptr;
78 thumb_color_uniform_ = nullptr;
79 thickness_uniform_ = nullptr;
80 rounding_uniform_ = nullptr;
81 max_arc_uniform_ = nullptr;
82 thumb_amount_uniform_ = nullptr;
83 start_pos_uniform_ = nullptr;
84 alpha_mult_uniform_ = nullptr;
85 open_gl.context.extensions.glDeleteBuffers(1, &vertex_buffer_);
86 open_gl.context.extensions.glDeleteBuffers(1, &indices_buffer_);
87
90}
91
92void OpenGlMultiQuad::render(OpenGlWrapper& open_gl, bool animate) {
93 Component* component = target_component_ ? target_component_ : this;
94 if (!active_ || (!draw_when_not_visible_ && !component->isVisible()) || !setViewPort(component, open_gl))
95 return;
96
97 Component* scissor_component = scissor_component_;
98 if (scissor_component)
99 setScissor(scissor_component, open_gl);
100
101 if (current_alpha_mult_ == 0.0f && alpha_mult_ == 0.0f)
102 return;
103
104 if (shader_ == nullptr)
105 init(open_gl);
106
107 glEnable(GL_BLEND);
108 glEnable(GL_SCISSOR_TEST);
110 glBlendFunc(GL_SRC_ALPHA, GL_ONE);
111 else
112 glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
113
114 if (dirty_) {
115 dirty_ = false;
116
117 for (int i = 0; i < num_quads_; ++i)
118 setDimensions(i, getQuadWidth(i), getQuadHeight(i), component->getWidth(), component->getHeight());
119
120 open_gl.context.extensions.glBindBuffer(GL_ARRAY_BUFFER, vertex_buffer_);
121
122 GLsizeiptr vert_size = static_cast<GLsizeiptr>(kNumFloatsPerQuad * max_quads_ * sizeof(float));
123 open_gl.context.extensions.glBufferData(GL_ARRAY_BUFFER, vert_size, data_.get(), GL_STATIC_DRAW);
124 open_gl.context.extensions.glBindBuffer(GL_ARRAY_BUFFER, 0);
125 }
126
127 shader_->use();
128
129 // Adjust alpha towards target
132 else
134
135 float alpha_color_mult = 1.0f;
138 else
139 alpha_color_mult = current_alpha_mult_;
140
141 color_uniform_->set(color_.getFloatRed(), color_.getFloatGreen(),
142 color_.getFloatBlue(), alpha_color_mult * color_.getFloatAlpha());
143
144 if (alt_color_uniform_) {
145 if (alt_color_.getFloatAlpha()) {
146 alt_color_uniform_->set(alt_color_.getFloatRed(), alt_color_.getFloatGreen(),
147 alt_color_.getFloatBlue(), alt_color_.getFloatAlpha());
148 }
149 else
150 alt_color_uniform_->set(color_.getFloatRed(), color_.getFloatGreen(), color_.getFloatBlue(), 0.0f);
151 }
152 if (mod_color_uniform_) {
153 if (mod_color_.getFloatAlpha()) {
154 mod_color_uniform_->set(mod_color_.getFloatRed(), mod_color_.getFloatGreen(),
155 mod_color_.getFloatBlue(), mod_color_.getFloatAlpha());
156 }
157 else
158 mod_color_uniform_->set(color_.getFloatRed(), color_.getFloatGreen(), color_.getFloatBlue(), 0.0f);
159 }
161 if (background_color_.getFloatAlpha()) {
162 background_color_uniform_->set(background_color_.getFloatRed(), background_color_.getFloatGreen(),
163 background_color_.getFloatBlue(), background_color_.getFloatAlpha());
164 }
165 else
166 background_color_uniform_->set(color_.getFloatRed(), color_.getFloatGreen(), color_.getFloatBlue(), 0.0f);
167 }
168
170 thumb_color_uniform_->set(thumb_color_.getFloatRed(), thumb_color_.getFloatGreen(),
171 thumb_color_.getFloatBlue(), thumb_color_.getFloatAlpha());
172 }
173
176
179
180 if (thickness_uniform_) {
183 }
188
189 open_gl.context.extensions.glBindBuffer(GL_ARRAY_BUFFER, vertex_buffer_);
190 open_gl.context.extensions.glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, indices_buffer_);
191
192 open_gl.context.extensions.glVertexAttribPointer(position_->attributeID, 2, GL_FLOAT,
193 GL_FALSE, kNumFloatsPerVertex * sizeof(float), nullptr);
194 open_gl.context.extensions.glEnableVertexAttribArray(position_->attributeID);
195 if (dimensions_) {
196 open_gl.context.extensions.glVertexAttribPointer(dimensions_->attributeID, 2, GL_FLOAT,
197 GL_FALSE, kNumFloatsPerVertex * sizeof(float),
198 (GLvoid*)(2 * sizeof(float)));
199 open_gl.context.extensions.glEnableVertexAttribArray(dimensions_->attributeID);
200 }
201 if (coordinates_) {
202 open_gl.context.extensions.glVertexAttribPointer(coordinates_->attributeID, 2, GL_FLOAT,
203 GL_FALSE, kNumFloatsPerVertex * sizeof(float),
204 (GLvoid*)(4 * sizeof(float)));
205 open_gl.context.extensions.glEnableVertexAttribArray(coordinates_->attributeID);
206 }
207 if (shader_values_) {
208 open_gl.context.extensions.glVertexAttribPointer(shader_values_->attributeID, 4, GL_FLOAT,
209 GL_FALSE, kNumFloatsPerVertex * sizeof(float),
210 (GLvoid*)(6 * sizeof(float)));
211 open_gl.context.extensions.glEnableVertexAttribArray(shader_values_->attributeID);
212 }
213
214 glDrawElements(GL_TRIANGLES, num_quads_ * kNumIndicesPerQuad, GL_UNSIGNED_INT, nullptr);
215
216 open_gl.context.extensions.glDisableVertexAttribArray(position_->attributeID);
217 if (dimensions_)
218 open_gl.context.extensions.glDisableVertexAttribArray(dimensions_->attributeID);
219 if (coordinates_)
220 open_gl.context.extensions.glDisableVertexAttribArray(coordinates_->attributeID);
221 if (shader_values_)
222 open_gl.context.extensions.glDisableVertexAttribArray(shader_values_->attributeID);
223 open_gl.context.extensions.glBindBuffer(GL_ARRAY_BUFFER, 0);
224 open_gl.context.extensions.glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
225 glDisable(GL_BLEND);
226 glDisable(GL_SCISSOR_TEST);
227}
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
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
static void setScissor(Component *component, OpenGlWrapper &open_gl)
Sets the OpenGL scissor region to the entire component's local bounds.
Definition open_gl_component.cpp:78
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
Colour background_color_
The background color of the component.
Definition open_gl_component.h:254
float current_alpha_mult_
Current alpha multiplier for gradual changes.
Definition open_gl_multi_quad.h:410
Shaders::FragmentShader fragment_shader_
The fragment shader used for rendering.
Definition open_gl_multi_quad.h:396
bool draw_when_not_visible_
If true, draw even if the component is not visible.
Definition open_gl_multi_quad.h:400
std::unique_ptr< OpenGLShaderProgram::Attribute > shader_values_
Definition open_gl_multi_quad.h:435
float thickness_
Target thickness.
Definition open_gl_multi_quad.h:414
Colour thumb_color_
Color for a "thumb" element (e.g., in a slider).
Definition open_gl_multi_quad.h:406
Colour alt_color_
Alternate color for shader use.
Definition open_gl_multi_quad.h:404
void setShaderValue(int i, float shader_value, int value_index=0)
Sets a shader value for all four vertices of a quad.
Definition open_gl_multi_quad.h:254
Colour mod_color_
Modulation color for shader.
Definition open_gl_multi_quad.h:405
bool active_
If false, nothing is rendered.
Definition open_gl_multi_quad.h:401
std::unique_ptr< OpenGLShaderProgram::Uniform > color_uniform_
Definition open_gl_multi_quad.h:421
virtual void init(OpenGlWrapper &open_gl) override
Initializes OpenGL buffers and shader attributes.
Definition open_gl_multi_quad.cpp:37
OpenGLShaderProgram * shader_
Definition open_gl_multi_quad.h:420
float thumb_amount_
Amount parameter for thumb effects.
Definition open_gl_multi_quad.h:408
force_inline float getQuadHeight(int i) const
Gets the height of the specified quad.
Definition open_gl_multi_quad.h:199
std::unique_ptr< OpenGLShaderProgram::Uniform > alt_color_uniform_
Definition open_gl_multi_quad.h:422
static constexpr float kThicknessDecay
Decay factor for thickness adjustments over time.
Definition open_gl_multi_quad.h:27
bool additive_blending_
Use additive blending if true.
Definition open_gl_multi_quad.h:412
float rounding_
Rounding radius for corners.
Definition open_gl_multi_quad.h:415
virtual void render(OpenGlWrapper &open_gl, bool animate) override
Renders the quads using OpenGL.
Definition open_gl_multi_quad.cpp:92
static constexpr int kNumFloatsPerVertex
Number of floats per vertex (x, y, w, h, plus custom shader values).
Definition open_gl_multi_quad.h:21
GLuint indices_buffer_
OpenGL buffer for index data.
Definition open_gl_multi_quad.h:438
virtual void destroy(OpenGlWrapper &open_gl) override
Releases OpenGL resources when the component is destroyed.
Definition open_gl_multi_quad.cpp:69
std::unique_ptr< OpenGLShaderProgram::Uniform > background_color_uniform_
Definition open_gl_multi_quad.h:424
void setCoordinates(int i, float x, float y, float w, float h)
Sets coordinates for a quad in normalized device space.
Definition open_gl_multi_quad.h:234
static constexpr float kAlphaInc
Increment for alpha blending adjustments.
Definition open_gl_multi_quad.h:29
static constexpr int kNumFloatsPerQuad
Number of floats total per quad (4 vertices * 10 floats each).
Definition open_gl_multi_quad.h:23
virtual ~OpenGlMultiQuad()
Destructor. Frees any allocated OpenGL resources.
Definition open_gl_multi_quad.cpp:35
static constexpr int kNumIndicesPerQuad
Number of indices per quad (2 triangles forming a rectangle).
Definition open_gl_multi_quad.h:25
std::unique_ptr< OpenGLShaderProgram::Uniform > mod_color_uniform_
Definition open_gl_multi_quad.h:423
GLuint vertex_buffer_
OpenGL buffer for vertex data.
Definition open_gl_multi_quad.h:437
force_inline float getQuadWidth(int i) const
Gets the width of the specified quad.
Definition open_gl_multi_quad.h:191
float max_arc_
Maximum arc for certain shader effects.
Definition open_gl_multi_quad.h:407
std::unique_ptr< OpenGLShaderProgram::Attribute > coordinates_
Definition open_gl_multi_quad.h:434
void setDimensions(int i, float quad_width, float quad_height, float full_width, float full_height)
Sets dimensions for a quad, typically to scale based on component size.
Definition open_gl_multi_quad.h:267
Colour color_
Base color tint.
Definition open_gl_multi_quad.h:403
std::unique_ptr< OpenGLShaderProgram::Attribute > position_
Definition open_gl_multi_quad.h:432
std::unique_ptr< OpenGLShaderProgram::Uniform > rounding_uniform_
Definition open_gl_multi_quad.h:427
std::unique_ptr< int[]> indices_
Index data for drawing quads.
Definition open_gl_multi_quad.h:418
std::unique_ptr< OpenGLShaderProgram::Uniform > thickness_uniform_
Definition open_gl_multi_quad.h:426
std::unique_ptr< OpenGLShaderProgram::Uniform > max_arc_uniform_
Definition open_gl_multi_quad.h:428
int max_quads_
Maximum number of quads.
Definition open_gl_multi_quad.h:397
std::unique_ptr< OpenGLShaderProgram::Uniform > start_pos_uniform_
Definition open_gl_multi_quad.h:430
Component * scissor_component_
The component used for scissoring (clipping).
Definition open_gl_multi_quad.h:395
bool dirty_
If true, vertex data is dirty and needs re-upload.
Definition open_gl_multi_quad.h:402
static constexpr int kNumVertices
Number of vertices per quad.
Definition open_gl_multi_quad.h:19
float alpha_mult_
Target alpha multiplier.
Definition open_gl_multi_quad.h:411
std::unique_ptr< float[]> data_
Vertex data for all quads.
Definition open_gl_multi_quad.h:417
float start_pos_
Start position parameter for shader effects.
Definition open_gl_multi_quad.h:409
Component * target_component_
The component this relates to for sizing/positioning.
Definition open_gl_multi_quad.h:394
std::unique_ptr< OpenGLShaderProgram::Attribute > dimensions_
Definition open_gl_multi_quad.h:433
std::unique_ptr< OpenGLShaderProgram::Uniform > thumb_color_uniform_
Definition open_gl_multi_quad.h:425
std::unique_ptr< OpenGLShaderProgram::Uniform > alpha_mult_uniform_
Definition open_gl_multi_quad.h:431
OpenGlMultiQuad(int max_quads, Shaders::FragmentShader shader=Shaders::kColorFragment)
Constructs an OpenGlMultiQuad with a given maximum number of quads.
Definition open_gl_multi_quad.cpp:6
std::unique_ptr< OpenGLShaderProgram::Uniform > thumb_amount_uniform_
Definition open_gl_multi_quad.h:429
int num_quads_
Current number of quads to draw.
Definition open_gl_multi_quad.h:398
float current_thickness_
Current thickness for gradual changes.
Definition open_gl_multi_quad.h:413
@ kPassthroughVertex
Definition shaders.h:29
FragmentShader
An enumeration of all available fragment shaders.
Definition shaders.h:58
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