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); }
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; }
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); }
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); } }
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); } }