예제 #1
0
void MeshLoader_v0::ReadVertexStream(VertexBufferPtr & vb, int & stride, int count, DataStreamPtr & stream)
{
    EXCEPTION_DEBUG(vb.IsNull(), "model file error.");

    stream->Read(&stride, sizeof(int));

    vb = VideoBufferManager::Instance()->CreateVertexBuffer(stride * count, stride);
    
    void * data = vb->Lock(0, 0, LOCK_DISCARD);

    stream->Read(data, stride * count);

    vb->Unlock();
}
예제 #2
0
void SimpleObj::UpdateGeomtry()
{
    int decl_flag = _DECL_POSITION;

    if (m_normals.Size())
    {
        debug_assert(m_normals.Size() == mositions.Size(), "normal size != position size.");
        decl_flag |= _DECL_NORMAL;
    }

    if (m_colors.Size())
    {
        debug_assert(m_colors.Size() == mositions.Size(), "color size != position size.");
        decl_flag |= _DECL_COLOR;
    }

    if (m_texcoords.Size())
    {
        debug_assert(m_texcoords.Size() == mositions.Size(), "texcoord size != position size.");
        decl_flag |= _DECL_TEXCOORD;
    }

    int stride = 0;

    if (decl_flag != m_decl_flag)
    {
        VertexDeclarationPtr decl = VideoBufferManager::Instance().CreateVertexDeclaration();

        decl->AddElement(0, 0, DECLTYPE_FLOAT3, DECLMETHOD_DEFAULT, DECLUSAGE_POSITION, 0);
        stride += 12;

        if (decl_flag & _DECL_NORMAL)
        {
            decl->AddElement(0, stride, DECLTYPE_FLOAT3, DECLMETHOD_DEFAULT, DECLUSAGE_NORMAL, 0);
            stride += 12;
        }

        if (decl_flag & _DECL_COLOR)
        {
            decl->AddElement(0, stride, DECLTYPE_FLOAT4, DECLMETHOD_DEFAULT, DECLUSAGE_COLOR, 0);
            stride += 16;
        }

        if (decl_flag & _DECL_TEXCOORD)
        {
            decl->AddElement(0, stride, DECLTYPE_FLOAT2, DECLMETHOD_DEFAULT, DECLUSAGE_TEXCOORD, 0);
            stride += 8;
        }

        decl->EndDecl();

        m_decl_flag = decl_flag;

        mVertexStream.SetDeclaration(decl);
    }

    stride = mVertexStream.GetDeclaration()->GetStreamSize(0);

    int size = stride * mositions.Size();

    VertexBufferPtr buffer = mVertexStream.GetStream(0);

    if (buffer.IsNull() || buffer->GetSize() < size)
    {
        buffer = VideoBufferManager::Instance().CreateVertexBuffer(size, USAGE_WRITEONLY, POOL_MANAGED);
    }


    //Update Geomtry;

    Vector<Vec3>::Iterator      pi;
    Vector<Vec3>::Iterator      pe;
    Vector<Vec3>::Iterator      ni;
    Vector<Vec3>::Iterator      ne;
    Vector<Color4>::Iterator    ci;
    Vector<Color4>::Iterator    ce;
    Vector<Vec2>::Iterator      ti;
    Vector<Vec2>::Iterator      te;

    pi = mositions.Begin();
    pe = mositions.End();
    ni = m_normals.Begin();
    ne = m_normals.End();
    ci = m_colors.Begin();
    ce = m_colors.End();
    ti = m_texcoords.Begin();
    te = m_texcoords.End();

    char * verteces;
    buffer->Lock(0, 0, (void**)&verteces, LOCK_DISCARD);

    while (pi != pe)
    {
        int offset = 0;

        if (m_decl_flag & _DECL_POSITION)
        {
            float * position = (float*)(verteces + offset);

            if (pi != pe)
            {
                position[0] = pi->x;
                position[1] = pi->y;
                position[2] = pi->z;

                ++pi;
            }

            offset += sizeof(Vec3);
        }


        if (m_decl_flag & _DECL_NORMAL)
        {
            float * normal = (float*)(verteces + offset);

            if (ni != ne)
            {
                normal[0] = ni->x;
                normal[1] = ni->y;
                normal[2] = ni->z;

                ++ni;
            }

            offset += sizeof(Vec3);
        }

        if (m_decl_flag & _DECL_COLOR)
        {
            float * color = (float*)(verteces + offset);

            if (ci != ce)
            {
                color[0] = ci->r;
                color[1] = ci->g;
                color[2] = ci->b;
                color[3] = ci->a;

                ++ci;
            }

            offset += sizeof(Color4);
        }

        if (m_decl_flag & _DECL_TEXCOORD)
        {
            float * texcoord = (float*)(verteces + offset);

            if (ti != te)
            {
                texcoord[0] = ti->x;
                texcoord[1] = ti->y;

                ++ti;
            }
        }

        verteces += stride;
    }
    
    buffer->Unlock();

    mVertexStream.Bind(0, buffer, stride);
    mVertexStream.SetCount(mositions.Size());

    //update index buffer
    if (mndeces.Size())
    {
        debug_assert(mndeces.Size() < 65536, "Simple object index buffer is to large.");
        size = sizeof(short) * mndeces.Size();

        IndexBufferPtr ibuffer = mIndexStream.GetStream();
        
        if (mIndexStream.GetCount() < mndeces.Size())
        {
            ibuffer = VideoBufferManager::Instance().CreateIndexBuffer(size, USAGE_WRITEONLY, POOL_MANAGED, FMT_INDEX16);
        }

        short * indeces;
        ibuffer->Lock(0, 0, (void**)&indeces, LOCK_DISCARD);
        Memcpy(indeces, &mndeces[0], size);
        ibuffer->Unlock();

        mIndexStream.Bind(ibuffer, 0);
    }

    mIndexStream.SetCount(mndeces.Size());

    switch (mPrimType)
    {
    case PRIM_POINTLIST:
        SetPrimitiveCount(mndeces.Size() ? mndeces.Size() : mositions.Size());
        break;

    case PRIM_LINELIST:
        SetPrimitiveCount(mndeces.Size() ? mndeces.Size() / 2 : mositions.Size() / 2);
        break;

    case PRIM_LINESTRIP:
        SetPrimitiveCount(mndeces.Size() ? mndeces.Size() - 1 : mositions.Size() - 1);
        break;

    case PRIM_TRIANGLELIST:
        SetPrimitiveCount(mndeces.Size() ? mndeces.Size() / 3 : mositions.Size() / 3);
        break;

    case PRIM_TRIANGLESTRIP:
        SetPrimitiveCount(mndeces.Size() ? mndeces.Size() - 2 : mositions.Size() - 2);
        break;

    case PRIM_TRIANGLEFAN:
        SetPrimitiveCount(mndeces.Size() ? mndeces.Size() - 2 : mositions.Size() - 2);
        break;
    }
}