예제 #1
0
static void
paint_scene (RigPaintContext *paint_ctx)
{
  RutPaintContext *rut_paint_ctx = &paint_ctx->_parent;
  RigEngine *engine = paint_ctx->engine;
  CoglContext *ctx = engine->ctx->cogl_context;
  CoglFramebuffer *fb = rut_camera_get_framebuffer (rut_paint_ctx->camera);

  if (paint_ctx->pass == RIG_PASS_COLOR_UNBLENDED)
    {
      CoglPipeline *pipeline = cogl_pipeline_new (ctx);
      cogl_pipeline_set_color4f (pipeline,
                                 engine->background_color.red,
                                 engine->background_color.green,
                                 engine->background_color.blue,
                                 engine->background_color.alpha);
      cogl_framebuffer_draw_rectangle (fb,
                                       pipeline,
                                       0, 0,
                                       engine->device_width, engine->device_height);
                                       //0, 0, engine->pane_width, engine->pane_height);
      cogl_object_unref (pipeline);
    }

  rut_graphable_traverse (engine->scene,
                          RUT_TRAVERSE_DEPTH_FIRST,
                          entitygraph_pre_paint_cb,
                          entitygraph_post_paint_cb,
                          paint_ctx);

  rig_journal_flush (engine->journal, paint_ctx);
}
예제 #2
0
static void
_rut_rectangle_paint(rut_object_t *object,
                     rut_paint_context_t *paint_ctx)
{
    rut_rectangle_t *rectangle = object;
    rut_object_t *camera = paint_ctx->camera;

    cg_framebuffer_draw_rectangle(rut_camera_get_framebuffer(camera),
                                  rectangle->pipeline,
                                  0,
                                  0,
                                  rectangle->width,
                                  rectangle->height);
}
예제 #3
0
static RutTraverseVisitFlags
entitygraph_post_paint_cb (RutObject *object,
                           int depth,
                           void *user_data)
{
  if (rut_object_is (object, RUT_INTERFACE_ID_TRANSFORMABLE))
    {
      RutPaintContext *rut_paint_ctx = user_data;
      CoglFramebuffer *fb = rut_camera_get_framebuffer (rut_paint_ctx->camera);
      cogl_framebuffer_pop_matrix (fb);
    }

  return RUT_TRAVERSE_VISIT_CONTINUE;
}
예제 #4
0
static RutTraverseVisitFlags
entitygraph_pre_paint_cb (RutObject *object,
                          int depth,
                          void *user_data)
{
  RigPaintContext *paint_ctx = user_data;
  RutPaintContext *rut_paint_ctx = user_data;
  RutCamera *camera = rut_paint_ctx->camera;
  CoglFramebuffer *fb = rut_camera_get_framebuffer (camera);

  if (rut_object_is (object, RUT_INTERFACE_ID_TRANSFORMABLE))
    {
      const CoglMatrix *matrix = rut_transformable_get_matrix (object);
      cogl_framebuffer_push_matrix (fb);
      cogl_framebuffer_transform (fb, matrix);
    }

  if (rut_object_get_type (object) == &rut_entity_type)
    {
      RutEntity *entity = RUT_ENTITY (object);
      RutObject *geometry;
      CoglMatrix matrix;

      if (!rut_entity_get_visible (entity) ||
          (paint_ctx->pass == RIG_PASS_SHADOW && !rut_entity_get_cast_shadow (entity)))
        return RUT_TRAVERSE_VISIT_CONTINUE;

      geometry =
        rut_entity_get_component (object, RUT_COMPONENT_TYPE_GEOMETRY);
      if (!geometry)
        {
          if (!paint_ctx->engine->play_mode &&
              object == paint_ctx->engine->light)
            draw_entity_camera_frustum (paint_ctx->engine, object, fb);
          return RUT_TRAVERSE_VISIT_CONTINUE;
        }

      cogl_framebuffer_get_modelview_matrix (fb, &matrix);
      rig_journal_log (paint_ctx->engine->journal,
                       paint_ctx,
                       entity,
                       &matrix);

      return RUT_TRAVERSE_VISIT_CONTINUE;
    }

  return RUT_TRAVERSE_VISIT_CONTINUE;
}
예제 #5
0
static void
rig_journal_flush (GArray *journal,
                   RigPaintContext *paint_ctx)
{
  RutPaintContext *rut_paint_ctx = &paint_ctx->_parent;
  RutCamera *camera = rut_paint_ctx->camera;
  CoglFramebuffer *fb = rut_camera_get_framebuffer (camera);
  int start, dir, end;
  int i;

  /* TODO: use an inline qsort implementation */
  g_array_sort (journal, (void *)sort_entry_cb);

  /* We draw opaque geometry front-to-back so we are more likely to be
   * able to discard later fragments earlier by depth testing.
   *
   * We draw transparent geometry back-to-front so it blends
   * correctly.
   */
  if ( paint_ctx->pass == RIG_PASS_COLOR_BLENDED)
    {
      start = 0;
      dir = 1;
      end = journal->len;
    }
  else
    {
      start = journal->len - 1;
      dir = -1;
      end = -1;
    }

  cogl_framebuffer_push_matrix (fb);

  for (i = start; i != end; i += dir)
    {
      RigJournalEntry *entry = &g_array_index (journal, RigJournalEntry, i);
      RutEntity *entity = entry->entity;
      RutComponent *geometry =
        rut_entity_get_component (entity, RUT_COMPONENT_TYPE_GEOMETRY);
      CoglPipeline *pipeline;
      CoglPrimitive *primitive;
      float normal_matrix[9];
      RutMaterial *material;

      pipeline = get_entity_pipeline (paint_ctx->engine,
                                      entity,
                                      geometry,
                                      paint_ctx->pass);

      if (paint_ctx->pass == RIG_PASS_DOF_DEPTH ||
          paint_ctx->pass == RIG_PASS_SHADOW)
        {
          /* FIXME: avoid updating these uniforms for every primitive if
           * the focal parameters haven't change! */
          set_focal_parameters (pipeline,
                                camera->focal_distance,
                                camera->depth_of_field);
        }
      else if (paint_ctx->pass == RIG_PASS_COLOR_UNBLENDED ||
               paint_ctx->pass == RIG_PASS_COLOR_BLENDED)
        {
          int location;
          RutLight *light = rut_entity_get_component (paint_ctx->engine->light,
                                                      RUT_COMPONENT_TYPE_LIGHT);
          /* FIXME: only update the lighting uniforms when the light has
           * actually moved! */
          rut_light_set_uniforms (light, pipeline);

          /* FIXME: only update the material uniforms when the material has
           * actually changed! */
          material = rut_entity_get_component (entity, RUT_COMPONENT_TYPE_MATERIAL);
          if (material)
            rut_material_flush_uniforms (material, pipeline);

          get_normal_matrix (&entry->matrix, normal_matrix);

          location = cogl_pipeline_get_uniform_location (pipeline, "normal_matrix");
          cogl_pipeline_set_uniform_matrix (pipeline,
                                            location,
                                            3, /* dimensions */
                                            1, /* count */
                                            FALSE, /* don't transpose again */
                                            normal_matrix);
        }

      if (rut_object_is (geometry, RUT_INTERFACE_ID_PRIMABLE))
        {
          primitive = rut_primable_get_primitive (geometry);
          cogl_framebuffer_set_modelview_matrix (fb, &entry->matrix);
          cogl_framebuffer_draw_primitive (fb,
                                           pipeline,
                                           primitive);
        }
      else if (rut_object_get_type (geometry) == &rut_text_type &&
               paint_ctx->pass == RIG_PASS_COLOR_BLENDED)
        {
          cogl_framebuffer_set_modelview_matrix (fb, &entry->matrix);
          rut_paintable_paint (geometry, rut_paint_ctx);
        }

      cogl_object_unref (pipeline);

      rut_refable_unref (entry->entity);
    }

  cogl_framebuffer_pop_matrix (fb);

  g_array_set_size (journal, 0);
}