osgQt创建场景数据并显示
一、流程
使用 osgQt 创建并显示场景的核心流程:
1、配置Qt项目配置(*.pro文件)
QT += core gui opengl widgets
LIBS += -losg -losgQt -losgViewer -losgGA -losgDB
2、创建场景数据。
osg::Node* createCube() {
osg::ref_ptr<osg::Geode> geode = new osg::Geode;
osg::ref_ptr<osg::Geometry> geometry = new osg::Geometry;
// 定义8个顶点(立方体)
osg::Vec3Array* vertices = new osg::Vec3Array;
vertices->push_back(osg::Vec3(-1.0f, -1.0f, 1.0f)); // 前左下
vertices->push_back(osg::Vec3( 1.0f, -1.0f, 1.0f)); // 前右下
vertices->push_back(osg::Vec3( 1.0f, 1.0f, 1.0f)); // 前右上
vertices->push_back(osg::Vec3(-1.0f, 1.0f, 1.0f)); // 前左上
vertices->push_back(osg::Vec3(-1.0f, -1.0f, -1.0f)); // 后左下
vertices->push_back(osg::Vec3( 1.0f, -1.0f, -1.0f)); // 后右下
vertices->push_back(osg::Vec3( 1.0f, 1.0f, -1.0f)); // 后右上
vertices->push_back(osg::Vec3(-1.0f, 1.0f, -1.0f)); // 后左上
geometry->setVertexArray(vertices);
// 定义法线
osg::Vec3Array* normals = new osg::Vec3Array;
normals->push_back(osg::Vec3( 0.0f, 0.0f, 1.0f)); // 前
normals->push_back(osg::Vec3( 0.0f, 0.0f, -1.0f)); // 后
normals->push_back(osg::Vec3( 1.0f, 0.0f, 0.0f)); // 右
normals->push_back(osg::Vec3(-1.0f, 0.0f, 0.0f)); // 左
normals->push_back(osg::Vec3( 0.0f, 1.0f, 0.0f)); // 上
normals->push_back(osg::Vec3( 0.0f, -1.0f, 0.0f)); // 下
geometry->setNormalArray(normals, osg::Array::BIND_PER_PRIMITIVE_SET);
// 定义6个面(12个三角形)
osg::DrawElementsUInt* faces = new osg::DrawElementsUInt(osg::PrimitiveSet::TRIANGLES, 0);
// 前面
faces->push_back(0); faces->push_back(1); faces->push_back(2);
faces->push_back(2); faces->push_back(3); faces->push_back(0);
// 后面
faces->push_back(5); faces->push_back(4); faces->push_back(7);
faces->push_back(7); faces->push_back(6); faces->push_back(5);
// 右面
faces->push_back(1); faces->push_back(5); faces->push_back(6);
faces->push_back(6); faces->push_back(2); faces->push_back(1);
// 左面
faces->push_back(4); faces->push_back(0); faces->push_back(3);
faces->push_back(3); faces->push_back(7); faces->push_back(4);
// 上面
faces->push_back(3); faces->push_back(2); faces->push_back(6);
faces->push_back(6); faces->push_back(7); faces->push_back(3);
// 下面
faces->push_back(4); faces->push_back(5); faces->push_back(1);
faces->push_back(1); faces->push_back(0); faces->push_back(4);
geometry->addPrimitiveSet(faces);
geode->addDrawable(geometry);
return geode.release();
}
3、初始化Viewer与QT窗口绑定。
osgWidget = findChild<osgQOpenGLWidget*>("openGLWidget");
osgViewer::Viewer *viewer = osgWidget->getOsgViewer();
viewer->setSceneData(createCube());
viewer->setCameraManipulator(new osgGA::TrackballManipulator);
viewer->getCamera()->setViewport(0, 0, osgWidget->width(), osgWidget->height());
viewer->getCamera()->setClearColor(osg::Vec4(0.1, 0.1, 0.3, 1.0)); // 深蓝色背景
// 设置摄像机视角
viewer->getCamera()->setViewMatrixAsLookAt(
osg::Vec3d(0,5,5), // 视点
osg::Vec3d(0,0,0), // 中心点
osg::Vec3d(0,0,1) // 上方向
);
二、代码示例
mainwindow.h
#ifndef MAINWINDOW_H
#define MAINWINDOW_H
#include <QMainWindow>
#include <osgQOpenGL/osgQOpenGLWidget>
#include <osg/ref_ptr>
#include <osgGA/TrackballManipulator>
QT_BEGIN_NAMESPACE
namespace Ui { class MainWindow; }
QT_END_NAMESPACE
class MainWindow : public QMainWindow
{
Q_OBJECT
public:
MainWindow(QWidget *parent = nullptr);
~MainWindow();
private slots:
void on_pushButton_clicked();
private:
Ui::MainWindow *ui;
private:
osgQOpenGLWidget *osgWidget;
// QWidget interface
protected:
void showEvent(QShowEvent *event);
};
#endif // MAINWINDOW_H
mainwindow.cpp
#include "mainwindow.h"
#include "ui_mainwindow.h"
#include <osgDB/ReadFile>
#include <osg/PositionAttitudeTransform>
#include <osg/Node>
#include <osgViewer/Viewer>
#include <QDebug>
#include <osg/Geode>
#include <osg/Geometry>
#include <osgDB/WriteFile>
osg::Node* createCube() {
osg::ref_ptr<osg::Geode> geode = new osg::Geode;
osg::ref_ptr<osg::Geometry> geometry = new osg::Geometry;
// 定义8个顶点(立方体)
osg::Vec3Array* vertices = new osg::Vec3Array;
vertices->push_back(osg::Vec3(-1.0f, -1.0f, 1.0f)); // 前左下
vertices->push_back(osg::Vec3( 1.0f, -1.0f, 1.0f)); // 前右下
vertices->push_back(osg::Vec3( 1.0f, 1.0f, 1.0f)); // 前右上
vertices->push_back(osg::Vec3(-1.0f, 1.0f, 1.0f)); // 前左上
vertices->push_back(osg::Vec3(-1.0f, -1.0f, -1.0f)); // 后左下
vertices->push_back(osg::Vec3( 1.0f, -1.0f, -1.0f)); // 后右下
vertices->push_back(osg::Vec3( 1.0f, 1.0f, -1.0f)); // 后右上
vertices->push_back(osg::Vec3(-1.0f, 1.0f, -1.0f)); // 后左上
geometry->setVertexArray(vertices);
// 定义法线
osg::Vec3Array* normals = new osg::Vec3Array;
normals->push_back(osg::Vec3( 0.0f, 0.0f, 1.0f)); // 前
normals->push_back(osg::Vec3( 0.0f, 0.0f, -1.0f)); // 后
normals->push_back(osg::Vec3( 1.0f, 0.0f, 0.0f)); // 右
normals->push_back(osg::Vec3(-1.0f, 0.0f, 0.0f)); // 左
normals->push_back(osg::Vec3( 0.0f, 1.0f, 0.0f)); // 上
normals->push_back(osg::Vec3( 0.0f, -1.0f, 0.0f)); // 下
geometry->setNormalArray(normals, osg::Array::BIND_PER_PRIMITIVE_SET);
// 定义6个面(12个三角形)
osg::DrawElementsUInt* faces = new osg::DrawElementsUInt(osg::PrimitiveSet::TRIANGLES, 0);
// 前面
faces->push_back(0); faces->push_back(1); faces->push_back(2);
faces->push_back(2); faces->push_back(3); faces->push_back(0);
// 后面
faces->push_back(5); faces->push_back(4); faces->push_back(7);
faces->push_back(7); faces->push_back(6); faces->push_back(5);
// 右面
faces->push_back(1); faces->push_back(5); faces->push_back(6);
faces->push_back(6); faces->push_back(2); faces->push_back(1);
// 左面
faces->push_back(4); faces->push_back(0); faces->push_back(3);
faces->push_back(3); faces->push_back(7); faces->push_back(4);
// 上面
faces->push_back(3); faces->push_back(2); faces->push_back(6);
faces->push_back(6); faces->push_back(7); faces->push_back(3);
// 下面
faces->push_back(4); faces->push_back(5); faces->push_back(1);
faces->push_back(1); faces->push_back(0); faces->push_back(4);
geometry->addPrimitiveSet(faces);
geode->addDrawable(geometry);
return geode.release();
}
MainWindow::MainWindow(QWidget *parent)
: QMainWindow(parent)
, ui(new Ui::MainWindow)
{
ui->setupUi(this);
osgWidget = findChild<osgQOpenGLWidget*>("openGLWidget");
}
MainWindow::~MainWindow()
{
delete ui;
}
void MainWindow::on_pushButton_clicked()
{
osgViewer::Viewer *viewer = osgWidget->getOsgViewer();
viewer->setSceneData(createCube());
viewer->setCameraManipulator(new osgGA::TrackballManipulator);
viewer->getCamera()->setViewport(0, 0, osgWidget->width(), osgWidget->height());
viewer->getCamera()->setClearColor(osg::Vec4(0.1, 0.1, 0.3, 1.0)); // 深蓝色背景
// 设置摄像机视角
viewer->getCamera()->setViewMatrixAsLookAt(
osg::Vec3d(0,5,5), // 视点
osg::Vec3d(0,0,0), // 中心点
osg::Vec3d(0,0,1) // 上方向
);
}
void MainWindow::showEvent(QShowEvent *event)
{
on_pushButton_clicked();
}
main.cpp
#include "mainwindow.h"
#include <QApplication>
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
MainWindow w;
w.show();
return a.exec();
}
xxx.pro
QT += core gui
greaterThan(QT_MAJOR_VERSION, 4): QT += widgets
CONFIG += c++11
# The following define makes your compiler emit warnings if you use
# any Qt feature that has been marked deprecated (the exact warnings
# depend on your compiler). Please consult the documentation of the
# deprecated API in order to know how to port your code away from it.
DEFINES += QT_DEPRECATED_WARNINGS
# You can also make your code fail to compile if it uses deprecated APIs.
# In order to do so, uncomment the following line.
# You can also select to disable deprecated APIs only up to a certain version of Qt.
#DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0x060000 # disables all the APIs deprecated before Qt 6.0.0
SOURCES += \
main.cpp \
mainwindow.cpp
HEADERS += \
mainwindow.h
FORMS += \
mainwindow.ui
INCLUDEPATH += F:/develop/OpenSceneGraph-3.6.5/include
INCLUDEPATH += F:/develop/osgQt/include
win32:CONFIG(release, debug|release): LIBS += -LF:/develop/OpenSceneGraph-3.6.5/lib/ -LF:/develop/osgQt/lib-x64/release/ -losg -lOpenThreads -losgDB -losgGA -losgText -losgUtil -losgWidget -losgViewer -losgQt
else: LIBS += -LF:/develop/OpenSceneGraph-3.6.5/lib/ -LF:/develop/osgQt/lib-x64/debug/ -losgd -lOpenThreadsd -losgDBd -losgGAd -losgTextd -losgUtild -losgWidgetd -losgViewerd -losgQt
# Default rules for deployment.
qnx: target.path = /tmp/$${TARGET}/bin
else: unix:!android: target.path = /opt/$${TARGET}/bin
!isEmpty(target.path): INSTALLS += target
编译并执行