OSG 显示文字与 HUD




本文转自:http://hi.baidu.com/guzhou_diaoke/item/9380d46d06e7df02a1cf0fcf

‍// 显示汉字
#include <osgDB/ReadFile>
#include <osgViewer/Viewer>
#include <osg/Geode>
#include <osg/Depth>
#include <osg/CameraNode>
#include <osgText/Text>

#pragma comment(lib, "osgd.lib")
#pragma comment(lib, "osgDBd.lib")
#pragma comment(lib, "osgViewerd.lib")
#pragma comment(lib, "osgUtild.lib")

#pragma comment(lib, "OpenThreadsd.lib")
#pragma comment(lib, "osgFXd.lib")
#pragma comment(lib, "osgGAd.lib")
#pragma comment(lib, "osgManipulatord.lib")
#pragma comment(lib, "osgParticled.lib")
#pragma comment(lib, "osgShadowd.lib")
#pragma comment(lib, "osgSimd.lib")
#pragma comment(lib, "osgTerraind.lib")
#pragma comment(lib, "osgTextd.lib")

osg::Node* createHUD()
{
osg::Geode* geode = new osg::Geode();
//设置字体,必须是汉字字体,如果没有可以自己找个黑体宋体什么的,这里是华文彩云。
std::string caiyun("/fonts/YGY2.TTF");
//设置状态,关闭灯光
osg::StateSet* stateset = geode->getOrCreateStateSet();
stateset->setMode(GL_LIGHTING,osg::StateAttribute::OFF);
osg::Vec3 position(150.0f, 500.0f, 0.0f);
//设置字体属性
osgText::Text* text = new osgText::Text; geode->addDrawable( text );
//设置字体
text->setFont(caiyun);
//设置位置
text->setPosition(position);
text->setText(L"孤舟钓客:泛舟四海,笑傲江湖!");

//设置相机
osg::Camera* camera = new osg::CameraNode;
//设置透视矩阵
camera->setProjectionMatrix(osg::Matrix::ortho2D(0,1024,0,768));
camera->setReferenceFrame(osg::Transform::ABSOLUTE_RF);
//得到默认设置
camera->setViewMatrix(osg::Matrix::identity());
//设置背景为透明,否则的话可以设置ClearColor
camera->setClearMask(GL_DEPTH_BUFFER_BIT);
//设置渲染顺序,必须在最后渲染
camera->setRenderOrder(osg::CameraNode::POST_RENDER);
camera->addChild(geode); return camera;
};

int main( int argc, char **argv )
{
osgViewer::Viewer viewer;
osg::ref_ptr<osg::Node> scene = osgDB::readNodeFile("ceep.ive");
osg::ref_ptr<osg::Group> group = new osg::Group;
if (scene.valid())
   group->addChild(scene.get());
//创建HUD
group->addChild(createHUD());
viewer.setSceneData(group.get());
viewer.realize();
viewer.run();
return 0;
}

‍// HUD 与显示汉字
#include <osg/Node>
#include <osg/Group>
#include <osg/Geode>
#include <osg/Geometry>
#include <osg/PositionAttitudeTransform>
#include <osgViewer/Viewer>
#include <osgDB/readFile>
#include <osg/Texture2D>
#include <osg/ShapeDrawable>
#include <osg/TexEnv>
#include <osgText/Text>
#include <osgDB/Registry>

#include <osgText/Font>
#include <osg/MatrixTransform>
#include <osg/Projection>
#include <osg/ShapeDrawable>
#include <osgGA/TrackballManipulator>

#pragma comment(lib, "osgd.lib")
#pragma comment(lib, "osgDBd.lib")
#pragma comment(lib, "osgViewerd.lib")
#pragma comment(lib, "osgUtild.lib")

#pragma comment(lib, "OpenThreadsd.lib")
#pragma comment(lib, "osgFXd.lib")
#pragma comment(lib, "osgGAd.lib")
#pragma comment(lib, "osgManipulatord.lib")
#pragma comment(lib, "osgParticled.lib")
#pragma comment(lib, "osgShadowd.lib")
#pragma comment(lib, "osgSimd.lib")
#pragma comment(lib, "osgTerraind.lib")
#pragma comment(lib, "osgTextd.lib")

