Skip to main content
GameDev.net gamedev.net
🔒 Locked

3D Coordinates to Screen Coordinates

Started by allenm84 Sep 22, 2006 at 5:22 PM 6 replies 2k views
Original Post
allenm84
allenm84
Just a basic question. How would I convert 3D coordinates to screen coordinates? I know about the Matrix.Translation but that seems to return a Matrix with the original coordinates inside. I need the actual coordinates.
Endurion
Endurion
In C++ there's a function D3DXVec3Project. There's a similar function for managed DirectX as well.

Feed it the three matrices and the viewport.

Hint: The D3DDevice->GetTransform calls can fail if you've got a pure device.
Fruny: Ftagn! Ia! Ia! std::time_put_byname! Mglui naflftagn std::codecvt eY'ha-nthlei!,char,mbstate_t>
allenm84
allenm84
thanks a lot for the reply! The D3DDevice->GetTransform do fail (I assume because I have a pure device, although I don't know what that means) so I just defined the projection/view matrices in the constructor of my class. I assume the viewport comes from the D3DDevice.

I created a Vector3 with the coordinates (10,10,10) and called the Vector3Project function of that vector, feeding it the matrices and viewport, but it returned an x/y coordinate of a negative value and a z-value. The values it returned were
(-413.915771, -634.956, 0.9887586). Is this normal? Should I drop the z-value and feed the x/y values into an absolute value function to get the 2D coordinates?
Endurion
Endurion
Hmm. Make sure you have the correct matrices as you used to render the scene. Also don't forget the correct world matrix if you take a 3d point from an object.

The viewport is pretty easy to create if getviewport fails (it will also fail on a pure device):

x,y = 0, width and height is your backbuffer size. MinZ and MaxZ are usually set to 0.0 and 1.0.


A pure device is a device that does not buffer matrices and render states for you. This can result in a small speedup as it doesn't check if a previously set value is the same as the new one.
Fruny: Ftagn! Ia! Ia! std::time_put_byname! Mglui naflftagn std::codecvt eY'ha-nthlei!,char,mbstate_t>
allenm84
allenm84
I know C# and C++, so the unmanaged version works too. In this function:

D3DVECTOR2 GetScreenCoords(D3DVECTOR3 point, D3DXMATRIX worldViewProjection){D3DVECTOR4 temp = D3DVECTOR4(point.X, point.Y, point.Z, 1);temp *= worldViewProjection;return D3DVECTOR2(temp.X, temp.Y);}


should I be dividing the parts of temp before returning the Vector2?
don
don
If you transform a vertex by the WorldViewProjection matrix, you'll end up in projective clip space, not screen space. You have to perform a shift/scale/and y-axis inversion to get into screen space from clip space. More about this can be found on in the following whitepaper:

http://msdn.microsoft.com/library/default.asp?url=/library/en-us/directx9_c/The_Direct3D_Transformation_Pipeline.asp


You might want to consider using D3DXVec3Project. Even if you want to do the transformation grunt work yourself you can still use this D3DX function to validate your results as you work through the kinks.
allenm84
allenm84
Thanks again for the replies! I read over the MSDN article and it was very helpful. I tried using the Vec3Project function and it returned negative values when I fed it my project, view, world and viewport with the Vector3 = {10,10,10}.

Topic Locked

This topic has been locked by a moderator. New replies are not allowed.

Sign in to reply to this topic.