예제 #1
0
static bool
match_component_sizeable(rut_object_t *component, void *user_data)
{
    if (rut_object_is(component, RUT_TRAIT_ID_SIZABLE)) {
        rut_object_t **sizeable = user_data;
        *sizeable = component;
        return false; /* break */
    }

    return true; /* continue */
}
예제 #2
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;
}
예제 #3
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;
}
예제 #4
0
파일: rut-graphable.c 프로젝트: cee1/rig
void
rut_graphable_apply_transform (RutObject *graphable,
                               CoglMatrix *transform_matrix)
{
  int depth = 0;
  RutObject **transform_nodes;
  RutObject *node = graphable;
  int i;

  do {
    RutGraphableProps *graphable_priv =
      rut_object_get_properties (node, RUT_INTERFACE_ID_GRAPHABLE);

    depth++;

    node = graphable_priv->parent;
  } while (node);

  transform_nodes = g_alloca (sizeof (RutObject *) * depth);

  node = graphable;
  i = 0;
  do {
    RutGraphableProps *graphable_priv;

    if (rut_object_is (node, RUT_INTERFACE_ID_TRANSFORMABLE))
      transform_nodes[i++] = node;

    graphable_priv =
      rut_object_get_properties (node, RUT_INTERFACE_ID_GRAPHABLE);
    node = graphable_priv->parent;
  } while (node);

  for (i--; i >= 0; i--)
    {
      const CoglMatrix *matrix = rut_transformable_get_matrix (transform_nodes[i]);
      cogl_matrix_multiply (transform_matrix, transform_matrix, matrix);
    }
}
예제 #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);
}