OSG系列文章目录


文章目录

前言

之前osg代码可以正常运行,最近突然就看不到渲染效果了,程序也没有崩溃,就是场景时空的,感觉好奇怪。
不管怎么说肯定是哪里出了问题。

一、问题定位?

1. 首先检查代码,看是不是代码的问题。

#include "osg/Group"
#include "osgText/Text"
#include "osg/Geode"
#include "osg/Geometry"
#include "osgText/Font"
#include "osgDB/WriteFile"
#include "osgDB/ReadFile"
#include "osg/Node"
#include "osg/ref_ptr"
#include "osgViewer/View"
#include "osgViewer/Viewer"
#include "osg/Matrix"
#include "osg/MatrixTransform"
#include "osg/ShadeModel"

//创建背板
osg::ref_ptr<osg::Drawable> createBase()
{
osg::ref_ptr<osg::Group> group = new osg::Group;
osg::ref_ptr<osg::Geometry> geom = new osg::Geometry;

osg::Matrix m;
osg::ref_ptr<osg::MatrixTransform> mt = new osg::MatrixTransform();
m.makeRotate(45.f, osg::Vec3(0.f, 1.f, 0.f));
mt->setMatrix(m);
group->addChild(mt.get());
mt->addChild(geom.get());

//设置状态属性
osg::ref_ptr<osg::StateSet> state = mt->getOrCreateStateSet();
osg::ref_ptr<osg::ShadeModel> sm = new osg::ShadeModel; //默认背面剔除
sm->setMode(osg::ShadeModel::FLAT);



osg::ref_ptr<osg::Vec3Array> v = new osg::Vec3Array;
geom->setVertexArray(v.get());
v->push_back(osg::Vec3(-1.f, 0.f, -1.f));
v->push_back(osg::Vec3(1.f, 0.f, -1.f));
v->push_back(osg::Vec3(1.f, 0.f, 1.f));
v->push_back(osg::Vec3(-1.f, 0.f, 1.f));

osg::ref_ptr<osg::Vec4Array> c = new osg::Vec4Array;
geom->setColorArray(c.get());
/*setColorBinding()和setNormalBinding() - 这些方法用于设置Geometry 类
中颜色和法线数据的绑定方式。其输入参数为Geometry 类的枚举量。
清单2 - 1 中,颜色绑定方式为osg::Geometry::BIND_PER_VERTEX,即
每种颜色对应一个顶点。而法线的绑定方式为
osg::Geometry::BIND_OVERALL,即整个Geometry 几何体对应唯一的
一个法线数据。*/
geom->setColorBinding(osg::Geometry::BIND_PER_VERTEX);
c->push_back(osg::Vec4(1.f, 1.f, 0.f, 1.f));
c->push_back(osg::Vec4(0.f, 1.f, 0.f, 1.f));
c->push_back(osg::Vec4(0.f, 0.f, 1.f, 1.f));
c->push_back(osg::Vec4(1.f, 1.f, 1.f, 1.f));

//法线
osg::ref_ptr<osg::Vec3Array> n = new osg::Vec3Array;
geom->setNormalArray(n.get());
/*而法线的绑定方式为
osg::Geometry::BIND_OVERALL,即整个Geometry 几何体对应唯一的
一个法线数据。*/
geom->setNormalBinding(osg::Geometry::BIND_OVERALL);
n->push_back(osg::Vec3(0.f, 1.f, 0.f));

geom->addPrimitiveSet(new osg::DrawArrays(osg::PrimitiveSet::TRIANGLE_FAN, 0, 4));

return (geom.release());

}

