vs2017 实现 Qt + OSG 并在osg上用qpainter画图

小白学习记录

先贴几个之前看到很有帮助的博客:

(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();
}

效果

 

  • 0
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
使用VS2019编译OSG 3.7.0、OSGEarth 3.3和OSGQt需要按照以下步骤进行操作: 1. 首先,确保你已经安装了Visual Studio 2019。可以从官方网站上下载并按照指南进行安装。 2. 接下来,下载OSG 3.7.0的源代码。可以从OSG的官方网站上找到源代码的下载链接。 3. 在Visual Studio 2019中创建一个新的空白项目。选择合适的项目类型,例如Win32控制台应用程序。 4. 将下载的OSG 3.7.0源代码解压缩到项目文件夹中。在Visual Studio 2019中添加这些源代码文件到项目中。 5. 打开项目的属性窗口。在“配置属性”部分,选择“所有配置”和“所有平台”,然后选择“C/C++”项。 6. 添加OSG的头文件目录和库文件目录到“附加包含目录”和“附加库目录”中。 7. 编译项目,并确保没有错误或警告。 8. 下载OSGEarth 3.3的源代码。可以从OSGEarth的官方网站上找到源代码的下载链接。 9. 将下载的OSGEarth 3.3源代码解压缩到项目文件夹中。在Visual Studio 2019中添加这些源代码文件到项目中。 10. 打开项目的属性窗口。在“配置属性”部分,选择“所有配置”和“所有平台”,然后选择“C/C++”项。 11. 添加OSGEarth的头文件目录和库文件目录到“附加包含目录”和“附加库目录”中。 12. 编译项目,并确保没有错误或警告。 13. 最后,下载OSGQt的源代码。可以从OSGQt的官方网站上找到源代码的下载链接。 14. 将下载的OSGQt源代码解压缩到项目文件夹中。在Visual Studio 2019中添加这些源代码文件到项目中。 15. 打开项目的属性窗口。在“配置属性”部分,选择“所有配置”和“所有平台”,然后选择“C/C++”项。 16. 添加OSGQt的头文件目录和库文件目录到“附加包含目录”和“附加库目录”中。 17. 编译项目,并确保没有错误或警告。 以上是使用VS2019编译OSG 3.7.0、OSGEarth 3.3和OSGQt的大致步骤。请根据具体环境和需求进行相应的设置和调整。如果出现问题,可以参考相关的文档和论坛进行进一步的解决。
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值