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 */ }
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; }
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; }
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); } }
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); }