}
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
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)
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)
{
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;
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)
{
else
gst_query_add_allocation_pool (query, pool, size, min, max);
+ gst_gl_test_src_init_shader (src);
+
gst_object_unref (pool);
return TRUE;