Пример #1
0
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);
}
Пример #2
0
StageID StageManager::new_stage(AvailablePartitioner partitioner) {
    return StageManager::manager_new(StageID(), partitioner);
}