Sign in to follow this  

How to set DirectX (C++) on a right-handed coordinate system by default?

This topic is 3376 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

According to the MSDN we need to do the follow: _____________________________________________________________________________ Direct3D uses a left-handed coordinate system. If you are porting an application that is based on a right-handed coordinate system, you must make two changes to the data passed to Direct3D. 1. Flip the order of triangle vertices so that the system traverses them clockwise from the front. In other words, if the vertices are v0, v1, v2, pass them to Direct3D as v0, v2, v1. 2. Use the view matrix to scale world space by -1 in the z-direction. To do this, flip the sign of the _31, _32, _33, and _34 member of the D3DMATRIX structure that you use for your view matrix. To obtain what amounts to a right-handed world, use the D3DXMatrixPerspectiveRH and D3DXMatrixOrthoRH functions to define the projection transform. However, be careful to use the corresponding D3DXMatrixLookAtRH function, reverse the backface-culling order, and lay out the cube maps accordingly. _____________________________________________________________________________ Well, I have a Mesh (X. file), now I need to implement the next code to do de (1) point: This code swap two of the three indices in the index buffer.This code is from the forum: Problem with triangle winding order by kovacsp. void ReverseCulling(ID3DXMesh* p_mesh) { Int nFaces = p_mesh->GetNumFaces(); IndexBuffer indices(p_mesh, 0); for (int i = 0; i < nFaces; i++) { DWORD tmp; tmp = indices[i * 3]; indices[i * 3] = indices[i * 3 + 1]; indices[i * 3 + 1] = tmp; } } But I do not how to read and write indices of my buffer that has the indices of my mesh(X files)to implement the previous function. I know that there are many functions(like Get_Set IndexBuffer, LockIndexBuffer) but they have caused me a lot of problems. That’s why I need any suggestion and if it is possible an example. In conclusion How to implement the function “IndexBuffer indices(p_mesh, 0)” and how to set the indices in the buffer again with C++? [Edited by - vacing on September 15, 2008 11:08:10 AM]

Share this post


Link to post
Share on other sites
With LockIndexBuffer(). Example (Untested):

void ReverseCulling(ID3DXMesh* p_mesh)
{
int nFaces = p_mesh->GetNumFaces();
WORD* indices;
HRESULT hResult = p_mesh->LockIndexBuffer(0, (void**)&indices);
if(FAILED(hResult))
{
// Failed to lock index buffer
return;
}

for (int i = 0; i < nFaces; i++) {
DWORD tmp;
tmp = indices[i * 3];
indices[i * 3] = indices[i * 3 + 1];
indices[i * 3 + 1] = tmp;
}

p_mesh->UnlockIndexBuffer()
}




EDIT: Assuming a 16-bit index buffer. If it's 32-bit you'll need to change indices to a DWORD*. If you want to support 16 and 32-bit index buffers, you'll have to have code to check the index buffer format and act accordingly.

Share this post


Link to post
Share on other sites
Evil Steve, Thanks a lot!! The function is so good, but I haven’t figured out the problem yet.

Review all that I have did until now,
1) Flip the order of triangle vertices so that the system traverses them clockwise from the front. In other words, if the vertices are v0, v1, v2, pass them to Direct3D as v0, v2, v1 implementing the function exposed previously.
______________________________________________________________________________
. . .LoadXFile("Beam.x", &mBeamMesh, mMtrl, mTex);. . .

. . .ReverseCulling(mBoneMesh);. . .


void RobotArmDemo::ReverseCulling(ID3DXMesh* p_mesh)
{
int nFaces = p_mesh->GetNumFaces();
WORD* indices;
HRESULT hResult = p_mesh->LockIndexBuffer(0, (void**)&indices);
if(FAILED(hResult))
{
// Failed to lock index buffer
return;
}

for (int i = 0; i < nFaces; i++) {
WORD tmp;
tmp = indices[i * 3];
indices[i * 3] = indices[i * 3 + 1];
indices[i * 3 + 1] = tmp;
}

p_mesh->UnlockIndexBuffer();
}
______________________________________________________________________________
2.) Use the view matrix to scale world space by -1 in the z-direction. To do this, flip the sign of the _31, _32, _33, and _34 member of the D3DMATRIX structure that you use for your view matrix.

______________________________________________________________________________

D3DXVECTOR3 pos(3000,0,0);
D3DXVECTOR3 target(0.0f, 0.0f, 0.0f);
D3DXVECTOR3 up(0.0f, 0.0f, 1.0f);
D3DXMatrixLookAtRH(&mView, &pos, &target, &up);

D3DXMATRIX transpose_mView,matrizViewFinal,Temp, toSeeMview;

D3DXMATRIX Ineg3File(1.0f,0.0f,0.0f,0.0f,0.0f,1.0f,0.0f,0.0f,0.0f,0.0f,-1.0f,0.0f,0.0f,0.0f,0.0f,1.0f);

D3DXMatrixTranspose(&transpose_mView,&mView);
Temp=transpose_mView*Ineg3Fila;
D3DXMatrixTranspose(&matrizViewFinal,&Temp);


mView=matrizViewFinal;//Where _31, _32, _33, and _34 * (-1).

______________________________________________________________________________

3. )To obtain what amounts to a right-handed world, use the D3DXMatrixPerspectiveRH and D3DXMatrixOrthoRH functions to define the projection transform. However, be careful to use the corresponding D3DXMatrixLookAtRH function, reverse the backface-culling order, and lay out the cube maps accordingly.
______________________________________________________________________________

…D3DXMatrixPerspectiveFovRH(&mProj, D3DX_PI * 0.25f, w/h, 1.0f, 5000.0f);…
______________________________________________________________________________


But I saw that the result is wrong. What is the error???.

I have a simple application to check the coordinate system. It consists in a beam. The beam is along of axes “y”(based on a right-handed coordinate system).

The check consists in rotate the beam around the x-axis, producing the beam moves in the counterclockwise direction to the x-axis positive position. (based on a right-handed coordinate system).


If I use the next instruction the rotation is good for pi/2 rad.
______________________________________________________________________________
D3DXMatrixRotationX(&R3x,D3DX_PI/2.0f);
______________________________________________________________________________

But if I implement the following matrix,
______________________________________________________________________________
D3DXMATRIX R3(1,0,0,0,0,cosf(theta13),-sinf(theta13),0,0,sinf(theta13),cosf(theta13),0,0,0,0,1);
______________________________________________________________________________

It should Rotate the beam around the x-axis(based on a right-handed coordinate system), which it should be equal to the previous instruction of rotation, it produces the beam moves in the counterclockwise direction to the x-axis negative position.

Another thing is that If I move the position of the beam along the positive z-axis like the next instruction:
______________________________________________________________________________
mMeshBeam.pos = D3DXVECTOR3(0.0f, 0.0f,600.0f);
______________________________________________________________________________
it move to negative z-axis.

All This mean that the directX continue based on a left-handed coordinate system, despite of all changes That I did.



What’s wrong with that???

Share this post


Link to post
Share on other sites

This topic is 3376 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

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