Irrlicht学习之载入irr文件和自定义场景节点

Irrlicht学习之载入irr文件和自定义场景节点

 

         在上一篇文章中,我尝试载入了Irrlicht自定义的场景文件irr文件。这回我将尝试用代码将irr文件载入以及自定义场景节点绘制出坐标轴。

Irr文件实质上是一个XML文件,它里面包含了场景的各种资源,可以被引擎中的一个模块IrrXML进行读取,生成则主要由IrrEdit来完成。

演示程序和源代码下载地址:这里

首先是演示程序截图:

         程序中载入了一个irr文件的场景、创建了XYZ轴,最后读取了sydney角色。整个场景中没有用到光照,所以场景中的颜色是其本原色。

         载入irr场景非常简单。在获得了ISceneManager的指针后,可以通过调用

virtual bool irr::scene::ISceneManager::loadScene (const io::path& filename, ISceneUserDataSerializer* userDataSerializer = 0)

来载入irr场景。下面介绍一下如何自定义场景节点。

首先需要定义一个自定义类,继承于ISceneNode类,随后重载OnRegisterSceneNode()、render()、getBoundingBox()、getMaterialCount()、getMaterial()这几个虚函数。这里需要注意一下,哪怕场景节点是像坐标轴那样只有颜色,几乎没有什么材质纹理的,我们重载getMaterialCount()、getMaterial()时也要返回1和一个材质。否则会导致其颜色成为全局光的颜色以及深度值错乱等等现象。我在Irrlicht论坛上提问了,最后还是自己解决的。下面是自定义坐标轴类的源代码:

#ifndef _AXISNODE_H_
#define _AXISNODE_H_
 
#include <ISceneNode.h>
 
class AxisNode: public ISceneNode
{
public:
    AxisNode( ISceneNode* pParent, ISceneManager* pMgr, s32 id ):
      ISceneNode( pParent,pMgr, id )
      {
         const f32 length = 40.0f;
         vertices[0] =S3DVertex(
             0, 0, 0,               // 位置
             0, 1, 0,               // 法线
             SColor( 255, 255,0, 0 ), // 颜色
             0, 0 );                // 纹理坐标
         vertices[1] =S3DVertex(
             length, 0, 0,             // 位置
             0, 1, 0,               // 法线
             SColor( 255, 255,0, 0 ), // 颜色
             0, 0 );                // 纹理坐标
         vertices[2] =S3DVertex(
             0, 0, 0,               // 位置
             0, 1, 0,               // 法线
             SColor( 255, 0, 255,0 ), // 颜色
             0, 0 );                // 纹理坐标
         vertices[3] =S3DVertex(
             0, length, 0,             // 位置
             0, 1, 0,               // 法线
             SColor( 255, 0,255, 0 ), // 颜色
             0, 0 );                // 纹理坐标
         vertices[4] =S3DVertex(
             0, 0, 0,               // 位置
             0, 1, 0,               // 法线
             SColor( 255, 0, 0,255 ), // 颜色
             0, 0 );                // 纹理坐标
         vertices[5] =S3DVertex(
             0, 0, length,             // 位置
             0, 1, 0,               // 法线
             SColor( 255, 0, 0,255 ), // 颜色
             0, 0 );                // 纹理坐标
 
         // 添加到碰撞盒中
         box.reset(vertices[0].Pos );
         for ( s32 i = 1; i < 6; ++i )box.addInternalPoint( vertices[i].Pos );
 
         // 新添加坐标文字
        SceneManager->addTextSceneNode(
            SceneManager->getGUIEnvironment( )->getSkin( )->getFont( ),  // 字体
             L"x",                  // 文字
             SColor( 255, 255, 0, 0 ), // 颜色
             this,                  // 父节点
             vector3df( length,0.0f, 0.0f ),// 相对位置
             -1 );                  //ID号
 
        SceneManager->addTextSceneNode(
            SceneManager->getGUIEnvironment( )->getSkin( )->getFont( ),  // 字体
             L"y",                  // 文字
             SColor( 255, 0, 255, 0 ), // 颜色
             this,                  // 父节点
             vector3df( 0.0f,length, 0.0f ),// 相对位置
             -1 );                  //ID号
 
        SceneManager->addTextSceneNode(
            SceneManager->getGUIEnvironment( )->getSkin( )->getFont( ),  // 字体
             L"z",                  // 文字
             SColor( 255, 0, 0,255 ), // 颜色
             this,                  // 父节点
             vector3df( 0.0f,0.0f, length ),// 相对位置
             -1 );                  //ID号
      }
      virtualvoid OnRegisterSceneNode()
      {
         if ( IsVisible )
            SceneManager->registerNodeForRendering( this);
        ISceneNode::OnRegisterSceneNode( );
      }
      virtualvoid render( void)
      {
         static u16 indices[ ] = { 0, 1, 2, 3, 4, 5 };
         IVideoDriver* pDriver= SceneManager->getVideoDriver( );
 
        pDriver->setMaterial( getMaterial( 0 ) );
         pDriver->setTransform(video::ETS_WORLD, AbsoluteTransformation );// 设置矩阵变换
        pDriver->drawVertexPrimitiveList(
             &vertices[0],          // 顶点数组的首地址
             6,                 // 顶点数目
             &indices[0],       // 索引数组的首地址
             3,                 // 图元数目
             EVT_STANDARD,          // 顶点的种类
             EPT_LINES,         // 图元形状
             EIT_16BIT );       // 索引位大小
      }
      virtualconst core::aabbox3d<f32>&getBoundingBox( void ) const
      {
         return box;
      }
      virtualu32 getMaterialCount( void ) const
      {
         return 1;
      }
      virtualvideo::SMaterial& getMaterial( u32 i )
      {
         static SMaterial dummyMaterial;
         return dummyMaterial;
      }
private:
    S3DVertex            vertices[6];
    core::aabbox3d<f32>      box;
};
 
#endif

  • 3
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 11
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 11
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值