diff --git a/gst-libs/gst/gl/gstgldisplay.c b/gst-libs/gst/gl/gstgldisplay.c index b332242086..57f224b1ad 100644 --- a/gst-libs/gst/gl/gstgldisplay.c +++ b/gst-libs/gst/gl/gstgldisplay.c @@ -48,7 +48,6 @@ static void gst_gl_display_thread_init_download (GstGLDisplay *display); static void gst_gl_display_thread_do_download (GstGLDisplay* display); static void gst_gl_display_thread_gen_fbo (GstGLDisplay *display); static void gst_gl_display_thread_use_fbo (GstGLDisplay *display); -static void gst_gl_display_thread_use_fbo_2 (GstGLDisplay *display); static void gst_gl_display_thread_del_fbo (GstGLDisplay *display); static void gst_gl_display_thread_gen_shader (GstGLDisplay *display); static void gst_gl_display_thread_del_shader (GstGLDisplay *display); @@ -79,17 +78,17 @@ static void gst_gl_display_thread_do_download_draw (GstGLDisplay* display); //------------------------------------------------------------ -//-------------------- Glut context management --------------- +//-------------------- GL context management ----------------- //------------------------------------------------------------ //(key=int glutWinId) and (value=GstGLDisplay *display) -static GHashTable *gst_gl_display_map = NULL; +static GHashTable* gst_gl_display_map = NULL; //all glut functions and opengl primitives are called in this thread -static GThread *gst_gl_display_glutThread = NULL; +static GThread* gst_gl_display_glutThread = NULL; //-timepoped by glutIdleFunc -static GAsyncQueue *gst_gl_display_messageQueue = NULL; +static GAsyncQueue* gst_gl_display_messageQueue = NULL; //------------------------------------------------------------ @@ -135,7 +134,6 @@ gst_gl_display_init (GstGLDisplay *display, GstGLDisplayClass *klass) display->cond_do_download = g_cond_new (); display->cond_gen_fbo = g_cond_new (); display->cond_use_fbo = g_cond_new (); - display->cond_use_fbo_2 = g_cond_new (); display->cond_del_fbo = g_cond_new (); display->cond_gen_shader = g_cond_new (); display->cond_del_shader = g_cond_new (); @@ -182,10 +180,12 @@ gst_gl_display_init (GstGLDisplay *display, GstGLDisplayClass *klass) display->use_fbo_width = 0; display->use_fbo_height = 0; display->use_fbo_scene_cb = NULL; - display->use_shader = 0; - display->use_fbo_scene_cb_2 = NULL; - display->p1 = NULL; - display->p2 = NULL; + display->use_fbo_proj_param1 = 0; + display->use_fbo_proj_param2 = 0; + display->use_fbo_proj_param3 = 0; + display->use_fbo_proj_param4 = 0; + display->use_fbo_projection = 0; + display->use_fbo_stuff = NULL; display->input_texture_width = 0; display->input_texture_height = 0; display->input_texture = 0; @@ -382,10 +382,6 @@ gst_gl_display_finalize (GObject *object) g_cond_free (display->cond_del_fbo); display->cond_del_fbo = NULL; } - if (display->cond_use_fbo_2) { - g_cond_free (display->cond_use_fbo_2); - display->cond_use_fbo_2 = NULL; - } if (display->cond_use_fbo) { g_cond_free (display->cond_use_fbo); display->cond_use_fbo = NULL; @@ -432,12 +428,8 @@ gst_gl_display_finalize (GObject *object) display->clientDrawCallback = NULL; if (display->use_fbo_scene_cb) display->use_fbo_scene_cb = NULL; - if (display->use_fbo_scene_cb_2) - display->use_fbo_scene_cb_2 = NULL; - if (display->p1) - display->p1 = NULL; - if (display->p2) - display->p2 = NULL; + if (display->use_fbo_stuff) + display->use_fbo_stuff = NULL; //at this step, the next condition imply that the last display has been pushed if (g_hash_table_size (gst_gl_display_map) == 0) @@ -556,9 +548,6 @@ gst_gl_display_thread_dispatch_action (GstGLDisplayMsg* msg) case GST_GL_DISPLAY_ACTION_USE_FBO: gst_gl_display_thread_use_fbo (msg->display); break; - case GST_GL_DISPLAY_ACTION_USE_FBO2: - gst_gl_display_thread_use_fbo_2 (msg->display); - break; case GST_GL_DISPLAY_ACTION_DEL_FBO: gst_gl_display_thread_del_fbo (msg->display); break; @@ -600,7 +589,6 @@ gst_gl_display_thread_check_msg_validity (GstGLDisplayMsg *msg) case GST_GL_DISPLAY_ACTION_DO_DOWNLOAD: case GST_GL_DISPLAY_ACTION_GEN_FBO: case GST_GL_DISPLAY_ACTION_USE_FBO: - case GST_GL_DISPLAY_ACTION_USE_FBO2: case GST_GL_DISPLAY_ACTION_DEL_FBO: case GST_GL_DISPLAY_ACTION_GEN_SHADER: case GST_GL_DISPLAY_ACTION_DEL_SHADER: @@ -625,6 +613,9 @@ gst_gl_display_thread_check_msg_validity (GstGLDisplayMsg *msg) //------------------ BEGIN GL THREAD ACTIONS ----------------- //------------------------------------------------------------ +//The following functions are thread safe because +//called by the "gst_gl_display_thread_dispatch_action" +//in a lock/unlock scope. /* Called in the gl thread */ static void @@ -1261,8 +1252,20 @@ gst_gl_display_thread_use_fbo (GstGLDisplay *display) glMatrixMode(GL_PROJECTION); glPushMatrix(); glLoadIdentity(); - gluPerspective(45, (gfloat)display->use_fbo_width/(gfloat)display->use_fbo_height, 0.1, 100); - //gluOrtho2D(0.0, display->use_fbo_width, 0.0, display->use_fbo_height); + + switch (display->use_fbo_projection) + { + case GST_GL_DISPLAY_PROJECTION_ORTHO2D: + gluOrtho2D(display->use_fbo_proj_param1, display->use_fbo_proj_param2, + display->use_fbo_proj_param3, display->use_fbo_proj_param4); + break; + case GST_GL_DISPLAY_PROJECTION_PERSPECIVE: + gluPerspective(display->use_fbo_proj_param1, display->use_fbo_proj_param2, + display->use_fbo_proj_param3, display->use_fbo_proj_param4); + break; + default: + g_assert_not_reached (); + } glMatrixMode(GL_MODELVIEW); glPushMatrix(); @@ -1276,7 +1279,7 @@ gst_gl_display_thread_use_fbo (GstGLDisplay *display) //the opengl scene display->use_fbo_scene_cb (display->input_texture_width, display->input_texture_height, - display->input_texture, display->use_shader); + display->input_texture, display->use_fbo_stuff); glDrawBuffer(GL_NONE); @@ -1296,66 +1299,6 @@ gst_gl_display_thread_use_fbo (GstGLDisplay *display) } -/* Called in the gl thread */ -static void -gst_gl_display_thread_use_fbo_2 (GstGLDisplay *display) -{ - glutSetWindow (display->glutWinId); - - glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, display->use_fbo); - - //setup a texture to render to - glBindTexture(GL_TEXTURE_RECTANGLE_ARB, display->use_fbo_texture); - glTexImage2D(GL_TEXTURE_RECTANGLE_ARB, 0, GL_RGBA8, - display->use_fbo_width, display->use_fbo_height, 0, GL_RGBA, GL_UNSIGNED_BYTE, NULL); - glTexParameteri (GL_TEXTURE_RECTANGLE_ARB, GL_TEXTURE_MAG_FILTER, GL_LINEAR); - glTexParameteri (GL_TEXTURE_RECTANGLE_ARB, GL_TEXTURE_MIN_FILTER, GL_LINEAR); - glTexParameteri (GL_TEXTURE_RECTANGLE_ARB, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); - glTexParameteri (GL_TEXTURE_RECTANGLE_ARB, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); - - //attach the texture to the FBO to renderer to - glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT, - GL_TEXTURE_RECTANGLE_ARB, display->use_fbo_texture, 0); - - glPushAttrib(GL_VIEWPORT_BIT); - - glMatrixMode(GL_PROJECTION); - glPushMatrix(); - glLoadIdentity(); - gluOrtho2D(0.0, display->use_fbo_width, 0.0, display->use_fbo_height); - - glMatrixMode(GL_MODELVIEW); - glPushMatrix(); - glLoadIdentity(); - - glViewport(0, 0, display->use_fbo_width, display->use_fbo_height); - - glDrawBuffer(GL_COLOR_ATTACHMENT0_EXT); - glClearColor(0.0, 0.0, 0.0, 0.0); - glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); - - //the opengl scene - display->use_fbo_scene_cb_2 (display->p1, display->p2, - display->use_fbo_width, display->use_fbo_height); - - glDrawBuffer(GL_NONE); - - glUseProgramObjectARB (0); - - glDisable(GL_TEXTURE_RECTANGLE_ARB); - - glPopMatrix(); - glMatrixMode(GL_PROJECTION); - glPopMatrix(); - glMatrixMode(GL_MODELVIEW); - glPopAttrib(); - - glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0); - - g_cond_signal (display->cond_use_fbo_2); -} - - /* Called in the gl thread */ static void gst_gl_display_thread_del_fbo (GstGLDisplay* display) @@ -1867,8 +1810,10 @@ gst_gl_display_gen_fbo (GstGLDisplay* display, gint width, gint height, void gst_gl_display_use_fbo (GstGLDisplay* display, gint texture_fbo_width, gint texture_fbo_height, guint fbo, guint depth_buffer, guint texture_fbo, GLCB cb, - guint input_texture_width, guint input_texture_height, guint input_texture, - GLhandleARB shader) + gint input_texture_width, gint input_texture_height, guint input_texture, + gdouble proj_param1, gdouble proj_param2, + gdouble proj_param3, gdouble proj_param4, + GstGLDisplayProjection projection, gpointer* stuff) { gst_gl_display_lock (display); display->use_fbo = fbo; @@ -1877,7 +1822,12 @@ gst_gl_display_use_fbo (GstGLDisplay* display, gint texture_fbo_width, gint text display->use_fbo_width = texture_fbo_width; display->use_fbo_height = texture_fbo_height; display->use_fbo_scene_cb = cb; - display->use_shader = shader; + display->use_fbo_proj_param1 = proj_param1; + display->use_fbo_proj_param2 = proj_param2; + display->use_fbo_proj_param3 = proj_param3; + display->use_fbo_proj_param4 = proj_param4; + display->use_fbo_projection = projection; + display->use_fbo_stuff = stuff; display->input_texture_width = input_texture_width; display->input_texture_height = input_texture_height; display->input_texture = input_texture; @@ -1887,27 +1837,6 @@ gst_gl_display_use_fbo (GstGLDisplay* display, gint texture_fbo_width, gint text } -/* Called by gltestsrc */ -void -gst_gl_display_use_fbo_2 (GstGLDisplay* display, gint texture_fbo_width, gint texture_fbo_height, - guint fbo, guint depth_buffer, guint texture_fbo, GLCB2 cb2, - gpointer* p1, gpointer* p2) -{ - gst_gl_display_lock (display); - display->use_fbo = fbo; - display->use_depth_buffer = depth_buffer; - display->use_fbo_texture = texture_fbo; - display->use_fbo_width = texture_fbo_width; - display->use_fbo_height = texture_fbo_height; - display->use_fbo_scene_cb_2 = cb2; - display->p1 = p1; - display->p2 = p2; - gst_gl_display_post_message (GST_GL_DISPLAY_ACTION_USE_FBO2, display); - g_cond_wait (display->cond_use_fbo_2, display->mutex); - gst_gl_display_unlock (display); -} - - /* Called by gltestsrc and glfilter */ void gst_gl_display_del_fbo (GstGLDisplay* display, guint fbo, diff --git a/gst-libs/gst/gl/gstgldisplay.h b/gst-libs/gst/gl/gstgldisplay.h index feb2b6f9d2..208b0f1e6b 100644 --- a/gst-libs/gst/gl/gstgldisplay.h +++ b/gst-libs/gst/gl/gstgldisplay.h @@ -49,6 +49,13 @@ typedef enum { } GstGLDisplayConversion; +//Projection type +typedef enum { + GST_GL_DISPLAY_PROJECTION_ORTHO2D, + GST_GL_DISPLAY_PROJECTION_PERSPECIVE +} GstGLDisplayProjection; + + //Message type typedef enum { GST_GL_DISPLAY_ACTION_CREATE_CONTEXT, @@ -64,7 +71,6 @@ typedef enum { GST_GL_DISPLAY_ACTION_DO_DOWNLOAD, GST_GL_DISPLAY_ACTION_GEN_FBO, GST_GL_DISPLAY_ACTION_USE_FBO, - GST_GL_DISPLAY_ACTION_USE_FBO2, GST_GL_DISPLAY_ACTION_DEL_FBO, GST_GL_DISPLAY_ACTION_GEN_SHADER, GST_GL_DISPLAY_ACTION_DEL_SHADER @@ -91,8 +97,7 @@ typedef void (* CRCB) ( GLuint, GLuint ); typedef gboolean (* CDCB) ( GLuint, GLuint, GLuint); //opengl scene callback -typedef void (* GLCB) ( GLuint, GLuint, GLuint, GLhandleARB); -typedef void (* GLCB2) ( gpointer* p1, gpointer* p2, gint w, gint h); +typedef void (* GLCB) ( gint, gint, guint, gpointer stuff); struct _GstGLDisplay { GObject object; @@ -121,7 +126,6 @@ struct _GstGLDisplay { GCond* cond_do_download; GCond* cond_gen_fbo; GCond* cond_use_fbo; - GCond* cond_use_fbo_2; GCond* cond_del_fbo; GCond* cond_gen_shader; GCond* cond_del_shader; @@ -168,10 +172,12 @@ struct _GstGLDisplay { GLuint use_fbo_width; GLuint use_fbo_height; GLCB use_fbo_scene_cb; - GLhandleARB use_shader; - GLCB2 use_fbo_scene_cb_2; - gpointer* p1; - gpointer* p2; + gdouble use_fbo_proj_param1; + gdouble use_fbo_proj_param2; + gdouble use_fbo_proj_param3; + gdouble use_fbo_proj_param4; + GstGLDisplayProjection use_fbo_projection; + gpointer* use_fbo_stuff; GLuint input_texture_width; GLuint input_texture_height; GLuint input_texture; @@ -263,11 +269,10 @@ void gst_gl_display_gen_fbo (GstGLDisplay* display, gint width, gint height, guint* fbo, guint* depthbuffer); void gst_gl_display_use_fbo (GstGLDisplay* display, gint texture_fbo_width, gint texture_fbo_height, guint fbo, guint depth_buffer, guint texture_fbo, GLCB cb, - guint input_texture_width, guint input_texture_height, guint input_texture, - GLhandleARB shader); -void gst_gl_display_use_fbo_2 (GstGLDisplay* display, gint texture_fbo_width, gint texture_fbo_height, - guint fbo, guint depth_buffer, guint texture_fbo, GLCB2 cb2, - gpointer* p1, gpointer* p2); + gint input_texture_width, gint input_texture_height, guint input_texture, + gdouble proj_param1, gdouble proj_param2, + gdouble proj_param3, gdouble proj_param4, + GstGLDisplayProjection projection, gpointer* stuff); void gst_gl_display_del_fbo (GstGLDisplay* display, guint fbo, guint depth_buffer); diff --git a/gst/gl/gstglfilterapp.c b/gst/gl/gstglfilterapp.c index 264d49e6e9..482395fda6 100644 --- a/gst/gl/gstglfilterapp.c +++ b/gst/gl/gstglfilterapp.c @@ -55,7 +55,7 @@ static gboolean gst_gl_filter_app_set_caps (GstGLFilter* filter, GstCaps* incaps, GstCaps* outcaps); static gboolean gst_gl_filter_app_filter (GstGLFilter* filter, GstGLBuffer* inbuf, GstGLBuffer* outbuf); -static void gst_gl_filter_app_callback (guint width, guint height, guint texture, GLhandleARB shader); +static void gst_gl_filter_app_callback (gint width, gint height, guint texture, gpointer stuff); static void @@ -154,7 +154,9 @@ gst_gl_filter_app_filter (GstGLFilter* filter, GstGLBuffer* inbuf, //blocking call, use a FBO gst_gl_display_use_fbo (filter->display, filter->width, filter->height, filter->fbo, filter->depthbuffer, outbuf->texture, app_filter->clientDrawCallback, - inbuf->width, inbuf->height, inbuf->texture, 0); + inbuf->width, inbuf->height, inbuf->texture, + 45, (gfloat)filter->width / (gfloat)filter->height, 0.1, 100, + GST_GL_DISPLAY_PROJECTION_PERSPECIVE, NULL); } //default else @@ -162,7 +164,9 @@ gst_gl_filter_app_filter (GstGLFilter* filter, GstGLBuffer* inbuf, //blocking call, use a FBO gst_gl_display_use_fbo (filter->display, filter->width, filter->height, filter->fbo, filter->depthbuffer, outbuf->texture, gst_gl_filter_app_callback, - inbuf->width, inbuf->height, inbuf->texture, 0); + inbuf->width, inbuf->height, inbuf->texture, + 0, filter->width, 0, filter->height, + GST_GL_DISPLAY_PROJECTION_ORTHO2D, NULL); } return TRUE; @@ -170,7 +174,7 @@ gst_gl_filter_app_filter (GstGLFilter* filter, GstGLBuffer* inbuf, //opengl scene, params: input texture (not the output filter->texture) static void -gst_gl_filter_app_callback (guint width, guint height, guint texture, GLhandleARB shader) +gst_gl_filter_app_callback (gint width, gint height, guint texture, gpointer stuff) { glEnable (GL_TEXTURE_RECTANGLE_ARB); glBindTexture (GL_TEXTURE_RECTANGLE_ARB, texture); diff --git a/gst/gl/gstglfiltercube.c b/gst/gl/gstglfiltercube.c index dabf857790..595d3e5b3a 100644 --- a/gst/gl/gstglfiltercube.c +++ b/gst/gl/gstglfiltercube.c @@ -35,11 +35,18 @@ static const GstElementDetails element_details = enum { - PROP_0 + PROP_0, + PROP_RED, + PROP_GREEN, + PROP_BLUE, + PROP_FOVY, + PROP_ASPECT, + PROP_ZNEAR, + PROP_ZFAR }; #define DEBUG_INIT(bla) \ - GST_DEBUG_CATEGORY_INIT (gst_gl_filter_cube_debug, "glfiltercube", 0, "glfiltercube element"); + GST_DEBUG_CATEGORY_INIT (gst_gl_filter_cube_debug, "glfiltercube", 0, "glfiltercube element"); GST_BOILERPLATE_FULL (GstGLFilterCube, gst_gl_filter_cube, GstGLFilter, GST_TYPE_GL_FILTER, DEBUG_INIT); @@ -49,9 +56,11 @@ static void gst_gl_filter_cube_set_property (GObject* object, guint prop_id, static void gst_gl_filter_cube_get_property (GObject* object, guint prop_id, GValue* value, GParamSpec* pspec); +static gboolean gst_gl_filter_cube_set_caps (GstGLFilter* filter, + GstCaps* incaps, GstCaps* outcaps); static gboolean gst_gl_filter_cube_filter (GstGLFilter* filter, GstGLBuffer* inbuf, GstGLBuffer* outbuf); -static void gst_gl_filter_cube_callback (guint width, guint height, guint texture, GLhandleARB shader); +static void gst_gl_filter_cube_callback (gint width, gint height, guint texture, gpointer stuff); static void @@ -71,23 +80,79 @@ gst_gl_filter_cube_class_init (GstGLFilterCubeClass * klass) gobject_class->set_property = gst_gl_filter_cube_set_property; gobject_class->get_property = gst_gl_filter_cube_get_property; + GST_GL_FILTER_CLASS (klass)->set_caps = gst_gl_filter_cube_set_caps; GST_GL_FILTER_CLASS (klass)->filter = gst_gl_filter_cube_filter; + + g_object_class_install_property (gobject_class, PROP_RED, + g_param_spec_float ("red", "Red", "Background red color", + 0.0f, 1.0f, 0.0f, G_PARAM_WRITABLE)); + + g_object_class_install_property (gobject_class, PROP_GREEN, + g_param_spec_float ("green", "Green", "Background reen color", + 0.0f, 1.0f, 0.0f, G_PARAM_WRITABLE)); + + g_object_class_install_property (gobject_class, PROP_BLUE, + g_param_spec_float ("blue", "Blue", "Background blue color", + 0.0f, 1.0f, 0.0f, G_PARAM_WRITABLE)); + + g_object_class_install_property (gobject_class, PROP_FOVY, + g_param_spec_double ("fovy", "Fovy", "Field of view angle in degrees", + 0.0, 180.0, 45.0, G_PARAM_WRITABLE)); + + g_object_class_install_property (gobject_class, PROP_ASPECT, + g_param_spec_double ("aspect", "Aspect", "Field of view in the x direction", + 0.0, 100, 0.0, G_PARAM_WRITABLE)); + + g_object_class_install_property (gobject_class, PROP_ZNEAR, + g_param_spec_double ("znear", "Znear", + "Specifies the distance from the viewer to the near clipping plane", + 0.0, 100.0, 0.1, G_PARAM_WRITABLE)); + + g_object_class_install_property (gobject_class, PROP_ZFAR, + g_param_spec_double ("zfar", "Zfar", + "Specifies the distance from the viewer to the far clipping plane", + 0.0, 1000.0, 100.0, G_PARAM_WRITABLE)); } static void gst_gl_filter_cube_init (GstGLFilterCube* filter, GstGLFilterCubeClass* klass) { + filter->fovy = 45; + filter->aspect = 0; + filter->znear = 0.1; + filter->zfar = 100; } static void gst_gl_filter_cube_set_property (GObject* object, guint prop_id, const GValue* value, GParamSpec* pspec) { - //GstGLFilterCube *filter = GST_GL_FILTER_CUBE (object); + GstGLFilterCube* filter = GST_GL_FILTER_CUBE (object); switch (prop_id) { + case PROP_RED: + filter->red = g_value_get_float (value); + break; + case PROP_GREEN: + filter->green = g_value_get_float (value); + break; + case PROP_BLUE: + filter->blue = g_value_get_float (value); + break; + case PROP_FOVY: + filter->fovy = g_value_get_double (value); + break; + case PROP_ASPECT: + filter->aspect = g_value_get_double (value); + break; + case PROP_ZNEAR: + filter->znear = g_value_get_double (value); + break; + case PROP_ZFAR: + filter->zfar = g_value_get_double (value); + break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); break; @@ -98,7 +163,7 @@ static void gst_gl_filter_cube_get_property (GObject* object, guint prop_id, GValue* value, GParamSpec* pspec) { - //GstGLFilterCube *filter = GST_GL_FILTER_CUBE (object); + //GstGLFilterCube* filter = GST_GL_FILTER_CUBE (object); switch (prop_id) { @@ -108,28 +173,44 @@ gst_gl_filter_cube_get_property (GObject* object, guint prop_id, } } +static gboolean +gst_gl_filter_cube_set_caps (GstGLFilter* filter, GstCaps* incaps, + GstCaps* outcaps) +{ + GstGLFilterCube* cube_filter = GST_GL_FILTER_CUBE (filter); + + if (cube_filter->aspect == 0) + cube_filter->aspect = (gdouble)filter->width / (gdouble)filter->height; + + return TRUE; +} + static gboolean gst_gl_filter_cube_filter (GstGLFilter* filter, GstGLBuffer* inbuf, GstGLBuffer* outbuf) { - //GstGLFilterCube* cube_filter = GST_GL_FILTER_CUBE(filter); - + GstGLFilterCube* cube_filter = GST_GL_FILTER_CUBE (filter); + //blocking call, use a FBO gst_gl_display_use_fbo (filter->display, filter->width, filter->height, filter->fbo, filter->depthbuffer, outbuf->texture, gst_gl_filter_cube_callback, - inbuf->width, inbuf->height, inbuf->texture, 0); + inbuf->width, inbuf->height, inbuf->texture, + cube_filter->fovy, cube_filter->aspect, cube_filter->znear, cube_filter->zfar, + GST_GL_DISPLAY_PROJECTION_PERSPECIVE, (gpointer)cube_filter); return TRUE; } //opengl scene, params: input texture (not the output filter->texture) static void -gst_gl_filter_cube_callback (guint width, guint height, guint texture, GLhandleARB shader) +gst_gl_filter_cube_callback (gint width, gint height, guint texture, gpointer stuff) { static GLfloat xrot = 0; static GLfloat yrot = 0; static GLfloat zrot = 0; + GstGLFilterCube* cube_filter = GST_GL_FILTER_CUBE (stuff); + glEnable(GL_DEPTH_TEST); glEnable (GL_TEXTURE_RECTANGLE_ARB); @@ -140,6 +221,7 @@ gst_gl_filter_cube_callback (guint width, guint height, guint texture, GLhandleA glTexParameteri (GL_TEXTURE_RECTANGLE_ARB, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); glTexEnvi (GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE); + glClearColor(cube_filter->red, cube_filter->green, cube_filter->blue, 0.0); glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); glMatrixMode(GL_MODELVIEW); glLoadIdentity(); diff --git a/gst/gl/gstglfiltercube.h b/gst/gl/gstglfiltercube.h index 93a2380b57..59c836f266 100644 --- a/gst/gl/gstglfiltercube.h +++ b/gst/gl/gstglfiltercube.h @@ -38,6 +38,17 @@ typedef struct _GstGLFilterCubeClass GstGLFilterCubeClass; struct _GstGLFilterCube { GstGLFilter filter; + + //background color + gfloat red; + gfloat green; + gfloat blue; + + //perspective + gdouble fovy; + gdouble aspect; + gdouble znear; + gdouble zfar; }; struct _GstGLFilterCubeClass diff --git a/gst/gl/gstglfilteredge.c b/gst/gl/gstglfilteredge.c index b2372d9744..bdc6acb709 100644 --- a/gst/gl/gstglfilteredge.c +++ b/gst/gl/gstglfilteredge.c @@ -53,7 +53,7 @@ static void gst_gl_filter_edge_reset (GstGLFilter* filter); static void gst_gl_filter_edge_init_shader (GstGLFilter* filter); static gboolean gst_gl_filter_edge_filter (GstGLFilter * filter, GstGLBuffer * inbuf, GstGLBuffer * outbuf); -static void gst_gl_filter_edge_callback (guint width, guint height, guint texture, GLhandleARB shader); +static void gst_gl_filter_edge_callback (gint width, gint height, guint texture, gpointer stuff); static void @@ -156,7 +156,7 @@ gst_gl_filter_edge_get_property (GObject* object, guint prop_id, static void gst_gl_filter_edge_init_shader (GstGLFilter* filter) { - GstGLFilterEdge* edge_filter = GST_GL_FILTER_EDGE(filter); + GstGLFilterEdge* edge_filter = GST_GL_FILTER_EDGE (filter); //blocking call, wait the opengl thread has compiled the shader program gst_gl_display_gen_shader (filter->display, edge_filter->textShader, &edge_filter->handleShader); @@ -166,36 +166,32 @@ static gboolean gst_gl_filter_edge_filter (GstGLFilter* filter, GstGLBuffer* inbuf, GstGLBuffer* outbuf) { - GstGLFilterEdge* edge_filter = GST_GL_FILTER_EDGE(filter); - + gpointer edge_filter = GST_GL_FILTER_EDGE (filter); + //blocking call, generate a FBO gst_gl_display_use_fbo (filter->display, filter->width, filter->height, filter->fbo, filter->depthbuffer, outbuf->texture, gst_gl_filter_edge_callback, - inbuf->width, inbuf->height, inbuf->texture, edge_filter->handleShader); + inbuf->width, inbuf->height, inbuf->texture, + 0, filter->width, 0, filter->height, + GST_GL_DISPLAY_PROJECTION_ORTHO2D, edge_filter); return TRUE; } //opengl scene, params: input texture (not the output filter->texture) static void -gst_gl_filter_edge_callback (guint width, guint height, guint texture, GLhandleARB shader) +gst_gl_filter_edge_callback (gint width, gint height, guint texture, gpointer stuff) { + GstGLFilterEdge* edge_filter = GST_GL_FILTER_EDGE (stuff); gint i=0; - glViewport(0, 0, width, height); - - glDrawBuffer(GL_COLOR_ATTACHMENT0_EXT); - - glClearColor(0.0, 0.0, 0.0, 0.0); - glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); - - glUseProgramObjectARB (shader); - glMatrixMode (GL_PROJECTION); glLoadIdentity (); + glUseProgramObjectARB (edge_filter->handleShader); + glActiveTextureARB(GL_TEXTURE0_ARB); - i = glGetUniformLocationARB (shader, "tex"); + i = glGetUniformLocationARB (edge_filter->handleShader, "tex"); glUniform1iARB (i, 0); glBindTexture (GL_TEXTURE_RECTANGLE_ARB, texture); diff --git a/gst/gl/gstgltestsrc.c b/gst/gl/gstgltestsrc.c index 6e02048082..f3745267c4 100644 --- a/gst/gl/gstgltestsrc.c +++ b/gst/gl/gstgltestsrc.c @@ -88,6 +88,8 @@ static GstFlowReturn gst_gl_test_src_create (GstPushSrc* psrc, static gboolean gst_gl_test_src_start (GstBaseSrc* basesrc); static gboolean gst_gl_test_src_stop (GstBaseSrc* basesrc); +static void gst_gl_test_src_callback (gint width, gint height, guint texture, gpointer stuff); + #define GST_TYPE_GL_TEST_SRC_PATTERN (gst_gl_test_src_pattern_get_type ()) static GType gst_gl_test_src_pattern_get_type (void) @@ -524,8 +526,8 @@ gst_gl_test_src_is_seekable (GstBaseSrc* psrc) static GstFlowReturn gst_gl_test_src_create (GstPushSrc* psrc, GstBuffer** buffer) { - GstGLTestSrc *src; - GstGLBuffer *outbuf; + GstGLTestSrc* src; + GstGLBuffer* outbuf; //GstFlowReturn res; GstClockTime next_time; @@ -554,12 +556,18 @@ gst_gl_test_src_create (GstPushSrc* psrc, GstBuffer** buffer) src->make_image = gst_gl_test_src_white; else src->make_image = gst_gl_test_src_black; - } + } + + src->buffer = outbuf; //blocking call, generate a FBO - gst_gl_display_use_fbo_2 (src->display, src->width, src->height, - src->fbo, src->depthbuffer, outbuf->texture, (GLCB2)src->make_image, - (gpointer*)src, (gpointer*)outbuf); + gst_gl_display_use_fbo (src->display, src->width, src->height, + src->fbo, src->depthbuffer, outbuf->texture, + gst_gl_test_src_callback, + 0, 0, 0, //no input texture + 0, src->width, 0, src->height, + GST_GL_DISPLAY_PROJECTION_ORTHO2D, + (gpointer)src); GST_BUFFER_TIMESTAMP (GST_BUFFER (outbuf)) = src->timestamp_offset + src->running_time; @@ -633,3 +641,12 @@ gst_gl_test_src_stop (GstBaseSrc* basesrc) return TRUE; } + +//opengl scene +static void +gst_gl_test_src_callback (gint width, gint height, guint texture, gpointer stuff) +{ + GstGLTestSrc* src = GST_GL_TEST_SRC (stuff); + + src->make_image (src, src->buffer, src->width, src->height); +} diff --git a/gst/gl/gstgltestsrc.h b/gst/gl/gstgltestsrc.h index 9f7dbf220f..b7d5185cf8 100644 --- a/gst/gl/gstgltestsrc.h +++ b/gst/gl/gstgltestsrc.h @@ -99,6 +99,8 @@ struct _GstGLTestSrc { guint fbo; guint depthbuffer; + GstGLBuffer* buffer; + /* private */ GstGLDisplay *display; gint64 timestamp_offset; /* base offset */ @@ -106,7 +108,7 @@ struct _GstGLTestSrc { gint64 n_frames; /* total frames sent */ gboolean negotiated; - void (*make_image) (GstGLTestSrc *v, GstGLBuffer *buffer, int w, int h); + void (*make_image) (GstGLTestSrc* v, GstGLBuffer* buffer, gint w, gint h); }; struct _GstGLTestSrcClass {