Ogre:Hardwarebuffer-阿里云开发者社区

开发者社区> leonwei> 正文

Ogre:Hardwarebuffer

简介:
+关注继续查看
  1.      
  2. Ogre中的硬件缓存是指在显卡上的存储,这和在内存上的存储一样是可以访问的。有三种硬件缓存:HardwareVertexBuffer(顶点缓存,存储顶点的各种数据)、HardwareIndexBuffer(索引缓存,存储一个mesh的面片的顶点索引),HardwarePixelBuffer(纹理缓存,存储某个纹理贴图的数据)。这些数据在程序运行时都在显卡的存储上,然而你可以去读和写这些数据,来操控程序中物体的形状、纹理等。这个用处是非常大的。在Ogre中与访问这些硬件缓存有关的类及他们相互间的关系如下图:
  1. hardwarebuffer 
  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");

版权声明:本文内容由阿里云实名注册用户自发贡献,版权归原作者所有,阿里云开发者社区不拥有其著作权,亦不承担相应法律责任。具体规则请查看《阿里云开发者社区用户服务协议》和《阿里云开发者社区知识产权保护指引》。如果您发现本社区中有涉嫌抄袭的内容,填写侵权投诉表单进行举报,一经查实,本社区将立刻删除涉嫌侵权内容。

相关文章
怎么设置阿里云服务器安全组?阿里云安全组规则详细解说
阿里云服务器安全组设置规则分享,阿里云服务器安全组如何放行端口设置教程
7122 0
阿里云服务器ECS远程登录用户名密码查询方法
阿里云服务器ECS远程连接登录输入用户名和密码,阿里云没有默认密码,如果购买时没设置需要先重置实例密码,Windows用户名是administrator,Linux账号是root,阿小云来详细说下阿里云服务器远程登录连接用户名和密码查询方法
3081 0
阿里云服务器端口号设置
阿里云服务器初级使用者可能面临的问题之一. 使用tomcat或者其他服务器软件设置端口号后,比如 一些不是默认的, mysql的 3306, mssql的1433,有时候打不开网页, 原因是没有在ecs安全组去设置这个端口号. 解决: 点击ecs下网络和安全下的安全组 在弹出的安全组中,如果没有就新建安全组,然后点击配置规则 最后如上图点击添加...或快速创建.   have fun!  将编程看作是一门艺术,而不单单是个技术。
4539 0
使用OpenApi弹性释放和设置云服务器ECS释放
云服务器ECS的一个重要特性就是按需创建资源。您可以在业务高峰期按需弹性的自定义规则进行资源创建,在完成业务计算的时候释放资源。本篇将提供几个Tips帮助您更加容易和自动化的完成云服务器的释放和弹性设置。
7949 0
windows server 2008阿里云ECS服务器安全设置
最近我们Sinesafe安全公司在为客户使用阿里云ecs服务器做安全的过程中,发现服务器基础安全性都没有做。为了为站长们提供更加有效的安全基础解决方案,我们Sinesafe将对阿里云服务器win2008 系统进行基础安全部署实战过程! 比较重要的几部分 1.
5492 0
阿里云服务器安全组设置内网互通的方法
虽然0.0.0.0/0使用非常方便,但是发现很多同学使用它来做内网互通,这是有安全风险的,实例有可能会在经典网络被内网IP访问到。下面介绍一下四种安全的内网互联设置方法。 购买前请先:领取阿里云幸运券,有很多优惠,可到下文中领取。
9462 0
腾讯云服务器 设置ngxin + fastdfs +tomcat 开机自启动
在tomcat中新建一个可以启动的 .sh 脚本文件 /usr/local/tomcat7/bin/ export JAVA_HOME=/usr/local/java/jdk7 export PATH=$JAVA_HOME/bin/:$PATH export CLASSPATH=.
2188 0
+关注
87
文章
0
问答
文章排行榜
最热
最新
相关电子书
更多
文娱运维技术
立即下载
《SaaS模式云原生数据仓库应用场景实践》
立即下载
《看见新力量:二》电子书
立即下载