void DiInstanceBatchHardware::SetupVertices( const DiSubMesh* baseSubMesh )
    {
        mRemoveOwnVertexData = true;    

        mVerticesNum = baseSubMesh->GetVerticeNum();

        DiVertexElements elements = baseSubMesh->GetVertexElements();
        int blendSource = RemoveBlendData(elements);

        mVertexDecl = Driver->CreateVertexDeclaration();
        mVertexDecl->AddElements(elements);
        uint16 nextFreeStream = 0;
        
        if (blendSource != -1)
            nextFreeStream = (uint16)blendSource;
        else
            nextFreeStream = mVertexDecl->GetElements().GetStreams();

        uint16 nextFreeUV = mVertexDecl->GetElements().GetNextFreeTexcoord();
        if (nextFreeUV > 8-2)
        {
            DI_WARNING("No enough rooms for texcoords");
            return;
        }

        mVertexDecl->AddElement(nextFreeStream, VERT_TYPE_FLOAT4, VERT_USAGE_TEXCOORD,5);
        mVertexDecl->AddElement(nextFreeStream, VERT_TYPE_FLOAT4, VERT_USAGE_TEXCOORD,6);
        mVertexDecl->AddElement(nextFreeStream, VERT_TYPE_FLOAT4, VERT_USAGE_TEXCOORD,7);
        mVertexDecl->Create();

        DiSubMesh::SourceDataIterator si = baseSubMesh->GetSourceDataIterator();
        while (si.HasMoreElements())
        {
            DiSubMesh::SourceData sd = si.GetNext();

            if ((int)(sd.stream) == blendSource)
            {
                continue;
            }

            DiVertexBuffer* buf = Driver->CreateVertexBuffer();
            uint32 size = sd.GetSize();
            buf->SetStride(sd.stride);
            buf->Create(size,RU_WRITE_ONLY,sd.stream);
            buf->WriteData(0, size, sd.data);
            buf->SetInstanceState(SOURCE_INSTANCE_INDEX);
            buf->SetInstanceNum(mInstancesPerBatch);
            mSourceData.push_back(buf);
        }

        DiVertexBuffer* buf = Driver->CreateVertexBuffer();
        uint32 stride = mVertexDecl->GetElements().GetStreamElementsSize(nextFreeStream);
        uint32 size = mInstancesPerBatch * stride ;
        buf->SetStride(stride);
        buf->Create(size, RU_WRITE_ONLY, nextFreeStream);
        buf->SetInstanceState(SOURCE_INSTANCE_DATA);
        mSourceData.push_back(buf);
    }
Esempio n. 2
0
    size_t DiMeshSerializerImpl::CalcStreamDataSize( const DiSubMesh* pSub )
    {
        size_t size = 0;
        DiSubMesh::SourceDataIterator it = pSub->GetSourceDataIterator();
        while (it.HasMoreElements())
        {
            DiSubMesh::SourceData sd = it.GetNext();

            size += MSTREAM_OVERHEAD_SIZE;
            size += sizeof(uint16);    
            size += sizeof(uint16);    
            size += sd.GetSize();    
        }

        return size;
    }
Esempio n. 3
0
    void DiInstanceBatchShader::SetupNoSkinned( const DiSubMesh* baseSubMesh )
    {
        mVertexDecl = Driver->CreateVertexDeclaration();
        mVertexDecl->AddElements(baseSubMesh->GetVertexElements());
        mVertexDecl->AddElement(mVertexDecl->GetElements().GetStreams(),VERT_TYPE_UBYTE4,VERT_USAGE_BLENDINDICES,0);
        mVertexDecl->Create();

        DiSubMesh::SourceDataIterator si = baseSubMesh->GetSourceDataIterator();
        while (si.HasMoreElements())
        {
            DiSubMesh::SourceData sd = si.GetNext();

            DiVertexBuffer* buf = Driver->CreateVertexBuffer();
            uint32 size = sd.GetSize() * mInstancesPerBatch;
            buf->SetStride(sd.stride);
            buf->Create(size,RU_WRITE_ONLY,sd.stream);
            BYTE* data = (BYTE*)buf->Lock(0,size);
            for( size_t j=0; j < mInstancesPerBatch; ++j )
            {
                memcpy(data + sd.GetSize()*j,sd.data,sd.GetSize());
            }
            buf->Unlock();
            mSourceData.push_back(buf);
        }

        uint16 lastStream = mVertexDecl->GetElements().GetStreams()-1;
        DiVertexBuffer* buf = Driver->CreateVertexBuffer();
        uint32 stride = mVertexDecl->GetElements().GetStreamElementsSize(lastStream);
        uint32 size = baseSubMesh->GetVerticeNum() * stride * mInstancesPerBatch;
        buf->SetStride(stride);
        buf->Create(size, RU_WRITE_ONLY, lastStream);
        char* thisBuf = static_cast<char*>(buf->Lock(0,size));
        for( size_t j=0; j < mInstancesPerBatch; ++j )
        {
            for( size_t k=0; k<baseSubMesh->GetVerticeNum(); ++k )
            {
                *thisBuf++ = mInstancesPerBatch - j - 1;
                *thisBuf++ = mInstancesPerBatch - j - 1;
                *thisBuf++ = mInstancesPerBatch - j - 1;
                *thisBuf++ = mInstancesPerBatch - j - 1;
            }
        }
        buf->Unlock();
        mSourceData.push_back(buf);
    }
