Matrix classes Directx & OpenGL
I have the following C++ matrix class:
transform.h transform.cpp
I am using this coupled with a renderer, for which there is an opengl and a directx implementation.
I have a test example where the coordinates of the mouse within the window are used to position a graphic under the cursor. This works as expected under OpenGL.
Because directx is row major and opengl is column major, I reverse the matrix as follows and pass it to directx before rendering:
if(o->tree){
CObjectTransform* t = o->tree->GetTransform(o->transformID);
D3DMATRIX d;
float* m = (float*)&d;
for (int u=0; u<4; u++){
for (int v=0; v<4; v++){
m[u +v*4] = t->worldtransform.matrix[v+u*4];
}
}
pd3dDevice->SetTransform(D3DTS_WORLD, &d);
}
The result of this is nothing is shown in the visible area from the graphics, regardless of here I put my cursor.
So:
- Is my transform class correctly implemented?
- How do I get it working with directx?
edit:
the following code was setup:
float* m = (float*)&d;
for (int u=0; u<4; u++){
for (int v=0; v<4; v++){
m[u +v*4] = t->worldtransform.matrix[v+u*4];
}
}
开发者_如何学编程 float test[16] = { 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 };
memcpy(test,&d,sizeof(d));
The values of the matrix class:
1,0,0,0
0,1,0,0 0,0,1,0 47,-30,0,1The values of the swapped matrix:
1,0,0,47
0,1,0,-30 0,0,1,0 0,0,0,1So the matrix is being swapped around. This rules out the swapping round code as the cause of the problem.
OpenGL and DirectX have opposing matrix representations, but they also have opposite vector * matrix
order:
- OpenGL:
M * v
. M is column major in memory - DirectX:
v * M
. M is row major in memory
since the multiplication is reversed, you have to transpose your OpenGL matrix to pass to DX. But since DX uses row major, you have to transpose again. Transpose twice is really the identity.
How about you try with no transformation at all ?
I'm assuming you're compiling this as C++.
This:
m[u,v] = t->worldtransform.matrix[v,u];
Probably doesn't do what you want it to do. in C++, a 2D array is indexed as m[u][v]
.
What this line actually does is use the ,
operator which evaluates to its statement, so m[u,v]
actually returns the float
of the v
coordinates.
what you probably want to do is this:
m[u + 4*v] = t->worldtransform.matrix[v + 4*u];
You appreciate that, of the 2 matrices you show above, the first is a correct DirectX matrix. The second will not work under DX at all ...
精彩评论