zoukankan      html  css  js  c++  java
  • 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++;
            }
            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;
    }
  • 相关阅读:
    PIC基础学习3
    增强WebClient的同步下载功能
    同步模式下的端口映射程序
    .Net并行库介绍——Parallel
    写了一个测试正则表达式的小工具
    Windows 7下的虚拟光驱
    昨天发的一篇帖子竟然上了60天点击排行榜了
    .Net中的Junction Points操作
    在技嘉主板上实现USB启动
    正则表达式测试工具原型完成
  • 原文地址:https://www.cnblogs.com/tangmiao/p/7753539.html
Copyright © 2011-2022 走看看