Jump to content
  • Advertisement

Archived

This topic is now archived and is closed to further replies.

IFooBar

would u move a square with wold matrix or by changing the xyz coordinates??

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

hi all i was wondering what would be the most efficient, and better way to move objects in d3d. would you go about it by changing the world matrix every scene and then rendering the object or would you change the xyz coordinates of the object, in an update function, and then render it. thanks

Share this post


Link to post
Share on other sites
Advertisement
If you update the x,y,z data inside the object you have to write 3 values for each involved vertex. Which could be many.

The world transformation gets applied to the object on every DrawPrimitive or Proccessvertices call. And changing the x,y,z data in the world matrix sets 3 values no matter how big the object.

Question now is how long updating the world matrix takes. I''d say it''s rather fast. So you better use the world matrix.

---------------------------
I may be getting older, but I refuse to grow up

Share this post


Link to post
Share on other sites
so in a render(float x, float y, float z) function i should have something like

D3DXMATRIX trans;
D3DXMatrixTranslate(&trans, x, y, z);
pD3DDevice->SetTransform(D3DTS_WORLD, &trans);

pD3DDevice->DrawPrimitive(...);

and i would have to have this for every shape and mesh in my program.

does it matter if you setTransform for many different objects each frame? is that how its all done??

thanks again

Share this post


Link to post
Share on other sites
Guest Anonymous Poster
Greetings!

Let''s assume you have a 3D object, say a box in your 3D world.

You store the position of the object as a 3D vector or point. You would also define the way the object is facing in the static world.

(*)You then use the postion and rotation of the object to build the translation matrix for the object.

So the rendering process goes something like this:

Set world Matrix to Identity or whatever translation required (usually none).

Set your View Matrix to the camera position and rotation.

Render static world geometry.

Then go through every non static object and build the world translation matricies for them and render them to the screen (See *). Be sure to leave your View Matrix Alone during this procedure.

You don''t want to change the object''s primitive coordinates every cycle, just the translation. See (*)

-James

Share this post


Link to post
Share on other sites
ok so let me get this straight.
*first you would set the world mat to an identity or whatever.

*then you draw all objects that are not supposed to move.

*then if you wanted to move a cube a little to the left you would make a translation matrix and set the world matrix to that translation so that cube would move left, then render the cube.

*then if you had another sphere, you again make a matrix that translates it to wherever else you want and set the wold matrix again when you render the sphere.

--> ok now before i render the sphere would i have to reset the world position to its original state as it was before i rendered the non moving objects?

am i on the same page here?

thanks for the help

Share this post


Link to post
Share on other sites
First of all, I would highly recommend reading up on matrices and how they apply to game programming. A good place to start would might even be the DirectX SDK. There''s also a nice matrix and quaternion faq on this sitw. Quaternions would be another thing you should check out if you''re ever going to do character animation.

quote:

ok so let me get this straight.
*first you would set the world mat to an identity or whatever.

*then you draw all objects that are not supposed to move.


That would be correct. You have to realize, there''s no exact way to do anything. That would be the fastest way but there''s always exceptions. Using the fixed function pipeline, you would just set your transforms whenever you need to draw objects. There is no exact order. By the way, yes, it''s an identity matrix. Multiplying it with another yealds the same result.

quote:

*then if you wanted to move a cube a little to the left you would make a translation matrix and set the world matrix to that translation so that cube would move left, then render the cube.

*then if you had another sphere, you again make a matrix that translates it to wherever else you want and set the wold matrix again when you render the sphere.


That would be one way to do it. That way you create transformation matrix for each object. Then again, there''s always the frame-based method. Just keep in mind that there really is no "exact" way to do anything here.

My Site

Share this post


Link to post
Share on other sites
quote:
Original post by Dreamforger
If you update the x,y,z data inside the object you have to write 3 values for each involved vertex. Which could be many.

The world transformation gets applied to the object on every DrawPrimitive or Proccessvertices call. And changing the x,y,z data in the world matrix sets 3 values no matter how big the object.

Question now is how long updating the world matrix takes. I''d say it''s rather fast. So you better use the world matrix.

---------------------------
I may be getting older, but I refuse to grow up



That''s where you''re wrong. If you''ve ever worked with vertex shaders you''d know that the transformation is applied to every vertex. The only difference is that there is no excess data transfer.

In order to change the vertices of an object (unless it''s on the system memory), one would have to read the data from the card, process every vertex, and send the new data back to the card. Reading and writing from a video card is a very expensive operation due to the limitations of AGP. Reading is about 2-3 times more expensive than writing, but that''s a whole other subject.

When one sets the transformation matrix, only the 4*4 float matrix (4 * 4 * sizeof(float) = 64 bytes) is sent to the card. The vertices are then transformed on the video card, using the card''s optimizations, and leaving the cpu free to perform other tasks. There is no case where the manual setting of vertices would be sensible (none that I can think of at least).

Share this post


Link to post
Share on other sites
quote:
There is no case where the manual setting of vertices would be sensible (none that I can think of at least).


Then you''ve not considered the cost of poor batching

If the object being rendered only has a few vertices (say 4 for a quad in a 2D engine or a particle/billboard in a 3D engine) and you''re doing a SetTransform and Draw*Primitive for every quad then that''s going to cripple performance!

Sending less than 50 or so vertices at a time through D3D software vertex processing doesn''t give the PSGP SIMD code a chance to get warm (i.e. there is a cost associated with setup, that cost is only hidden when you transform a decent batch size).

Hardware vertex processing is the same, except the number is at least 200 vertices (going off figures in nVidia presentations and from chats to various IHV devrel people).

On top of the batch size, too many draw calls ends up quickly filling the command FIFO and leaving the hardware starved.

Summary:

1) if each object has less than 50-200 vertices and uses the same renderstates, use a smallish dynamic vertex buffer and the correct dynamic lock flags (to get the most out of buffer renaming). Set the world matrix to identity and offset the vertices manually. Batch together all the objects within the buffer within a single lock and render as many as possible with a single Draw*Primitive* call. This is commonly the case with things such as particles and sprites which may share a texture plate and states, but require independent locations/orientations.

2) if each object has more than 50-200 vertices and rarely needs to change actual shape, use a static vertex buffer large enough for the object. Use SetTransform to position/orient the object. [If using DX7, batch together as many static objects into a single static VB as possible since there was an overly large cost for changing VB]. This is commonly the case with level geometry and anything which can be easily animated in a vertex shader such as skinned meshes.

3) if each object has more than 50-200 vertices and changes reasonably often (<150 frames between changes), use a dynamic vertex buffer as in 1. But use SetTransform to position/orient the object. This is commonly the case for things like morph target animation with the CPU - interpolate straight into the locked VB (don''t store the result then copy, just do it direct).

--
Simon O''Connor
Creative Asylum Ltd
www.creative-asylum.com

Share this post


Link to post
Share on other sites
Interesting.. I guess I should catch up on the nVidia docs.

I suppose it really depends on the optimizations, but I use vertex shaders for almost every object in my engine so it doesnt really make a difference to me. But the point is that almga should be using world transformations for now.

But for reference sake.. do you think you could post a link to that doc?

Share this post


Link to post
Share on other sites

  • Advertisement
×

Important Information

By using GameDev.net, you agree to our community Guidelines, Terms of Use, and Privacy Policy.

We are the game development community.

Whether you are an indie, hobbyist, AAA developer, or just trying to learn, GameDev.net is the place for you to learn, share, and connect with the games industry. Learn more About Us or sign up!

Sign me up!