gltestsrc: port to gles2/gl3

This makes gltestsrc work everywhere \o/

- workaround RPi returning invalid values for positive coords in the
  checker shader
- reduce the number of iterations in the mandelbrot shader for gles2

https://bugzilla.gnome.org/show_bug.cgi?id=751540
This commit is contained in:
Matthew Waters 2016-02-26 20:55:47 +11:00
parent 00828b8c4c
commit a2d82e329a
4 changed files with 310 additions and 179 deletions

View file

@ -40,7 +40,9 @@ libgstopengl_la_SOURCES = \
gstglfilterapp.c \ gstglfilterapp.c \
gstglviewconvert.c \ gstglviewconvert.c \
gstglstereosplit.c \ gstglstereosplit.c \
gstglstereomix.c gstglstereomix.c \
gltestsrc.c \
gstgltestsrc.c
noinst_HEADERS = \ noinst_HEADERS = \
gstglbasemixer.h \ gstglbasemixer.h \
@ -63,22 +65,20 @@ noinst_HEADERS = \
gstglfilterapp.h \ gstglfilterapp.h \
gstglstereosplit.h \ gstglstereosplit.h \
gstglstereomix.h \ gstglstereomix.h \
gstglviewconvert.h gstglviewconvert.h \
gltestsrc.h
gstgltestsrc.h
# full opengl required # full opengl required
if USE_OPENGL if USE_OPENGL
libgstopengl_la_SOURCES += \ libgstopengl_la_SOURCES += \
gstglfilterglass.c \ gstglfilterglass.c \
gstgldeinterlace.c \ gstgldeinterlace.c \
gltestsrc.c \
gstgltestsrc.c \
gstglmosaic.c gstglmosaic.c
noinst_HEADERS += \ noinst_HEADERS += \
gstglfilterglass.h \ gstglfilterglass.h \
gstgldeinterlace.h \ gstgldeinterlace.h \
gltestsrc.h \
gstgltestsrc.h \
gstglmosaic.h \ gstglmosaic.h \
effects/gstgleffectscurves.h \ effects/gstgleffectscurves.h \
effects/gstgleffectlumatocurve.h effects/gstgleffectlumatocurve.h

View file

