OSG能够在当前帧截图,也就是能转换视角后马上截图

#include <Windows.h>
#include <osg/GraphicsContext>
#include <osg/Group>
#include <osg/Node>
#include <osg/Geode>
#include <osgViewer/Viewer>
#include <osgDB/ReadFile>
#include <osgUtil/Optimizer>
#include <osgDB/WriteFile>
#include <osgGA/TrackballManipulator>
osg::ref_ptr<osg::Image> captureImage = new osg::Image;
osg::ref_ptr<osgGA::TrackballManipulator> track = new osgGA::TrackballManipulator;
osg::Vec3d center;
int captureAngelCount = 0;
osg::Vec3d shotEye[2600];
osg::Vec3d shotup[2600];
struct CaptureCallback :public osg::Camera::DrawCallback
{
    CaptureCallback()
    {
    }
    ~CaptureCallback() {}

    virtual void operator()(const osg::Camera &camera) const
    {
        //得到窗口系统接口
        osg::ref_ptr<osg::GraphicsContext::WindowingSystemInterface> wsi = osg::GraphicsContext::getWindowingSystemInterface();
        unsigned int width, height;
        //得到分辨率
        wsi->getScreenResolution(osg::GraphicsContext::ScreenIdentifier(0), width, height);
        static int cnt = 1;
        //读取像素信息抓图
        captureImage->readPixels((width - 128) / 2, (height - 128) / 2, 128, 128, GL_RGBA, GL_UNSIGNED_BYTE);
        char filename[128];
        sprintf(filename, "ScreenShot//ScreenShot%d.png", cnt++);
        osgDB::writeImageFile(*captureImage, filename);
    }
};


int CountLines(char *filename)
{
    std::ifstream ReadFile;
    int n = 0;
    std::string tmp;
    ReadFile.open(filename, std::ios::in);//ios::in 表示以只读的方式读取文件  
    if (ReadFile.fail())//文件打开失败:返回0  
    {
        return 0;
    }
    else//文件存在  
    {
        while (getline(ReadFile, tmp, '\n'))
        {
            n++;
        }
        ReadFile.close();
        return n;
    }
}

int main()
{
    osg::ref_ptr<osgViewer::Viewer> viewer = new osgViewer::Viewer;
    osg::ref_ptr<osg::Group> root = new osg::Group;
    osg::ref_ptr<osg::Node>node = osgDB::readNodeFile("F://C++代码//CaptureTest//tio//osg_vertex_visitor_test//model2.ive");
    root->addChild(node);
    osg::ref_ptr<osg::GraphicsContext::Traits> traits = new osg::GraphicsContext::Traits;
    {
        traits->x = 0;
        traits->y = 0;
        traits->width = 1920;
        traits->height = 1080;
        //支持窗口扩展,默认是不支持的
        traits->windowDecoration = true;
        //支持双缓存,默认不支持
        traits->doubleBuffer = true;
        traits->sharedContext = 0;
        traits->red = 8;
        traits->blue = 8;
        traits->green = 8;
        //支持alpha,默认不支持为0,这里改为支持,使截出来的图片具有alpha值
        traits->alpha = 8;

        osg::ref_ptr<osg::GraphicsContext> gc = osg::GraphicsContext::createGraphicsContext(traits.get());
        if (gc.valid())
        {
            std::cout << "create gc success" << std::endl;
        }
        double fovy, aspectRatio, zNear, zFar;
        viewer->getCamera()->getProjectionMatrixAsPerspective(fovy, aspectRatio, zNear, zFar);
        double newAspectRatio = double(traits->width) / double(traits->height);
        double aspectRatioChange = newAspectRatio / aspectRatio;
        if (aspectRatioChange != 1.0)
        {
            viewer->getCamera()->getProjectionMatrix() *= osg::Matrix::scale(1.0 / aspectRatioChange, 1.0, 1.0);
        }
        viewer->getCamera()->setViewport(0, 0, 1920, 1080);
        viewer->getCamera()->setClearColor(osg::Vec4(1, 1, 1, 0));
        viewer->setCameraManipulator(track);
        viewer->getCamera()->setGraphicsContext(gc.get());
        osgUtil::Optimizer optimizer;
        optimizer.optimize(root.get());

        viewer->setSceneData(root.get());
        viewer->realize();
        viewer->getCamera()->setFinalDrawCallback(new CaptureCallback());
    }
    {
        const osg::BoundingSphere bs = node->getBound();
        std::cout << "NodeRadius: " << bs.radius() << std::endl;
        //设置getTextureDistance以后开始使用贴图
        //float getTextureDistance = 1000000.0f;
        float getTextureDistance = bs.radius() * 25;
        osg::Vec3 viewDirection[2600];
        center = bs.center();
        //读取拍照点,并求up值集合
        {
            std::ifstream file;
            int LINES;
            char filename[100] = "shotEye258.txt";
            file.open(filename, std::ios::in);
            if (file.fail())
            {
                std::cout << "文件不存在." << std::endl;
                file.close();
            }
            else//文件存在  
            {
                LINES = CountLines(filename);
                while (LINES--) //读取数据到数组  
                {
                    float a, b, c;
                    file >> a;
                    file >> b;
                    file >> c;
                    viewDirection[++captureAngelCount].set(a, b, c);
                }
            }

            file.close();

            for (int i = 1; i <= captureAngelCount; i++)
            {
                shotEye[i] = center + viewDirection[i] * getTextureDistance;
            }
            int cnt = 0;
            for (int i = 1; i <= captureAngelCount; i++)
            {
                osg::Vec3 temp = center - shotEye[i];
                //如果与X轴平行,那么与Y轴叉乘

                if ((temp^osg::Vec3(1, 0, 0)) == osg::Vec3(0, 0, 0))
                {
                    cnt++;
                    shotup[i] = temp^osg::Vec3(0, 1, 0);
                    shotup[i].normalize();
                }
                else
                {
                    shotup[i] = temp^osg::Vec3(1, 0, 0);
                    shotup[i].normalize();
                }
            }

        }
    }
    static int cnt = 1;
    
    
        for (; cnt <= captureAngelCount; cnt++)
        {
            track->setByInverseMatrix(osg::Matrix::lookAt(shotEye[cnt], center, shotup[cnt]));
            viewer->frame();
            //Sleep(100);
            
        }
    return 0;
}

 

posted @ 2017-10-30 10:50  唐淼  阅读(2356)  评论(0编辑  收藏  举报