gltestsrc: implement snow pattern with GLSL.

https://bugzilla.gnome.org/show_bug.cgi?id=735131
This commit is contained in:
Lubosz Sarnecki 2014-08-21 02:13:58 +02:00 committed by Matthew Waters
parent 82a3a34475
commit 3736f944b5
4 changed files with 114 additions and 20 deletions

View file

@ -189,29 +189,78 @@ gst_gl_test_src_smpte (GstGLTestSrc * v, GstBuffer * buffer, int w, int h)
}
void
gst_gl_test_src_snow (GstGLTestSrc * v, GstBuffer * buffer, int w, int h)
gst_gl_test_src_shader (GstGLTestSrc * v, GstBuffer * buffer, int w, int h)
{
#if GST_GL_HAVE_OPENGL
if (gst_gl_context_get_gl_api (v->context) & GST_GL_API_OPENGL) {
glClearColor (0.0, 0.0, 0.0, 1.0);
glClear (GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glMatrixMode (GL_PROJECTION);
glLoadIdentity ();
GstGLFuncs *gl = v->context->gl_vtable;
glMatrixMode (GL_MODELVIEW);
glLoadIdentity ();
/* *INDENT-OFF* */
/* FIXME snow requires a fragment shader. Please write. */
glColor4f (0.5, 0.5, 0.5, 1.0);
glBegin (GL_QUADS);
glVertex3f (-1.0 + 2.0 * (0.0), -1.0 + 2.0 * 1, 0);
glVertex3f (-1.0 + 2.0 * (1.0), -1.0 + 2.0 * 1, 0);
glVertex3f (-1.0 + 2.0 * (1.0), -1.0 + 2.0 * (0.0), 0);
glVertex3f (-1.0 + 2.0 * (0.0), -1.0 + 2.0 * (0.0), 0);
glEnd ();
const GLfloat positions[] = {
-1.0, 1.0, 0.0, 1.0,
1.0, 1.0, 0.0, 1.0,
1.0, -1.0, 0.0, 1.0,
-1.0, -1.0, 0.0, 1.0,
};
const GLfloat identitiy_matrix[] = {
1.0, 0.0, 0.0, 0.0,
0.0, 1.0, 0.0, 0.0,
0.0, 0.0, 1.0, 0.0,
0.0, 0.0, 0.0, 1.0,
};
const GLfloat uvs[] = {
0.0, 1.0,
1.0, 1.0,
1.0, 0.0,
0.0, 0.0,
};
/* *INDENT-ON* */
GLushort indices[] = { 0, 1, 2, 3, 0 };
GLint attr_position_loc = 0;
GLint attr_uv_loc = 0;
if (gst_gl_context_get_gl_api (v->context)) {
gst_gl_context_clear_shader (v->context);
gl->BindTexture (GL_TEXTURE_2D, 0);
gl->Disable (GL_TEXTURE_2D);
gst_gl_shader_use (v->shader);
attr_position_loc =
gst_gl_shader_get_attribute_location (v->shader, "position");
attr_uv_loc = gst_gl_shader_get_attribute_location (v->shader, "uv");
/* Load the vertex position */
gl->VertexAttribPointer (attr_position_loc, 4, GL_FLOAT,
GL_FALSE, 0, positions);
/* Load the texture coordinate */
gl->VertexAttribPointer (attr_uv_loc, 2, GL_FLOAT, GL_FALSE, 0, uvs);
gl->EnableVertexAttribArray (attr_position_loc);
gl->EnableVertexAttribArray (attr_uv_loc);
gst_gl_shader_set_uniform_matrix_4fv (v->shader, "mvp",
1, GL_FALSE, identitiy_matrix);
gst_gl_shader_set_uniform_1f (v->shader, "time",
(gfloat) v->running_time / GST_SECOND);
gst_gl_shader_set_uniform_1f (v->shader, "aspect_ratio",
(gfloat) w / (gfloat) h);
gl->DrawElements (GL_TRIANGLE_STRIP, 5, GL_UNSIGNED_SHORT, indices);
gl->DisableVertexAttribArray (attr_position_loc);
gl->DisableVertexAttribArray (attr_uv_loc);
gst_gl_context_clear_shader (v->context);
}
#endif
}
static void

View file

@ -32,7 +32,7 @@ struct vts_color_struct {
void gst_gl_test_src_smpte (GstGLTestSrc * v,
GstBuffer *buffer, int w, int h);
void gst_gl_test_src_snow (GstGLTestSrc * v,
void gst_gl_test_src_shader (GstGLTestSrc * v,
GstBuffer *buffer, int w, int h);
void gst_gl_test_src_black (GstGLTestSrc * v,
GstBuffer *buffer, int w, int h);

View file

@ -111,6 +111,8 @@ static gboolean gst_gl_test_src_decide_allocation (GstBaseSrc * basesrc,
static void gst_gl_test_src_callback (gpointer stuff);
static gboolean gst_gl_test_src_init_shader (GstGLTestSrc * gltestsrc);
#define GST_TYPE_GL_TEST_SRC_PATTERN (gst_gl_test_src_pattern_get_type ())
static GType
gst_gl_test_src_pattern_get_type (void)
@ -227,6 +229,27 @@ gst_gl_test_src_fixate (GstBaseSrc * bsrc, GstCaps * caps)
return caps;
}
const gchar *snow_vertex_src = "attribute vec4 position; \
attribute vec2 uv; \
uniform mat4 mvp; \
varying vec2 out_uv; \
void main() \
{ \
gl_Position = mvp * position; \
out_uv = uv; \
}";
const gchar *snow_fragment_src = "uniform float time; \
varying vec2 out_uv; \
\
float rand(vec2 co){ \
return fract(sin(dot(co.xy, vec2(12.9898,78.233))) * 43758.5453); \
} \
void main() \
{ \
gl_FragColor = rand(time * out_uv) * vec4(1); \
}";
static void
gst_gl_test_src_set_pattern (GstGLTestSrc * gltestsrc, gint pattern_type)
{
@ -239,7 +262,9 @@ gst_gl_test_src_set_pattern (GstGLTestSrc * gltestsrc, gint pattern_type)
gltestsrc->make_image = gst_gl_test_src_smpte;
break;
case GST_GL_TEST_SRC_SNOW:
gltestsrc->make_image = gst_gl_test_src_snow;
gltestsrc->vertex_src = snow_vertex_src;
gltestsrc->fragment_src = snow_fragment_src;
gltestsrc->make_image = gst_gl_test_src_shader;
break;
case GST_GL_TEST_SRC_BLACK:
gltestsrc->make_image = gst_gl_test_src_black;
@ -446,6 +471,19 @@ gst_gl_test_src_is_seekable (GstBaseSrc * psrc)
return TRUE;
}
static gboolean
gst_gl_test_src_init_shader (GstGLTestSrc * gltestsrc)
{
if (gst_gl_context_get_gl_api (gltestsrc->context)) {
/* blocking call, wait until the opengl thread has compiled the shader */
if (gltestsrc->vertex_src == NULL)
return FALSE;
return gst_gl_context_gen_shader (gltestsrc->context, gltestsrc->vertex_src,
gltestsrc->fragment_src, &gltestsrc->shader);
}
return TRUE;
}
static GstFlowReturn
gst_gl_test_src_fill (GstPushSrc * psrc, GstBuffer * buffer)
{
@ -691,6 +729,8 @@ gst_gl_test_src_decide_allocation (GstBaseSrc * basesrc, GstQuery * query)
else
gst_query_add_allocation_pool (query, pool, size, min, max);
gst_gl_test_src_init_shader (src);
gst_object_unref (pool);
return TRUE;

View file

@ -98,6 +98,8 @@ struct _GstGLTestSrc {
GLuint fbo;
GLuint depthbuffer;
GstGLShader *shader;
GstBuffer* buffer;
GstBufferPool *pool;
@ -111,6 +113,9 @@ struct _GstGLTestSrc {
gint64 n_frames; /* total frames sent */
gboolean negotiated;
const gchar *vertex_src;
const gchar *fragment_src;
void (*make_image) (GstGLTestSrc* v, GstBuffer* buffer, gint w, gint h);
};