@ -1,5 +1,6 @@
/* GStreamer /* GStreamer
* Copyright (C) <1999> Erik Walthinsen <omega@cse.ogi.edu> * Copyright (C) <1999> Erik Walthinsen <omega@cse.ogi.edu>
* Copyright (C) <2016> Matthew Waters <matthew@centricular.com>
* *
* This library is free software; you can redistribute it and/or * This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Library General Public * modify it under the terms of the GNU Library General Public
@ -23,14 +24,16 @@
#include "gltestsrc.h" #include "gltestsrc.h"
#define MAX_ATTRIBUTES 4
struct vts_color_struct struct vts_color_struct
{ {
gfloat R, G, B; gfloat R, G, B;
}; };
struct XYZW struct XYZWRGB
{ {
gfloat X, Y, Z, W; gfloat X, Y, Z, W, R, G, B;
}; };
enum enum
@ -87,21 +90,115 @@ static const GLfloat positions[] = {
static const GLushort indices_quad[] = { 0, 1, 2, 0, 2, 3 }; static const GLushort indices_quad[] = { 0, 1, 2, 0, 2, 3 };
/* *INDENT-ON* */ /* *INDENT-ON* */
struct attribute
{
const gchar *name;
gint location;
guint n_elements;
GLenum element_type;
guint offset; /* in bytes */
guint stride; /* in bytes */
};
struct SrcShader struct SrcShader
{ {
struct BaseSrcImpl base; struct BaseSrcImpl base;
GstGLShader *shader; GstGLShader *shader;
gint attr_position; guint vao;
gint attr_texcoord; guint vbo;
/* x, y, z, w */ guint vbo_indices;
const gfloat *vertices;
guint n_vertices; guint n_attributes;
struct attribute attributes[MAX_ATTRIBUTES];
gconstpointer vertices;
gsize vertices_size;
const gushort *indices; const gushort *indices;
guint index_offset;
guint n_indices; guint n_indices;
}; };
static void
_bind_buffer (struct SrcShader *src)
{
GstGLContext *context = src->base.context;
const GstGLFuncs *gl = context->gl_vtable;
gint i;
gl->BindBuffer (GL_ELEMENT_ARRAY_BUFFER, src->vbo_indices);
gl->BindBuffer (GL_ARRAY_BUFFER, src->vbo);
/* Load the vertex position */
for (i = 0; i < src->n_attributes; i++) {
struct attribute *attr = &src->attributes[i];
if (attr->location == -1)
attr->location =
gst_gl_shader_get_attribute_location (src->shader, attr->name);
gl->VertexAttribPointer (attr->location, attr->n_elements,
attr->element_type, GL_FALSE, attr->stride,
(void *) (gintptr) attr->offset);
gl->EnableVertexAttribArray (attr->location);
}
}
static void
_unbind_buffer (struct SrcShader *src)
{
GstGLContext *context = src->base.context;
const GstGLFuncs *gl = context->gl_vtable;
gint i;
gl->BindBuffer (GL_ELEMENT_ARRAY_BUFFER, 0);
gl->BindBuffer (GL_ARRAY_BUFFER, 0);
for (i = 0; i < src->n_attributes; i++) {
struct attribute *attr = &src->attributes[i];
gl->DisableVertexAttribArray (attr->location);
}
}
static gboolean
_src_shader_init (gpointer impl, GstGLContext * context, GstVideoInfo * v_info)
{
struct SrcShader *src = impl;
const GstGLFuncs *gl = context->gl_vtable;
src->base.context = context;
if (!src->vbo) {
if (gl->GenVertexArrays) {
gl->GenVertexArrays (1, &src->vao);
gl->BindVertexArray (src->vao);
}
gl->GenBuffers (1, &src->vbo);
gl->BindBuffer (GL_ARRAY_BUFFER, src->vbo);
gl->BufferData (GL_ARRAY_BUFFER, src->vertices_size,
src->vertices, GL_STATIC_DRAW);
gl->GenBuffers (1, &src->vbo_indices);
gl->BindBuffer (GL_ELEMENT_ARRAY_BUFFER, src->vbo_indices);
gl->BufferData (GL_ELEMENT_ARRAY_BUFFER, src->n_indices * sizeof (gushort),
src->indices, GL_STATIC_DRAW);
if (gl->GenVertexArrays) {
_bind_buffer (src);
gl->BindVertexArray (0);
}
gl->BindBuffer (GL_ARRAY_BUFFER, 0);
gl->BindBuffer (GL_ELEMENT_ARRAY_BUFFER, 0);
}
return TRUE;
}
static gboolean static gboolean
_src_shader_fill_bound_fbo (gpointer impl) _src_shader_fill_bound_fbo (gpointer impl)
{ {
@ -114,21 +211,47 @@ _src_shader_fill_bound_fbo (gpointer impl)
gst_gl_shader_use (src->shader); gst_gl_shader_use (src->shader);
if (src->attr_position != -1) { if (gl->GenVertexArrays)
gl->VertexAttribPointer (src->attr_position, 4, GL_FLOAT, GL_FALSE, 0, gl->BindVertexArray (src->vao);
src->vertices); else
gl->EnableVertexAttribArray (src->attr_position); _bind_buffer (src);
}
gl->DrawElements (GL_TRIANGLES, src->n_indices, GL_UNSIGNED_SHORT, gl->DrawElements (GL_TRIANGLES, src->n_indices, GL_UNSIGNED_SHORT,
src->indices); (gpointer) (gintptr) src->index_offset);
if (gl->GenVertexArrays)
gl->BindVertexArray (0);
else
_unbind_buffer (src);
if (src->attr_position != -1)
gl->DisableVertexAttribArray (src->attr_position);
gst_gl_context_clear_shader (src->base.context); gst_gl_context_clear_shader (src->base.context);
return TRUE; return TRUE;
} }
static void
_src_shader_deinit (gpointer impl)
{
struct SrcShader *src = impl;
const GstGLFuncs *gl = src->base.context->gl_vtable;
if (src->shader)
gst_object_unref (src->shader);
src->shader = NULL;
if (src->vao)
gl->DeleteVertexArrays (1, &src->vao);
src->vao = 0;
if (src->vbo)
gl->DeleteBuffers (1, &src->vbo);
src->vbo = 0;
if (src->vbo_indices)
gl->DeleteBuffers (1, &src->vbo_indices);
src->vbo_indices = 0;
}
/* *INDENT-OFF* */ /* *INDENT-OFF* */
static const gchar *smpte_vertex_src = static const gchar *smpte_vertex_src =
"attribute vec4 position;\n" "attribute vec4 position;\n"
@ -182,11 +305,7 @@ struct SrcSMPTE
GstGLShader *snow_shader; GstGLShader *snow_shader;
GstGLShader *color_shader; GstGLShader *color_shader;
gint a_color_loc; gint attr_snow_position;
gfloat *vertices;
gushort *indices;
struct vts_color_struct *colors;
}; };
static gpointer static gpointer
@ -203,68 +322,66 @@ static gboolean
_src_smpte_init (gpointer impl, GstGLContext * context, GstVideoInfo * v_info) _src_smpte_init (gpointer impl, GstGLContext * context, GstVideoInfo * v_info)
{ {
struct SrcSMPTE *src = impl; struct SrcSMPTE *src = impl;
struct XYZW *plane_positions; struct XYZWRGB *coord;
gushort *plane_indices; gushort *plane_indices;
struct vts_color_struct *colors;
GError *error = NULL; GError *error = NULL;
int color_idx = 0; int color_idx = 0;
int i; int i;
src->base.base.context = context; src->base.base.context = context;
colors = g_new0 (struct vts_color_struct, N_QUADS * 4); coord = g_new0 (struct XYZWRGB, N_QUADS * 4);
plane_positions = g_new0 (struct XYZW, N_QUADS * 4);
plane_indices = g_new0 (gushort, N_QUADS * 6); plane_indices = g_new0 (gushort, N_QUADS * 6);
/* top row */ /* top row */
for (int i = 0; i < 7; i++) { for (int i = 0; i < 7; i++) {
plane_positions[color_idx * 4 + 0].X = -1.0f + i * (2.0f / 7.0f); coord[color_idx * 4 + 0].X = -1.0f + i * (2.0f / 7.0f);
plane_positions[color_idx * 4 + 0].Y = 1.0f / 3.0f; coord[color_idx * 4 + 0].Y = 1.0f / 3.0f;
plane_positions[color_idx * 4 + 1].X = -1.0f + (i + 1) * (2.0f / 7.0f); coord[color_idx * 4 + 1].X = -1.0f + (i + 1) * (2.0f / 7.0f);
plane_positions[color_idx * 4 + 1].Y = 1.0f / 3.0f; coord[color_idx * 4 + 1].Y = 1.0f / 3.0f;
plane_positions[color_idx * 4 + 2].X = -1.0f + (i + 1) * (2.0f / 7.0f), coord[color_idx * 4 + 2].X = -1.0f + (i + 1) * (2.0f / 7.0f);
plane_positions[color_idx * 4 + 2].Y = -1.0f; coord[color_idx * 4 + 2].Y = -1.0f;
plane_positions[color_idx * 4 + 3].X = -1.0f + i * (2.0f / 7.0f); coord[color_idx * 4 + 3].X = -1.0f + i * (2.0f / 7.0f);
plane_positions[color_idx * 4 + 3].Y = -1.0f; coord[color_idx * 4 + 3].Y = -1.0f;
color_idx++; color_idx++;
} }
/* middle row */ /* middle row */
for (int i = 0; i < 7; i++) { for (int i = 0; i < 7; i++) {
plane_positions[color_idx * 4 + 0].X = -1.0f + i * (2.0f / 7.0f); coord[color_idx * 4 + 0].X = -1.0f + i * (2.0f / 7.0f);
plane_positions[color_idx * 4 + 0].Y = 0.5f; coord[color_idx * 4 + 0].Y = 0.5f;
plane_positions[color_idx * 4 + 1].X = -1.0f + (i + 1) * (2.0f / 7.0f); coord[color_idx * 4 + 1].X = -1.0f + (i + 1) * (2.0f / 7.0f);
plane_positions[color_idx * 4 + 1].Y = 0.5f; coord[color_idx * 4 + 1].Y = 0.5f;
plane_positions[color_idx * 4 + 2].X = -1.0f + (i + 1) * (2.0f / 7.0f); coord[color_idx * 4 + 2].X = -1.0f + (i + 1) * (2.0f / 7.0f);
plane_positions[color_idx * 4 + 2].Y = 1.0f / 3.0f; coord[color_idx * 4 + 2].Y = 1.0f / 3.0f;
plane_positions[color_idx * 4 + 3].X = -1.0f + i * (2.0f / 7.0f); coord[color_idx * 4 + 3].X = -1.0f + i * (2.0f / 7.0f);
plane_positions[color_idx * 4 + 3].Y = 1.0f / 3.0f; coord[color_idx * 4 + 3].Y = 1.0f / 3.0f;
color_idx++; color_idx++;
} }
/* bottom row, left three */ /* bottom row, left three */
for (int i = 0; i < 3; i++) { for (int i = 0; i < 3; i++) {
plane_positions[color_idx * 4 + 0].X = -1.0f + i / 3.0f; coord[color_idx * 4 + 0].X = -1.0f + i / 3.0f;
plane_positions[color_idx * 4 + 0].Y = 1.0f; coord[color_idx * 4 + 0].Y = 1.0f;
plane_positions[color_idx * 4 + 1].X = -1.0f + (i + 1) / 3.0f; coord[color_idx * 4 + 1].X = -1.0f + (i + 1) / 3.0f;
plane_positions[color_idx * 4 + 1].Y = 1.0f; coord[color_idx * 4 + 1].Y = 1.0f;
plane_positions[color_idx * 4 + 2].X = -1.0f + (i + 1) / 3.0f; coord[color_idx * 4 + 2].X = -1.0f + (i + 1) / 3.0f;
plane_positions[color_idx * 4 + 2].Y = 0.5f; coord[color_idx * 4 + 2].Y = 0.5f;
plane_positions[color_idx * 4 + 3].X = -1.0f + i / 3.0f; coord[color_idx * 4 + 3].X = -1.0f + i / 3.0f;
plane_positions[color_idx * 4 + 3].Y = 0.5f; coord[color_idx * 4 + 3].Y = 0.5f;
color_idx++; color_idx++;
} }
/* bottom row, middle three (the blacks) */ /* bottom row, middle three (the blacks) */
for (int i = 0; i < 3; i++) { for (int i = 0; i < 3; i++) {
plane_positions[color_idx * 4 + 0].X = i / 6.0f; coord[color_idx * 4 + 0].X = i / 6.0f;
plane_positions[color_idx * 4 + 0].Y = 1.0f; coord[color_idx * 4 + 0].Y = 1.0f;
plane_positions[color_idx * 4 + 1].X = (i + 1) / 6.0f; coord[color_idx * 4 + 1].X = (i + 1) / 6.0f;
plane_positions[color_idx * 4 + 1].Y = 1.0f; coord[color_idx * 4 + 1].Y = 1.0f;
plane_positions[color_idx * 4 + 2].X = (i + 1) / 6.0f; coord[color_idx * 4 + 2].X = (i + 1) / 6.0f;
plane_positions[color_idx * 4 + 2].Y = 0.5f; coord[color_idx * 4 + 2].Y = 0.5f;
plane_positions[color_idx * 4 + 3].X = i / 6.0f; coord[color_idx * 4 + 3].X = i / 6.0f;
plane_positions[color_idx * 4 + 3].Y = 0.5f; coord[color_idx * 4 + 3].Y = 0.5f;
color_idx++; color_idx++;
} }
@ -295,9 +412,11 @@ _src_smpte_init (gpointer impl, GstGLContext * context, GstVideoInfo * v_info)
} }
for (j = 0; j < 4; j++) { for (j = 0; j < 4; j++) {
plane_positions[i * 4 + j].Z = 0.0f; coord[i * 4 + j].Z = 0.0f;
plane_positions[i * 4 + j].W = 1.0f; coord[i * 4 + j].W = 1.0f;
colors[i * 4 + j] = vts_colors[k]; coord[i * 4 + j].R = vts_colors[k].R;
coord[i * 4 + j].G = vts_colors[k].G;
coord[i * 4 + j].B = vts_colors[k].B;
} }
for (j = 0; j < 6; j++) for (j = 0; j < 6; j++)
@ -305,22 +424,24 @@ _src_smpte_init (gpointer impl, GstGLContext * context, GstVideoInfo * v_info)
} }
/* snow */ /* snow */
plane_positions[color_idx * 4 + 0].X = 0.5f; coord[color_idx * 4 + 0].X = 0.5f;
plane_positions[color_idx * 4 + 0].Y = 1.0f; coord[color_idx * 4 + 0].Y = 1.0f;
plane_positions[color_idx * 4 + 0].Z = 0.0f; coord[color_idx * 4 + 0].Z = 0.0f;
plane_positions[color_idx * 4 + 0].W = 1.0f; coord[color_idx * 4 + 0].W = 1.0f;
plane_positions[color_idx * 4 + 1].X = 1.0f; coord[color_idx * 4 + 1].X = 1.0f;
plane_positions[color_idx * 4 + 1].Y = 1.0f; coord[color_idx * 4 + 1].Y = 1.0f;
plane_positions[color_idx * 4 + 1].Z = 0.0f; coord[color_idx * 4 + 1].Z = 0.0f;
plane_positions[color_idx * 4 + 1].W = 1.0f; coord[color_idx * 4 + 1].W = 1.0f;
plane_positions[color_idx * 4 + 2].X = 1.0f; coord[color_idx * 4 + 2].X = 1.0f;
plane_positions[color_idx * 4 + 2].Y = 0.5f; coord[color_idx * 4 + 2].Y = 0.5f;
plane_positions[color_idx * 4 + 2].Z = 0.0f; coord[color_idx * 4 + 2].Z = 0.0f;
plane_positions[color_idx * 4 + 2].W = 1.0f; coord[color_idx * 4 + 2].W = 1.0f;
plane_positions[color_idx * 4 + 3].X = 0.5f; coord[color_idx * 4 + 3].X = 0.5f;
plane_positions[color_idx * 4 + 3].Y = 0.5f; coord[color_idx * 4 + 3].Y = 0.5f;
plane_positions[color_idx * 4 + 3].Z = 0.0f; coord[color_idx * 4 + 3].Z = 0.0f;
plane_positions[color_idx * 4 + 3].W = 1.0f; coord[color_idx * 4 + 3].W = 1.0f;
for (i = 0; i < 6; i++)
plane_indices[color_idx * 6 + i] = color_idx * 4 + indices_quad[i];
color_idx++; color_idx++;
if (src->color_shader) if (src->color_shader)
@ -355,60 +476,59 @@ _src_smpte_init (gpointer impl, GstGLContext * context, GstVideoInfo * v_info)
return FALSE; return FALSE;
} }
gst_gl_shader_use (src->color_shader); src->attr_snow_position = -1;
src->base.attr_position =
gst_gl_shader_get_attribute_location (src->color_shader, "position");
if (src->base.attr_position == -1) {
GST_ERROR_OBJECT (src->base.base.src, "No position attribute");
return FALSE;
}
src->a_color_loc = src->base.n_attributes = 2;
gst_gl_shader_get_attribute_location (src->color_shader, "a_color");
/* if (src->a_color_loc == -1) {
GST_ERROR_OBJECT (src->base.base.src, "No color attribute");
return FALSE;
}*/
gst_gl_context_clear_shader (src->base.base.context);
src->vertices = (gfloat *) plane_positions; src->base.attributes[0].name = "position";
src->indices = plane_indices; src->base.attributes[0].location = -1;
src->colors = colors; src->base.attributes[0].n_elements = 4;
src->base.attributes[0].element_type = GL_FLOAT;
src->base.attributes[0].offset = 0;
src->base.attributes[0].stride = sizeof (struct XYZWRGB);
return TRUE; src->base.attributes[1].name = "a_color";
src->base.attributes[1].location = -1;
src->base.attributes[1].n_elements = 3;
src->base.attributes[1].element_type = GL_FLOAT;
src->base.attributes[1].offset = 4 * sizeof (gfloat);
src->base.attributes[1].stride = sizeof (struct XYZWRGB);
src->base.shader = src->color_shader;
src->base.vertices = (gfloat *) coord;
src->base.vertices_size = sizeof (struct XYZWRGB) * N_QUADS * 4;
src->base.indices = plane_indices;
src->base.n_indices = N_QUADS * 6;
return _src_shader_init (impl, context, v_info);
} }
static gboolean static gboolean
_src_smpte_fill_bound_fbo (gpointer impl) _src_smpte_fill_bound_fbo (gpointer impl)
{ {
struct SrcSMPTE *src = impl; struct SrcSMPTE *src = impl;
const GstGLFuncs *gl = src->base.base.context->gl_vtable; gint attr_color_position = -1;
if (src->a_color_loc != -1) { src->base.n_attributes = 2;
gl->VertexAttribPointer (src->a_color_loc, 3, GL_FLOAT, GL_FALSE, 0,
src->colors);
gl->EnableVertexAttribArray (src->a_color_loc);
}
src->base.shader = src->color_shader; src->base.shader = src->color_shader;
src->base.vertices = src->vertices;
src->base.n_vertices = (N_QUADS - 1) * 4 * 4;
src->base.indices = src->indices;
src->base.n_indices = (N_QUADS - 1) * 6; src->base.n_indices = (N_QUADS - 1) * 6;
src->base.index_offset = 0;
if (!_src_shader_fill_bound_fbo (impl)) if (!_src_shader_fill_bound_fbo (impl))
return FALSE; return FALSE;
if (src->a_color_loc != -1) attr_color_position = src->base.attributes[0].location;
gl->DisableVertexAttribArray (src->a_color_loc);
src->base.attributes[0].location = src->attr_snow_position;
src->base.n_attributes = 1;
src->base.shader = src->snow_shader; src->base.shader = src->snow_shader;
src->base.vertices = &src->vertices[src->base.n_vertices];
src->base.n_vertices = 4;
src->base.indices = src->indices;
src->base.n_indices = 6; src->base.n_indices = 6;
src->base.index_offset = (N_QUADS - 1) * 6 * sizeof (gushort);
gst_gl_shader_use (src->snow_shader); gst_gl_shader_use (src->snow_shader);
gst_gl_shader_set_uniform_1f (src->snow_shader, "time", gst_gl_shader_set_uniform_1f (src->snow_shader, "time",
(gfloat) src->base.base.src->running_time / GST_SECOND); (gfloat) src->base.base.src->running_time / GST_SECOND);
if (!_src_shader_fill_bound_fbo (impl)) if (!_src_shader_fill_bound_fbo (impl))
return FALSE; return FALSE;
src->attr_snow_position = src->base.attributes[0].location;
src->base.attributes[0].location = attr_color_position;
return TRUE; return TRUE;
} }
@ -421,13 +541,10 @@ _src_smpte_free (gpointer impl)
if (!impl) if (!impl)
return; return;
if (src->base.shader) _src_shader_deinit (impl);
gst_object_unref (src->base.shader);
src->base.shader = NULL;
g_free (src->vertices); g_free ((gpointer) src->base.vertices);
g_free (src->indices); g_free ((gpointer) src->base.indices);
g_free (src->colors);
g_free (impl); g_free (impl);
} }
@ -545,9 +662,13 @@ static const struct SrcFuncs src_blink = {
/* *INDENT-OFF* */ /* *INDENT-OFF* */
static const gchar *checkers_vertex_src = "attribute vec4 position;\n" static const gchar *checkers_vertex_src = "attribute vec4 position;\n"
"varying vec2 uv;\n"
"void main()\n" "void main()\n"
"{\n" "{\n"
" gl_Position = position;\n" " gl_Position = position;\n"
/* RPi gives incorrect results for positive uv (plus it makes us start on
* the right pixel color i.e. red) */
" uv = position.xy - 1.0;\n"
"}"; "}";
static const gchar *checkers_fragment_src = static const gchar *checkers_fragment_src =
@ -555,14 +676,16 @@ static const gchar *checkers_fragment_src =
"precision mediump float;\n" "precision mediump float;\n"
"#endif\n" "#endif\n"
"uniform float checker_width;\n" "uniform float checker_width;\n"
"uniform float width;\n"
"uniform float height;\n"
"varying vec2 uv;\n"
"void main()\n" "void main()\n"
"{\n" "{\n"
" vec2 xy_index= floor((gl_FragCoord.xy-vec2(0.5,0.5))/checker_width);\n" " vec2 xy_mod = floor (0.5 * uv * vec2(width, height) / (checker_width));\n"
" vec2 xy_mod=mod(xy_index,vec2(2.0,2.0));\n" " float result = mod (xy_mod.x + xy_mod.y, 2.0);\n"
" float result=mod(xy_mod.x+xy_mod.y,2.0);\n" " gl_FragColor.r = step (result, 0.5);\n"
" gl_FragColor.r=step(result,0.5);\n" " gl_FragColor.g = 1.0 - gl_FragColor.r;\n"
" gl_FragColor.g=1.0-gl_FragColor.r;\n" " gl_FragColor.ba = vec2(0.0, 1.0);\n"
" gl_FragColor.ba=vec2(0,1);\n"
"}"; "}";
/* *INDENT-ON* */ /* *INDENT-ON* */
@ -598,23 +721,30 @@ _src_checkers_init (gpointer impl, GstGLContext * context,
return FALSE; return FALSE;
} }
src->base.attr_position = src->base.n_attributes = 1;
gst_gl_shader_get_attribute_location (src->base.shader, "position");
if (src->base.attr_position == -1) { src->base.attributes[0].name = "position";
GST_ERROR_OBJECT (src->base.base.src, "No position attribute"); src->base.attributes[0].location = -1;
return FALSE; src->base.attributes[0].n_elements = 4;
} src->base.attributes[0].element_type = GL_FLOAT;
src->base.attributes[0].offset = 0;
src->base.attributes[0].stride = 4 * sizeof (gfloat);
src->base.vertices = positions; src->base.vertices = positions;
src->base.n_vertices = 4; src->base.vertices_size = sizeof (positions);
src->base.indices = indices_quad; src->base.indices = indices_quad;
src->base.n_indices = 6; src->base.n_indices = 6;
gst_gl_shader_use (src->base.shader); gst_gl_shader_use (src->base.shader);
gst_gl_shader_set_uniform_1f (src->base.shader, "checker_width", gst_gl_shader_set_uniform_1f (src->base.shader, "checker_width",
src->checker_width); src->checker_width);
gst_gl_shader_set_uniform_1f (src->base.shader, "width",
(gfloat) GST_VIDEO_INFO_WIDTH (v_info));
gst_gl_shader_set_uniform_1f (src->base.shader, "height",
(gfloat) GST_VIDEO_INFO_HEIGHT (v_info));
gst_gl_context_clear_shader (src->base.base.context); gst_gl_context_clear_shader (src->base.base.context);
return TRUE; return _src_shader_init (impl, context, v_info);
} }
static void static void
@ -625,9 +755,7 @@ _src_checkers_free (gpointer impl)
if (!src) if (!src)
return; return;
if (src->base.shader) _src_shader_deinit (impl);
gst_object_unref (src->base.shader);
src->base.shader = NULL;
g_free (impl); g_free (impl);
} }
@ -687,18 +815,21 @@ _src_snow_init (gpointer impl, GstGLContext * context, GstVideoInfo * v_info)
return FALSE; return FALSE;
} }
src->attr_position = src->n_attributes = 1;
gst_gl_shader_get_attribute_location (src->shader, "position");
if (src->attr_position == -1) { src->attributes[0].name = "position";
GST_ERROR_OBJECT (src->base.src, "No position attribute"); src->attributes[0].location = -1;
return FALSE; src->attributes[0].n_elements = 4;
} src->attributes[0].element_type = GL_FLOAT;
src->attributes[0].offset = 0;
src->attributes[0].stride = 4 * sizeof (gfloat);
src->vertices = positions; src->vertices = positions;
src->n_vertices = 4; src->vertices_size = sizeof (positions);
src->indices = indices_quad; src->indices = indices_quad;
src->n_indices = 6; src->n_indices = 6;
return TRUE; return _src_shader_init (impl, context, v_info);
} }
static gboolean static gboolean
@ -724,9 +855,7 @@ _src_snow_free (gpointer impl)
if (!src) if (!src)
return; return;
if (src->shader) _src_shader_deinit (impl);
gst_object_unref (src->shader);
src->shader = NULL;
g_free (impl); g_free (impl);
} }
@ -783,7 +912,7 @@ static const gchar *mandelbrot_fragment_src =
"}\n" "}\n"
"vec4 iterate_pixel(vec2 position) {\n" "vec4 iterate_pixel(vec2 position) {\n"
" vec2 c = vec2(0);\n" " vec2 c = vec2(0);\n"
" for (int i=0; i < 100; i++) {\n" " for (int i=0; i < 20; i++) {\n"
" if (c.x*c.x + c.y*c.y > 2.0*2.0)\n" " if (c.x*c.x + c.y*c.y > 2.0*2.0)\n"
" return i_to_rgb(i);\n" " return i_to_rgb(i);\n"
" c = mandelbrot(c, position);\n" " c = mandelbrot(c, position);\n"
@ -820,14 +949,17 @@ _src_mandelbrot_init (gpointer impl, GstGLContext * context,
return FALSE; return FALSE;
} }
src->attr_position = src->n_attributes = 1;
gst_gl_shader_get_attribute_location (src->shader, "position");
if (src->attr_position == -1) { src->attributes[0].name = "position";
GST_ERROR_OBJECT (src->base.src, "No position attribute"); src->attributes[0].location = -1;
return FALSE; src->attributes[0].n_elements = 4;
} src->attributes[0].element_type = GL_FLOAT;
src->attributes[0].offset = 0;
src->attributes[0].stride = 4 * sizeof (gfloat);
src->vertices = positions; src->vertices = positions;
src->n_vertices = 4; src->vertices_size = sizeof (positions);
src->indices = indices_quad; src->indices = indices_quad;
src->n_indices = 6; src->n_indices = 6;
@ -837,7 +969,7 @@ _src_mandelbrot_init (gpointer impl, GstGLContext * context,
(gfloat) GST_VIDEO_INFO_HEIGHT (v_info)); (gfloat) GST_VIDEO_INFO_HEIGHT (v_info));
gst_gl_context_clear_shader (src->base.context); gst_gl_context_clear_shader (src->base.context);
return TRUE; return _src_shader_init (impl, context, v_info);
} }
static gboolean static gboolean
@ -863,9 +995,7 @@ _src_mandelbrot_free (gpointer impl)
if (!src) if (!src)
return; return;
if (src->shader) _src_shader_deinit (impl);
gst_object_unref (src->shader);
src->shader = NULL;
g_free (impl); g_free (impl);
} }
@ -942,14 +1072,17 @@ _src_circular_init (gpointer impl, GstGLContext * context,
return FALSE; return FALSE;
} }
src->attr_position = src->n_attributes = 1;
gst_gl_shader_get_attribute_location (src->shader, "position");
if (src->attr_position == -1) { src->attributes[0].name = "position";
GST_ERROR_OBJECT (src->base.src, "No position attribute"); src->attributes[0].location = -1;
return FALSE; src->attributes[0].n_elements = 4;
} src->attributes[0].element_type = GL_FLOAT;
src->attributes[0].offset = 0;
src->attributes[0].stride = 4 * sizeof (gfloat);
src->vertices = positions; src->vertices = positions;
src->n_vertices = 4; src->vertices_size = sizeof (positions);
src->indices = indices_quad; src->indices = indices_quad;
src->n_indices = 6; src->n_indices = 6;
@ -959,7 +1092,7 @@ _src_circular_init (gpointer impl, GstGLContext * context,
(gfloat) GST_VIDEO_INFO_HEIGHT (v_info)); (gfloat) GST_VIDEO_INFO_HEIGHT (v_info));
gst_gl_context_clear_shader (src->base.context); gst_gl_context_clear_shader (src->base.context);
return TRUE; return _src_shader_init (impl, context, v_info);
} }
static void static void
@ -970,9 +1103,7 @@ _src_circular_free (gpointer impl)
if (!src) if (!src)
return; return;
if (src->shader) _src_shader_deinit (impl);
gst_object_unref (src->shader);
src->shader = NULL;
g_free (impl); g_free (impl);
} }

