小白学习记录
先贴几个之前看到很有帮助的博客:
(1)建议学习看完这个博主的文章,很有帮助,这里踩了个坑原本我用的是QGLWidget看了后换QOpenGLWidget
https://blog.csdn.net/qq21497936/article/details/94585803
(2)这里介绍了如何使用QOpenGLWidget,感谢大佬的分享
https://blog.csdn.net/qq_34719188/article/details/92806907
https://vicrucann.github.io/tutorials/cmake-qt-osg-1/
由于网上的资料杂七杂八,找了一堆感觉就上面的有实质性帮助
1、环境
(1)这里我用的osg3.0.0是由于项目中部分配置原因,跟最新版本不兼容,所以没有使用最新版本。
注意:由于osg最新版里生成qt相关的库,需要自己去GitHub上下载回来,然后cmake编译。
(2)这里qt5.14.2,就正常安装并结合到vs2017上即可,网上资料很多没啥好说的。
2、项目
在vs里面新建一个qt项目
项目建好后包含下osg的包含目录库目录等等(正常osg项目的过程)
源码:5部分main.cpp QtOSGWidget.h QtOSGWidget.cpp QtOSGWidget_1.h QtOSGWidget_1.cpp
QtOSGWidget_1.h 项目头文件包含绘图部分的函数
#pragma once
#include <QtWidgets/QMainWindow>
#include "ui_QtOSGWidget_1.h"
class QtOSGWidget_1 : public QMainWindow
{
Q_OBJECT
public:
QtOSGWidget_1(QWidget *parent = Q_NULLPTR);
//过滤器
bool eventFilter(QObject*, QEvent*);
//绘图事件
void paintEvent();
private:
Ui::QtOSGWidget_1Class ui;
};
QtOSGWidget.h 这是osg使用QOpenGLWidget绘制
#pragma once
#include<Windows.h>
#include<iostream>
#include<qapplication.h>
#include<qopenglwidget.h>
#include<qdesktopwidget.h>
#include<qwidget.h>
#include<qmouseevent.h>
#include<qdesktopwidget.h>
#include<qscreen.h>
#include<qglobal.h>
#include<qwindow.h>
#include<qlabel.h>
#include<osg/ref_ptr>
#include<osgViewer/Viewer>
#include<osgViewer/GraphicsWindow>
#include<osg/Camera>
#include<osg/ShapeDrawable>
#include<osg/StateSet>
#include<osg/Material>
#include<osgGA/EventQueue>
#include<osgGA/TrackballManipulator>
#include<osgDB/ReadFile>
class QtOSGWidget : public QOpenGLWidget
{
public:
QtOSGWidget(QWidget *parent = Q_NULLPTR );
/*
QtOSGWidget(QWidget *parent = 0) : QOpenGLWidget(parent), _mGraphicsWindow(new osgViewer::GraphicsWindowEmbedded(this->x(), this->y(),
this->width(), this->height())), _mViewer(new osgViewer::Viewer)
// take care of HDPI screen, e.g. Retina display on Mac
, m_scale(QApplication::desktop()->devicePixelRatio())
{
osg::Cylinder *cylinder = new osg::Cylinder(osg::Vec3(0.f, 0.f, 0.f), 0.25f, 0.5f);
osg::ShapeDrawable *sd = new osg::ShapeDrawable(cylinder);
sd->setColor(osg::Vec4(0.8f, 0.5f, 0.2f, 1.f));
osg::ref_ptr<osg::Node> node = osgDB::readNodeFile("glider.osg");
osg::Geode *geode = new osg::Geode;
geode->addDrawable(sd);
osg::Camera *camera = new osg::Camera;
camera->setViewport(0, 0, this->width(), this->height());
camera->setClearColor(osg::Vec4(0.2f, 0.2f, 0.4f, 0.0f));
float aspectRatio = static_cast<float>(this->width()) / static_cast<float>(this->height());
camera->setProjectionMatrixAsPerspective(30.f, aspectRatio, 1.f, 1000.f);
camera->setGraphicsContext(_mGraphicsWindow);
_mViewer->setCamera(camera);
_mViewer->setSceneData(node.get());
osgGA::TrackballManipulator *manipulator = new osgGA::TrackballManipulator;
manipulator->setAllowThrow(false);
this->setMouseTracking(true);
_mViewer->setCameraManipulator(manipulator);
_mViewer->setThreadingModel(osgViewer::Viewer::SingleThreaded);
_mViewer->realize();
}
*/
virtual ~QtOSGWidget() {}
protected:
virtual void paintGL() {
_mViewer->frame();
}
virtual void resizeGL(int width, int height) {
this->getEventQueue()->windowResize(this->x()*m_scale, this->y() * m_scale, width * m_scale, height * m_scale);
_mGraphicsWindow->resized(this->x()*m_scale, this->y() * m_scale, width * m_scale, height * m_scale);
osg::Camera *camera = _mViewer->getCamera();
camera->setViewport(0, 0, this->width()*m_scale, this->height()* m_scale);
}
virtual void initializeGL() {
osg::Geode *geode = dynamic_cast<osg::Geode *>(_mViewer->getSceneData());
osg::StateSet *stateSet = geode->getOrCreateStateSet();
osg::Material *material = new osg::Material;
material->setColorMode(osg::Material::AMBIENT_AND_DIFFUSE);
stateSet->setAttributeAndModes(material, osg::StateAttribute::ON);
stateSet->setMode(GL_DEPTH_TEST, osg::StateAttribute::ON);
}
virtual void mouseMoveEvent(QMouseEvent *event) {
this->getEventQueue()->mouseMotion(event->x()*m_scale, event->y()*m_scale);
}
virtual void mousePressEvent(QMouseEvent *event) {
unsigned int button = 0;
switch (event->button()) {
case Qt::LeftButton:
button = 1;
break;
case Qt::MiddleButton:
button = 2;
break;
case Qt::RightButton:
button = 3;
break;
default:
break;
}
this->getEventQueue()->mouseButtonPress(event->x()*m_scale, event->y()*m_scale, button);
}
virtual void mouseReleaseEvent(QMouseEvent *event) {
unsigned int button = 0;
switch (event->button()) {
case Qt::LeftButton:
button = 1;
break;
case Qt::MiddleButton:
button = 2;
break;
case Qt::RightButton:
button = 3;
break;
default:
break;
}
this->getEventQueue()->mouseButtonRelease(event->x()*m_scale, event->y()*m_scale, button);
}
virtual void wheelEvent(QWheelEvent *event) {
int delta = event->delta();
osgGA::GUIEventAdapter::ScrollingMotion motion = delta > 0 ?
osgGA::GUIEventAdapter::SCROLL_UP : osgGA::GUIEventAdapter::SCROLL_DOWN;
this->getEventQueue()->mouseScroll(motion);
}
virtual bool event(QEvent *event) {
bool handled = QOpenGLWidget::event(event);
this->update();
return handled;
}
private:
osgGA::EventQueue *getEventQueue() const {
osgGA::EventQueue *eventQueue = _mGraphicsWindow->getEventQueue();
return eventQueue;
}
osg::ref_ptr<osgViewer::GraphicsWindowEmbedded> _mGraphicsWindow;
osg::ref_ptr<osgViewer::Viewer>_mViewer;
qreal m_scale;
};
QtOSGWidget.cpp
#include<QtOSGWidget.h>
QtOSGWidget::QtOSGWidget(QWidget *parent) : QOpenGLWidget(parent), _mGraphicsWindow(new osgViewer::GraphicsWindowEmbedded(this->x(), this->y(),
this->width(), this->height())), _mViewer(new osgViewer::Viewer), m_scale(QApplication::desktop()->devicePixelRatio())
{
osg::Cylinder *cylinder = new osg::Cylinder(osg::Vec3(0.f, 0.f, 0.f), 0.25f, 0.5f);
osg::ShapeDrawable *sd = new osg::ShapeDrawable(cylinder);
sd->setColor(osg::Vec4(0.8f, 0.5f, 0.2f, 1.f));
osg::ref_ptr<osg::Node> node = osgDB::readNodeFile("glider.osg");
osg::Geode *geode = new osg::Geode;
geode->addDrawable(sd);
osg::Camera *camera = new osg::Camera;
camera->setViewport(0, 0, this->width(), this->height());
camera->setClearColor(osg::Vec4(0.2f, 0.2f, 0.4f, 0.0f));
float aspectRatio = static_cast<float>(this->width()) / static_cast<float>(this->height());
camera->setProjectionMatrixAsPerspective(30.f, aspectRatio, 1.f, 1000.f);
camera->setGraphicsContext(_mGraphicsWindow);
_mViewer->setCamera(camera);
_mViewer->setSceneData(node.get());
osgGA::TrackballManipulator *manipulator = new osgGA::TrackballManipulator;
manipulator->setAllowThrow(false);
this->setMouseTracking(true);
_mViewer->setCameraManipulator(manipulator);
_mViewer->setThreadingModel(osgViewer::Viewer::SingleThreaded);
_mViewer->realize();
}
QtOSGWidget_1.cpp
#include "QtOSGWidget_1.h"
#include<QtOSGWidget.h>
#include<qpainter.h>
QtOSGWidget_1::QtOSGWidget_1(QWidget *parent)
: QMainWindow(parent)
{
ui.setupUi(this);
QtOSGWidget *osgwidget = new QtOSGWidget();
QWidget *CentralWidget = new QWidget();//主窗口
osgwidget->setParent(CentralWidget);
osgwidget->setGeometry(0, 0, 900, 700);
ui.widget->setParent(CentralWidget);//绘制窗口
ui.widget->setGeometry(200, 200, 100, 100);
//开始绘制
ui.widget->installEventFilter(this);
ui.widget->raise();
resize(900, 700);
setCentralWidget(CentralWidget);
}
//*
bool QtOSGWidget_1::eventFilter(QObject *watched, QEvent *event)
{
if (watched == ui.widget && event->type() == QEvent::Paint)
{
paintEvent();//响应函数
}
return QWidget::eventFilter(watched, event);
}
void QtOSGWidget_1::paintEvent()
{
//实例化画家对象 this指定的是绘图设备
QPainter painter(ui.widget);
//设置画笔
QPen pen(QColor(255, 0, 0));
//这是画笔宽度
pen.setWidth(3);
//设置画笔的风格
pen.setStyle(Qt::DotLine);
//让画家使用这个画笔
painter.setPen(pen);
//设置画刷
QBrush brush(Qt::cyan);
//设置画刷风格
brush.setStyle(Qt::Dense1Pattern);
//让画家使用画刷
painter.setBrush(brush);
//画线
painter.drawLine(QPoint(0, 0), QPoint(100, 100));
//画圆,椭圆
painter.drawEllipse(QPoint(100, 100), 50, 50);
//画矩形
painter.drawRect(QRect(20, 20, 50, 50));
//画文字
painter.drawText(QRect(10, 200, 150, 50), "好好学习,天天向上");
}
//*/
main.cpp
#include "QtOSGWidget_1.h"
#include <QtWidgets/QApplication>
#include<QtOSGWidget.h>
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
QtOSGWidget_1 w;
w.show();
return a.exec();
}
效果