Ogre中的材质(Material)

     在Ogre中,Overlay、Entity、Particle等都会用到材质。 Ogre中的材质脚本只不过是指定程序该如何去使用纹理(Texture),具体关于材质脚本的编写及参数可参考ogre中文手册。下面来说说一般的材质应用:

    材质做为一种资源,它也有它自己的资源管理器(MaterialManager)。 一般管理器都是使用了单件模式,在程序中都只有一个对像。 要获取一个材质在程序中就可以这样MaterialPtr mat= MaterialManager::getSingleton().getByName(strName),其中strName就是材质脚本中定义材质的名字了。这样我们就可以通过mat(可以是在当指针的方式用)在程序动态修改我们的材质了。

    在材质脚本中,第一行应该是定义材质名,如:material Example/CloudSky。那么“Example/CloudSky”就是这个材质的名字了(在Ogre中名种脚本资源名并不是用文件名来定义的,因为一个文件中可以存在多个资源脚本,包括Overlay、Particle也是这样)。下面来个最简单的材质脚本:

material Template/texture_map
{
   technique
   {
      pass
       {
         texture_unit
         {
           texture image.png
         }
      }  
   }
}

在该材质脚本中,定义了一个技术(在脚本中可以有多个技术存在,以支持不同的配置的电脑,一般对硬件要求高的技术会放在前面),定义了一个通道和一个纹理单元。

在材质中实现透明贴图。 很多时候,我们希望在我们使用的材质能够透明地贴在已有的纹理上(透明的地方不显示),这样我们可以在Pass里面的scene_blend设置为alpha_blend来实现。同样,如果我们要在程序中实现可以这样:mat->getTechnique(0)->getpass(0)->setSceneBlending(SBT_TRANSPARENT_ALPHA)。当然,我们可以以一定的透明度来显示,可以在TextureUnit中通过设置alpha_op_ex来实现。如我们要实现0.5的透明度:在脚本中:alpha_op_ex modulate src_texture src_manual 0.5  ;在程序中,我们可以这样设置mat->getTechnique(0)->getpass(0)->getTextureUnitState(0)->setAlphaOperation(LBX_MODULATE,LBS_TEXTURE,LBS_MANUAL,1.0,0.5);

   深度缓冲。在材质中我们还可以在Pass中把深度缓冲(depth_check)关掉(在脚本中加入:depth_check off),这样应用该材质的实体或其它就不会被其它前面的东西所遮住了。有时我们需要这样做,比如在Overlay中加入一个3D实体,不能让移动时Overlay加入的3D实体让场景中的实体给遮住了。

  材质继承。 材质脚本是可以继承的(其实叫复制更准确),但确实让我们少写了很多重复的设置。当我们的几个材质的大部分设置相同的时候(比如二个材质仅仅是使用的纹理不同),那使用材质继承最好不过了。比如:

material OldMaterial
{
   technique
   {
      pass
       {
          lighting off
          scene_blend alpha_blend
         texture_unit
         {

           texture_alias StateTexture       // 在这里需要给纹理单元设置一个别名
           tex_address_mode  clamp       // 设置纹理寻址模式,具体请看Ogre手册
           texture OldFile.png
         }
      }  
   }
}

现在我们的新材质 NewMaterial  要继承 OldMaterial 。仅仅只设置不同的纹理,而其它属性和OldMaterial 相同,我们可以这样写:

material NewMaterial  : OldMaterial  // 像不像C语言里面的继承,只是没有了修饰类型而已。 

{

      set_texture_alias StateTexture newFile.png   // 设置新的纹理,这里纹理别名就重要了

}                         是不是我们要写的脚本更方便,更准确了呢?

当然我们还可以在材质继承中设置或修改属性。比如在 NewMaterial  继承 OldMaterial  时把光照打开:

material NewMaterial  : OldMaterial 

{
   technique
   {
      pass
       {
         lighting on
         texture_unit
         {
           texture newFile.png     // 这样就用不着纹理别名了
         }
      }  
   }
}

   纹理操作。在材质脚本中,纹理单元可以用scroll_anim设置一个纹理滚动动画,后面二个属性是水平和垂直方向的滚动量,当然在程序中也可以用TextureUnitState::setScrollAnimation();来设置;scroll可以指定纹理的滚动量,在程序中用TextureUnitState::setTextureScroll();。用rotate_anim来指定纹理的旋转动画,在程序中可以用TextureUnitState::setRotateAnimation();来设置;rotate可以指定纹理的旋转量,在程序中用TextureUnitState::setTextureRotate();来设置。  scale 可以用来设置当前大小,程序中使用TextureUnitState::setTextureScale();来设置应用比例。当然,如果你会操作矩阵,你也可以用transform 来设置以上各种效果。 在脚本中还可以用wave_xform 来实现各种波动效果,这常常用于实现水波等效果。

  其实在材质脚本中还可以实现其它很多效果,比如镜面反射、反光等。还可以实现地面效果,可以看这里:http://www.ogre3d.org/wiki/index.php/

你可能感兴趣的:(OGRE)