osg系列文章目录
文章目录
- osg系列文章目录
- 前言
- 二、使用步骤
前言
OSG(OpenSceneGraph)多视图多窗⼝渲染,在不同的窗口渲染不同的场景,实现不知道有什么用的多窗口渲染有两种情况:
1.多个不同的窗口渲染完全不同,相互独立的场景
2.多个窗口渲染一个场景的不同部分
二、使用步骤
1.第一种情况代码
多个不同的窗口渲染完全不同,相互独立的场景
#include "osg/Node"
#include "osg/Geode"
#include "osg/Geometry"
#include "osg/Group"
#include "osg/MatrixTransform" //移动节点的矩阵类,最常⽤的移动节点的类。可随动、旋转控制节点
#include "osg/PositionAttitudeTransform" //位置变换节点类,提供模型的位置变换、⼤⼩缩放、原点位置的设置、坐标系的变换
#include "osg/Camera" //相机节点,管理OSG中的模型——视图矩阵,相机的管理主要是通过各种变换实现的
#include "osgDB/ReadFile"
#include "osgDB/WriteFile"
#include "osgUtil/Optimizer"
#include "osgViewer/Viewer"
#include "osgViewer/CompositeViewer" //多视图的管理,负责多个视图的管理及同步
#include<osgUtil/Optimizer>
#include<osg/StateSet>
#include<osg/TexGen>
#include <osgViewer/ViewerEventHandlers> //事件监听
#include <osgGA/StateSetManipulator> //事件响应类,对渲染状态进行控制
#include <osgUtil/Simplifier> //简化几何体
#include <osgUtil/DelaunayTriangulator>
osg::ref_ptr<osgViewer::Viewer> MultipleView(osg::ref_ptr<osg::Node> node, int i)
{
int xoffset = 50;
int yoffset = 200;
//设置图形环境特性
osg::ref_ptr<osg::GraphicsContext::Traits> traits = new osg::GraphicsContext::Traits();
//两个视图窗⼝的横坐标位置不同,否则会重叠
if (i == 1)
{
traits->x = xoffset + 0;
}
else
{
traits->x = xoffset + 600;
}
traits->y = yoffset + 0;
traits->width = 600;
traits->height = 480;
traits->windowDecoration = true;
traits->doubleBuffer = true;
traits->sharedContext = 0;
//创建视图
osg::ref_ptr<osgViewer::Viewer> viewer = new osgViewer::Viewer();
//创建相机
osg::ref_ptr<osg::Camera> camera = viewer->getCamera();
//创建图形环境特性
osg::ref_ptr<osg::GraphicsContext> gc = osg::GraphicsContext::createGraphicsContext(traits.get());
//设置图形环境
camera->setGraphicsContext(gc.get());
//设置视⼝
camera->setViewport(new osg::Viewport(0, 0, traits->width, traits->height));
//设置缓冲
GLenum buffer = traits->doubleBuffer ? GL_BACK : GL_FRONT;
//设置缓冲区(设置每帧开始绘制时,绘制哪个缓存)
camera->setDrawBuffer(buffer);
camera->setReadBuffer(buffer);
//设置场景数据
viewer->setSceneData(node.get());
return viewer.get();
}
int main()
{
//读取模型,分别作为两个视图的节点
osg::ref_ptr<osg::Node> cow = osgDB::readNodeFile("cessnafire.osg");
osg::ref_ptr<osg::Node> cessna = osgDB::readNodeFile("skydome.osgt");
//关联纹理
osg::ref_ptr<osg::Image> image = osgDB::readImageFile("texture.jpg");
if (image.get())
{
osg::ref_ptr<osg::Texture2D> texture = new osg::Texture2D();
texture->setImage(image.get());
//设置自动生成纹理坐标
osg::ref_ptr<osg::TexGen> texgen = new osg::TexGen();
texgen->setMode(osg::TexGen::SPHERE_MAP);
//设置纹理环境,模式为BLEND
osg::ref_ptr<osg::TexEnv> texenv = new osg::TexEnv;
texenv->setMode(osg::TexEnv::Mode::BLEND);// ADD
texenv->setColor(osg::Vec4(0.6, 0.6, 0.6, 0.0));
//启动单元一自动生成纹理坐标,并使用纹理
osg::ref_ptr<osg::StateSet> state = new osg::StateSet;
state->setTextureAttributeAndModes(1, texture.get(), osg::StateAttribute::ON);
state->setTextureAttributeAndModes(1, texgen.get(), osg::StateAttribute::ON);
state->setTextureAttribute(0, texenv.get());
cow->setStateSet(state.get());
}
else
{
std::cout << "Unable to load data file Exiting." << std::endl;
}
/*cow.release();*/
//优化场景数据
osgUtil::Optimizer optimizer;
optimizer.optimize(cow.get());
optimizer.optimize(cessna.get());
//创建两个视图
osg::ref_ptr<osgViewer::Viewer> viewer1 = MultipleView(cow, 1);
osg::ref_ptr<osgViewer::Viewer> viewer2 = MultipleView(cessna, 2);
//创建⼀个CompositeViewer对象
osg::ref_ptr<osgViewer::CompositeViewer> viewer = new osgViewer::CompositeViewer();
//添加视图
viewer->addView(viewer1.get());
viewer->addView(viewer2.get());
viewer->realize();
return viewer->run();
}
第二种情况代码
#include <osgDB/ReadFile>
#include <osgDB/WriteFile>
#include <osgViewer/Viewer>
#include <osgGA/TrackballManipulator>
#include <osgGA/FlightManipulator>
#include <osgGA/AnimationPathManipulator>
#include <iostream>
//实现多窗口渲染
void multipleWindowMultipleCameras(osgViewer::Viewer& viewer, bool multipleScreens)
{
osg::GraphicsContext::WindowingSystemInterface* wsi = osg::GraphicsContext::getWindowingSystemInterface();
unsigned int width, height; wsi->getScreenResolution(osg::GraphicsContext::ScreenIdentifier(0), width, height);
//窗口数量
unsigned int numCameras = 6;
//缩放比率
double aspectRatioScale = (double)numCameras;
double translate_x = double(numCameras)-1;
//创建六个图形上下文
for(unsigned int i=0; i<numCameras;++i, translate_x -= 2.0)
{
osg::ref_ptr<osg::GraphicsContext::Traits> traits = new osg::GraphicsContext::Traits;
traits->screenNum = multipleScreens ? i / 3 : 0;
traits->x = (i*width)/numCameras;
traits->y = 0;
traits->width = width / numCameras - 1;
traits->height = height;
//这个设置窗口要有边框修饰,否则不设置边框
traits->windowDecoration = true;
traits->doubleBuffer = true;
traits->sharedContext = 0;
osg::ref_ptr<osg::GraphicsContext> gc = osg::GraphicsContext::createGraphicsContext(traits.get());
//每一个对应一个窗口
osg::ref_ptr<osg::Camera> camera = new osg::Camera;
camera->setGraphicsContext(gc.get());
camera->setViewport(new osg::Viewport(0,0, width/numCameras, height));
GLenum buffer = traits->doubleBuffer ? GL_BACK : GL_FRONT;
camera->setDrawBuffer(buffer); camera->setReadBuffer(buffer);
viewer.addSlave(camera.get(), osg::Matrix::scale(aspectRatioScale, 1.0, 1.0)*osg::Matrix::translate(translate_x, 0.0, 0.0), osg::Matrix() );
}
}
int main( int argc, char **argv )
{
osgViewer::Viewer viewer ;
multipleWindowMultipleCameras(viewer, false);
viewer.setSceneData(osgDB::readNodeFile("glider.osg"));
viewer.realize();
viewer.run();
return 0;
}
运行效果
第一种情况,2个窗口完全独立,相互不影响
第二种情况,多个窗口渲染同一个场景的不同部分
源码下载
源码下载地址