Transformation question

Started by
2 comments, last by ynkm169 16 years, 5 months ago
I have this: HR(mSprite->Begin(D3DXSPRITE_OBJECTSPACE|D3DXSPRITE_DONOTMODIFY_RENDERSTATE)); HR(gd3dDevice->SetRenderState(D3DRS_ALPHABLENDENABLE, true)); D3DXVECTOR4 objectSpacePosition; HR(mSprite->Draw(mTexture, 0, 0, &objectSpacePosition, 0xffffffff)); HR(mSprite->End()); HR(gd3dDevice->SetRenderState(D3DRS_ALPHABLENDENABLE, false)); And I have this: HR(mSprite->Begin(D3DXSPRITE_ALPHABLEND)); D3DXVECTOR4 screenSpacePosition; HR(mSprite->Draw(mTexture, 0, 0, &screenSpacePosition, 0xffffffff)); HR(mSprite->End()); How can I build a matrix that can convert objectSpacePosition to screenSpacePosition and another matrix that can convert from screenSpacePosition to objectSpacePosition so both textures in the two cases are drawn in the same position on my monitor? I tried to use: D3DXVec4Transform(&screenSpacePosition, &objectSpacePosition, &mWVPMatrix); //Here: D3DXMatrixMultiply(&mWVPMatrix, &mProjectionMatrix, &mViewMatrix); and D3DXVec4Transform(&objectSpacePosition, &screenSpacePosition, &mWVPMatrixInverse); //Here:D3DXMatrixInverse(&mWVPMatrixInverse, NULL, &mWVPMatrix); But none of them work properly. Although I understand the transformation pipeline, since I havn't taken linear algebra, I am not able to do this transformation. Thanks. [Edited by - ynkm169 on November 5, 2007 6:51:24 PM]
Advertisement
Transforming your point by the viewProjection matrix will put it in clip space, which is where your screen bounds are x = [-1, 1] and y = [-1, 1]. I would assume you need screen coordinates, where (0,0) is the top left corner of the screen and (resX, resY) are at the bottom right. To accomplish this, you'll to convert the x and y portions of your clip-space position to [0,1] (multiply by 0.5 and then add 0.5) and then multiply by the size of your viewport (your screen resolition).
Quote:Original post by MJP
Transforming your point by the viewProjection matrix will put it in clip space, which is where your screen bounds are x = [-1, 1] and y = [-1, 1]. I would assume you need screen coordinates, where (0,0) is the top left corner of the screen and (resX, resY) are at the bottom right. To accomplish this, you'll to convert the x and y portions of your clip-space position to [0,1] (multiply by 0.5 and then add 0.5) and then multiply by the size of your viewport (your screen resolition).


It doesn't work.

I set up my device like this, and there is only view and projection transformation. I don't see any screen space transformation, therefore, i guess there is no need to do it.

// Sets up the camera 1000 units back looking at the origin.
D3DXMATRIX mViewMatrix;
D3DXVECTOR3 pos(0.0f, 0.0f, -1000.0f);
D3DXVECTOR3 up(0.0f, 1.0f, 0.0f);
D3DXVECTOR3 target(0.0f, 0.0f, 0.0f);
D3DXMatrixLookAtLH(&mViewMatrix, &pos, &target, &up);
HR(gd3dDevice->SetTransform(D3DTS_VIEW, &mViewMatrix));

// The following code defines the volume of space the camera sees.
D3DXMATRIX P;
RECT R;
GetClientRect(mhMainWnd, &R);
float width = (float)R.right;
float height = (float)R.bottom;
D3DXMatrixPerspectiveFovLH(&mProjectionMatrix, D3DX_PI*0.25f, width/height, 1.0f, 5000.0f);
HR(gd3dDevice->SetTransform(D3DTS_PROJECTION, &mProjectionMatrix));

// This code sets texture filters, which helps to smooth out distortions
// when you scale a texture.
HR(gd3dDevice->SetSamplerState(0, D3DSAMP_MAGFILTER, D3DTEXF_LINEAR));
HR(gd3dDevice->SetSamplerState(0, D3DSAMP_MINFILTER, D3DTEXF_LINEAR));
HR(gd3dDevice->SetSamplerState(0, D3DSAMP_MIPFILTER, D3DTEXF_LINEAR));

// This line of code disables Direct3D lighting.
HR(gd3dDevice->SetRenderState(D3DRS_LIGHTING, false));

// The following code specifies an alpha test and reference value.
HR(gd3dDevice->SetRenderState(D3DRS_ALPHAREF, 10));
HR(gd3dDevice->SetRenderState(D3DRS_ALPHAFUNC, D3DCMP_GREATER));

// The following code is used to setup alpha blending.
HR(gd3dDevice->SetTextureStageState(0, D3DTSS_ALPHAARG1, D3DTA_TEXTURE));
HR(gd3dDevice->SetTextureStageState(0, D3DTSS_ALPHAOP, D3DTOP_SELECTARG1));
HR(gd3dDevice->SetRenderState(D3DRS_SRCBLEND, D3DBLEND_SRCALPHA));
HR(gd3dDevice->SetRenderState(D3DRS_DESTBLEND, D3DBLEND_INVSRCALPHA));

// Indicates that we are using 2D texture coordinates.
HR(gd3dDevice->SetTextureStageState(
0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT2));
D3DXMatrixMultiply(&mWVPMatrix, &mViewMatrix, &mProjectionMatrix);
D3DXMatrixInverse(&mWVPMatrixInverse, NULL, &mWVPMatrix);

What I am really trying to do is to convert coordinate transformed by gd3dDevice->SetTransform() to my screen coordinates and vice versa because my mouse is drawn using gd3dDevice->SetTransform() but I want to get it's coordinates in screen space so I can do some work on buttons and controls drawn using screen space

[Edited by - ynkm169 on November 5, 2007 6:04:57 PM]
I did it! I am so happy.
I turns out my original method was right.
However, I don't know why, but I have to reverse the sign of the coordinate before I transform it using my mWVPMatrix and mWVPMatrixInverse.
So the code should be something like

objectSpacePosition.y = -objectSpacePosition.y
D3DXVec4Transform(&screenSpacePosition, &objectSpacePosition, &mWVPMatrix);
//Here: D3DXMatrixMultiply(&mWVPMatrix, &mProjectionMatrix, &mViewMatrix);

objectSpacePosition.y = -screenSpacePosition.y
and D3DXVec4Transform(&objectSpacePosition, &screenSpacePosition, &mWVPMatrixInverse);
//Here:D3DXMatrixInverse(&mWVPMatrixInverse, NULL, &mWVPMatrix);

This topic is closed to new replies.

Advertisement