Esempio n. 4
0
    void DiMeshSerializerImpl::WriteGeometryVertexBuffer( DiSubMesh* pMesh )
    {
        DiSubMesh::SourceDataIterator it = pMesh->GetSourceDataIterator();
        while (it.HasMoreElements())
        {
            DiSubMesh::SourceData sd = it.GetNext();

            size_t size = MSTREAM_OVERHEAD_SIZE;
            size += sizeof(uint16);
            size += sizeof(uint16);
            size += sd.GetSize();    

            WriteChunkHeader(DI_GEOMETRY_VERTEX_BUFFER,size);
            WriteShorts(&sd.stream,1);
            WriteShorts(&sd.stride,1);
            WriteData(sd.data,sd.GetSize(),1);
        }
    }
Esempio n. 5
0
    void DiInstanceBatchShader::SetupHardwareSkinned( const DiSubMesh* baseSubMesh )
    {
        const size_t numBones = mMotionReference->GetSkeleton()->GetNumBones();//baseSubMesh->GetBlendIndexToBoneIndexMap().size();
        m_usNumWorldMatrices = mInstancesPerBatch * numBones;


        DiVertexElements eles = baseSubMesh->GetVertexElements();

        uint16 nextFreeUV = eles.GetNextFreeTexcoord();
        if (nextFreeUV > 8-1)
        {
            DI_WARNING("No enough rooms of texcoord");
            return;
        }

        uint16 blendstream = eles.GetTypeUsageAtStream(VERT_TYPE_UBYTE4,VERT_USAGE_BLENDINDICES);
        eles.AddElement(blendstream, VERT_TYPE_FLOAT1, VERT_USAGE_TEXCOORD, 7);    //instanceID
        mVertexDecl = Driver->CreateVertexDeclaration();
        mVertexDecl->AddElements(eles);
        mVertexDecl->Create();

        DiSubMesh::SourceDataIterator si = baseSubMesh->GetSourceDataIterator();
        while (si.HasMoreElements())
        {
            DiSubMesh::SourceData sd = si.GetNext();

            DiVertexElements& ves = const_cast<DiSubMesh*>(baseSubMesh)->GetVertexElements();
            DiVertexElements::ElementsList elementlist = ves.GetElementsAtStream(sd.stream);

            DiVertexBuffer* buf = Driver->CreateVertexBuffer();
            uint32 size = sd.GetSize() * mInstancesPerBatch;
            buf->SetStride(sd.stride);
            buf->Create(size, RU_WRITE_ONLY, sd.stream);
            BYTE* startBuf = (BYTE*)buf->Lock(0,size);
            BYTE* data = startBuf;
            BYTE* startSrcBuf = (BYTE*)sd.data;
            BYTE* dataSrc = startSrcBuf;

            for( size_t j=0; j < mInstancesPerBatch; ++j )
            {
                dataSrc = startSrcBuf;
                for (uint32 v = 0; v < sd.numVertices; v++)
                {
                    for (size_t ei = 0; ei < elementlist.size(); ei++)
                    {
                        if (elementlist[ei].Usage == VERT_USAGE_BLENDINDICES)
                        {
                            *(data + elementlist[ei].Offset + 0) = *(dataSrc + elementlist[ei].Offset + 0) + j * numBones;
                            *(data + elementlist[ei].Offset + 1) = *(dataSrc + elementlist[ei].Offset + 1) + j * numBones;
                            *(data + elementlist[ei].Offset + 2) = *(dataSrc + elementlist[ei].Offset + 2) + j * numBones;
                            *(data + elementlist[ei].Offset + 3) = *(dataSrc + elementlist[ei].Offset + 3) + j * numBones;
                        }
                        else if (elementlist[ei].Usage == VERT_USAGE_TEXCOORD && elementlist[ei].UsageIndex == 7)
                        {
                            float* d = (float*)(data + elementlist[ei].Offset);
                            *d = (float)(j*numBones);
                        }
                        else
                        {
                            memcpy(data + elementlist[ei].Offset,dataSrc + elementlist[ei].Offset,
                                DiVertexElements::GetElementTypeSize(DiVertexType(elementlist[ei].Type)));
                        }
                    }
                    data    += const_cast<DiSubMesh*>(baseSubMesh)->GetVertexElements().GetStreamElementsSize(sd.stream);
                    dataSrc += const_cast<DiSubMesh*>(baseSubMesh)->GetVertexElements().GetStreamElementsSize(sd.stream);
                }
            }
            buf->Unlock();
            mSourceData.push_back(buf);
        }
    }