如下代码为osg::Box添加jpg的纹理:
#include<osgDB\ReadFile>
#include<osgViewer\Viewer>
#include<osg\ShapeDrawable>
#include<osg\Geode>
#include<osg\StateSet>
#include<osg\Image>
#include<osg\Texture2D>
#include<osg\Material>
#include<osg\MatrixTransform>
osg::ref_ptr<osg::Geode> createBox()
{
osg::ref_ptr<osg::Geode> spGeode = new osg::Geode;//Geode是Node的派生类,为了绘制图元的管理类
osg::ref_ptr<osg::TessellationHints> hints = new osg::TessellationHints;//设置精度的类
osg::ref_ptr < osg::ShapeDrawable >shape = new osg::ShapeDrawable(new osg::Box(osg::Vec3(0.0, 0.0, 0.0), 10.0, 10.0, 10.0), hints.get());
osg::ref_ptr<osg::Material> material = new osg::Material;
shape->setColor(osg::Vec4(0.5, 0.5, 0.5, 0.5));//颜色
hints->setDetailRatio(0.5);//设置精度
//设置材质
material->setAmbient(osg::Material::FRONT_AND_BACK, osg::Vec4f(1.0, 1.0, 1.0, 0.7));//面向,和光照颜色第四个参数管透明度?
material->setDiffuse(osg::Material::FRONT_AND_BACK, osg::Vec4f(1.0, 1.0, 1.0, 0.7));//混合
material->setSpecular(osg::Material::FRONT_AND_BACK, osg::Vec4f(1.0, 1.0, 1.0, 0.7));//反射
material->setShininess(osg::Material::FRONT_AND_BACK, 60.0);//反射面积
//把材质放进去,如果有就get状态,如果没有就set
spGeode->getOrCreateStateSet()->setAttributeAndModes(material.get(), osg::StateAttribute::ON);
// 设置纹理
osg::ref_ptr<osg::Texture2D>spTexture2D = new osg::Texture2D;
osg::ref_ptr<osg::Image> spImage = osgDB::readImageFile("guangzhou_tower.jpg");
if (spImage.valid())//看看能用不?
{
spTexture2D->setImage(spImage.get());
}
spTexture2D->setWrap(osg::Texture2D::WRAP_S, osg::Texture::CLAMP);
spTexture2D->setWrap(osg::Texture2D::WRAP_T, osg::Texture::CLAMP);
spTexture2D->setFilter(osg::Texture2D::MIN_FILTER, osg::Texture::LINEAR);
spTexture2D->setFilter(osg::Texture2D::MAG_FILTER, osg::Texture::LINEAR);
spGeode->getOrCreateStateSet()->setTextureAttributeAndModes(0, spTexture2D.get(), osg::StateAttribute::ON);
spGeode->addDrawable(shape.get());
// 开启光照,要不然几何体有些面转到正对相机时是黑色的
spGeode->getOrCreateStateSet()->setMode(GL_LIGHTING, osg::StateAttribute::ON);
osg::ref_ptr<osg::Light> spLight = new osg::Light;
spLight->setDiffuse(osg::Vec4d(0.0, 1.0, 0.5, 1.0)); // 漫反射光颜色
spLight->setAmbient(osg::Vec4d(0.6, 0.6, 0.6, 1.0)); // 设置环境光颜色
spLight->setPosition(osg::Vec4d(1, -1, 1, 0)); // 设置光源位置
spGeode->getOrCreateStateSet()->setAttributeAndModes(spLight, osg::StateAttribute::ON); // 开启纹理
return spGeode;
}
int main()
{
osg::ref_ptr<osgViewer::Viewer> viewer = new osgViewer::Viewer;
osg::ref_ptr<osg::MatrixTransform> spMatrixTransform = new osg::MatrixTransform;
// 绕y、z轴转动下,这样便于观察效果
spMatrixTransform->setMatrix(osg::Matrix::rotate(osg::PI / 3.0, osg::Vec3(0, 0, 1)) * osg::Matrix::rotate(osg::PI / 5.0, osg::Vec3(1, 0, 0)));
spMatrixTransform->addChild(createBox());
viewer->setSceneData(spMatrixTransform);
return viewer->run();
}
效果如下:
上述代码开启了光照,因为如果不开启光照,则当几何体有些面转到正对相机时,是黑色的,开启光照,则看得清些。
注意:
有些机器或有些版本的osg,需要开启材质功能,纹理才能显示,即第32行代码那样,这个原因不知道。
对于某些图片作为纹理,需要相应的插件才行。如:读取jpg,故请保证jpg插件存在,否则读取jpg会失败。如下为读取png类型图片时,因为没有png的插件弹出的错误:
Error reading file Qt.png: read error (Could not find plugin to read objects from file "Qt.png".)
关于怎么编译jpg插件到osg,请参见:https://blog.youkuaiyun.com/danshiming/article/details/115412956
如何为自绘制几何体增加纹理,参见: