void RenderSequence::run_pipeline(Pipeline::ptr pipeline_stage) { if(!pipeline_stage->is_active()) { return; } Camera& camera = scene_.camera(pipeline_stage->camera_id()); Viewport& viewport = scene_.window().viewport(pipeline_stage->viewport_id()); viewport.apply(); //FIXME apply shouldn't exist signal_pipeline_started_(*pipeline_stage); if(pipeline_stage->ui_stage_id()) { //This is a UI stage, so just render that auto ui_stage = scene_.ui_stage(pipeline_stage->ui_stage_id()); ui_stage->__resize(viewport.width(), viewport.height()); //FIXME: GL 2.x rubbish glPushMatrix(); glMatrixMode(GL_PROJECTION); glLoadMatrixf(camera.projection_matrix().mat); glMatrixMode(GL_MODELVIEW); glLoadIdentity(); ui_stage->__render(); glMatrixMode(GL_PROJECTION); glLoadIdentity(); glMatrixMode(GL_MODELVIEW); glPopMatrix(); } else { Stage& stage = scene_.stage(pipeline_stage->stage_id()); std::vector<SubActor::ptr> buffers = stage.partitioner().geometry_visible_from(pipeline_stage->camera_id()); /* * Go through the visible objects, sort into queues and for * each material pass add the subactor. The result is that a tree * of material properties (uniforms) will be created with the child nodes * being the meshes */ typedef std::tr1::unordered_map<uint32_t, std::vector<RootGroup::ptr> > QueueGroups; static QueueGroups queues; //Empty the queues for(auto queue: queues) { for(auto group: queue.second) { group->clear(); } } //Go through the visible actors for(SubActor::ptr ent: buffers) { //Get the priority queue for this actor (e.g. RENDER_PRIORITY_BACKGROUND) QueueGroups::mapped_type& priority_queue = queues[(uint32_t)ent->_parent().render_priority()]; auto mat = stage.material(ent->material_id()); //Go through the actors material passes for(uint8_t pass = 0; pass < mat->technique().pass_count(); ++pass) { //Create a new render group if necessary RootGroup::ptr group; if(priority_queue.size() <= pass) { group = RootGroup::ptr(new RootGroup(stage, camera)); priority_queue.push_back(group); } else { group = priority_queue[pass]; } //Insert the actor into the RenderGroup tree group->insert(*ent, pass); } } /* * At this point, we will have a render group tree for each priority level * when we render, we can apply the uniforms/textures/shaders etc. by traversing the * tree and calling bind()/unbind() at each level */ renderer_->set_current_stage(stage.id()); for(RenderPriority priority: RENDER_PRIORITIES) { QueueGroups::mapped_type& priority_queue = queues[priority]; for(RootGroup::ptr pass_group: priority_queue) { std::function<void (SubActor&)> f = [=](SubActor& subactor) { renderer_->render_subactor(subactor, pipeline_stage->camera_id()); }; pass_group->traverse(f); } } renderer_->set_current_stage(StageID()); } /* std::sort(buffers.begin(), buffers.end(), [](SubActor::ptr lhs, SubActor::ptr rhs) { return lhs->_parent().render_priority() < rhs->_parent().render_priority(); }); //TODO: Batched rendering renderer_->set_current_stage(stage.id()); renderer_->render(buffers, stage->camera_id()); renderer_->set_current_stage(StageID());*/ signal_pipeline_finished_(*pipeline_stage); }
StageID StageManager::new_stage(AvailablePartitioner partitioner) { return StageManager::manager_new(StageID(), partitioner); }