Thread: DirectX transformations

  1. #1
    Pursuing knowledge confuted's Avatar
    Join Date
    Jun 2002
    Posts
    1,916

    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
    Last edited by confuted; 08-02-2003 at 04:35 PM.
    Away.

  2. #2
    Pursuing knowledge confuted's Avatar
    Join Date
    Jun 2002
    Posts
    1,916
    Darn, it didn't work. I thought I was on to something with BeginScene() and EndScene(). Can anyone offer me guidance?
    Away.

  3. #3
    Registered User
    Join Date
    Apr 2002
    Posts
    1,571
    If you post the code I will take a look at it.
    "...the results are undefined, and we all know what "undefined" means: it means it works during development, it works during testing, and it blows up in your most important customers' faces." --Scott Meyers

  4. #4
    Pursuing knowledge confuted's Avatar
    Join Date
    Jun 2002
    Posts
    1,916
    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);
    Last edited by confuted; 08-02-2003 at 06:52 PM.
    Away.

  5. #5
    Registered User
    Join Date
    Apr 2002
    Posts
    1,571
    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.
    "...the results are undefined, and we all know what "undefined" means: it means it works during development, it works during testing, and it blows up in your most important customers' faces." --Scott Meyers

  6. #6
    Pursuing knowledge confuted's Avatar
    Join Date
    Jun 2002
    Posts
    1,916
    I added that in, but it didn't fix the problem of the primitive not being displayed.

    Here's the modified ctransformation.cpp file
    Last edited by confuted; 08-02-2003 at 07:05 PM.
    Away.

  7. #7
    Registered User
    Join Date
    Apr 2002
    Posts
    1,571
    Wrong file.
    "...the results are undefined, and we all know what "undefined" means: it means it works during development, it works during testing, and it blows up in your most important customers' faces." --Scott Meyers

  8. #8
    Pursuing knowledge confuted's Avatar
    Join Date
    Jun 2002
    Posts
    1,916
    whoops. Fixed.
    Away.

  9. #9
    Registered User
    Join Date
    Apr 2002
    Posts
    1,571
    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.
    "...the results are undefined, and we all know what "undefined" means: it means it works during development, it works during testing, and it blows up in your most important customers' faces." --Scott Meyers

  10. #10
    Pursuing knowledge confuted's Avatar
    Join Date
    Jun 2002
    Posts
    1,916
    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.
    Away.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Isometric Tile Engine using DirectX
    By Wraithan in forum Game Programming
    Replies: 3
    Last Post: 07-17-2006, 12:16 PM
  2. DirectSound header issues
    By dxfoo in forum C++ Programming
    Replies: 0
    Last Post: 03-19-2006, 07:16 PM
  3. DirectX - Starting Guide?
    By Zeusbwr in forum Game Programming
    Replies: 13
    Last Post: 11-25-2004, 12:49 AM
  4. DirectX 8 with Borland
    By Tommaso in forum Game Programming
    Replies: 11
    Last Post: 08-12-2003, 09:30 AM
  5. Directx SDK Documentation
    By Zoalord in forum Game Programming
    Replies: 4
    Last Post: 05-08-2003, 06:07 AM