实现方式
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
运行效果图: