Sign in to follow this  
GRoss

Multiple objects in DirectX 9 - transformation and rendering

Recommended Posts

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[i]);
D3D_Device->SetTexture(0, TextureList[i]);

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!

Share this post


Link to post
Share on other sites

D3DXMATRIX world1; // first transformation matrix
D3DXMatrixIdentity(&world1);

// sets world1 as current transfomation matrix
// for all meshes drawn below
D3D_Device->SetTransform(D3DTS_WORLD, &world1);

for(DWORD i = 0; i < numMaterials; i++)
{
D3D_Device->SetMaterial(&MaterialList[i]); // sets material color
D3D_Device->SetTexture(0, TextureList[i]); // sets texture

SpaceInvader_2->DrawSubset(i);
}

// now to draw same model but to different location
D3DXMATRIX 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 matrix
D3D_Device->SetTransform(D3DTS_WORLD, &world2);

// draw same model
for(DWORD i = 0; i < numMaterials; i++)
{
D3D_Device->SetMaterial(&MaterialList[i]); // sets material color
D3D_Device->SetTexture(0, TextureList[i]); // sets texture

SpaceInvader_2->DrawSubset(i);
}

// repeat above for as many instances as you want


Share this post


Link to post
Share on other sites
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...

Share this post


Link to post
Share on other sites
I'v done this a bit different.
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);



Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this