Ogre中手动创建mesh

来源:互联网 发布:linux 清空tmp 编辑:程序博客网 时间:2024/06/10 03:28

在一个可以正常运行的ogre程序里边,找到createscene函数,添加如下代码:

 

//定义对象并设置材质名称与绘制模式

ManualObject* manual = mSceneMgr->createManualObject("manual");

manual->begin("BaseWhiteNoLighting", nderOperation::OT_LINE_STRIP);

       bool test = false;

       if(test)

       {     

           //平面

           //指定定点位置

           manual->position(-100.0, -100.0, 0.0);

           manual->position( 100.0, -100.0, 0.0);

           manual->position( 100.0,  100.0, 0.0);

           manual->position(-100.0,  100.0, 0.0);

           manual->position(0,200.0,0);

//指定索引顺序,就是绘制定点的顺序,如果不指定就一句定点列出的顺序依次绘制        

           manual->index(0);

           manual->index(1);

           manual->index(2);

           manual->index(4);

           manual->index(3);   

           manual->index(0);

          

       }

       else

       {

           //立方体

           //指定定点位置

           manual->position(-100.0, -100.0, 100.0);

           manual->position( 100.0, -100.0, 100.0);

           manual->position( 100.0,  -100.0, -100.0);

           manual->position(-100.0,  -100.0, -100.0);

           manual->position(-100.0,   100.0,100.0);

           manual->position( 100.0,  100.0, 100.0);

           manual->position(100.0,  100.0, -100.0);

           manual->position(-100,100.0,-100);

   //指定索引顺序,就是绘制定点的顺序,如果不指定就一句定点列出的顺序依次绘制

           manual->index(0);

           manual->index(1);

           manual->index(2);

           manual->index(3);

           manual->index(0);   

           manual->index(4);

           manual->index(5);

           manual->index(6);

           manual->index(7);

           manual->index(4);

           manual->index(7);

           manual->index(3);

           manual->index(2);

           manual->index(6);

           manual->index(5);

           manual->index(1);

       }

 

       manual->end(); //结束定点设置。这里的beginend对应于d3d中读写定点缓存时的loack unlock !

       //将手动对象创建为mesh

       manual->convertToMesh("testMesh");

       Entity * tempEntity = SceneMgr->createEntity("cube","testMesh");

mSceneMgr->getRootSceneNode()->createChildSceneNode()->attachObject(tempEntity);

 

//也可以不创建mesh,直接将对象挂在节点也是可以显示的

mSceneMgr->getRootSceneNode()->createChildSceneNode()->attachObject(manual)

 

绘制模式参数设置参看参看

 

http://www.ogre3d.org/wiki/index.php/ManualObject

 

Ogre手动创建mesh(N个submesh)

 

Mesh与submesh以及创建submesh中数据项之间的关系如下:

  

下面是代码示例:

 

在程序中加入如下2个函数:

 

//为mesh创建2个submesh,并填充submesh的数据。

