回调的使用

今天学习回调,回调分为更新回调、拣选回调、绘制。自以为顺序是从左到右的,即更新>拣选>绘制。根据海军教程里的内容,我今天将回调用到之前博客中的地球上,之前的那篇博客只是将球体贴上了世界地图的纹理,现在我们让它自转起来,当然能自转也一定能公转(这个就先不做了,不过一定能够实现)。

1.定义一个用户自定义数据类,当然,这个类一定要从osg::Referenced类派生。

2.定义回调类,重写操作符()。

3.安装回调类。

4.循环仿真。

userData.h

#pragma once
#include <osg/Node>
#include <osg/MatrixTransform>
#include <iostream>
#include <osgText/Text>
#include "myFindNodeVisitor.h"


#ifdef _DEBUG
#pragma comment(lib,"osgd.lib")
#pragma comment(lib,"osgTextd.lib")
#else
#pragma comment(lib,"osg.lib")
#pragma commnet(lib,"osgText.lib")
#endif

class UserData : public osg::Referenced
{
public:
	//构造函数,需要设定从哪个点查找,并设置地球自转速度
	UserData(osg::Node* node,double speed)
	{
		if (node)
		{
			m_earth = NULL;
			m_text = NULL;
			m_rotation = 0.0f;
			m_speed = speed;
			//这个类是前一个博客中的查找结点的类
			myFindNodeVisitor findNode("earthRotation");
			node->accept(findNode);
			osg::MatrixTransform* earth = dynamic_cast<osg::MatrixTransform*>(findNode.getFirst());
			if (earth)
			{
				m_earth = earth;
			}
		}
		
		
		
	}
	void upateRotation()
	{
		if (!m_earth)
		{
			std::cout<<"UserData::m_earth is NULL!"<<std::endl;
			return;
		}
		m_rotation += m_speed;
		if (m_rotation>osg::DegreesToRadians(360.0f))
		{
			m_rotation = 0.0f;
		}
		m_earth->setMatrix(osg::Matrix::rotate(m_rotation,osg::Vec3(0,0,1)));
	}
	
protected:
	
	osg::MatrixTransform* m_earth;
	double m_rotation;
	double m_speed;
};

class callBack : public osg::NodeCallback
{
public:
	//重写操作符()在这里调用用户定义的功能
	virtual void operator ()(osg::Node* node, osg::NodeVisitor* nv)
	{

		osg::ref_ptr<UserData> userData = dynamic_cast<UserData*>(node->getUserData());
		if (userData)
		{
			userData->upateRotation();
			
		}
		traverse(node,nv);
	}
};


 

main.cpp

//By smells2 at Lab 2012-02-21
#include <osg/Group>
#include <osg/Geode>
#include <osg/ShapeDrawable>
#include <osg/Texture2D>
#include <osgViewer/Viewer>
#include <osgDB/readfile>
#include <osgDB/WriteFile>
#include <osg/MatrixTransform>

#include <osg/PositionAttitudeTransform>
#include <osg/TexEnv>
#include <osg/Texture2D>
#include <iostream>
#include "UserData.h"
int main()
{
	osg::ref_ptr<osg::Group> root = new osg::Group;
	osgViewer::Viewer myViewer;

	//Declear Sphere instance,the constructor takes an osg::vec3 to define
	//center and a float to define the radius.
	//Then we declear the ShapDrawable instance that derive from Drawable .We should 
	//initalize it with the shape we create above .
	osg::ref_ptr<osg::Geode> unitSphere = new osg::Geode;
	osg::ref_ptr<osg::Sphere> sphere = new osg::Sphere(osg::Vec3(0,0,0), 1.0f);
	osg::ref_ptr<osg::ShapeDrawable> shapeDrawable = new osg::ShapeDrawable(sphere.get());
	unitSphere->addDrawable(shapeDrawable.get());
	osg::ref_ptr<osg::PositionAttitudeTransform> sphereForm = new osg::PositionAttitudeTransform;
	sphereForm->setPosition(osg::Vec3(2.5,0.0,0.0));
	//sphereForm->addChild(unitSphere.get());
	osg::MatrixTransform* rot = new osg::MatrixTransform;
	rot->setName("earthRotation");
	rot->addChild(unitSphere.get());
	//root->addChild(rot);
	sphereForm->addChild(rot);
	root->addChild(sphereForm.get());
	
	//load image from the file
	osg::ref_ptr<osg::Texture2D> earthTexture = new osg::Texture2D;
	earthTexture->setDataVariance(osg::Object::DYNAMIC);
	osg::ref_ptr<osg::Image> earthImage = osgDB::readImageFile("D:\\OSG\\osg2.9\\OpenSceneGraph2.9.5\\data\\Images\\land_shallow_topo_2048.jpg");
	if (!earthImage.get())
	{
		std::cout<<"load texture failed !"<<std::endl;
		return -1;
	}

	//assign the texture from the image file
	earthTexture->setImage(earthImage.get());

	//set the stateset for decal texture
	osg::ref_ptr<osg::TexEnv> texenv = new osg::TexEnv;
	osg::ref_ptr<osg::StateSet> stateset = new osg::StateSet;
	texenv->setMode(osg::TexEnv::DECAL);
	stateset->setTextureAttributeAndModes(0,earthTexture.get(),osg::StateAttribute::ON);
	stateset->setTextureAttribute(0,texenv.get());

	
	//这里设置回调函数
	UserData* userData = new UserData(root.get(),0.001);
	root->setUserData(userData);
	root->setUpdateCallback(new callBack);

	//realize
	root->setStateSet(stateset.get());
	myViewer.setSceneData(root.get());
	myViewer.realize();
	myViewer.run();
}


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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值