Archived

This topic is now archived and is closed to further replies.

31337

Accessing values of D3DXMATRIX?

Recommended Posts

Hello, I am trying to write functions that will convert D3DXMATRIX''s to my own custom matrix class. My matrix class stores matrices in a floating point array of 16 items where myMatrix[1] is the item in the second row, first column, and myMatrix[4] is the item in the first row and second column. How do I do it? Thanks

Share this post


Link to post
Share on other sites
Create a custom assignment operator, something like this:


const MyMatrix &MyMatrix::operator = (const D3DXMATRIX &rhs)
{
for (int c = 0; c < 4; ++c)
for (int r = 0; r < 4; ++r)
data [c * 4 + r] = rhs (r, c);
}


I don''t recall whether D3DXMATRIX is stored in a row-major or column-major fashion. If it is stored in the same way your matrix class is, then just do a memcpy or something...

Share this post


Link to post
Share on other sites
For some reason on MSDN it doesn''t seem to indicate how D3DXMATRIX stores the values. What is that rhs business?

Share this post


Link to post
Share on other sites
The rhs is just the name of the D3DXMATRIX variable... make it

const MyMatrix &MyMatrix::operator = (const D3DXMATRIX &Bob)
{
for (int c = 0; c < 4; ++c)
for (int r = 0; r < 4; ++r)
data [c * 4 + r] = Bob (r, c);
}

if you want. It''s completely arbitrary.

Share this post


Link to post
Share on other sites
You don''t really need to create a D3DXMATRIX operator, all the dx functions use D3DXMATRIX*, so its alot faster to just write a D3DXMATRIX* conversion operator like so,


MyMatrix::operator D3DXMATRIX*()
{
return (D3DXMATRIX)this;
}


asumming you follow the alignment like D3DX does. You can look at parts of the code by openening up the D3DX headers from your SDK, as alot of its inline.

regards,
-Eric

Share this post


Link to post
Share on other sites
Data in D3DXMATRIX''s are in row-major order.

------------------------------
BASIC programmers don''t die, they just GOSUB and don''t return.

Share this post


Link to post
Share on other sites
You have two choices. You can either store your data in row major form so that there is no need to convert any data for DX to use, or you can transpose your matrix. Transposing a matrix means that all the columns of the source matrix become the rows of the destination matrix.

If your matrix class is only going to be used with DX, then I would say that you should store your matrix in row major format and be done with it. If you need your matrices in column major format for some specific purpose, then ok. But if not, then storing your matrix in column major format would just cause you to incur the overhead of transposing the matrix every time you needed to do something with DX.

neneboricua

Share this post


Link to post
Share on other sites
The problem is is that the reason why I''m even dealing with my own matrix class is because its for my 3D engine Glaucomy which works with OpenGL too...

Share this post


Link to post
Share on other sites
quote:
Original post by 31337
The problem is is that the reason why I''m even dealing with my own matrix class is because its for my 3D engine Glaucomy which works with OpenGL too...

Ohh, i see. I''m not sure how your engine works but if the developer has to decide at compile time which API (either D3D or OpenGL) they''re going to use, you can solve this problem by using templates. This is what you can do. You can write two classes.

The first one will just be a standard matrix class but it will store matrices in column major format (for OpenGL). Try to make the interface match the one for the DX matrices. This is pretty basic stuff.

Now you have to make these two classes work together in your engine. The trick here is to write a second matrix class that is a template class around the D3D matrices and your OpenGL matrix class. This second class will just provide a generic matrix interface. It will be extremely thin. This is what I mean:

template <class MATRIX_TYPE>
class CMatrix
{
private:
MATRIX_TYPE m_matrix;
public:
CMatrix() { ZeroMemory(&m_matrix, sizeof(MATRIX_TYPE)) };
virtual ~CMatrix() {}

// assignment operators

MATRIX_TYPE& operator *= ( CONST MATRIX_TYPE& rhs )
{
return m_matrix *= rhs;
}
MATRIX_TYPE& operator += ( CONST MATRIX_TYPE& rhs )
{
return m_matrix += rhs;
}
MATRIX_TYPE& operator -= ( CONST MATRIX_TYPE& rhs )
{
return m_matrix -= rhs;
}
MATRIX_TYPE& operator *= ( FLOAT f )
{
return m_matrix *= f;
}
MATRIX_TYPE& operator /= ( FLOAT f )
{
return m_matrix /= f;
}

// More matrix stuff...

};

You get the idea. This is just a very thin wrapper around your matrix interfaces. But the cool thing is that with a template, you don''t incur the overhead of using inheritance. The compiler will know at compile time which type of matrix you are using. Also, since these methods are essentially a one line call into the underlying methods of either the D3D matrix or your OpenGL version, you should put them all in the class definition because, according to the C++ standard, all functions implemented within the class definition are inlined by the compiler. For methods this small, we definately want the compiler to inline them.

You would use this class like so...
CMatrix matTranslate;
or
CMatrix matTranslate;

Here I''ve assumed that you named your OpenGL matrix class COGLMATRIX but you can name it whatever you want.

If you allow the engine to switch between D3D and OpenGL during runtime, then you''ll either have to use inheritance, or just impelment everything in either row-major or column-major and transpose the data when needed.

Hope this helps,
neneboricua

Share this post


Link to post
Share on other sites
Well, I don''t want to use templates because I don''t want 3D API to be compile time, but rather run time. Thanks for the advice though.

Share this post


Link to post
Share on other sites