mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2024-11-27 04:01:08 +00:00
gltestsrc: implement snow pattern with GLSL.
https://bugzilla.gnome.org/show_bug.cgi?id=735131
This commit is contained in:
parent
ccf8f014f0
commit
67732e4883
4 changed files with 114 additions and 20 deletions
|
@ -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
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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);
|
||||
};
|
||||
|
||||
|
|
Loading…
Reference in a new issue