欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

osg设置模型纹理

程序员文章站 2022-06-10 21:12:31
...

概述:

1.开发随笔记录分享两种纹理设置方式:
a.自定义顶点方式进行设置纹理坐标;
b.自动生成纹理坐标

示例代码:

自动生成纹理坐标

	//读取文件路径
	std::string path = CSingletonShared::GetInstance().GetApplicationPath();
	osg::ref_ptr<osg::Image> image = osgDB::readImageFile(CSingletonShared::GetInstance().GetApplicationPath() + "\\TeeImage.jpg");
	if (image.get())
	{
		osg::ref_ptr<osg::Texture2D> texture = new osg::Texture2D();
		texture->setImage(image.get());
		//设置自动生成纹理坐标
		osg::ref_ptr<osg::TexGen> texgen = new osg::TexGen();
		texgen->setMode(osg::TexGen::SPHERE_MAP);
		//设置纹理环境,模式为BLEND
		osg::ref_ptr<osg::TexEnv> texenv = new osg::TexEnv;
		texenv->setMode(osg::TexEnv::Mode::ADD);
		//texenv->setColor(osg::Vec4(0.6, 0.6, 0.6, 0.0));
		//启动单元一自动生成纹理坐标,并使用纹理
		osg::ref_ptr<osg::StateSet> state = new osg::StateSet;
		state->setTextureAttributeAndModes(1, texture.get(), osg::StateAttribute::ON);
		state->setTextureAttributeAndModes(1, texgen.get(), osg::StateAttribute::ON);
		state->setTextureAttribute(1, texenv.get());
		node->setStateSet(state.get());
	}
	pSceneRoot->addChild(node);

自定义顶点方式设置纹理坐标

bool RackVolume::Model_Create(osg::Node * _node)
{
	if (nullptr == _node)
	{
		return false;
	}
	osg::ref_ptr<osg::Group> pGroop = new osg::Group;
	osg::ref_ptr<osg::Geometry> pGeometry = new osg::Geometry;
	osg::ref_ptr<osg::Vec3Array> pVec3 = new osg::Vec3Array;
	pVec3->push_back(osg::Vec3(0.0, 0.0, 1.0));
	pVec3->push_back(osg::Vec3(1.0, 0.0, 1.0));
	pVec3->push_back(osg::Vec3(1.0, 1.0, 1.0));
	pVec3->push_back(osg::Vec3(0.0, 1.0, 1.0));
	// 添加四个顶点
	pGeometry->setVertexArray(pVec3.get());
	std::string path = CSingletonShared::GetInstance().GetApplicationPath();
	osg::ref_ptr<osg::Image> image = osgDB::readImageFile(CSingletonShared::GetInstance().GetApplicationPath() + "\\TeeImage.jpg");
	if (image.get())
	{
		osg::ref_ptr<osg::Texture2D> texture2D = new osg::Texture2D;
		texture2D->setImage(image.get());
		// 绑定纹理后,释放内部的ref_ptr<Image>,删除image图像
		texture2D->setUnRefImageDataAfterApply(true);
		// 建立纹理顶点
		osg::ref_ptr<osg::Vec2Array> pVec2Array = new osg::Vec2Array;
		//纹理单元号
		pVec2Array->push_back(osg::Vec2(0.0, 0.0));
		pVec2Array->push_back(osg::Vec2(1.0, 0.0));
		pVec2Array->push_back(osg::Vec2(1.0, 1.0));
		pVec2Array->push_back(osg::Vec2(0.0,1.0));
		
		// 失败
		// osg::ref_ptr<osg::StateSet> pStateSet = new osg::StateSet;
		// Texture类关联到渲染状态StateSet
		osg::ref_ptr<osg::StateSet> pStateSet = pGeometry->getOrCreateStateSet();
		// 将纹理关联给StateSet纹理单元0、osg::StateAttribute::OFF关闭纹理
		pStateSet->setTextureAttributeAndModes(0, texture2D.get(), osg::StateAttribute::ON);
		pGeometry->setTexCoordArray(0, pVec2Array.get());
		// 建立法线一个数组    法线: normal
		osg::ref_ptr<osg::Vec3Array> pVec3ArrayNormal = new osg::Vec3Array;
		pGeometry->setNormalArray(pVec3ArrayNormal.get());
		pGeometry->setNormalBinding(osg::Geometry::BIND_OVERALL);
		//垂直于Z轴负方向
		pVec3ArrayNormal->push_back(osg::Vec3(0.0, 0.0, -1.0));
		pGeometry->setStateSet(pStateSet);
		// 保存的数据绘制四个顶点的多边形
		pGeometry->addPrimitiveSet(new osg::DrawArrays(osg::PrimitiveSet::QUADS, 0, 4));
		// 向Geode类添加几何体(Drawable)
		osg::ref_ptr<osg::Geode> pGeode = new osg::Geode;
		pGeode->addDrawable(pGeometry.get());
		pGroop->addChild(pGeode);
	}
	//创建一个矩阵
	osg::ref_ptr<osg::MatrixTransform> ms = new osg::MatrixTransform;
	ms->setMatrix(osg::Matrix::scale(_info.fXRate, _info.fYRate, _info.fZRate)
		*osg::Matrix::rotate(osg::DegreesToRadians(-_info.fRotationAngle), osg::Z_AXIS)
		*osg::Matrix::translate(_info.fXcoordinate, _info.fYcoordinate, _info.fZcoordinate)
	);
	ms->addChild(nodeDragger);
	ms->setName(_info.str_ID);
	pGroop->addChild(ms/*.release()*/);
	pSceneRoot->addChild(pGroop->asNode());
	return true;
}

over:

欢迎大家关注作者在文末评论、点赞、转发以及批评指正!
如果大家有更好的方法或有问题可以在文末评论一起讨论!
共同学习!
共同进步!

文末一句话:

既要知其然也要知其所以然;