前言
使用《OpenSceneGraph Quick Start Guide》中文版及源码,里面的一个例子TextureMapping,在我本机上运行没有问题,但拷贝到公司电脑,发现总是运行异常,无法读取纹理图片,
调试到136行 image创建出来总是为空,纹理文件是有的,
#include "osgDB/ReadFile"
#include "osg/Geode"
#include "osg/Geometry"
#include "osg/StateSet"
#include "osg/StateAttribute"
#include "osg/Texture2D"
#include "osg/BlendColor"
#include "osg/AlphaFunc"
#include "osg/Notify"
#include "osg/BlendFunc"
#include "osgDB/WriteFile"
#include "osgDB/ReadFile"
#include "osgViewer/Viewer"
#include "osg/Texture1D"
#include "osg/Texture2D"
#include "osg/Texture3D"
#include "osg/Texture2DArray"
//Geometry->Drawable->Node->Object->Referenced
//AlphaFunc->StateAttribute->Object->Referenced
//StateAttributeCallback->Callback->Object->Referenced
//ClearNode->Group->Node->Object->Referenced
//CoordinateSystemNode->Group->Node->Object->Referenced
//Billboard->Geode->Group->Node->Object->Referenced
//Image->BufferData->Object->Referenced
//Texture1D/Texture2D/Texture2DArray/Texture3D->Texture->TextureAttribute->StateAttribute->Object->Referenced
osg::ref_ptr<osg::Node> createGeode()
{
osg::ref_ptr<osg::Vec3Array> v = new osg::Vec3Array;
v->push_back(osg::Vec3(0.f, 0.f, 0.f)); // 0
v->push_back(osg::Vec3(0.f, 0.f, 4.f));
v->push_back(osg::Vec3(-1.f, 0.f, 0.f));
v->push_back(osg::Vec3(1.f, 0.f, 0.f)); //3
v->push_back(osg::Vec3(1.f, 0.f, 4.f));
v->push_back(osg::Vec3(-1.f, 0.f, 4.f));
v->push_back(osg::Vec3(0.f, -1.f, 0.f)); //6
v->push_back(osg::Vec3(0.f, 1.f, 0.f));
v->push_back(osg::Vec3(0.f, 1.f, 4.f));
v->push_back(osg::Vec3(0.f, -1.f, 4.f)); //9
osg::ref_ptr<osg::Vec2Array> tc = new osg::Vec2Array;
tc->push_back(osg::Vec2(.5f, 0.f));
tc->push_back(osg::Vec2(.5f, 1.f));
tc->push_back(osg::Vec2(0.f, 0.f));
tc->push_back(osg::Vec2(1.f, 0.f));
tc->push_back(osg::Vec2(1.f, 1.f));
tc->push_back(osg::Vec2(0.f, 1.f));
tc->push_back(osg::Vec2(0.f, 0.f));
tc->push_back(osg::Vec2(1.f, 0.f));
tc->push_back(osg::Vec2(1.f, 1.f));
tc->push_back(osg::Vec2(0.f, 1.f));
osg::ref_ptr<osg::Vec4Array> c = new osg::Vec4Array;
c->push_back(osg::Vec4(1.f, 1.f, 1.f, 1.f));
osg::ref_ptr<osg::Group> grp = new osg::Group;
{
osg::ref_ptr<osg::Geometry> geom = new osg::Geometry;
geom->setVertexArray(v.get());
geom->setTexCoordArray(0, tc.get());
geom->setColorArray(c.get());
geom->setColorBinding(osg::Geometry::BIND_OVERALL);
// -X panal
GLushort indices[] = {
2, 0, 1, 5 };
geom->addPrimitiveSet(new osg::DrawElementsUShort(osg::PrimitiveSet::QUADS, 4, indices));
osg::ref_ptr<osg::Geode> geode = new osg::Geode;
geode->addDrawable(geom.get());
grp->addChild(geode.get());
}
{
osg::ref_ptr<osg::Geometry> geom = new osg::Geometry;
geom->setVertexArray(v.get());
geom->setTexCoordArray(0, tc.get());
geom->setColorArray(c.get());
geom->setColorBinding(osg::Geometry::BIND_OVERALL);
// +X panal
GLushort indices[] = {
2, 3, 4, 5 };
geom->addPrimitiveSet(new osg::DrawElementsUShort(osg::PrimitiveSet::QUADS, 4, indices));
osg::ref_ptr<osg::Geode> geode = new osg::Geode;
geode->addDrawable(geom.get());
grp->addChild(geode);
//grp->addChild(geode.get());
}
{
osg::ref_ptr<osg::Geometry> geom = new osg::Geometry;
geom->setVertexArray(v.get());
geom->setTexCoordArray(0, tc.get());
geom->setColorArray(c.get());
geom->setColorBinding(osg::Geometry::BIND_OVERALL);
GLushort indices[] = {
6, 0, 1, 9 };
geom->addPrimitiveSet(new osg::DrawElementsUShort(osg::PrimitiveSet::QUADS, 4, indices));
osg::ref_ptr<osg::Geode> geode = new osg::Geode;
geode->addDrawable(geom.get());
grp->addChild(geode.get());
}
{
osg::ref_ptr<osg::Geometry> geom = new osg::Geometry;
geom->setVertexArray(v.get());
geom->setTexCoordArray(0, tc.get());
geom->setColorArray(c.get());
geom->setColorBinding(osg::Geometry::BIND_OVERALL);
GLushort indices[] = {
0, 7, 8, 1 };
geom->addPrimitiveSet(new osg::DrawElementsUShort(osg::PrimitiveSet::QUADS, 4, indices));
osg::ref_ptr<osg::Geode> geode = new osg::Geode;
geode->addDrawable(geom.get());
grp->addChild(geode.get());
}
return grp.release();
}
osg::ref_ptr <osg::Node> createSceneGraph()
{
//osg::ref_ptr<osg::Node> node = new osg::Node;
osg::ref_ptr<osg::Node> node = createGeode();
//osg::ref_ptr<osg::StateSet> state = new osg::StateSet;
osg::ref_ptr<osg::StateSet> state = node->getOrCreateStateSet();
state->setMode(GL_LIGHTING, osg::StateAttribute::OFF | osg::StateAttribute::PROTECTED);
state->setRenderingHint(osg::StateSet::TRANSPARENT_BIN);
// Load the texture image
// Image courtesy Virtual Terrain Project (http://vterrain.org/)
std::string fileName("Picea_pungens__blue_spruce15_256.png");
osg::ref_ptr<osg::Image> image = osgDB::readImageFile(fileName);
if (!image.valid())
{
osg::notify(osg::FATAL) << "Unable to load data file. Exiting." << std::endl;
return (NULL);
}
// Set the image in a Texture2D object
osg::ref_ptr<osg::Texture2D> tex = new osg::Texture2D;
tex->setImage(image.get());
// After creating the OpenGL texture object, release the
// internal ref_ptr<Image> (to delete the Image).
tex->setUnRefImageDataAfterApply(true);
state->setTextureAttributeAndModes(0, tex.get());
// Turn on blending
//osg::BlendFunc* bf = new osg::BlendFunc;
osg::ref_ptr<osg::BlendFunc> bf = new osg::BlendFunc(osg::BlendFunc::SRC_ALPHA, osg::BlendFunc::ONE_MINUS_SRC_ALPHA); //有参数不需要括号构造函数
state->setAttributeAndModes(bf);
// Turn on alpha testing
osg::ref_ptr<osg::AlphaFunc> af = new osg::AlphaFunc(osg::AlphaFunc::GREATER, 0.05f);
state->setAttributeAndModes(af);
return (node.release());
}
int main(int argc, char** argv)
{
//osg::ref_ptr<osg::Node> root = new osg::Node;
osg::ref_ptr<osg::Node> root = createSceneGraph();
if (!root.valid())
{
//std::cout <<
osg::notify(osg::FATAL) << "Failed in createSceneGraph()." << std::endl;
return (1);
}
std::string out("TextureMapping.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("TextureMapping.osg"));
return viewer.run();
return 0;
}
解决
没有配置环境变量,根据自己机器实际路径添加,我的机器路径如下
1.在系统环境变量中加入:
(1)OSG_FILE_PATH
(2)OSG_NOTIFY_LEVEL
2.在path中加入
(1)E:\osg\OpenSceneGraph_build_vs2019_x64\bin
(2)E:\osg\3rdParty\3rdParty_x64\x64\lib
(3)E:\osg\3rdParty\3rdParty_x64\x64\bin