Ogre:Hardwarebuffer

  1.      
  2. Ogre中的硬件缓存是指在显卡上的存储,这和在内存上的存储一样是可以访问的。有三种硬件缓存:HardwareVertexBuffer(顶点缓存,存储顶点的各种数据)、HardwareIndexBuffer(索引缓存,存储一个mesh的面片的顶点索引),HardwarePixelBuffer(纹理缓存,存储某个纹理贴图的数据)。这些数据在程序运行时都在显卡的存储上,然而你可以去读和写这些数据,来操控程序中物体的形状、纹理等。这个用处是非常大的。在Ogre中与访问这些硬件缓存有关的类及他们相互间的关系如下图:
  1.  
  2. 根据这个图进行解释
  3. 1、最上面的hardwarevertexbuffer
  4. 读写:如果mesh使用的所有子mesh共享buffer的形式,则用mesh的sharedvertexdata,否则用submesh的vertexdata来得到vertexdata结构,vertexdata封装了对该mesh的顶点缓存数据的访问方式,但是却不直接包含这些顶点缓存数据。vertexdata中的vettexbufferbinding可以知道当前的vertexdata对应了确切的硬件上的哪块buffer,可以通过vettexbufferbinding的getBuffer确切的得到该顶点缓存,而vertexdata中的vertexdeclaration则是一个对他对应的buffer进行各种访问的接口,里面有访问的格式等。如果要开始操纵这个buffer,需要将getbuffer得到的hardwarevertexbuffer调用lock,然后将这片缓存上锁,这个lock返回了一个void指针,指向的就是缓存数据。拿着这个指针就可以读取改写等
  5. 创建:使用hardwarebuffermanager的create来创建,创建后利用hardwarevertexbuffer的write写入数据
  6. 2.中间的hardwareindexbuffer
  7. 读写:直接使用submesh的indexdata来得到一个indexdata结构,再调用它的hardwareindexbuffer的来得到这个顶点缓存,童年顶点缓存一样再调用lock来进行读写操作

创建:同顶点缓存

3最下面的hardwarepixelbuffer

读写:从texture中可以直接得到这个hardwarepixelbuffer,然后对它lock后就可以得到一个pixelbox的数据,pixebox封装了所有纹理数据及其各种属性信息

创建:texture是由texturemanager创建的

下面是一些具体的使用硬件缓存的例子

读取顶点和索引缓存

    Ogre::MeshPtr meshPtr=mainEntity->getMesh();
   //假设这里使用的是share的形式
    Ogre::VertexData* vertex_data=meshPtr->sharedVertexData;

   //得到位置数据的信息
    const Ogre::VertexElement* posElem =vertex_data->vertexDeclaration->findElementBySemantic(Ogre::VES_POSITION);

//得到纹理坐标数据的信息
    const Ogre::VertexElement* texcoElem=vertex_data->vertexDeclaration->findElementBySemantic(Ogre::VES_TEXTURE_COORDINATES );
    //得到位置和纹理的缓存
    Ogre::HardwareVertexBufferSharedPtr posBuf =vertex_data->vertexBufferBinding->getBuffer(posElem->getSource());
    Ogre::HardwareVertexBufferSharedPtr texcoBuf =vertex_data->vertexBufferBinding->getBuffer(texcoElem->getSource());
     //顶点位置缓存的lock,读取
    unsigned char* vertexPos =static_cast<unsigned char*>(posBuf->lock(Ogre::HardwareBuffer::HBL_READ_ONLY));

//将第一个点的位置读出
    float* pReal;

//这个函数的作用是将当前vertexPos指向的数据用其他型(这里是float*)的指针指向,这样读出来的数据就是float型的了,或者用float型的数据进行写入
    posElem->baseVertexPointerToElement(vertexPos, &pReal);
   Ogre::Vector3 pt(pReal[0], pReal[1], pReal[2]);
//访问之后要上锁
    posBuf->unlock();
   
    //读取索引信息
          Ogre::SubMesh* submesh = meshPtr->getSubMesh( i );

     //得到这个submesh的indexdata
        Ogre::IndexData* index_data = submesh->indexData;
        int numTris = index_data->indexCount / 3;

//得到indexbuffer
        Ogre::HardwareIndexBufferSharedPtr ibuf = index_data->indexBuffer;
        bool use32bitindexes = (ibuf->getType() == Ogre::HardwareIndexBuffer::IT_32BIT);

//得到具体的索引缓存数据
        unsigned long*  pLong = static_cast<unsigned long*>(ibuf->lock(Ogre::HardwareBuffer::HBL_READ_ONLY));
        unsigned short* pShort = reinterpret_cast<unsigned short*>(pLong);

          … …
          ibuf->unlock();

访问纹理缓存

    Ogre::HardwarePixelBufferSharedPtr crossPixbufferPtr=texture.getPointer()->getBuffer(0,0);       
    crossPixbufferPtr->lock(Ogre::HardwareBuffer::HBL_NORMAL);
    Ogre::PixelBox pb=crossPixbufferPtr->getCurrentLock();
    int height = pb.getHeight();
    int width = pb.getWidth();
    int pitch = pb.rowPitch; // Skip between rows of image   
    uint32* data=static_cast<uint32*>(pb.data);

     ……操纵data……
    crossPixbufferPtr->unlock();

创建顶点缓存和索引缓存,进而根据其创建一个自定义的mesh

