OSG嵌入Qt窗口中+实时渲染数据输出

14 篇文章 5 订阅
5 篇文章 3 订阅
本文介绍了如何在Qt中使用OSG创建一个可定制的3D窗口,包括窗口基类的实现、QGLWidget的重写以及关键函数如initializeGL和paintGL的定制。展示了如何加载模型和实现像素操作以实现实时更新。
摘要由CSDN通过智能技术生成

实现方式
1、首先设置一个Qt下的一个窗口基类;
2、窗口基类继承自一个重写的QGLWidget类和一个osgViewer::Viewer类
3、重新QGLWidget类,实现OSG在windows窗口的使能。
4、更新窗口继承类,重写构造函数和virtual void initializeGL();
virtual void paintGL();函数。
窗口基类

#ifndef QTOSGVRWIDGET_H
#define QTOSGVRWIDGET_H

#include <QTimer>
#include "qtosgviewerwidget.h"
#include "Include.h"

class QtOSGVRWidget : public QtOSGViewerWidget, public osgViewer::Viewer
{
public:
	~QtOSGVRWidget();
	QtOSGVRWidget(QWidget * parent = 0, const char * name = 0, const QGLWidget * shareWidget = 0, WindowFlags f = 0):
	QtOSGViewerWidget(parent, name, shareWidget, f)
	{
		getCamera()->setViewport(new osg::Viewport(0,0,width(),height()));
		getCamera()->setProjectionMatrixAsPerspective(30.0f, static_cast<double>(width())/static_cast<double>(height()), 1.0f, 10000.0f);
		getCamera()->setGraphicsContext(getGraphicsWindow());
		setThreadingModel(osgViewer::Viewer::SingleThreaded);
		connect(&m_timer, SIGNAL(timeout()), this, SLOT(updateGL()));
		m_timer.start(10);
	}
private:
	virtual void initializeGL();
	virtual void paintGL();
private:

	std::fstream myfile1;
	std::fstream myfile;

	QTimer m_timer;

	unsigned char *buf;
	unsigned char *buftrtr;

	unsigned short *buf1;
	unsigned short *buf2;

};

#endif // QTOSGVRWIDGET_H

#include "qtosgvrwidget.h"

QtOSGVRWidget::~QtOSGVRWidget()
{
	myfile1.close();
	myfile.close();
}

void QtOSGVRWidget::initializeGL()
{
	glClearColor(1.0, 0.2, 0.3, 1.0);

	glShadeModel(GL_SMOOTH);
	glEnable(GL_DEPTH);

	this->setMaximumSize(512, 512);
	this->setMinimumSize(512, 512);

	buf = new unsigned char[width()*height()*3];
	buftrtr = new unsigned char[width()*height()*3];

	buf1 = new unsigned short[width()*height()];
	buf2 = new unsigned short[width()*height()];

	
	myfile1.open("F-22-hei.raw", std::ios::binary | std::ios::out | std::ios::app);
	
	myfile.open("F-22.raw", std::ios::binary | std::ios::out | std::ios::app);
}

void QtOSGVRWidget::paintGL()
{
	glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);//清除屏幕和深度缓存
	glLoadIdentity();

	frame();

#if 1
	int w = width();
	int h = height();
	
	glReadPixels(0, 0, width(), height(), GL_RGB, GL_UNSIGNED_BYTE, buf);
	for (int i = 0; i < width()*height()*3; i++)
	{
		buftrtr[i] = buf[width()*height()*3-1-i];
	}

	for (int i = 0; i < width()*height()*3 - 3; )
	{
		if (i < width()*height()*3 - 3)
		{
			unsigned char tmp1 = buftrtr[i];
			unsigned char tmp2 = buftrtr[i+1];
			unsigned char tmp3 = buftrtr[i+2];

			buftrtr[i] = tmp3;
			buftrtr[i+1] = tmp2;
			buftrtr[i+2] = tmp1;

			i+=3;
		}
		
	}

	
	myfile.write((char*)buftrtr, width()*height()*3);
	

	//delete []buf;
	//buf = nullptr;

	
	glReadPixels(0, 0, width(), height(), GL_RED, GL_UNSIGNED_SHORT, buf1);
	
	for (int i = 0; i < width()*height(); i++)
	{
		buf2[i] = buf1[width()*height()-1-i];
	}
	
	
	myfile1.write((char*)buf2, width()*height()*2);
	
#endif

	//delete []buf1;
	//buf1 = nullptr;
}