osg::ref_ptr<osg::Node> createSceneGraph()
{
// Create the root (and only) node.
osg::ref_ptr<osg::Geode> geode = new osg::Geode;
geode->addDrawable(createBase());

//字体
osg::ref_ptr<osgText::Font> font = new osgText::Font;
font = osgText::readFontFile("fonts/arial.ttf");




osg::Vec4 white(osg::Vec4(1.f, 1.f, 1.f, 1.f));
{
//Text.osg文件中有个默认参数:autoRotateToScreen,始终保持字体面向屏幕
osg::ref_ptr<osgText::Text> text = new osgText::Text;
text->setFont(font.get());
text->setColor(osg::Vec4(0.f, 1.f, 1.f, 1.f)); //青色
text->setCharacterSize(.15f);
text->setPosition(osg::Vec3(1.f, 0.f, 1.f));
/*如果要创建一个一直朝向视口的广告牌形式的文
字,可以使用Text::SCREEN。*/
text->setAxisAlignment(osgText::Text::XY_PLANE);//因为没有设置SCREEN,所以在Text.osg文件中没有autoRotateToScreen TRUE 属性
text->setAlignment(osgText::Text::LEFT_TOP); //左上基准点开始的字体
text->setText("right_right");
geode->addDrawable(text.get());

text->setDataVariance(osg::Object::DYNAMIC);
}

{
osg::ref_ptr<osgText::Text> text = new osgText::Text;
text->setFont(font.get());
text->setColor(osg::Vec4(1.f, 0.f, 0.f, 1.f));
text->setCharacterSize(.15f);
text->setPosition(osg::Vec3(-1.f, 0.f, 0.f));
text->setAxisAlignment(osgText::Text::SCREEN); //因为没有设置SCREEN,所以在Text.osg文件中有autoRotateToScreen TRUE 属性
text->setText("right_right");
text->setText("Top_left");
geode->addDrawable(text.get());
}

{
osg::ref_ptr<osgText::Text> text = new osgText::Text;
text->setFont(font.get());
text->setColor(osg::Vec4(0.f, 1.f, 0.f, 1.f));
text->setCharacterSize(.15f);
text->setPosition(osg::Vec3(-1.f, -1.f, 0.f));
text->setAxisAlignment(osgText::Text::SCREEN);
text->setText("Bottom_left");
geode->addDrawable(text.get());
}

{
osg::ref_ptr<osgText::Text> text = new osgText::Text;
text->setFont(font.get());
text->setColor(osg::Vec4(0.f, 0.f, 1.f, 1.f));
text->setCharacterSize(.15f);
text->setPosition(osg::Vec3(1.f, -1.f, 0.f));
text->setAxisAlignment(osgText::Text::SCREEN); //因为没有设置SCREEN,所以在Text.osg文件中有autoRotateToScreen TRUE 属性
text->setText("Bottom_right");
geode->addDrawable(text.get());
}

{
osg::ref_ptr<osgText::Text> text = new osgText::Text;
text->setFont(font.get());
/*用户程序通常需要改变字体纹理贴图的图形分辨率,以避免文字出现模糊。
缺省情况下,osgText 为每个图形分配了32×32 个像素元。要改变这个数值的话,
可以使用Text::setFontResolution()方法。下面的代码增加了字体的分辨率,osgText
将因此为每个图形分配128×128 个像素元。*/
text->setFontResolution(128, 128);
text->setColor(osg::Vec4(1.f, 0.f, 1.f, 1.f));
text->setCharacterSize(.15f);
text->setPosition(osg::Vec3(0.f, 0.f, 0.f));
//text->setAxisAlignment(osgText::Text::SCREEN);
text->setAxisAlignment(osgText::Text::XZ_PLANE); //沿xz平面,倒下
/*文字相对于自身坐标位置*/
text->setAlignment(osgText::Text::CENTER_TOP);
text->setText("Hello osg world");
geode->addDrawable(text.get());
}

return geode.release();
}

int main(int argc, char** argv)
{
osg::ref_ptr<osg::Node> root = createSceneGraph();
if (!root.valid())
{
osg::notify(osg::FATAL) << "Failed in createSceneGraph()." << std::endl;
return 1;
}

// 已经有Text.osg文件,暂时不用写此文件
std::string out("Text.osg");
if (!(osgDB::writeNodeFile(*(root.get()), out))) //这里不能有封号, 切记 切记 切记!!!!!
{
osg::notify(osg::FATAL) << "Failed in osgDB::writeNodeFile()." << std::endl;
//return 1;
}

osg::notify(osg::ALWAYS) << "Successfully wrote \"" << out << "\". Execute \" osgviewer " << out << "\" to view." << std::endl;

osgViewer::Viewer viewer;
viewer.setSceneData(osgDB::readNodeFile("Text.osg"));
return viewer.run();

/*osg::ref_ptr<osgViewer::View> viewer = new osgViewer::View;
auto node = osgDB::readNodeFile("Text.osg");
return viewer.run();*/

return 0;
}

2.查看工程配置

看头文件配置
osg程序运行出错_OSG字体使用
看静态库配置
osg程序运行出错_osg渲染出错_02
osg程序运行出错_#include_03
osg程序运行出错_osg渲染出错_04
看运行时动态库是否有缺失
osg程序运行出错_osg渲染出错_05
确认过眼神,都没有问题

二、环境变量

1.osg bin路径

osg程序运行出错_#include_06

运行结果

osg程序运行出错_OSG场景渲染_07

代码下载

​代码下载地址​

总结

果然是环境变量的问题,之前因为osg装了2.8和3.6.5,怕冲突,所以把osg3.6.5的环境变量删除了,所以,导致运行时没有在场景中看到渲染字体