void createColourCube()
    {
    /// Create the mesh via the MeshManager
    Ogre::MeshPtr msh = MeshManager::getSingleton().createManual("ColourCube", "General");
    /// Create one submesh
    SubMesh* sub = msh->createSubMesh();
    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
    };
    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
    /// Define 12 triangles (two triangles per cube face)
    /// The values in this table refer to vertices in the above table
    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
    };
    /// Create vertex data structure for 8 vertices shared between submeshes
    msh->sharedVertexData = new VertexData();
    msh->sharedVertexData->vertexCount = nVertices;
    /// Create declaration (memory format) of vertex data
    VertexDeclaration* decl = msh->sharedVertexData->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, msh->sharedVertexData->vertexCount, HardwareBuffer::HBU_STATIC_WRITE_ONLY);
    /// Upload the vertex data to the card
    vbuf->writeData(0, vbuf->getSizeInBytes(), vertices, true);
    /// Set vertex buffer binding so buffer 0 is bound to our vertex buffer
    VertexBufferBinding* bind = msh->sharedVertexData->vertexBufferBinding;
    bind->setBinding(0, vbuf);
    // 2nd buffer
    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, msh->sharedVertexData->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
    sub->useSharedVertices = true;
    sub->indexData->indexBuffer = ibuf;
    sub->indexData->indexCount = ibufCount;
    sub->indexData->indexStart = 0;
    /// 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();
    }

然后可以从mesh直接创建entity放在场景中

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

时间: 2024-09-19 08:54:09

Ogre:Hardwarebuffer的相关文章

OGRE 1.7 例子程序分析

如果你自己都不清楚所谈论的东西,就根本不可能精确的描述它--冯诺依曼   今天我就试着来表述一件众人皆知的事情,以测试自己到底有没有明白这件事情.   OGRE是著名的设计模式大师,这已是不争的事实.可以说OGRE里将设计模式用得淋漓尽致.在这里我就不批判设计模式该不该用了.反正OGRE已经用了,并且没有出现什么不好的结果.适合的就是最好的,OGRE证明了这一点.   随着OGRE  1.7的发布,大家熟悉的DEMO程序不见了,换来的是一个个的DLL库.而这些库,就是作为OGRE的一个插件而存在

OGRE学习笔记之一

开始学习3D了,很早就想学了,怎奈数学不好,一直畏惧,可是如果不直面它,就永远的害怕,永远的逃避,这是在很糟.于是,我终于开始了我的3D之旅.在学校时候就看上了OGRE,十几万行代码的图形引擎,它给我的感觉很好.不过奇怪的是国内似乎根本没有OGRE的社区,曾经是在91看到的,可是那边早已经荒废了. 我使用的是OGRE的 1.2.4,VC是VC.net 2003,也就是VC7.1.我是下载源代码,自行编译的,编译需要两个包,我选择了以下两个包:OgreDependencies_VC71_1.2.0

ogre中 如何将载入的.mesh 读出它的具体信息,比如geometry,bounds等

问题描述 ogre中 如何将载入的.mesh 读出它的具体信息,比如geometry,bounds等 在做 一个类似ogre meshy的软件,不知道载入文件后,.mesh文件的内容是怎么显示出来的 解决方案 http://blog.csdn.net/zhuxiaoyang2000/article/details/6122079

OGRE材质

"材质(material)",材质是一个很基本的术语,表示你的物体对光的反射方式.但是对它的实现并不像其解释这样简单,我们会用这一章节进行详细地介绍Ogre中相关的技术. 我们刚才提及过,材质定义了物体对光线反射的处理方法.这里暗示了材质的表现与光源的类型相关:聚光(Spotlights).点光源(point lights)以及有向光(directional lights)对材质的表现有着完全不同的影响.简单来讲,它们都是对物理世界真实光源类型的模拟,所以材质对它们的反射也遵守着其在物

Ogre:Animation(Ogre中的动画)

   在Ogre中Animation是一块非常重要的部分,但是笔者在学习Ogre的动画时遗憾的发现关于Ogre中动画的资料非常的少,Ogre的sample中只有最简单的导入一个骨骼动画的例子,在网上也很少有人谈及,Ogre Wiki中的教程也是边边角角,不知这么重要的部分为什么不做一个全面的tutorial.我从网上的仅有的一些资料和自己的亲自试验总结了一下基本的Ogre动画的使用,当然Ogre的动画模块非常庞大,我总结的只是冰山一角,但是也是最常用的部分.    Ogre的动画框架: 这其中最

如何将ogre编译成apk 运行 求详细步骤或者链接也可以.

问题描述 如何将ogre编译成apk 运行 求详细步骤或者链接也可以. 如何将ogre编译成apk 运行 求详细步骤或者链接也可以.

OGRE Code Review HOWTO

Table of Contents Introduction The Process What to Look For Style Design Guidelines OGRE Specific Guidelines Introduction The time has come for all good men to come to the aid of their favorite rendering engine. The OGRE Project needs you to help wit

Ogre中手动创建硬代码材质(Material)

Ogre中的材质一般都是读取*.material尾缀的文件. 1.首先使用Ogre::MaterialManager中的create方法创建一个材质,例如:         Ogre::MaterialPtr red            = Ogre::MaterialManager::getSingleton().create("DebugLines/Disabled","DebugLines"); 第一个参数为 材质名:第二个参数为 资源组,用来卸载的时候用.

ogre-particle Universe plugin在OGRE中如何使用

问题描述 particle Universe plugin在OGRE中如何使用 怎样使用已做好的粒子特效呢,在OGRE中,教程上说的不是太清楚 解决方案 Ogre粒子编辑器ParticleUniversehttp://blog.csdn.net/zhuxiaoyang2000/article/details/9209959 解决方案二: http://blog.csdn.net/zhuxiaoyang2000/article/details/9209959