void createColourCube()

    {

       /// 从mesh管理器中创建mesh

    Ogre::MeshPtr msh = MeshManager::getSingleton().createManual("ColourCube", "General");

 

       //mesh包含2个子实体

       SubMesh * sub1 = msh->createSubMesh("2");

       SubMesh * sub2 = msh->createSubMesh("1");

       //分别为个子实体填充数据

        fillSubMesh(sub1,1); //fill函数在后边定义

         fillSubMesh(sub2,2);

 

 

       /// Set bounding information (for culling)

       msh->_setBounds(AxisAlignedBox(-100,-100,-100,100,100,100));

       msh->_setBoundingSphereRadius(Math::Sqrt(3*100*100));

       /// Notify Mesh object that it has been loaded

       msh->load();

    }

    //填充顶点的所需要的信息,并写入缓存

    void fillSubMesh(SubMesh * submeshPtr, int i)

    {

       //填充子实体所需的数据项

       //法线

       const float sqrt13 = 0.577350269f; /* sqrt(1/3) */

           /// Define the vertices (8 vertices, each consisting of 2 groups of 3 floats

       const size_t nVertices = 8;

       const size_t vbufCount = 3*2*nVertices;

       float vertices[vbufCount] = {

           -100.0,100.0,-100.0,        //0 position

           -sqrt13,sqrt13,-sqrt13,     //0 normal

           100.0,100.0,-100.0,         //1 position

           sqrt13,sqrt13,-sqrt13,      //1 normal

           100.0,-100.0,-100.0,        //2 position

           sqrt13,-sqrt13,-sqrt13,     //2 normal

           -100.0,-100.0,-100.0,       //3 position

           -sqrt13,-sqrt13,-sqrt13,    //3 normal

           -100.0,100.0,100.0,         //4 position

           -sqrt13,sqrt13,sqrt13,      //4 normal

           100.0,100.0,100.0,          //5 position

           sqrt13,sqrt13,sqrt13,       //5 normal

           100.0,-100.0,100.0,         //6 position

           sqrt13,-sqrt13,sqrt13,      //6 normal

           -100.0,-100.0,100.0,        //7 position

           -sqrt13,-sqrt13,sqrt13,     //7 normal

       };

 

       float vertices2[vbufCount] = {

           200.0,100.0,-100.0,        //0 position

           -sqrt13,sqrt13,-sqrt13,     //0 normal

           400.0,100.0,-100.0,         //1 position

           sqrt13,sqrt13,-sqrt13,      //1 normal

           400.0,-100.0,-100.0,        //2 position

           sqrt13,-sqrt13,-sqrt13,     //2 normal

           200.0,-100.0,-100.0,       //3 position

           -sqrt13,-sqrt13,-sqrt13,    //3 normal

           200.0,100.0,100.0,         //4 position

           -sqrt13,sqrt13,sqrt13,      //4 normal

           400.0,100.0,100.0,          //5 position

           sqrt13,sqrt13,sqrt13,       //5 normal

           400.0,-100.0,100.0,         //6 position

           sqrt13,-sqrt13,sqrt13,      //6 normal

           200.0,-100.0,100.0,        //7 position

           -sqrt13,-sqrt13,sqrt13,     //7 normal

       };

 

       //给每个点点设置颜色

       RenderSystem* rs = Root::getSingleton().getRenderSystem();

       RGBA colours[nVertices];

       RGBA *pColour = colours;

       // Use render system to convert colour value since colour packing varies

rs->convertColourValue(ColourValue(1.0,0.0,0.0), pColour++); //0 colour

           rs->convertColourValue(ColourValue(1.0,1.0,0.0), pColour++); //1 colour

       rs->convertColourValue(ColourValue(0.0,1.0,0.0), pColour++); //2 colour

       rs->convertColourValue(ColourValue(0.0,0.0,0.0), pColour++); //3 colour

       rs->convertColourValue(ColourValue(1.0,0.0,1.0), pColour++); //4 colour

       rs->convertColourValue(ColourValue(1.0,1.0,1.0), pColour++); //5 colour

       rs->convertColourValue(ColourValue(0.0,1.0,1.0), pColour++); //6 colour

       rs->convertColourValue(ColourValue(0.0,0.0,1.0), pColour++); //7 colour

 

       /// 定义个面所需要的个三角形的索引顺序

       const size_t ibufCount = 36;

       unsigned short faces[ibufCount] = {

           0,2,3,

           0,1,2,

           1,6,2,

           1,5,6,

           4,6,5,

           4,7,6,

           0,7,4,

           0,3,7,

           0,5,1,

           0,4,5,

           2,7,3,

           2,6,7

       };

 

      

      

      

      

      

         /// 为子实体创建存储定点数据的空间以及指定顶点的数量

           submeshPtr->vertexData = new VertexData();

           submeshPtr->vertexData->vertexCount = nVertices;

 

           // Create declaration (memory format) of vertex data

           //指定顶点使用的格式    

 VertexDeclaration*    decl = submeshPtr->vertexData->vertexDeclaration;

           size_t offset = 0;

           // 1st buffer

           //写入顶点坐标数据信息

           decl->addElement(0, offset, VET_FLOAT3, VES_POSITION);

           offset += VertexElement::getTypeSize(VET_FLOAT3);

           decl->addElement(0, offset, VET_FLOAT3, VES_NORMAL);

           offset += VertexElement::getTypeSize(VET_FLOAT3);

              /// Allocate vertex buffer of the requested number of vertices (vertexCount)

           /// and bytes per vertex (offset) 

           //分配顶点所需要的硬件缓冲 

           HardwareVertexBufferSharedPtr vbuf =

              HardwareBufferManager::getSingleton().createVertexBuffer(

                    offset, submeshPtr->vertexData->vertexCount, HardwareBuffer::HBU_STATIC_WRITE_ONLY);

           /// Upload the vertex data to the card

           //将数据写入缓存

 

       if(i == 1)

       {

           vbuf->writeData(0, vbuf->getSizeInBytes(), vertices, true);     //将顶点信息写入缓存

       }

       if(i == 2)

       {

           vbuf->writeData(0, vbuf->getSizeInBytes(), vertices2, true);     //将顶点信息写入缓存

 

       }

      

 

       /// Set vertex buffer binding so buffer 0 is bound to our vertex buffer

        VertexBufferBinding* bind = submeshPtr->vertexData->vertexBufferBinding;

        bind->setBinding(0, vbuf);

 

      

 

 

       //顶点颜色缓存创建

       offset = 0;

   

    decl->addElement(1, offset, VET_COLOUR, VES_DIFFUSE);

       offset += VertexElement::getTypeSize(VET_COLOUR);

       /// Allocate vertex buffer of the requested number of vertices (vertexCount)

       /// and bytes per vertex (offset)

       vbuf = HardwareBufferManager::getSingleton().createVertexBuffer(

           offset, submeshPtr->vertexData->vertexCount, HardwareBuffer::HBU_STATIC_WRITE_ONLY);

       /// Upload the vertex data to the card

       vbuf->writeData(0, vbuf->getSizeInBytes(), colours, true);

       /// Set vertex buffer binding so buffer 1 is bound to our colour buffer

       bind->setBinding(1, vbuf);

 

       //创建索引缓存并写入

       /// Allocate index buffer of the requested number of vertices (ibufCount)

       HardwareIndexBufferSharedPtr ibuf = HardwareBufferManager::getSingleton().createIndexBuffer(                                 HardwareIndexBuffer::IT_16BIT,                                        ibufCount,                                          

                  HardwareBuffer::HBU_STATIC_WRITE_ONLY);

// Upload the index data to the card     

ibuf->writeData(0, ibuf->getSizeInBytes(), faces, true);

// Set parameters of the submesh      

       submeshPtr->useSharedVertices = false;

       submeshPtr->indexData->indexBuffer = ibuf;

       submeshPtr->indexData->indexCount = ibufCount;

       submeshPtr->indexData->indexStart = 0;

   

}

 

 

 

 

 

 

 

 

 

 

