osg 貼圖

爲了在VR手柄上作按鈕所作的一個研究, 假設圖片分爲上下兩部分, 一個是射線移入的狀態(正指向本按鈕的狀態) 一個是射線移開的初始的狀態.node

上次切換圖片, 會出現內存出錯, 此次用改變帖圖座標的方式. 本例用的貼圖是OSG data文件夾帶有的.數組

運行結果是: 測試

隔5幀替換一次帖圖幀:code

代碼:orm

#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();	
}
相關文章
相關標籤/搜索