-
DirectX transformations
This is giving me trouble, and I can't figure out any logical reason why it works one way and won't work the other.
This way works:
In WinMain(), I declared the following variables:
Code:
D3DXMATRIX matRotationX, matRotationY, matRotationZ, matTranslation;
Those are the matrices to take coordinates from object space and convert them to world space. So, of course, in my DirectX loop I have the following calls:
Code:
D3DXMatrixRotationX(&matRotationX,g_Transform.GetXRotation());
D3DXMatrixRotationY(&matRotationY,g_Transform.GetYRotation());
D3DXMatrixRotationZ(&matRotationZ,g_Transform.GetZRotation());
D3DXMatrixTranslation(&matTranslation,g_Transform.GetXTranslation(),
g_Transform.GetYTranslation(),g_Transform.GetZTranslation());
g_App.GetDevice()->SetTransform(D3DTS_WORLD,&(matRotationX*matRotationY*matRotationZ*matTranslation));
g_App is a global instance of my CApplication class, which basically just handles initializing a window and direct3D, and then initializing the scene (render states, and temporarily, lighting).
g_Transform is a global instance of my CTransformation class. In the version that works, it just contains the following variables and methods for setting/getting each of them (should be self-explanatory)
Code:
float fRotationX,fRotationY,fRotationZ,
fTranslationX,fTranslationY,fTranslationZ;
That works great. The only problem is that it's going to turn into a mess down the line if I handle those matrices in WinMain(), as soon as I get more than one primitive and they need to be transformed differently.
So, I wanted to put the matrices in the CTransformtion class, and have the class keep them updated when the rotation/translation variables are changed, and just have WinMain call a method of CTransform which would return the world matrix.
I coded that in, with a bunch of methods that look like this:
Code:
float CTransformation::ChangeXRotation(float fDeltaX)
{
fRotationX+=fDeltaX;
D3DXMatrixRotationX(&matRotationX, fRotationX);
return fRotationX;
}
and then
Code:
D3DXMATRIX* CTransformation::GetWorldTransform(void)
{
return &(matRotationX*matRotationY*
matRotationZ*matTranslation);
}
I changed WinMain() in the appropriate places to reflect the changes to the CTransformation class, and it compiled without error, but when I executed it, the primitive was no longer displayed. Switching WinMain() back to the original version makes it work again, so I think the problem must lie either in the new code in the CTransformation class, or there is something within DirectX that explains it. Any ideas? I'm going to try sticking all the calls which change a matrix between BeginScene() and EndScene() calls and see if that does anything... just thought of that. If it works, I'll post again with a "nevermind" ;) Comments about any inefficiencies you see with what I just said would be appreciated though.
edits: formatting the code to require less scrolling on the board
-
Darn, it didn't work. I thought I was on to something with BeginScene() and EndScene(). Can anyone offer me guidance?
-
If you post the code I will take a look at it.
-
Source for the whole program (so far) is attached. It's around 1,000 lines though, so I hope you can narrow it down quickly.
edit: I just realized there's a (very minor) error in the code I attached. Replace
inline D3DXMATRIX* GetWorldTransform(void) {return &(matRotationX*matRotationY*matRotationZ*matTransl ation);}
in ctransformation.h with this:
D3DXMATRIX* GetWorldTransform(void);
-
Okay found your problem.
When you are multiplying all of your matrices together check the values ;) You need to load in the identity matrices for matrices you haven't altered. In the constructor try this.
Code:
D3DXMatrixIdentity( &matRotationX );
D3DXMatrixIdentity( &matRotationY );
D3DXMatrixIdentity( &matRotationZ );
D3DXMatrixIdentity( &matTranslation );
If you just create a matrix with D3DX's default constructor it will be all zero's not identity. And when you multiply by that it will be bad. Enjoy.
-
I added that in, but it didn't fix the problem of the primitive not being displayed. :confused:
Here's the modified ctransformation.cpp file
-
-
-
Okay, I won't lie to you. I converted your project over to DirectX 8.1 and fixed it there. So maybe the problem is 9 specific? I'm currently downloading the 9 sdk ( on my father's machine ) and I will try again.
-
Woot!
I fixed it.
Code:
//in main
g_App.GetDevice()->SetTransform(D3DTS_WORLD,&(g_Transform.GetWorldTransform()));
//in ctransformation
D3DXMATRIX CTransformation::GetWorldTransform(void)
{
D3DXMatrixRotationX(&matRotationX,fRotationX);
D3DXMatrixRotationY(&matRotationY,fRotationY);
D3DXMatrixRotationZ(&matRotationZ,fRotationZ);
D3DXMatrixTranslation(&matTranslation,fTranslationX,fTranslationY,fTranslationZ);
return (matRotationX*matRotationY*matRotationZ*matTranslation);
}
I realized I didn't have to update the matrices every time one of the floats changed either. The problem was just some silly business with pointers... I didn't think before I wrote that and I got it wrong.