Ogre:Hardwarebuffer

來源:互聯網
上載者:User

     
Ogre中的硬體緩衝是指在顯卡上的儲存,這和在記憶體上的儲存一樣是可以訪問的。有三種硬體緩衝:HardwareVertexBuffer(頂點緩衝,儲存頂點的各種資料)、HardwareIndexBuffer(索引緩衝,儲存一個mesh的面片的頂點索引),HardwarePixelBuffer(紋理緩衝,儲存某個紋理貼圖的資料)。這些資料在程式運行時都在顯卡的儲存上,然而你可以去讀和寫這些資料,來操控程式中物體的形狀、紋理等。這個用處是非常大的。在Ogre中與訪問這些硬體緩衝有關的類及他們相互間的關係如: 
 

  1.  

根據這個圖進行解釋

1、最上面的hardwarevertexbuffer
讀寫:如果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指標,指向的就是快取資料。拿著這個指標就可以讀取改寫等

建立:使用hardwarebuffermanager的create來建立,建立後利用hardwarevertexbuffer的write寫入資料

2.中間的hardwareindexbuffer
讀寫:直接使用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");

 

本文來自CSDN部落格,轉載請標明出處:http://blog.csdn.net/leonwei/archive/2010/08/10/5799770.aspx

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.