Jump to content

  • Log In with Google      Sign In   
  • Create Account


We have 4 x Pro Licences (valued at $59 each) for 2d modular animation software Spriter to give away in this Thursday's GDNet Direct email newsletter.

Read more in this forum topic or make sure you're signed up (from the right-hand sidebar on the homepage) and read Thursday's newsletter to get in the running!


Member Since 13 May 2012
Offline Last Active May 16 2012 04:05 AM

Topics I've Started

Direct3D9 - D3DXVec3Project + WorldViewProj Matrix

13 May 2012 - 12:19 PM


First and foremost, I am not that familiar with the D3D scene of things (no pun intended), so all and any help would be appreciated.

I am currently working with a game which has a pure device, and this means that the buffered-state get functions fail, of course (i.e. GetTransform, GetViewport, etc.). Additionally, SetTransform does not get called, so I can't internally set a temporary variable to store the last known projection and view transformation matricies.

What I am trying to accomplish is to render a rectangle at a certain coordinate in the game. On non-pure devices, this is a very simple process, as I would just grab D3DTS_VIEW, D3DTS_PROJECTION, the viewport, an identity matrix, and the world coordinate, and throw them into the nice and friendly D3DXVec3Project function to get the screen space coordinate from the world coordinate.

However, in this particular game, I didn't have such luxuries. I read some articles online, where I discovered that the game is shader-based and that I could potentially grab the projection and view matricies from the shader registers. Here is an excerpt of the dump from the shader file which lists all of these registers:

// Registers:
//   Name			 Reg   Size
//   ---------------- ----- ----
//   gWorld		   c0	   4
//   gWorldViewProj   c8	   4
//   gViewInverse	 c12	  4
//   globalScalars	c39	  1
//   globalScalars2   c40	  1
//   gDayNightEffects c45	  1
//   globalAnimUV0	c208	 1
//   globalAnimUV1	c209	 1

Now, unlike some games, I now realized that there wasn't individual matricies, which could be passed into D3DXVec3Project. I assume the only one which I would need is the gWorldViewProj matrix (WorldViewProjection = World * View * Projection). The problem is what to do with it.

I also read that transforming that matrix using the point and the function D3DXVec3TransformCoord would NOT put it into screen coordinates: instead, it would put it into projection clip coordinates. Therefore, my best guess would be to somehow fit it into the D3DXVec3Project function.

Let's show some sample code to work off of:
. . .
// The location of the entity in the world where I want to draw the sprite on top of.
D3DXVECTOR3 vecPosition(-100.5f, 1000.f, 15.f), vecOutput;
. . .
D3DVIEWPORT9 Viewport = {0, 0, 1920, 1080, 0, 1};
. . .
// Grab the WorldViewProjection matrix from the shader buffer at register 8 as 4 float4's.
D3DXMATRIX matWorldViewProj;
pDevice->GetVertexShaderConstantF(8, matWorldViewProj, 4);
. . .
D3DXVec3Project(&vecOutput, &vecPosition, &Viewport, ???, ???, ???);

This is really a learning experience for me, if anything. If and when it works, I can start playing around with the shader information (as I'm also new to that concept) and hopefully gain an appreciation for what's going on behind the scenes.

Do I have the right idea? Do I need to manually transform the matricies? Is this even possible, given my limitations?

Thanks again!