Sign in to follow this  

Direct3D Transforms Applied To Vertex Bufer When?

This topic is 4855 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

I'm reading up on Direct3D. I understand about setting up the vertex buffer and even creating the transformation matrices (I think). But my question is, when is the vertex list transformed by the matrices (world, view, etc.)? Does Direct3D know which is which by the DTS_WORLD type tags and apply them in order when we ask it to draw a primitive? I hope I'm being clear. I would have expected that there would have to be a call that tells Direct3D to apply the transformation matrices we've set up to the vertex list. Or have I got it all wrong?

Share this post


Link to post
Share on other sites
It is important to understand that the fixed-function-pipeline is just a collection of shaders that are supported on graphics hardware. The world, view, and projection transforms are applied to the vertices on a per-vertex basis, in the vertex shader. They are actually multiplied together, to form one final transform:

matFinalTransform = matWorld * matView * matProjection

Consider this:

float4 MyVertexShader( float4 positionIn )
{
// This is our vertex shader. Most vertex shaders start off like this
// matWorldViewProj is a constant. It holds the (world * view * proj) matrix
float4 positionOut;
positionOut = mul( positionIn, matWorldViewProj );

return positionOut;
}


If you don't know much (or anything) about shaders, then you probably won't really understand this.

Share this post


Link to post
Share on other sites
In which Donavon tries to explain this using his admittedly creaky power of metaphor:

When you call one of the DrawPrimitive functions, you are basically pushing a button on a machine (the 3D hardware). The machine will take in the vertices (and possibly indices) that you've set up to be fed in on the input end. You've already configured the machine with transformation matrices and lighting/material values, plus a bunch of other crap. (Forget about shaders for in this discussion.) So the vertex and index conveyor belts start up, feeding raw materials into the machine.

After a number of stages, what the machine spits out are color values into the render target, depth values into the z-buffer, and stencil values into the stencil buffer, depending on what configuration of these outputs you've set it up for.

Note that there are no other outputs (at least not on DX8-class machines, and assuming I haven't overlooked anything in my tired state[smile]). The transformation of vertices that you're asking about occurs inside the machine. Nobody gets to see the results, not directly. They are not an output.

If you want access to the transformed (and/or lit) vertices, you have to forget about the machine down on the factory floor, because again, it is not designed to spit that sort of thing out. Instead you have to use your crack team of software vertex processors. They work in the CPU department, and the way to give them orders for this sort of job is with the ProcessVertices function. This is a function exclusively of the CPU department. They can take your vertices (and/or indices, etc.) and process them in the same way that the machine does, but sometimes slower, and eh, maybe sometimes even faster. And unlike the machine, they can give you back the results.

(Parenthetically, this metaphor helps explain why it's important to batch as many primitives as you can into Draw*Primitives calls: Because reconfiguring the machine involves stopping part or all of it for the reconfiguration process.)

I don't know, does that help? [smile]

Share this post


Link to post
Share on other sites
Thanks all! That does help. I thought as much, but I wanted to make sure. It seemed to make sense given that we had to tag the transformation matrices we set up as WORLD, VIEW, etc...so DirectX knows which is which as we aren't applying them ourselves.

I read somewhere the DirectX will combine the 3 transforms into one matrix before it applies them. So, should we still do this in our code? Or is this a waste of time given that DirectX will try to do it again?

And yes, Donavon, your analogy is a good one. :)

Share this post


Link to post
Share on other sites
Quote:
Original post by Low Bias
I read somewhere the DirectX will combine the 3 transforms into one matrix before it applies them. So, should we still do this in our code? Or is this a waste of time given that DirectX will try to do it again?

Typically, the matrices are concatenated into one matrix before transforming the vertices.
However, when you're setting the matrices (IDirect3DDevice9::SetTransform), set each one separately - this gives you the ability to change just one at a time (Typically, the projection matrix is constant, world and view matrices change all the time).

However, when you're transforming the vertices on the CPU for some reason, concatenate the matrices first.

Share this post


Link to post
Share on other sites
also as an optimization I employ:

proj = constant (set at init)
view = identity
world = (view * world)

because setting each of these matrices on the device is more costly than multiplying view * world and setting only 1.
DXSDK docs have an explanation and an example if u look under performance tips.

Share this post


Link to post
Share on other sites

This topic is 4855 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