View file

@ -49,7 +49,7 @@
#include <gst/gst-i18n-plugin.h> #include <gst/gst-i18n-plugin.h>
#define USE_PEER_BUFFERALLOC #define USE_PEER_BUFFERALLOC
#define SUPPORTED_GL_APIS GST_GL_API_OPENGL #define SUPPORTED_GL_APIS (GST_GL_API_OPENGL | GST_GL_API_OPENGL3 | GST_GL_API_GLES2)
GST_DEBUG_CATEGORY_STATIC (gl_test_src_debug); GST_DEBUG_CATEGORY_STATIC (gl_test_src_debug);
#define GST_CAT_DEFAULT gl_test_src_debug #define GST_CAT_DEFAULT gl_test_src_debug

View file

@ -62,6 +62,7 @@
#include "gstglstereosplit.h" #include "gstglstereosplit.h"
#include "gstglstereomix.h" #include "gstglstereomix.h"
#include "gstglviewconvert.h" #include "gstglviewconvert.h"
#include "gstgltestsrc.h"
#if HAVE_GRAPHENE #if HAVE_GRAPHENE
#include "gstgltransformation.h" #include "gstgltransformation.h"
@ -74,7 +75,6 @@
#endif /* HAVE_JPEG */ #endif /* HAVE_JPEG */
#if GST_GL_HAVE_OPENGL #if GST_GL_HAVE_OPENGL
#include "gstgltestsrc.h"
#include "gstglfilterglass.h" #include "gstglfilterglass.h"
/* #include "gstglfilterreflectedscreen.h" */ /* #include "gstglfilterreflectedscreen.h" */
#include "gstgldeinterlace.h" #include "gstgldeinterlace.h"
@ -226,6 +226,11 @@ plugin_init (GstPlugin * plugin)
GST_RANK_NONE, GST_TYPE_GL_STEREO_MIX)) { GST_RANK_NONE, GST_TYPE_GL_STEREO_MIX)) {
return FALSE; return FALSE;
} }
if (!gst_element_register (plugin, "gltestsrc",
GST_RANK_NONE, GST_TYPE_GL_TEST_SRC)) {
return FALSE;
}
#if HAVE_JPEG #if HAVE_JPEG
#if HAVE_PNG #if HAVE_PNG
if (!gst_element_register (plugin, "gloverlay", if (!gst_element_register (plugin, "gloverlay",
@ -235,11 +240,6 @@ plugin_init (GstPlugin * plugin)
#endif /* HAVE_PNG */ #endif /* HAVE_PNG */
#endif /* HAVE_JPEG */ #endif /* HAVE_JPEG */
#if GST_GL_HAVE_OPENGL #if GST_GL_HAVE_OPENGL
if (!gst_element_register (plugin, "gltestsrc",
GST_RANK_NONE, GST_TYPE_GL_TEST_SRC)) {
return FALSE;
}
if (!gst_element_register (plugin, "glfilterglass", if (!gst_element_register (plugin, "glfilterglass",
GST_RANK_NONE, GST_TYPE_GL_FILTER_GLASS)) { GST_RANK_NONE, GST_TYPE_GL_FILTER_GLASS)) {
return FALSE; return FALSE;