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