manual_object

来源:互联网 发布:合金弹头 知乎 编辑:程序博客网 时间:2024/06/18 11:57

通常在Ogre中我们是导入点mesh文件来进行构造实体的,但是很多情况下我们可能就需要创建一个非常简单的平面或是线,或是有时想自己在程序中创建这样物体,这就需要用到Ogre的manual object。

class _OgreExport ManualObject : public MovableObject{public:    ManualObject(const String& name);    virtual ~ManualObject();    ...}

MO是movable object的简写。moveableobject 在Ogre 3D中,可作为多种不同类的基类。可借助场景结点移动的所有东西都是继承自movableobject类。
只有MovableObject的子类可以被关联到场景结点上。

所有继承自movableobject类的子类的思维图

创建MovableObject步骤通常是:

  1. 需要先用场景管理器去创建一个ManualObject的指针

    Ogre::ManualObject* pRectManual  = mSceneMgr->createManualObject("RectManual");

    其中,createManualObject函数的定义:

    virtual ManualObject* createManualObject(const String& name);
  2. 然后使用ManualObject的begin/end对进行绘制:

    pRectManual ->begin("MyMaterial", RenderOperation::OT_TRIANGLE_LIST);...pRectManual ->end();

    其中,begin函数的定义:

    virtual void begin(const String& materialName,            RenderOperation::OperationType opType = RenderOperation::OT_TRIANGLE_LIST);

    首先制定你需要绘制什么元素,用什么材质。然后下面就制定点的信息

    • 每次用pRectManual->position指定一个点的位置

    • 然后在这句后面和下一个pRectManual->position前面指定这个顶点的颜色、法向等

    • 如果不指定颜色信息,那么该点的颜色为上一个指定了颜色的顶点的颜色。

    • 最后加pRectManual ->end();

    • 你可以再一个manulobject中书写多个begin end对

      如1:

      pRectManual ->begin("MyMaterial", RenderOperation::OT_TRIANGLE_LIST);pRectManual ->position(5.0, 0.0, 0.0);//位置坐标pRectManual ->textureCoord(0,1);      //纹理坐标pRectManual ->position(-5.0, 10.0, 0.0);pRectManual ->textureCoord(1,0);pRectManual ->position(-5.0, 0.0, 0.0);pRectManual ->textureCoord(1,1);pRectManual ->position(5.0, 10.0, 0.0);pRectManual ->textureCoord(0,0);//使用索引来描述四边形manual->index(0);manual->index(1);manual->index(2);manual->index(0);manual->index(3);manual->index(1);pRectManual ->end();//为四边形创建点

      如2:

      manual->begin("MyMaterial1", RenderOperation::OT_TRIANGLE_LIST);manual->position(2.5, 0.0, 4.3);manual->textureCoord(1,1);manual->position(-2.5, 10.0, -4.3);manual->textureCoord(0,0);manual->position(-2.0, 0.0, -4.3);manual->textureCoord(0,1);manual->position(2.5, 0.0, 4.3);manual->textureCoord(1,1);manual->position(2.5, 10.0, 4.3);manual->textureCoord(1,0);manual->position(-2.5, 10.0, -4.3);manual->textureCoord(0,0);manual->end();
  3. 在场景中渲染(两种方法)

    • scenenode::attach到一个节点上
    mSceneMgr->getRootSceneNode()->createChildSceneNode("Node1")->attachObject(pRectManual );

    其中attachObject函数的定义为:

    virtual void attachObject(MovableObject* obj);
    • 或者有时你需要将这个manualobject转化为一个mesh,需要调用manualobject的convertToMesh函数
    pRectManual->convertToMesh("pRectManual");

    其中convertToMesh函数的定义为:

    virtual MeshPtr convertToMesh(const String& meshName,           const String& groupName =ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME);

六种方法来指定输出的manual object 的信息

有三种不同东西可以使用manual object 创建,即为:点,线和三角形

    1. 点被简单的存储为列。每次我们添加一个新的位置,我们创建一个新的点。这种模式被称为OT_POINT_LIST
  • 线

    有两种不同的方法来创建它们

    1. 一个比较易懂的方法就是使用第一和第二的点的连线作为第一条线,第三和第四个位置的连线作为第二条线,等等。这被称为OT_LINE_LIST

    2. 另一种方式使用开始两个点作为第一条线,然后每个新定义的点作为新线的最后一个点并使用最后一个点作为这条线的另一个端点; 这是OT_LINE_STRIP方式

    这里写图片描述

  • 三角形

    1. 第一种是最简单的方式是triangle list:前三个点作为一三角形,然后三个作为第二个三角形,如此类推。这被称为OT_TRIANGLE_LIST。

    2. 使用前点三个作为第一个三角形并且每个新点使用前两个定义了的点组成下一个三角形。这被称为OT_TRIANGLE_STRIP 。

    3. 最后一种方式是使用前三个点作为第一个三角形,然后第一个点,上次最后使用的点和新创建的点作为下一个三角形。OT_TRIANGLE_FAN。

    这里写图片描述

纹理映射(texture mapping)

每个顶点除了需要它的位置坐标还需要纹理坐标。纹理坐标由二元组来(u,v)组成。(u,v) 描述它们在图片中的位置,u 是用于x 轴,v 是用于y 轴。(0,0)表示纹理图片的左上角,(1,1)表示纹理图片的右下角。

如果我们使用大于1 的值,有很多种情况会发生,这取决于材质的设置。

  • 使用wrap 模式,那么纹理将会重复。
  • 使用clamp 模式,每个大于1 的值将会减到1.0。如果小于0 也是用同样的方式—— 坐标会被设为0。
  • 使用mirror 模式中,1 变为了0,2 变作了1,在这种情况下反射了纹理,如果它们的值大于2,原始的图片将会再次使用,翻转之后,又是原图,以此类推。
  • 最后的模式定义了边框颜色,在[0,1]之外的所有东西将会被渲染成边框的颜色。

本文的源代码PS:可直接运行.exe