材质做为一种资源,它也有它自己的资源管理器(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/Materials