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); }
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); for( size_t j=0; j < mInstancesPerBatch; ++j ) buf->WriteData(sd.GetSize()*j, sd.GetSize(), sd.data); 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* thisBufOrg = DI_NEW char[size]; char* thisBuf = thisBufOrg; 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->WriteData(0, size, thisBufOrg); DI_DELETE[] thisBufOrg; mSourceData.push_back(buf); }