重写的QGLWidget类

#ifndef QTOSGVIEWERWIDGET_H
#define QTOSGVIEWERWIDGET_H

#include <QGLWidget>
#include "Include.h"

using Qt::WindowFlags;

class QtOSGViewerWidget : public QGLWidget
{
	Q_OBJECT

public:
	QtOSGViewerWidget(QWidget *parent);
	QtOSGViewerWidget(QWidget * parent = 0, const char * name = 0, const QGLWidget * shareWidget = 0, WindowFlags f = 0);
	~QtOSGViewerWidget();
	osgViewer::GraphicsWindow* getGraphicsWindow();
	const osgViewer::GraphicsWindow* getGraphicsWindow() const;
private:
	virtual void initializeGL();
	virtual void resizeGL( int width, int height );
	virtual void paintGL();
private:
	osg::ref_ptr<osgViewer::GraphicsWindowEmbedded> m_gw;
};

#endif // QTOSGVIEWERWIDGET_H

#include "qtosgviewerwidget.h"

QtOSGViewerWidget::QtOSGViewerWidget(QWidget *parent)
	: QGLWidget(parent)
{

}

QtOSGViewerWidget::QtOSGViewerWidget(QWidget * parent /*= 0*/, const char * name /*= 0*/, const QGLWidget * shareWidget /*= 0*/, WindowFlags f /*= 0*/)
{
	m_gw = new osgViewer::GraphicsWindowEmbedded(0,0,width(),height());
	setFocusPolicy(Qt::ClickFocus);
}

QtOSGViewerWidget::~QtOSGViewerWidget()
{
}

osgViewer::GraphicsWindow* QtOSGViewerWidget::getGraphicsWindow()
{
	return m_gw.get();
}

const osgViewer::GraphicsWindow* QtOSGViewerWidget::getGraphicsWindow() const
{
	return m_gw.get();
}

void QtOSGViewerWidget::initializeGL()
{
	glClearColor(1.0, 0.2, 0.3, 1.0);
	glShadeModel(GL_SMOOTH);
	glEnable(GL_DEPTH);
}

void QtOSGViewerWidget::resizeGL(int width, int height)
{
	m_gw->getEventQueue()->windowResize(0, 0, width, height );
	m_gw->resized(0,0,width,height);
}

void QtOSGViewerWidget::paintGL()
{

}

嵌入Qt窗口

#ifndef QTMYOSGWIDGET_H
#define QTMYOSGWIDGET_H

#include <QWidget>
#include "qtosgvrwidget.h"
#include "SkyModel.h"
#include "MyNodeCallback.h"
#include "ui_qtmyosgwidget.h"

class QtMyOSGWidget : public QWidget
{
	Q_OBJECT

public:
	QtMyOSGWidget(QWidget *parent = 0);
	~QtMyOSGWidget();

private:
	Ui::QtMyOSGWidget ui;
	CMyNodeCallback *m_pmyNode;
};

#endif // QTMYOSGWIDGET_H

#include <QGridLayout>
#include "MyOSGCamera.h"
#include "MyNodeCallback.h"
#include "qtmyosgwidget.h"

QtMyOSGWidget::QtMyOSGWidget(QWidget *parent)
	: QWidget(parent)
{
	ui.setupUi(this);

	QtOSGVRWidget *myVROSG = new QtOSGVRWidget;
	osg::ref_ptr<osg::Node> loadedModel = osgDB::readNodeFile("F-22.ive");
	osg::ref_ptr<osg::Node> myF35Node = osgDB::readNodeFile("F35IR.ive");
	//设置初始位置
	osg::ref_ptr<osg::PositionAttitudeTransform> chposF35 = new osg::PositionAttitudeTransform;
	osg::Quat quat(osg::DegreesToRadians(30.0), osg::Y_AXIS);	
	//姿态
	chposF35->setAttitude(quat);
	chposF35->addChild(myF35Node.get());
	//位置
	chposF35->setPosition(osg::Vec3(0, 0, 0));
	chposF35->setName("F-35");
	
	//加入天空盒子
	CSkyBox mysky;
	osg::ref_ptr<osg::Node> myNodesky = mysky.createSkyBox();
	//设置初始位置
	osg::ref_ptr<osg::PositionAttitudeTransform> chposSkyBox = new osg::PositionAttitudeTransform;
	//姿态
	chposSkyBox->addChild(myNodesky.get());
	//chposSkyBox->setPosition(osg::Vec3(10, 10, 10));
	chposSkyBox->setName("skybox");


	osg::ref_ptr<osg::Group> myroot = new osg::Group;
	myroot->addChild(loadedModel);
	//加入根节点
	myroot->addChild(chposF35.get());
	//加入根节点
	myroot->addChild(myNodesky.get());
	myVROSG->setCameraManipulator(new MyOSGCamera);

	m_pmyNode = new CMyNodeCallback();
	myroot->addEventCallback(m_pmyNode);

	myVROSG->setSceneData(myroot.get());
	
	QGridLayout *playout = new QGridLayout;
	playout->addWidget(myVROSG);
	setLayout(playout);
}

