给osg::Geometry(osg自带的几何体,如:BOX等)添加纹理(一)

该代码示例展示了如何在osg中为一个Box形状应用jpg纹理,并开启光照以避免几何体表面在特定角度变为黑色。创建了一个osg::Geode对象,附加了ShapeDrawable和Material,然后设置了Texture2D以加载jpg图像文件作为纹理。此外,还使用了MatrixTransform进行旋转以展示效果,并确保启用了GL_LIGHTING模式和Light对象以实现更好的视觉效果。
摘要由CSDN通过智能技术生成

如下代码为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.csdn.net/danshiming/article/details/115412956

如何为自绘制几何体增加纹理,参见:

osg给osg::Geometry(自己绘制的)添加纹理(二)

  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值