Home

Awesome

This binary file contains some baked 3D data (read bak3d with an inverted 'E' ) very much ready to be sent down to graphic APIs. The idea is to provide in the most direct way the data that we need to render some geometry.

It should not be considered as a scene, nor as a scene-graph. The only scene-graph-looking feature is the hierarchy of transformations. But I didn't want to venture to scene graph work for two reasons :

You should considere it as a piece of data that one would want to use in a more complex scene definition. In other words, a scene-graph definition could be maintaned outside, while a bk3d file would be used to add data to this graph. In other words, you could consider one bk3d file as one Mesh object.

bk3d file can be created from various ways (to be published here asap) :

Features

How to use it

The use of this file is fairly easy :

Note that this binary file obviously doesn't provide the tools to compute anything : it only contains data for these computations. This work must be done by the applications. For example, the curve computation, the transformations must be calculated by the application.

Here are the main objects available in this file :

Here is an example on how to use a Mesh in the simplest way ever : by using the immediate mode of OpenGL

glEnableClientState(GL_VERTEX_ARRAY);
glEnableClientState(GL_NORMAL_ARRAY);
for(int i=0; i< meshFile->pMeshes->n; i++)
{
    bk3d::Mesh *pMesh = meshFile->pMeshes->p[i];
    //glBindBuffer(GL_ARRAY_BUFFER, 0);
    glVertexPointer(
        pMesh->pAttributes->p[0].p->numComp, 
        pMesh->pAttributes->p[0].p->formatGL,
        pMesh->pAttributes->p[0].p->strideBytes,
        pMesh->pAttributes->p[0].p->pAttributeBufferData);
    glNormalPointer(
        pMesh->pAttributes->p[1].p->formatGL,
        pMesh->pAttributes->p[1].p->strideBytes,
        pMesh->pAttributes->p[1].p->pAttributeBufferData);
    for(int pg=0; pg<pMesh->pPrimGroups->n; pg++)
    {
        glDrawElements(
            pMesh->pPrimGroups->p[pg]->topologyGL,
            pMesh->pPrimGroups->p[pg]->indexCount,
            pMesh->pPrimGroups->p[pg]->indexFormatGL,
            pMesh->pPrimGroups->p[pg]->pIndexBufferData);
    }

}

Note that arguments for drawcalls are available from the bk3d data. The idea behind this approach : baked data are supposed to be usable as fast as possible. They grouping of primitives was done at export time and is available for rendering without further work.

The same is true for Direct 9/10/11 : arguments are also available directly from the bk3d data. However DX10/11 requires you to create an Input layout from the attributes to use. Such a structure is not available from here. However the data exposed here are enough to generate the Input Layout.

Every modern renderer will use buffers : VBO/IBO for OpenGL and vertex buffers for DX. In this case additional setup must be done prior to use bk3d meshes.

This essentially boils down to walk through Meshes and create a DX/OpenGL buffer object for every single buffer of vertices and every buffer of Elements.

A convenient way is to attach to any bk3d::Mesh data that will maintain DX or OpenGL resources : you can store these additional data via the "userPtr" ( bk3d::Mesh::userPtr, bk3d::Slot::userPtr and bk3d::PrimGroup::userPtr ) . Then everytime you need to access the Mesh's resources, you can use a wrapper to extend the access of extra data :

class OGLMeshWrapper
{
...
    Mesh *    m_pMesh;
    OGLMeshWrapper(Mesh *pMesh, COGLSceneHelper* pOwner=NULL) : m_pMesh(pMesh) {}
    inline  AttrMapping*        getAttrMapping() { 
        return (AttrMapping*) m_pMesh->userPtr;
    }
    inline  AttrMapping*        createAttrMapping(AttrMapping* p=NULL) { 
        m_pMesh->userPtr = (p ? p : malloc(sizeof(AttrMapping)));
        if(m_pMesh->userPtr) ZeroMemory(m_pMesh->userPtr, sizeof(AttrMapping));
        return (AttrMapping*) m_pMesh->userPtr;
    }
    // we can even redefine '->' operator to directly access m_pMesh...
...
{;

Then you can do a cheap wrapping of bk3d::Mesh with OGLMeshWrapper anywhere, as a local variable :

for(int i=0; i< header->pMeshes->n; i++) {
    OGLMeshWrapper oglMesh(header->pMeshes->p[i])
    ...

More details are available from COGLSceneHelper & OGLMeshWrapper classes, as an example.

TODO

\todo camera infos, deformers (Lattice, sculpt...), lights...


    Copyright (c) 2013, Tristan Lorach. All rights reserved.

    THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ``AS IS'' AND ANY
    EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
    IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
    PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR
    CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
    EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
    PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
    PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
    OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
    (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
    OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.