15
15
* Authored By: Alexandros Frantzis <alexandros.frantzis@canonical.com>
18
#include "gl_renderer.h"
19
#include "mir/compositor/compositing_criteria.h"
18
#include "mir/compositor/gl_renderer.h"
20
19
#include "mir/compositor/buffer_stream.h"
20
#include "mir/graphics/renderable.h"
21
21
#include "mir/graphics/buffer.h"
23
#define GLM_FORCE_RADIANS
23
24
#include <glm/gtc/matrix_transform.hpp>
24
25
#include <glm/gtc/type_ptr.hpp>
42
43
"uniform mat4 screen_to_gl_coords;\n"
43
44
"uniform mat4 display_transform;\n"
44
45
"uniform mat4 transform;\n"
46
"uniform vec2 centre;\n"
45
47
"varying vec2 v_texcoord;\n"
47
" gl_Position = display_transform * screen_to_gl_coords * transform * vec4(position, 1.0);\n"
49
" vec4 mid = vec4(centre, 0.0, 0.0);\n"
50
" vec4 transformed = (transform * (vec4(position, 1.0) - mid)) + mid;\n"
51
" transformed.z = 0.0;\n" // avoid clipping while we lack depth/perspective
52
" gl_Position = display_transform * screen_to_gl_coords * transformed;\n"
48
53
" v_texcoord = texcoord;\n"
64
struct VertexAttributes
71
* The texture coordinates are y-inverted to account for the difference in the
72
* texture and renderable pixel data row order. In particular, GL textures
73
* expect pixel data in rows starting from the bottom and moving up the image,
74
* whereas our renderables provide data in rows starting from the top and
75
* moving down the image.
77
VertexAttributes vertex_attribs[4] =
80
glm::vec3{-0.5f, -0.5f, 0.0f},
84
glm::vec3{-0.5f, 0.5f, 0.0f},
85
glm::vec2{0.0f, 1.0f},
88
glm::vec3{0.5f, -0.5f, 0.0f},
89
glm::vec2{1.0f, 0.0f},
92
glm::vec3{0.5f, 0.5f, 0.0f},
97
69
typedef void(*MirGLGetObjectInfoLog)(GLuint, GLsizei, GLsizei *, GLchar *);
98
70
typedef void(*MirGLGetObjectiv)(GLuint, GLenum, GLint *);
189
161
alpha_uniform_loc = glGetUniformLocation(program, "alpha");
190
162
position_attr_loc = glGetAttribLocation(program, "position");
191
163
texcoord_attr_loc = glGetAttribLocation(program, "texcoord");
164
centre_uniform_loc = glGetUniformLocation(program, "centre");
193
166
glUniform1i(tex_loc, 0);
196
glGenBuffers(1, &vertex_attribs_vbo);
198
glBindBuffer(GL_ARRAY_BUFFER, vertex_attribs_vbo);
199
glBufferData(GL_ARRAY_BUFFER, sizeof(vertex_attribs),
200
glm::value_ptr(vertex_attribs[0].position), GL_STATIC_DRAW);
202
168
glBindBuffer(GL_ARRAY_BUFFER, 0);
214
180
glDeleteShader(fragment_shader);
216
182
glDeleteProgram(program);
217
if (vertex_attribs_vbo)
218
glDeleteBuffers(1, &vertex_attribs_vbo);
219
183
for (auto& t : textures)
220
184
glDeleteTextures(1, &t.second.id);
223
void mc::GLRenderer::render(CompositingCriteria const& criteria, mg::Buffer& buffer) const
187
GLenum mc::GLRenderer::tessellate(graphics::Renderable const& renderable,
188
std::vector<Vertex>& vertices) const
190
auto const& rect = renderable.screen_position();
191
GLfloat left = rect.top_left.x.as_int();
192
GLfloat right = left + rect.size.width.as_int();
193
GLfloat top = rect.top_left.y.as_int();
194
GLfloat bottom = top + rect.size.height.as_int();
197
vertices[0] = {{left, top, 0.0f}, {0.0f, 0.0f}};
198
vertices[1] = {{left, bottom, 0.0f}, {0.0f, 1.0f}};
199
vertices[2] = {{right, top, 0.0f}, {1.0f, 0.0f}};
200
vertices[3] = {{right, bottom, 0.0f}, {1.0f, 1.0f}};
201
return GL_TRIANGLE_STRIP;
204
void mc::GLRenderer::render(mg::Renderable const& renderable, mg::Buffer& buffer) const
225
206
glUseProgram(program);
227
if (criteria.shaped() || criteria.alpha() < 1.0f)
208
if (renderable.shaped() || renderable.alpha() < 1.0f)
229
210
glEnable(GL_BLEND);
230
211
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
236
217
glActiveTexture(GL_TEXTURE0);
219
auto const& rect = renderable.screen_position();
220
GLfloat centrex = rect.top_left.x.as_int() +
221
rect.size.width.as_int() / 2.0f;
222
GLfloat centrey = rect.top_left.y.as_int() +
223
rect.size.height.as_int() / 2.0f;
224
glUniform2f(centre_uniform_loc, centrex, centrey);
238
226
glUniformMatrix4fv(transform_uniform_loc, 1, GL_FALSE,
239
glm::value_ptr(criteria.transformation()));
240
glUniform1f(alpha_uniform_loc, criteria.alpha());
227
glm::value_ptr(renderable.transformation()));
228
glUniform1f(alpha_uniform_loc, renderable.alpha());
242
/* Set up vertex attribute data */
243
glBindBuffer(GL_ARRAY_BUFFER, vertex_attribs_vbo);
230
std::vector<Vertex> vertices;
231
GLenum draw_mode = tessellate(renderable, vertices);
244
233
glVertexAttribPointer(position_attr_loc, 3, GL_FLOAT,
245
GL_FALSE, sizeof(VertexAttributes), 0);
234
GL_FALSE, sizeof(Vertex), &vertices[0].position);
246
235
glVertexAttribPointer(texcoord_attr_loc, 2, GL_FLOAT,
247
GL_FALSE, sizeof(VertexAttributes),
248
reinterpret_cast<void*>(sizeof(glm::vec3)));
236
GL_FALSE, sizeof(Vertex), &vertices[0].texcoord);
250
SurfaceID surf = &criteria; // temporary hack till we rearrange classes
238
SurfaceID surf = &renderable; // TODO: Add an id() to Renderable
251
239
auto& tex = textures[surf];
252
240
bool changed = true;
253
241
auto const& buf_id = buffer.id();
274
262
glEnableVertexAttribArray(position_attr_loc);
275
263
glEnableVertexAttribArray(texcoord_attr_loc);
276
glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
264
glDrawArrays(draw_mode, 0, vertices.size());
277
265
glDisableVertexAttribArray(texcoord_attr_loc);
278
266
glDisableVertexAttribArray(position_attr_loc);