Hi everybody!
I'm quite new to C++ and especially directX programming. I'm currently working on a very simple "Space Invaders" game, and by that I mean trying to get the very basics working.
Right now I have setup a basic window, loaded the .x model and have it transforming on the screen (just rotating). What I would like to do (for starters) is to have 2 objects of the same type (same model) on the screen, performing different transformations.
Now I think that in order to have multiple objects rendering on screen at 1 time, I will need to do this:
// Loop through all materials and draw each part of the model.
for(DWORD i = 0; i < numMaterials; i++)
{
D3D_Device->SetMaterial(&MaterialList);
D3D_Device->SetTexture(0, TextureList);
SpaceInvader_2->DrawSubset(i);
}
^^The above renders 1 mesh to screen (not 100% how it works, but it does :D).
I also have this code to transform the model every frame:
// This will hold the world matrix.
D3DXMATRIX WorldSpace;
//Buffer matrices
D3DXMATRIX M1;
D3DXMATRIX M2;
//Set the X-axis rotation value to the matrix M2
D3DXMatrixRotationX(&M2, angleX);
//Set the Y-axis rotation value to the matrix M1
D3DXMatrixRotationY(&M1, angleY);
//Multiply M1 and M2 matrices and store the resulting matrix in WorldSpace matrix
D3DXMatrixMultiply(&WorldSpace, &M1, &M2);
//Set the Z-axis rotation value to the matrix M1
D3DXMatrixRotationZ(&M1, angleZ);
//D3DXMatrixTranslation(WorldSpace, x, y, z);
D3DXMatrixMultiply(&WorldSpace, &WorldSpace, &M1);
// Set the matrix.
D3D_Device->SetTransform(D3DTS_WORLD, &WorldSpace);
//--------------------
The thing that I don't understand is how to have 2 meshes (from the same model .x file) in the scene at once, performing different transformations. I have been trying to find an answer in the directX documentation, but I wasn't able to.. Examples that do have more than 1 model on the screen, have WAAAAY to much other code, which makes it very confusing....
Any tips would be much appreciated!
Multiple objects in DirectX 9 - transformation and rendering
D3DXMATRIX world1; // first transformation matrixD3DXMatrixIdentity(&world1);// sets world1 as current transfomation matrix// for all meshes drawn belowD3D_Device->SetTransform(D3DTS_WORLD, &world1);for(DWORD i = 0; i < numMaterials; i++){ D3D_Device->SetMaterial(&MaterialList); // sets material color D3D_Device->SetTexture(0, TextureList); // sets texture SpaceInvader_2->DrawSubset(i);}// now to draw same model but to different locationD3DXMATRIX world2; // second transf. mat.D3DXMatrixIdentity(&world2);D3DXMatrixTranslation(&world, -10.0f, 0.0f, 0.0f); // add little offset to the left// set world2, now all models drawn below will be transformed by this matrixD3D_Device->SetTransform(D3DTS_WORLD, &world2);// draw same modelfor(DWORD i = 0; i < numMaterials; i++){ D3D_Device->SetMaterial(&MaterialList); // sets material color D3D_Device->SetTexture(0, TextureList); // sets texture SpaceInvader_2->DrawSubset(i);}// repeat above for as many instances as you want
Thank you VERY much!! That's exactly what I needed!
One question though - what if (and this is just an example) you needed to create a thousand objects, in that way... is there a more efficient way of doing that? Just curious...
One question though - what if (and this is just an example) you needed to create a thousand objects, in that way... is there a more efficient way of doing that? Just curious...
Then use geometry instancing:
http://msdn.microsoft.com/en-us/library/bb173349%28VS.85%29.aspx
http://msdn.microsoft.com/en-us/library/bb173349%28VS.85%29.aspx
I'v done this a bit different.
I choped it from my (unfinished framework) code for grass rendering:
in some init function
then in render function
I choped it from my (unfinished framework) code for grass rendering:
in some init function
DWORD numInstances = 3000;if(0 != MeshX) { D3DVERTEXELEMENT9 VertexElementsGeom[] = { {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0}, {0, 12, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_NORMAL, 0}, {0, 24, D3DDECLTYPE_FLOAT2, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 0}, {1, 0, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 1}, {1, 16, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 2}, {1, 32, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 3}, {1, 48, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 4}, D3DDECL_END() }; gvSizegeom = D3DXGetDeclVertexSize(VertexElementsGeom, 0); gvSizeInst = D3DXGetDeclVertexSize(VertexElementsGeom, 1); ... ... dev->CreateVertexDeclaration(VertexElementsGeom, &gVDeclaration); meshx->GetMesh()->GetVertexBuffer(&gVBufferGeom); meshx->GetMesh()->GetIndexBuffer(&gIBuffer); dev->CreateVertexBuffer(gvSizeInst * numInstances, D3DUSAGE_WRITEONLY, NULL, D3DPOOL_MANAGED, &gVBufferInst, NULL); Vector3D ppos, prot; ppos.SetAllZero(); prot.SetAllZero(); for(int k = 0; k < numInstances; k++) { ppos = Vector3D(Math::Random(1000.0f) - 1000.0f, -90.0f, Math::Random(1000.0f) - 1000.0f); prot = Vector3D(0.0f, Math::Random(PI * 2.0f), 0.0f); wrld[k].Identity(); wrld[k].SetRotation(prot); wrld[k].SetTranslation(ppos); } Matrix4* pData = 0; gVBufferInst->Lock(0, 0, (LPVOID*)&pData, 0); memcpy(pData, wrld, gvSizeInst * numInstances); gVBufferInst->Unlock(); ... ...}
then in render function
dev->SetVertexDeclaration(gVDeclaration); dev->SetIndices(gIBuffer); dev->SetStreamSourceFreq(0, (D3DSTREAMSOURCE_INDEXEDDATA | numInstances)); dev->SetStreamSource(0, gVBufferGeom, 0, gvSizegeom); dev->SetStreamSourceFreq(1, (D3DSTREAMSOURCE_INSTANCEDATA | 1)); dev->SetStreamSource(1, gVBufferInst, 0, gvSizeInst);... ...gEffect->SetTechnique("tech"); gEffect->SetMatrix(...); ... ... gEffect->SetTexture(...); gEffect->SetFloat("timeNow", ...); gEffect->Begin(0, 0); gEffect->BeginPass(0); dev->DrawIndexedPrimitive(D3DPT_TRIANGLELIST, 0, 0, numVert, 0, numInd); gEffect->EndPass(); gEffect->End(); dev->SetStreamSourceFreq(0, 1); dev->SetStreamSourceFreq(1, 1);
This topic is closed to new replies.
Advertisement
Popular Topics
Advertisement