3 * Copyright (C) 2016 Matthew Waters <matthew@centricular.com>
5 * This library is free software; you can redistribute it and/or
6 * modify it under the terms of the GNU Library General Public
7 * License as published by the Free Software Foundation; either
8 * version 2 of the License, or (at your option) any later version.
10 * This library is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 * Library General Public License for more details.
15 * You should have received a copy of the GNU Library General Public
16 * License along with this library; if not, write to the
17 * Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
18 * Boston, MA 02110-1301, USA.
25 #include <gst/gl/gstglfuncs.h>
27 #include "gstglutils.h"
29 struct _compile_shader
32 const gchar *vertex_src;
33 const gchar *fragment_src;
37 _compile_shader (GstGLContext * context, struct _compile_shader *data)
40 GstGLSLStage *vert, *frag;
43 shader = gst_gl_shader_new (context);
45 if (data->vertex_src) {
46 vert = gst_glsl_stage_new_with_string (context, GL_VERTEX_SHADER,
47 GST_GLSL_VERSION_NONE,
48 GST_GLSL_PROFILE_ES | GST_GLSL_PROFILE_COMPATIBILITY, data->vertex_src);
49 if (!gst_glsl_stage_compile (vert, &error)) {
50 GST_ERROR_OBJECT (vert, "%s", error->message);
51 gst_object_unref (vert);
52 gst_object_unref (shader);
55 if (!gst_gl_shader_attach (shader, vert)) {
56 gst_object_unref (shader);
61 if (data->fragment_src) {
62 frag = gst_glsl_stage_new_with_string (context, GL_FRAGMENT_SHADER,
63 GST_GLSL_VERSION_NONE,
64 GST_GLSL_PROFILE_ES | GST_GLSL_PROFILE_COMPATIBILITY,
66 if (!gst_glsl_stage_compile (frag, &error)) {
67 GST_ERROR_OBJECT (frag, "%s", error->message);
68 gst_object_unref (frag);
69 gst_object_unref (shader);
72 if (!gst_gl_shader_attach (shader, frag)) {
73 gst_object_unref (shader);
78 if (!gst_gl_shader_link (shader, &error)) {
79 GST_ERROR_OBJECT (shader, "%s", error->message);
82 gst_gl_context_clear_shader (context);
83 gst_object_unref (shader);
87 *data->shader = shader;
90 /* Called by glfilter */
92 gst_gl_context_gen_shader (GstGLContext * context, const gchar * vert_src,
93 const gchar * frag_src, GstGLShader ** shader)
95 struct _compile_shader data;
97 g_return_val_if_fail (frag_src != NULL || vert_src != NULL, FALSE);
98 g_return_val_if_fail (shader != NULL, FALSE);
100 data.shader = shader;
101 data.vertex_src = vert_src;
102 data.fragment_src = frag_src;
104 gst_gl_context_thread_add (context, (GstGLContextThreadFunc) _compile_shader,
107 return *shader != NULL;
110 static const gfloat identity_matrix[] = {
111 1.0f, 0.0f, 0.0, 0.0f,
112 0.0f, 1.0f, 0.0, 0.0f,
113 0.0f, 0.0f, 1.0, 0.0f,
114 0.0f, 0.0f, 0.0, 1.0f,
117 static const gfloat from_ndc_matrix[] = {
118 0.5f, 0.0f, 0.0, 0.5f,
119 0.0f, 0.5f, 0.0, 0.5f,
120 0.0f, 0.0f, 0.5, 0.5f,
121 0.0f, 0.0f, 0.0, 1.0f,
124 static const gfloat to_ndc_matrix[] = {
125 2.0f, 0.0f, 0.0, -1.0f,
126 0.0f, 2.0f, 0.0, -1.0f,
127 0.0f, 0.0f, 2.0, -1.0f,
128 0.0f, 0.0f, 0.0, 1.0f,
132 gst_gl_multiply_matrix4 (const gfloat * a, const gfloat * b, gfloat * result)
135 gfloat tmp[16] = { 0.0f };
137 if (!a || !b || !result)
140 for (i = 0; i < 4; i++) {
141 for (j = 0; j < 4; j++) {
142 for (k = 0; k < 4; k++) {
143 tmp[i + (j * 4)] += a[i + (k * 4)] * b[k + (j * 4)];
148 for (i = 0; i < 16; i++)
152 void gst_gl_get_affine_transformation_meta_as_ndc_ext
153 (GstVideoAffineTransformationMeta * meta, gfloat * matrix)
158 for (i = 0; i < 16; i++) {
159 matrix[i] = identity_matrix[i];
162 gfloat tmp[16] = { 0.0f };
164 gst_gl_multiply_matrix4 (from_ndc_matrix, meta->matrix, tmp);
165 gst_gl_multiply_matrix4 (tmp, to_ndc_matrix, matrix);