osg texture

In order to do a research on the button on the VR handle, it is assumed that the picture is divided into two parts, one is the state of the ray moving in (the state of the button), and the other is the initial state of the ray moving away.

The last time I switched pictures, there would be a memory error. This time, I used the method of changing the coordinates of the posted image. The textures used in this example are from the OSG data folder.

The result of running is: 

Replace the post image frame every 5 frames:

Code:

#include <osgViewer/Viewer> // 加载 USE_GRAPHICSWINDOW() 所需
#include<osg/Texture2D>
#include<osg/BlendFunc>
#include<osg/AlphaFunc>
#include<osg/TexEnv>


/**
 * 生成一个面片
 */
osg::Node* CreateQuad()
{
	osg::Geode *g1 = new osg::Geode;// 白
	g1->setName("Quad1_为了按钮");

	osg::Geometry *gPlane1 = new osg::Geometry;
	g1->addDrawable(gPlane1);

	// 1.顶点:
	osg::Vec3Array *arrVertex1 = new osg::Vec3Array;
	arrVertex1->push_back(osg::Vec3(-1.0f,0.0f,-1.0f));// 顶点的顺序, 会影响贴图方向
	arrVertex1->push_back(osg::Vec3(-1.0f,0.0f,1.0f));
    arrVertex1->push_back(osg::Vec3(1.0f,0.0f,1.0f));
	arrVertex1->push_back(osg::Vec3(1.0f,0.0f,-1.0f));

	gPlane1->setVertexArray(arrVertex1);

	// 2.颜色:
	osg::Vec4Array *arrColor1 = new osg::Vec4Array;
	arrColor1->push_back(osg::Vec4(.5,.5,.5,1));
	gPlane1->setColorArray(arrColor1,osg::Array::BIND_OVERALL);

	// 3.法线:
	osg::Vec3Array *arrNormal = new osg::Vec3Array;
	arrNormal->push_back(osg::Vec3(0,1,1));
	gPlane1->setNormalArray(arrNormal,osg::Array::BIND_OVERALL);
	
	// 4.顶点关联方式
	gPlane1->addPrimitiveSet(new osg::DrawArrays(osg::PrimitiveSet::QUADS,0,arrVertex1->size()) );

	//为纹理创建数组
	osg::ref_ptr<osg::Vec2Array> tArr0 = new osg::Vec2Array;//创建一个 Vec2Array对象以保存纹理单元 0 的纹理坐标
	tArr0->push_back(osg::Vec2(0,0));
	tArr0->push_back(osg::Vec2(0,1));
	tArr0->push_back(osg::Vec2(1,1));
	tArr0->push_back(osg::Vec2(1,0));
	gPlane1->setTexCoordArray(0,tArr0.get());

	return g1;
}

osg::Node* CreateImageQuad()
{
	
	osg::Node *node1 = CreateQuad();
	
	// 为Quad贴图:
	osg::StateSet *state = node1->getOrCreateStateSet();
	//打开混合
	osg::BlendFunc* bf = new osg::BlendFunc(osg::BlendFunc::SRC_ALPHA, osg::BlendFunc::ONE_MINUS_SRC_ALPHA );
    state->setAttributeAndModes( bf ); 
	// 设不受光照影响:
	state->setMode( GL_LIGHTING, osg::StateAttribute::OFF | osg::StateAttribute::PROTECTED );
	//读图:
	osg::Image *img = osgDB::readImageFile("Images/osg256.png");// Images/lz.rgb
	osg::Texture2D *texture1 = new osg::Texture2D(img);
	state->setTextureAttributeAndModes( 0, texture1 , osg::StateAttribute::ON );

	return node1;
}

/*
测试按钮帧的替换
*/
class FrameCallback:public osg::NodeCallback
{
public:
	FrameCallback(osg::ref_ptr<osg::Vec2Array> v1, osg::Geometry *_geometry):
	  tArr1(v1),geometry(_geometry)
	{
	}

	void operator()(osg::Node* node , osg::NodeVisitor* nv)
	{
		static int i=0;
		++i;
		osg::notify(osg::NOTICE)<<node->getName()<<";"<<std::endl;
		if(0==i%5)
		{
			if(i%2)
			{
				(*tArr1)[3] = osg::Vec2(1,0);
				(*tArr1)[2] = osg::Vec2(1,0.5);		// 这里改变顺序,并不会改变贴图顺序
				(*tArr1)[0] = osg::Vec2(0,0);
				(*tArr1)[1] = osg::Vec2(0,0.5);
			}
			else
			{
				(*tArr1)[3] = osg::Vec2(1,0.5);
				(*tArr1)[2] = osg::Vec2(1,1);		// 这里改变顺序,并不会改变贴图顺序
				(*tArr1)[0] = osg::Vec2(0,0.5);
				(*tArr1)[1] = osg::Vec2(0,1);
			}
			geometry->setTexCoordArray(0,tArr1.get());
		}
		
		traverse(node,nv);
	}
private:
	osg::ref_ptr<osg::Vec2Array> tArr1;
	osg::Geometry *geometry;
};



int main()
{
	osgViewer::Viewer viewer1 ;
	osg::Group *gInteractiveScene = new osg::Group;

	osg::Node *node1 = CreateImageQuad();



	// 取得贴图数据:
	osg::Geode *draw1= node1->asGeode();
	if(!draw1)
	{
		osg::notify(osg::FATAL) << "没取到draw1" << std::endl;
	}
	osg::Drawable *draw2 = draw1->getDrawable(0);

	if(!draw2)
	{
		osg::notify(osg::FATAL) << "没取到draw2" << std::endl;
	}

	osg::Geometry *draw3 = draw2->asGeometry();
	if(!draw3)
	{
		osg::notify(osg::FATAL) << "没取到draw3" << std::endl;
	}

	draw3->getTexCoordArray(0);
	osg::ref_ptr<osg::Vec2Array> tArr1 = (osg::Vec2Array*)draw3->getTexCoordArray(0);
	
	(*tArr1)[0] = osg::Vec2(0,0.5);
	(*tArr1)[1] = osg::Vec2(0,1);
	(*tArr1)[2] = osg::Vec2(1,1);		
	(*tArr1)[3] = osg::Vec2(1,0.5);// 在此,单单修改帖图坐标是有效的, 但是在刷帧回调中, 还要加一句: geometry->setTexCoordArray(0,tArr1.get());

	
	// 刷帧回调:
	gInteractiveScene->addUpdateCallback( new FrameCallback( tArr1 , draw3 ) );


	gInteractiveScene->addChild(node1);	
	viewer1.setSceneData(gInteractiveScene);
	return viewer1.run();	
}

 

Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=324389741&siteId=291194637