网上查询过很多标牌绘制的功能,最终的绘制出的状态总是会不尽如人意,本人根据自身要求及摘录网上的代码,简单整理了一下对应类和接口,尽量简单的完成标牌绘制的接口,不多说,上代码:
代码基于OSG323+Earth2.7版本,IDE:QtCreate4.2.1
这是基本类:主要负责建立标牌
#ifndef DT_BILLBOARD_H
#define DT_BILLBOARD_H
#include <QString>
#include <QList>
#include <QMap>
#include <osgWidget/Box>
#include <osgWidget/Label>
#include <string>
class DT_Billboard : public osgWidget::Box
{
public:
explicit DT_Billboard(const std::string &id, osg::Node *posnode);
~DT_Billboard();
public:
// 设置简标牌的标题栏
void setSimpleTitle(const QString &title);
// 添加标牌的显示项(详标)
void addItem(const QString &text, int id);
int getDetailSize();
// 更新标牌显示项
void updateItem(int number, const QString &text);
// 设置标牌位置(屏幕坐标)
void setPos(osg::Vec3 pos);
// 设置标牌偏移量(屏幕坐标)
void setOffset(osg::Vec3 offset);
// 设置显隐详细信息
void setDetailVisible(bool b);
// 获取详细信息显隐状态
bool getDetailVisible();
/*******************
*@biref 设置简标的背景颜色
*@param unsigned int r : (0~255)
*@param unsigned int g : (0~255)
*@param unsigned int b : (0~255)
*@param unsigned int a : (0~255)
*@return bool
**********/
void setSimpleBackground(unsigned int r, unsigned int g, unsigned int b , unsigned int a);
osg::Vec3d getTargetPos();
// 获取标牌ID
std::string getID();
// 创建标牌与模型间的连接线
void createLine(const osg::Vec3 &startPt, const osg::Vec3 &endPt);
// 删除标牌与模型间的连接线
void delLine();
void onMouseEvent(const osgGA::GUIEventAdapter &ea, osgViewer::View *viewer);
private:
// 移动标牌
void move();
void clearSimple();
void clearDetail();
void reDrawBillboard();
public:// 文字编码格式转换
static void gb2312ToUnicode(const std::string& src, std::wstring& result);
static void unicodeToUTF8(const std::wstring &src, std::string& result);
static void gb2312ToUtf8(const std::string& src, std::string& result);
protected:
bool mouseDrag(double, double, const osgWidget::WindowManager *);
bool mousePush(double, double, const osgWidget::WindowManager *);
bool mouseRelease(double, double, const osgWidget::WindowManager *);
private:
std::string m_id; // 适配属性:唯一标识
osg::Node *m_positionNode; // 适配属性:位置节点
osg::ref_ptr<osg::Geode> m_geode; // 绘制目标与标牌线节点
osg::ref_ptr<osg::Geometry> m_line; // 绘制目标与标牌的线
osg::ref_ptr<osgWidget::Label> m_simpleLabel; // 简标
QMap<int, osg::ref_ptr<osgWidget::Label>> m_detailLabels; // 详标
bool m_isVisible;
bool m_isItemVisible;
bool m_isMousePush;
bool m_isMouseDrag;
osg::Vec3 m_pos;
osg::Vec3 m_offset;
osg::Vec3 m_LastPt;
osg::Vec3 m_LBDownPt;
};
#endif // DT_BILLBOARD_H
这是管理类:主要负责对标牌进行增删改查
#ifndef DTB_BILLBOARDMANAGER_H
#define DTB_BILLBOARDMANAGER_H
#include <osgGA/GUIEventHandler>
#include <osgViewer/View>
#include <osg/Group>
#include "DT_Billboard.h"
#include <QMutex>
#include <QVector>
class DTB_BillboardManager : public osgGA::GUIEventHandler
{
protected:
DTB_BillboardManager();
~DTB_BillboardManager();
public:
static DTB_BillboardManager *instance();
static void destroy();
public:
bool handle(const osgGA::GUIEventAdapter&ea, osgGA::GUIActionAdapter&aa);
// 增
bool addBoard(const std::string& id, osg::Node *pos, const std::string& simple, std::vector<std::string> detail);
// 删
bool delBoard(std::string id);
// 查/改
DT_Billboard* getBoard(std::string id);
// 清空
void clear();
void setWinManager(void *manager);
osg::ref_ptr<osgWidget::WindowManager> getWindowManager() const;
private:
void lock(bool b);
private:
osgWidget::WindowManager *m_pWindowManager; // 适配属性:窗口管理器
static DTB_BillboardManager *m_pInstance;
QVector<void *> m_labelList;
QMutex m_mutex; // 互斥量
};
#endif // DTB_BILLBOARDMANAGER_H
效果如下:
CSDN账号里面有对应资源,欢迎下载讨论