OSG(OpenSceneGraph)多视图多窗⼝渲染

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个窗口完全独立,相互不影响
在这里插入图片描述

在这里插入图片描述

第二种情况,多个窗口渲染同一个场景的不同部分

在这里插入图片描述

源码下载

源码下载地址

猜你喜欢

转载自blog.csdn.net/aoxuestudy/article/details/125277674