Vital
Loading...
Searching...
No Matches
open_gl_image.cpp
Go to the documentation of this file.
1#include "open_gl_image.h"
2
3#include "open_gl_component.h"
4#include "shaders.h"
5#include "utils.h"
6
7namespace {
8 constexpr int kNumPositions = 16; // Number of floats in the vertex data (4 vertices * 4 floats).
9 constexpr int kNumTriangleIndices = 6; // Number of indices for drawing two triangles forming a quad.
10} // namespace
11
12OpenGlImage::OpenGlImage() : dirty_(true), image_(nullptr), image_width_(0), image_height_(0),
13 additive_(false), use_alpha_(false), scissor_(false) {
14 position_vertices_ = std::make_unique<float[]>(kNumPositions);
15 float position_vertices[kNumPositions] = {
16 0.0f, 1.0f, 0.0f, 1.0f,
17 0.0f, -1.0f, 0.0f, 0.0f,
18 0.1f, -1.0f, 1.0f, 0.0f,
19 0.1f, 1.0f, 1.0f, 1.0f
20 };
21 memcpy(position_vertices_.get(), position_vertices, kNumPositions * sizeof(float));
22
23 position_triangles_ = std::make_unique<int[]>(kNumTriangleIndices);
24 int position_triangles[kNumTriangleIndices] = {
25 0, 1, 2,
26 2, 3, 0
27 };
28 memcpy(position_triangles_.get(), position_triangles, kNumTriangleIndices * sizeof(int));
29}
30
32
34 // Create and bind vertex buffer for position data
35 open_gl.context.extensions.glGenBuffers(1, &vertex_buffer_);
36 open_gl.context.extensions.glBindBuffer(GL_ARRAY_BUFFER, vertex_buffer_);
37
38 GLsizeiptr vert_size = static_cast<GLsizeiptr>(static_cast<size_t>(kNumPositions * sizeof(float)));
39 open_gl.context.extensions.glBufferData(GL_ARRAY_BUFFER, vert_size,
40 position_vertices_.get(), GL_STATIC_DRAW);
41
42 // Create and bind element buffer for triangle indices
43 open_gl.context.extensions.glGenBuffers(1, &triangle_buffer_);
44 open_gl.context.extensions.glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, triangle_buffer_);
45
46 GLsizeiptr tri_size = static_cast<GLsizeiptr>(static_cast<size_t>(kNumTriangleIndices * sizeof(float)));
47 open_gl.context.extensions.glBufferData(GL_ELEMENT_ARRAY_BUFFER, tri_size,
48 position_triangles_.get(), GL_STATIC_DRAW);
49
50 // Use a tinted image shader
52
53 image_shader_->use();
54 image_color_ = OpenGlComponent::getUniform(open_gl, *image_shader_, "color");
55 image_position_ = OpenGlComponent::getAttribute(open_gl, *image_shader_, "position");
56 texture_coordinates_ = OpenGlComponent::getAttribute(open_gl, *image_shader_, "tex_coord_in");
57}
58
60 // Load image into texture if a new image was set
61 mutex_.lock();
62 if (image_) {
63 texture_.loadImage(*image_);
64 image_ = nullptr;
65 }
66 mutex_.unlock();
67
68 glEnable(GL_BLEND);
69 if (scissor_)
70 glEnable(GL_SCISSOR_TEST);
71 else
72 glDisable(GL_SCISSOR_TEST);
73
74 // Set blending mode
75 if (additive_)
76 glBlendFunc(GL_ONE, GL_ONE);
77 else if (use_alpha_)
78 glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
79 else
80 glBlendFunc(GL_ONE, GL_ONE_MINUS_SRC_ALPHA);
81
82 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
83 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
84
85 // Update vertex data if needed
86 open_gl.context.extensions.glBindBuffer(GL_ARRAY_BUFFER, vertex_buffer_);
87 GLsizeiptr vert_size = static_cast<GLsizeiptr>(static_cast<size_t>(kNumPositions * sizeof(float)));
88
89 mutex_.lock();
90 if (dirty_)
91 open_gl.context.extensions.glBufferData(GL_ARRAY_BUFFER, vert_size, position_vertices_.get(), GL_STATIC_DRAW);
92 dirty_ = false;
93
94 open_gl.context.extensions.glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, triangle_buffer_);
95 texture_.bind();
96 open_gl.context.extensions.glActiveTexture(GL_TEXTURE0);
97 mutex_.unlock();
98
99 image_shader_->use();
100
101 // Set uniform color
102 image_color_->set(color_.getFloatRed(), color_.getFloatGreen(), color_.getFloatBlue(), color_.getFloatAlpha());
103
104 // Enable vertex attributes
105 open_gl.context.extensions.glVertexAttribPointer(image_position_->attributeID, 2, GL_FLOAT,
106 GL_FALSE, 4 * sizeof(float), nullptr);
107 open_gl.context.extensions.glEnableVertexAttribArray(image_position_->attributeID);
108 open_gl.context.extensions.glVertexAttribPointer(texture_coordinates_->attributeID, 2, GL_FLOAT,
109 GL_FALSE, 4 * sizeof(float),
110 (GLvoid*)(2 * sizeof(float)));
111 open_gl.context.extensions.glEnableVertexAttribArray(texture_coordinates_->attributeID);
112
113 // Draw the image quad
114 glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_INT, nullptr);
115
116 // Disable vertex attributes
117 open_gl.context.extensions.glDisableVertexAttribArray(image_position_->attributeID);
118 open_gl.context.extensions.glDisableVertexAttribArray(texture_coordinates_->attributeID);
119 texture_.unbind();
120
121 open_gl.context.extensions.glBindBuffer(GL_ARRAY_BUFFER, 0);
122 open_gl.context.extensions.glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
123
124 glDisable(GL_BLEND);
125 glDisable(GL_SCISSOR_TEST);
126}
127
129 texture_.release();
130
131 image_shader_ = nullptr;
132 image_color_ = nullptr;
133 image_position_ = nullptr;
134 texture_coordinates_ = nullptr;
135
136 open_gl.context.extensions.glDeleteBuffers(1, &vertex_buffer_);
137 open_gl.context.extensions.glDeleteBuffers(1, &triangle_buffer_);
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
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 ~OpenGlImage()
Destructor.
Definition open_gl_image.cpp:31
void init(OpenGlWrapper &open_gl)
Initializes the OpenGL buffers and shader attributes needed for rendering the image.
Definition open_gl_image.cpp:33
OpenGlImage()
Constructs an OpenGlImage with default settings.
Definition open_gl_image.cpp:12
void drawImage(OpenGlWrapper &open_gl)
Draws the image to the current OpenGL context.
Definition open_gl_image.cpp:59
void destroy(OpenGlWrapper &open_gl)
Releases any OpenGL resources allocated by this object.
Definition open_gl_image.cpp:128
@ kImageVertex
Definition shaders.h:28
@ kTintedImageFragment
Definition shaders.h:60
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...