   [D3D9] stream size too small
  I'm currently trying to extend my skinned animation system to include vertex tweening between morph targets (eg facial animation of the head mesh).  I'm almost there, except for one final hurdle:When I try to render the morphed vertices using multiple streams, I get the debug error:Direct3D9: (ERROR) :Stream 1 size is too smallFirst-chance exception at 0x7c812afb in d3d engine.exe: Microsoft C++ exception: long at memory location 0x0012f058..Direct3D9: (ERROR) :DrawIndexedPrimitive failed.D3D9 Helper: IDirect3DDevice9::DrawIndexedPrimitive failed: D3DERR_INVALIDCALLIf I run it in the retail runtime, it almost works.  It renders as if a few of the vertexes don't match up.I'm not really sure where the problem is though - the two meshes being used for data are exact copies in 3D studio, only one has some vertices translated.  And in the code they are clones of the same data.The code I use to load and clone the meshes into the required formats is:D3DVERTEXELEMENT9 elements[64];UINT numElements=0;g->FVF_Default3D->GetDeclaration(elements, &numElements);// clone mesh to suitable format for optimization and skinningID3DXMesh* tempMesh=NULL;if (f->pMeshContainer->MeshData.pMesh)f->pMeshContainer->MeshData.pMesh->CloneMesh(D3DXMESH_SYSTEMMEM, elements, g->d3d, &tempMesh);elseDebugBreak(); // no mesh found in the node that's supposed to have a mesh!if (!HasMeshGotNormals(tempMesh))GenerateNormals(tempMesh);DWORD* adj = new DWORD[tempMesh->GetNumFaces()*3];LPD3DXBUFFER remap=0;tempMesh->GenerateAdjacency(0.001f, adj);ID3DXMesh* oMesh=0;tempMesh->Optimize(D3DXMESH_SYSTEMMEM | D3DXMESHOPT_VERTEXCACHE | D3DXMESHOPT_ATTRSORT, adj,0, 0, &remap, &oMesh);tempMesh->Release();delete[] adj;mini->skin->Remap(oMesh->GetNumVertices(), (DWORD*)remap->GetBufferPointer());remap->Release();// convert to skinned meshDWORD numBoneCombo=0;ID3DXBuffer* boneTable=0;mini->numBones = mini->skin->GetNumBones();HRESULT hr = mini->skin->ConvertToIndexedBlendedMesh(oMesh, D3DXMESH_MANAGED,mini->numBones, 0, 0, 0, 0,&mini->maxBoneInfluences, &numBoneCombo, &boneTable, &mini->mesh);if (hr!=S_OK)DebugBreak(); // failed to build index blended mesh// clean up optimization varsif (oMesh)oMesh->Release();if (boneTable)boneTable->Release();if (mini->meshName.find("morph_")!=string::npos){// convert to morph targetD3DVERTEXELEMENT9 elems[64];UINT n;g->FVF_MorphTarget->GetDeclaration(elems, &n);LPD3DXMESH old = mini->mesh;mini->mesh->CloneMesh(D3DXMESH_MANAGED, elems, g->d3d, &mini->mesh);old->Release();}Where the code checks if it's named as a morph target, then converts the morph target to a declaration that is just 3 floats for position and 3 floats for normals.  (the morph targets are the data that gets sent into stream 1).  Then to render I do:if (m->activeMorphs && myfx->morphWeight){g->d3d->SetVertexDeclaration(m->decl);g->d3d->SetStreamSource(0, m->vBuffer, 0, m->stride);g->d3d->SetStreamSource(1, m->activeMorphTarget->vBuffer, 0, m->activeMorphTarget->stride);g->d3d->SetIndices(m->iBuffer);g->d3d->DrawIndexedPrimitive(D3DPT_TRIANGLELIST, 0, 0, m->mesh->GetNumVertices(),0, m->mesh->GetNumFaces());g->d3d->SetStreamSource(1, NULL, 0, 0);}where 'm' is a pointer to a struct containing various bits of mesh data.  The m->decl is a declaration that contains the standard blended mesh declaration, plus two more fields for position1 and normal1 in stream 1.The strides are correct - I double checked that.  With the stride in stream 0 being enough to stride only the stream 0 components of the declaration, and the stride used in stream 1 enough to stride the 6 floats (position and normal) in the vbuffer.So I'm at a loss as to why the buffer is too small.  PIX isn't being much help here as it shows the input buffers to be what I would expect, and it's saying it can't process the vertices and so won't let me check out the pre/post VS data.Anyone got any ideas why it's saying stream 1 is too small?   
  Can you show where you are setting your vertex declarations? (m->decl) Maybe something is wrong there?I have messed mine up several times, but usually I get the error that the stride doesn't match the declaration. So I personally haven't seen this error, just trying to help from what little I know.   ;  I have custom code that copies the declaration from the mesh to be morphed, and adds the two components for stream 1, so the code itself wouldn't make a lot of sense to anyone unfamiliar with it, but I checked it in PIX, and m->decl looks like:float3 position0;float2 blendweights;ubyte4 blendIndices;float3 normal0;DWORD color;float2 texcoord0;float3 position1; // stream 1float3 normal1 // stream 1I checked the byte offsets and they are all correct (it was actually the source of another bug I had where I forgot to set the stream 1 byte offsets to start at zero, so you can be sure they got a lot of attention).Also, checking in pix, stream 0 definitely gets the data pos0, blendweights, blendindices, normal0, color, texcoord0.  And stream 1 definitely gets pos1, normal1.  And yes, I know that the registers used are meaningless, and yes the data being fed in is the right size.  I checked this by setting up PIX's buffer display to show the fields as they are in the declaration, and they all matched up perfectly from start to finish.Right now I'm leaning towards the possibility the mesh data gets changed during the call to ConvertToIndexedBlendedMesh in some way that is affecting the indexing later on, but that seems unlikely.Also, could it be something to do with the frequency of data sampling from the streams?  I don't think I need to use SetStreamSourceFreq because I'm not instancing.  The two buffers should match up by stride size alone, but I've never used the frequency thing, so I'm not 100% sure if I have that right.   ;  It definitely wouldn't hurt to set the Stream Frequencies.I personally have only done it with instancing. But I think you should set them both to:SetStreamSourceFreq(0, (D3DSTREAMSOURCE_INDEXEDDATA | numToDraw))//Just guessing on this one...SetStreamSourceFreq(1, (D3DSTREAMSOURCE_INDEXEDDATA | numToDraw))//For me this was//SetStreamSourceFreq(1, (D3DSTREAMSOURCE_INSTANCEDATA | 1));//DRAWSetStreamSourceFreq(0,1);SetStreamSourceFreq(1,1);As for ConvertToIndexedBlendedMesh affecting the indexing... You have already done the remap so you should be fine.See if setting the frequency helps.   ;  Setting the frequency didn't help.  I tried setting the number to draw to both numFaces*3 and 1, (I figured maybe it should be 1 because I'm not instancing).  Neither helped, but the numFaces*3 crippled performance, so I'm guessing that's very wrong :)Maybe I'll try making some other meshes.  I can't see it being the meshes (they're exact duplicates of each other), but you never know.   ;  Hmm, seems I was wrong - the vertex buffers aren't quite the same size.  For some reason the morph target mesh (the position1, normal1 only mesh) has lost two vertices.  The base skinned mesh has 185 vertices, and the target mesh has 183.  How very strange.All I'm doing is cloning the mesh to a new declaration - how could that make it lose two vertices?This explains the small stream error problem, but it raises more questions than it answers.edit:Turns out it is the mesh - but it seems to be any mesh I make has this problem.In 3D Studio, the meshes are identical - they are simply clones of one another.  Same number of faces, same number of vertices, same materials etc.  Yet after exporting (using the panda exporter) one of them loses 2 vertices.I can't imagine it being the exporter - if it gets two meshes of identical structure, surely it would export two identical scene nodes.  This is going to be one of those annoying problems, I can feel it...edit2:Found it.  Thanks for your help guys, but it was a problem with the exporter after all.  Apparently if you export two identical meshes with the setting "optimized mesh", then it's a crapshoot as to whether or not they'll be identical in the file.  After I turned off optimization, the mesh counts matched and the tweening works perfectly.   ;  That is odd...Do you copy the data from the optimized one? (Or maybe optimize both?)Also, you could compare the two buffers, see which ones get lost.Edit: Well there you go! Congrats :)   