int main()
{
	init_stage();
	setup_stage();
	main_loop();
	cleanup();
	return 0;
}
Beispiel #2
0
static INLINE void 
emit_prim( struct draw_stage *stage, 
	   struct prim_header *prim,
	   unsigned hwprim,
	   unsigned nr )
{
   struct i915_context *i915 = setup_stage(stage)->i915;
   unsigned vertex_size;
   unsigned i;

   if (i915->dirty)
      i915_update_derived( i915 );

   if (i915->hardware_dirty)
      i915_emit_hardware_state( i915 );

   /* need to do this after validation! */
   vertex_size = i915->current.vertex_info.size * 4; /* in bytes */
   assert(vertex_size >= 12); /* never smaller than 12 bytes */

   if (!BEGIN_BATCH( 1 + nr * vertex_size / 4)) {
      FLUSH_BATCH(NULL);

      /* Make sure state is re-emitted after a flush: 
       */
      i915_emit_hardware_state( i915 );

      if (!BEGIN_BATCH( 1 + nr * vertex_size / 4)) {
	 assert(0);
	 return;
      }
   }

   /* Emit each triangle as a single primitive.  I told you this was
    * simple.
    */
   OUT_BATCH(_3DPRIMITIVE | 
	     hwprim |
	     ((4 + vertex_size * nr)/4 - 2));

   for (i = 0; i < nr; i++)
      emit_hw_vertex(i915, prim->v[i]);
}
Beispiel #3
0
int
main (int argc, char *argv[])
{
  GLenum err = 0;
#ifdef WIN32
  HGLRC clutter_gl_context = 0;
  HDC clutter_dc = 0;
#else
  Display *clutter_display = NULL;
  Window clutter_win = 0;
  GLXContext clutter_gl_context = NULL;
#endif
  GstPipeline *pipeline = NULL;
  GstBus *bus = NULL;
  GstElement *glupload = NULL;
  GstState state = 0;
  ClutterActor *stage = NULL;
  ClutterActor *clutter_texture = NULL;
  GAsyncQueue *queue_input_buf = NULL;
  GAsyncQueue *queue_output_buf = NULL;
  GstElement *fakesink = NULL;

  /* init gstreamer then clutter */

  gst_init (&argc, &argv);
  clutter_threads_init ();
  clutter_init (&argc, &argv);
  clutter_threads_enter ();
  g_print ("clutter version: %s\n", CLUTTER_VERSION_S);

  /* init glew */

  err = glewInit ();
  if (err != GLEW_OK)
    g_debug ("failed to init GLEW: %s", glewGetErrorString (err));

  /* avoid to dispatch unecesary events */

  clutter_ungrab_keyboard ();
  clutter_ungrab_pointer ();

  /* retrieve and turn off clutter opengl context */

  stage = clutter_stage_get_default ();

  /* retrieve and turn off clutter opengl context */

#ifdef WIN32
  clutter_gl_context = wglGetCurrentContext ();
  clutter_dc = wglGetCurrentDC ();
  wglMakeCurrent (0, 0);
#else
  clutter_display = clutter_x11_get_default_display ();
  clutter_win = clutter_x11_get_stage_window (CLUTTER_STAGE (stage));
  clutter_gl_context = glXGetCurrentContext ();
  glXMakeCurrent (clutter_display, None, 0);
#endif

  /* setup gstreamer pipeline */

  pipeline =
      GST_PIPELINE (gst_parse_launch
      ("videotestsrc ! video/x-raw-yuv, width=320, height=240, framerate=(fraction)30/1 ! "
          "glupload ! gleffects effect=5 ! glfiltercube ! fakesink sync=1",
          NULL));

  /* setup bus */

  bus = gst_pipeline_get_bus (GST_PIPELINE (pipeline));
  gst_bus_add_signal_watch (bus);
  g_signal_connect (bus, "message::error", G_CALLBACK (end_stream_cb), NULL);
  g_signal_connect (bus, "message::warning", G_CALLBACK (end_stream_cb), NULL);
  g_signal_connect (bus, "message::eos", G_CALLBACK (end_stream_cb), NULL);
  gst_object_unref (bus);

  /* clutter_gl_context is an external OpenGL context with which gst-plugins-gl want to share textures */

  glupload = gst_bin_get_by_name (GST_BIN (pipeline), "glupload0");
  g_object_set (G_OBJECT (glupload), "external-opengl-context",
      clutter_gl_context, NULL);
  g_object_unref (glupload);

  /* NULL to PAUSED state pipeline to make sure the gst opengl context is created and
   * shared with the clutter one */

  gst_element_set_state (GST_ELEMENT (pipeline), GST_STATE_PAUSED);
  state = GST_STATE_PAUSED;
  if (gst_element_get_state (GST_ELEMENT (pipeline), &state, NULL,
          GST_CLOCK_TIME_NONE) != GST_STATE_CHANGE_SUCCESS) {
    g_debug ("failed to pause pipeline\n");
    return -1;
  }

  /* turn on back clutter opengl context */

#ifdef WIN32
  wglMakeCurrent (clutter_dc, clutter_gl_context);
#else
  glXMakeCurrent (clutter_display, clutter_win, clutter_gl_context);
#endif

  /* clutter stage */

  clutter_actor_set_size (stage, 640, 480);
  clutter_actor_set_position (stage, 0, 0);
  clutter_stage_set_title (CLUTTER_STAGE (stage), "clutter and gst-plugins-gl");
  clutter_texture = setup_stage (CLUTTER_STAGE (stage));

  /* append a gst-gl texture to this queue when you do not need it no more */

  queue_input_buf = g_async_queue_new ();
  queue_output_buf = g_async_queue_new ();
  g_object_set_data (G_OBJECT (clutter_texture), "queue_input_buf",
      queue_input_buf);
  g_object_set_data (G_OBJECT (clutter_texture), "queue_output_buf",
      queue_output_buf);

  /* set a callback to retrieve the gst gl textures */

  fakesink = gst_bin_get_by_name (GST_BIN (pipeline), "fakesink0");
  g_object_set (G_OBJECT (fakesink), "signal-handoffs", TRUE, NULL);
  g_signal_connect (fakesink, "handoff", G_CALLBACK (on_gst_buffer),
      clutter_texture);
  g_object_unref (fakesink);

  /* play gst */

  gst_element_set_state (GST_ELEMENT (pipeline), GST_STATE_PLAYING);

  /* main loop */

  clutter_main ();

  /* before to deinitialize the gst-gl-opengl context,
   * no shared context (here the clutter one) must be current
   */
#ifdef WIN32
  wglMakeCurrent (0, 0);
#else
  glXMakeCurrent (clutter_display, None, 0);
#endif

  clutter_threads_leave ();

  /* stop and clean up the pipeline */

  gst_element_set_state (GST_ELEMENT (pipeline), GST_STATE_NULL);
  g_object_unref (pipeline);

  /* make sure there is no pending gst gl buffer in the communication queues 
   * between clutter and gst-gl
   */

  while (g_async_queue_length (queue_input_buf) > 0) {
    GstBuffer *buf = g_async_queue_pop (queue_input_buf);
    gst_buffer_unref (buf);
  }

  while (g_async_queue_length (queue_output_buf) > 0) {
    GstBuffer *buf = g_async_queue_pop (queue_output_buf);
    gst_buffer_unref (buf);
  }

  return 0;
}