QtMyOSGWidget::~QtMyOSGWidget()
{

}

//可以把此处多余的编译的头文件去掉,不影响编译

include.h

#pragma once
#include <osg/Node>
#include <osg/Group>
#include <osg/Geometry>
#include <osg/Geode>
#include <osg/ShapeDrawable>
#include <osg/CullFace>
#include <osg/Polytope>
#include <osg/BlendFunc>
#include <osg/AlphaFunc>
#include <osg/Matrixd>
#include <osg/Matrix>
#include <osg/MatrixTransform>
#include <osg/AutoTransform>
#include <osg/PositionAttitudeTransform>
#include <osg/Material>
#include <osg/TexGen>
#include <osg/Light>
#include <osg/LightSource>
#include <osg/BoundingSphere>
#include <osg/BoundingBox>
#include <osg/Fog>
#include <osg/StateAttribute>
#include <osg/Point>
#include <osg/LineSegment>
#include <osg/TextureCubeMap>
#include <osg/TexGen>
#include <osg/ComputeBoundsVisitor>
#include <osgViewer/Viewer>
#include <osgViewer/ViewerEventHandlers>
#include <osgViewer/GraphicsWindow>
#include <osgViewer/CompositeViewer>
#include <osgViewer/ViewerEventHandlers>
#include <osgGA/GUIEventAdapter>
#include <osgGA/CameraManipulator>
#include <osgGA/StateSetManipulator>
#include <osgGA/TrackballManipulator>
#include <osgGA/MultiTouchTrackballManipulator>
#include <osgDB/ReadFile>
#include <osgDB/Registry>
#include <osgText/Text>
#include <osgWidget/WindowManager>
#include <osgWidget/Box>
#include <osgWidget/Table>
#include <osgWidget/Label>
#include <osgParticle/PrecipitationEffect>
#include <osgUtil/SmoothingVisitor>
#include <osgUtil/Optimizer>
#include <osgUtil/IntersectionVisitor>
#include <osgUtil/PolytopeIntersector>
#include <osgQt/Export>
#include <osgQt/GraphicsWindowQt>
#include <osgQt/QFontImplementation>
#include <osgQt/QGraphicsViewAdapter>
#include <osgQt/QWidgetImage>

#ifdef _DEBUG
#pragma comment(lib, "osgd.lib")
#pragma comment(lib, "osgDBd.lib")
#pragma comment(lib, "osgViewerd.lib")
#pragma comment(lib, "OpenThreadsd.lib")
#pragma comment(lib, "osgGAd.lib")
#pragma comment(lib, "osgUtild.lib")
#pragma comment(lib, "osgTextd.lib")
#pragma comment(lib, "osgWidgetd.lib")
#pragma comment(lib, "glu32.lib") 
#pragma comment(lib, "opengl32.lib")
#pragma comment(lib, "osgShadowd.lib")
#pragma comment(lib, "osgAnimationd.lib")
#pragma comment(lib, "osgParticled.lib")
#pragma comment(lib, "osgQtd.lib")
#else
#pragma comment(lib, "osg.lib")
#pragma comment(lib, "osgDB.lib")
#pragma comment(lib, "osgViewer.lib")
#pragma comment(lib, "OpenThreads.lib")
#pragma comment(lib, "osgGA.lib")
#pragma comment(lib, "osgUtil.lib")
#pragma comment(lib, "osgText.lib")
#pragma comment(lib, "osgWidget.lib")
#pragma comment(lib, "glu32.lib") 
#pragma comment(lib, "opengl32.lib")
#pragma comment(lib, "osgShadow.lib")
#pragma comment(lib, "osgAnimation.lib")
#pragma comment(lib, "osgParticle.lib")
#pragma comment(lib, "osgQt.lib")
#endif

运行效果图:
在这里插入图片描述

评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值