Vital
Loading...
Searching...
No Matches
open_gl_multi_image.cpp
Go to the documentation of this file.
2
3#include "common.h"
4#include "shaders.h"
5
6OpenGlMultiImage::OpenGlMultiImage(int max_quads) : image_(nullptr), image_width_(0), image_height_(0),
7 max_quads_(max_quads), num_quads_(max_quads),
8 dirty_(false), additive_blending_(false), image_shader_(nullptr) {
9 static const int triangles[] = {
10 0, 1, 2,
11 2, 3, 0
12 };
13
14 data_ = std::make_unique<float[]>(max_quads_ * kNumFloatsPerQuad);
15 indices_ = std::make_unique<int[]>(max_quads_ * kNumIndicesPerQuad);
16 vertex_buffer_ = 0;
17 indices_buffer_ = 0;
18
19 // Initialize texture coordinates and default positions
20 for (int i = 0; i < max_quads_; ++i) {
21 int index = i * kNumFloatsPerQuad;
22
23 // Default texture coords
24 data_[index + 2] = 0.0f;
25 data_[index + 3] = 1.0f;
26 data_[index + 6] = 0.0f;
27 data_[index + 7] = 0.0f;
28 data_[index + 10] = 1.0f;
29 data_[index + 11] = 0.0f;
30 data_[index + 14] = 1.0f;
31 data_[index + 15] = 1.0f;
32
33 // Set indices for two triangles forming a quad
34 for (int j = 0; j < kNumIndicesPerQuad; ++j)
35 indices_[i * kNumIndicesPerQuad + j] = triangles[j] + i * kNumVertices;
36 }
37
38 setInterceptsMouseClicks(false, false);
39 setColor(Colours::white);
40}
41
43
45 open_gl.context.extensions.glGenBuffers(1, &vertex_buffer_);
46 open_gl.context.extensions.glBindBuffer(GL_ARRAY_BUFFER, vertex_buffer_);
47
48 GLsizeiptr vert_size = static_cast<GLsizeiptr>(max_quads_ * kNumFloatsPerQuad * sizeof(float));
49 open_gl.context.extensions.glBufferData(GL_ARRAY_BUFFER, vert_size, data_.get(), GL_STATIC_DRAW);
50
51 open_gl.context.extensions.glGenBuffers(1, &indices_buffer_);
52 open_gl.context.extensions.glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, indices_buffer_);
53
54 GLsizeiptr tri_size = static_cast<GLsizeiptr>(max_quads_ * kNumIndicesPerQuad * sizeof(int));
55 open_gl.context.extensions.glBufferData(GL_ELEMENT_ARRAY_BUFFER, tri_size, indices_.get(), GL_STATIC_DRAW);
56
58 image_shader_->use();
59 color_uniform_ = getUniform(open_gl, *image_shader_, "color");
60 position_ = getAttribute(open_gl, *image_shader_, "position");
61 texture_coordinates_ = getAttribute(open_gl, *image_shader_, "tex_coord_in");
62}
63
65 texture_.release();
66
67 image_shader_ = nullptr;
68 position_ = nullptr;
69 texture_coordinates_ = nullptr;
70 color_uniform_ = nullptr;
71
72 open_gl.context.extensions.glDeleteBuffers(1, &vertex_buffer_);
73 open_gl.context.extensions.glDeleteBuffers(1, &indices_buffer_);
74
75 vertex_buffer_ = 0;
76 indices_buffer_ = 0;
77}
78
79void OpenGlMultiImage::render(OpenGlWrapper& open_gl, bool animate) {
80 if (!setViewPort(open_gl))
81 return;
82
83 if (image_) {
84 texture_.loadImage(*image_);
85 image_ = nullptr;
86 }
87
88 if (image_shader_ == nullptr)
89 init(open_gl);
90
91 glEnable(GL_BLEND);
92 glEnable(GL_SCISSOR_TEST);
93 if (additive_blending_)
94 glBlendFunc(GL_ONE, GL_ONE);
95 else
96 glBlendFunc(GL_ONE, GL_ONE_MINUS_SRC_ALPHA);
97
98 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
99 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
100
101 texture_.bind();
102 open_gl.context.extensions.glActiveTexture(GL_TEXTURE0);
103
104 if (dirty_) {
105 dirty_ = false;
106 open_gl.context.extensions.glBindBuffer(GL_ARRAY_BUFFER, vertex_buffer_);
107
108 GLsizeiptr vert_size = static_cast<GLsizeiptr>(kNumFloatsPerQuad * max_quads_ * sizeof(float));
109 open_gl.context.extensions.glBufferData(GL_ARRAY_BUFFER, vert_size, data_.get(), GL_STATIC_DRAW);
110 open_gl.context.extensions.glBindBuffer(GL_ARRAY_BUFFER, 0);
111 }
112
113 image_shader_->use();
114 color_uniform_->set(color_.getFloatRed(), color_.getFloatGreen(),
115 color_.getFloatBlue(), color_.getFloatAlpha());
116
117 open_gl.context.extensions.glBindBuffer(GL_ARRAY_BUFFER, vertex_buffer_);
118 open_gl.context.extensions.glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, indices_buffer_);
119
120 open_gl.context.extensions.glVertexAttribPointer(position_->attributeID, 2, GL_FLOAT,
121 GL_FALSE, kNumFloatsPerVertex * sizeof(float), nullptr);
122 open_gl.context.extensions.glEnableVertexAttribArray(position_->attributeID);
123 open_gl.context.extensions.glVertexAttribPointer(texture_coordinates_->attributeID, 2, GL_FLOAT,
124 GL_FALSE, kNumFloatsPerVertex * sizeof(float),
125 (GLvoid*)(2 * sizeof(float)));
126 open_gl.context.extensions.glEnableVertexAttribArray(texture_coordinates_->attributeID);
127
128 glDrawElements(GL_TRIANGLES, num_quads_ * kNumIndicesPerQuad, GL_UNSIGNED_INT, nullptr);
129
130 open_gl.context.extensions.glDisableVertexAttribArray(position_->attributeID);
131 open_gl.context.extensions.glDisableVertexAttribArray(texture_coordinates_->attributeID);
132 open_gl.context.extensions.glBindBuffer(GL_ARRAY_BUFFER, 0);
133 open_gl.context.extensions.glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
134}
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 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 render(OpenGlWrapper &open_gl, bool animate) override
Renders the set of image quads using OpenGL.
Definition open_gl_multi_image.cpp:79
static constexpr int kNumFloatsPerQuad
Number of floats per quad (4 vertices * 4 floats each).
Definition open_gl_multi_image.h:23
static constexpr int kNumIndicesPerQuad
Number of indices per quad (2 triangles * 3 indices each).
Definition open_gl_multi_image.h:25
virtual void init(OpenGlWrapper &open_gl) override
Initializes OpenGL buffers and shader attributes for rendering.
Definition open_gl_multi_image.cpp:44
virtual ~OpenGlMultiImage()
Destructor. Frees any allocated OpenGL resources.
Definition open_gl_multi_image.cpp:42
void setColor(Colour color)
Sets the color tint applied to all image quads.
Definition open_gl_multi_image.h:112
virtual void destroy(OpenGlWrapper &open_gl) override
Destroys the OpenGL resources used by this class.
Definition open_gl_multi_image.cpp:64
static constexpr int kNumVertices
Number of vertices per quad (2 triangles forming a rectangle).
Definition open_gl_multi_image.h:19
OpenGlMultiImage(int max_images)
Constructs an OpenGlMultiImage with a given maximum number of quads.
Definition open_gl_multi_image.cpp:6
static constexpr int kNumFloatsPerVertex
Number of floats per vertex (x, y, u, v).
Definition open_gl_multi_image.h:21
@ 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