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