|
发表于 2013-5-16 15:10:58
|
显示全部楼层
给你个参考
int main()
{
osg::Group* root = new osg::Group(); // 初始化根节点
osg:ositionAttitudeTransform* 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:rtho2D(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:rawElementsUInt* 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();
}? |
|