int main()
{
osg::Group* root = new osg::Group();        // 初始化根节点
osg::PositionAttitudeTransform* tankXform;
osg::Geode* HUDGeode = new osg::Geode();       // HUD 几何体的叶节点

osgText::Text* textOne = new osgText::Text();      // 用于作HUD 显示的Text 实例
osgText::Text* tankLabel = new osgText::Text();      // 这个文字实例将跟随坦克显示

// 读入模型并关联到节点
osg::Node* tankNode = osgDB::readNodeFile("t72-tank_des.flt"); // 坦克节点
osg::Node* terrainNode = osgDB::readNodeFile("JoeDirt.flt"); // 地形节点

// 初始化位置变换节点,用于放置坦克模型
tankXform = new osg::PositionAttitudeTransform();
tankXform->setPosition(osg::Vec3d(5, 5, 8));

// 构件场景。将地形节点和位置变换节点关联到根节点
root->addChild(terrainNode);
root->addChild(tankXform);
tankXform->addChild(tankNode);

// 下一步,设置场景显示HUD 文字。这里我们向场景中添加一个子树,其顶层节点使用投影和模型观察矩阵。
// 将投影矩阵添加到根节点。投影矩阵的水平和垂直范围与屏幕的尺寸相同。因此该节点子树中的位置坐标将等同于像素坐标
osg::Projection* HUDProjectionMatrix = new osg::Projection; // 投影节点用于定义HUD 的视景体
HUDProjectionMatrix->setMatrix(osg::Matrix::ortho2D(0, 1024, 0, 768));

// HUD 模型观察矩阵应使用单位矩阵
osg::MatrixTransform* HUDModelViewMatrix = new osg::MatrixTransform;
HUDModelViewMatrix->setMatrix(osg::Matrix::identity());

// 确保模型观察矩阵不会被场景图形的位置变换影响
HUDModelViewMatrix->setReferenceFrame(osg::Transform::ABSOLUTE_RF);

// 添加HUD 投影矩阵到根节点,添加HUD 模型观察矩阵到HUD投影矩阵。
// 模型观察矩阵节点的所有子节点都可以使用该投影矩阵进行视景
// 浏览,并使用模型观察矩阵来安置位置
root->addChild(HUDProjectionMatrix);
HUDProjectionMatrix->addChild(HUDModelViewMatrix);

// 现在我们设置几何体。我们创建一个与屏幕坐标对齐的四边形,并设置其颜色和纹理参数。
// 将包含 HUD 几何体的Geode 节点作为HUD 模型观察矩阵的子节点
HUDModelViewMatrix->addChild(HUDGeode);

// 设置HUD 的四边形背景,并添加到Geode 节点
osg::Geometry* HUDBackgroundGeometry = new osg::Geometry();
osg::Vec3Array* HUDBackgroundVertices = new osg::Vec3Array;
HUDBackgroundVertices->push_back(osg::Vec3(0,    0,   -1));
HUDBackgroundVertices->push_back(osg::Vec3(1024, 0,   -1));
HUDBackgroundVertices->push_back(osg::Vec3(1024, 200, -1));
HUDBackgroundVertices->push_back(osg::Vec3(0,    200, -1));
osg::DrawElementsUInt* HUDBackgroundIndices = new osg::DrawElementsUInt(osg::PrimitiveSet::POLYGON, 0);
HUDBackgroundIndices->push_back(0);
HUDBackgroundIndices->push_back(1);
HUDBackgroundIndices->push_back(2);
HUDBackgroundIndices->push_back(3);
osg::Vec4Array* HUDcolors = new osg::Vec4Array;
HUDcolors->push_back(osg::Vec4(0.1f, 0.2f, 0.4f, 0.8f));
osg::Vec2Array* texcoords = new osg::Vec2Array(4);
(*texcoords)[0].set(0.0f, 0.0f);
(*texcoords)[1].set(1.0f, 0.0f);
(*texcoords)[2].set(1.0f, 1.0f);
(*texcoords)[3].set(0.0f, 1.0f);
HUDBackgroundGeometry->setTexCoordArray(0, texcoords);
osg::Texture2D* HUDTexture = new osg::Texture2D;
HUDTexture->setDataVariance(osg::Object::DYNAMIC);
osg::Image* hudImage;
hudImage = osgDB::readImageFile("hudbk.jpg");
HUDTexture->setImage(hudImage);
osg::Vec3Array* HUDnormals = new osg::Vec3Array;
HUDnormals->push_back(osg::Vec3(0.0f, 0.0f, 1.0f));
HUDBackgroundGeometry->setNormalArray(HUDnormals);
HUDBackgroundGeometry->setNormalBinding(osg::Geometry::BIND_OVERALL);
HUDBackgroundGeometry->addPrimitiveSet(HUDBackgroundIndices);
HUDBackgroundGeometry->setVertexArray(HUDBackgroundVertices);
HUDBackgroundGeometry->setColorArray(HUDcolors);
HUDBackgroundGeometry->setColorBinding(osg::Geometry::BIND_OVERALL);
HUDGeode->addDrawable(HUDBackgroundGeometry);

// 我们需要创建一个osg::StateSet,并禁止深度测试(总是在屏幕上绘制),允许Alpha 混合
// (使HUD 背景透明),以保证HUD 的渲染正确。然后我们使用一个指定数字的渲染元来分配
// 几何体在拣选遍历中的渲染顺序。代码如下所示:
// 设置渲染状态,使用上面定义的纹理
osg::StateSet* HUDStateSet = new osg::StateSet();
HUDGeode->setStateSet(HUDStateSet);
HUDStateSet->setTextureAttributeAndModes(0,HUDTexture,osg::StateAttribute::ON);

//打开GL_BLEND 混合模式(以保证Alpha 纹理正确)
HUDStateSet->setMode(GL_BLEND, osg::StateAttribute::ON);

// 禁止深度测试,因此几何体将忽略已绘制物体的深度值,直接进行绘制
HUDStateSet->setMode(GL_DEPTH_TEST, osg::StateAttribute::OFF);
HUDStateSet->setRenderingHint(osg::StateSet::TRANSPARENT_BIN);
// 确认该几何题在最后进行绘制。渲染元(RenderBin)按照数字顺序执行渲染,因此我们设置一个较大的数字值
HUDStateSet->setRenderBinDetails(11, "RenderBin");

// 最后我们设置文字。由于osg::Text 继承自osg::Drawable,其实例可以作为osg::Geode实例的子节点添加到场景中。
// 添加文字到 Geode 叶节点中
HUDGeode->addDrawable(textOne);

// 设置HUD 文字的参数
textOne->setCharacterSize(25);
textOne->setFont("/fonts/YGY2.ttf");
textOne->setText(L"孤舟钓客:泛舟四海,笑傲江湖!");
textOne->setAxisAlignment(osgText::Text::SCREEN);
textOne->setPosition(osg::Vec3(360, 165, -1.5));
textOne->setColor(osg::Vec4(199, 77, 15, 1));

// 声明一个叶节点来保存坦克的标签文字
osg::Geode* tankLabelGeode = new osg::Geode();

// 将坦克标签添加到场景中
tankLabelGeode->addDrawable(tankLabel);
tankXform->addChild(tankLabelGeode);

// 设置坦克标签文字的参数,与坦克的坐标对齐,
// 这里使用XZ_PLANE 保证文字与坦克的XZ 平面对齐
tankLabel->setCharacterSize(5);
tankLabel->setFont("/fonts/YGY2.ttf");
tankLabel->setText(L"Tank 1号");
tankLabel->setAxisAlignment(osgText::Text::XZ_PLANE);

// 设置文字渲染时包括一个对齐点和包围矩形
tankLabel->setDrawMode(osgText::Text::TEXT | osgText::Text::ALIGNMENT | osgText::Text::BOUNDINGBOX);
tankLabel->setAlignment(osgText::Text::CENTER_TOP);
tankLabel->setPosition(osg::Vec3(0, 0, 8));
tankLabel->setColor(osg::Vec4(1.0f, 0.0f, 0.0f, 1.0f));

// 最后,设置视景类并进入仿真循环。
osgViewer::Viewer viewer;
viewer.setSceneData(root);
return viewer.run();
}‍

  • 1
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值