然后在createscene函数中加入如下代码:

createColourCube();//创建数据

 

Entity* thisEntity = mSceneMgr->createEntity("cc", "ColourCube");

        thisEntity->getSubEntity("1")->setMaterialName("Test/ColourTest");

 

thisEntity->getSubEntity("2")->setMaterialName("Test/ColourTest");

SceneNode* thisSceneNode = mSceneMgr->getRootSceneNode()->createChildSceneNode();

       thisSceneNode->setPosition(-35, 0, 0);

       thisSceneNode->attachObject(thisEntity);

 

然后再将下面的材质脚本加入到ogre的General资源组中:

 

material Test/ColourTest

{

    technique

    {

        pass

        {

            ambient vertexcolour

        }

    }

}

之后编译运行,你可以看到有2个彩色的立方体在摄像机前面。下面给出过程总结:

1.  从mesh创建submesh。

2.  为submesh的各个数据结构分配空间并设置。

主要有如下几项:vertexdata,indexdata.

3.  为vertexdata指定顶点格式以及为其分配硬件缓存并与之绑定。

4.  分配indexdata的硬件空间和colorvalue的硬件空间。

5.  分别将对应的vertexdata,indexdata,colorvalue写入对应的缓存。

6.  之后做一些设置。如果没有使用mesh的共享缓存,则要关闭submesh的使用共享缓存设置。