Is this how vertex streams work?

Started by
7 comments, last by circlesoft 17 years, 11 months ago
Hi I've been previously using fvf, but now I'm working with the vertex streams. I did the tutorial from gametutorials.com, and I was wondering if this is how they work: Say I'm drawing solid 3d objects using: position, normals and texture coordinates, and also 3d lines which are using: position and diffuse, Would I have to use four vertex buffers to store each of the position, normals, texture coords and diffuse? And to draw it, is it required that I use an index buffer? Thanks
Advertisement
Check out DX documentation. But a short answer to your questions.
No, you do not have to separate the data in several vtx buffers, you can use the same buffer for all objects regardless of vertex type if you want. You would have to create vertex declarations for each type though.
The vertex declaration defines how your data is stored.
You are not required to use index buffers. See DrawPrimitives versus DrawIndexedPrimitives
Be careful of using multiple vertex streams. It is a lot of overhead and causes a lot of performance loss - upwards of at least 25%. If you are trying to stay independent of your shaders and avoid hardcoding in a set vertex format, you probably should instead construct a single buffer of arbitrary vertex data. This is kinda hard to explain, so I will do it like this:

These are commands that you would give your vertex stream constructor:- Here is the vertex declaration that I made from the shader- Here is a list of position elements for you to use, if you need them- Here is a list of normal elements for you to use, if you need them- Here is a list of texcoord elements for you to use, if you need them- ... (And so on for all of your different type of elements)Vertex Stream Constructor:- Ok, now I am going to take all of these separate element streams that you gaveme and combine them so that they are in the format of the vertex declaration. The end result is just one big buffer of vertices, in a format that the shaderexpects.


So it's kinda like that. Basically, you are doing the same thing that the D3D input assembler would be doing - except that you do it once at load-time, instead of every frame.
Dustin Franklin ( circlesoft :: KBase :: Mystic GD :: ApolloNL )
Quote:Original post by circlesoft
Be careful of using multiple vertex streams. It is a lot of overhead and causes a lot of performance loss - upwards of at least 25%.


ATI mentioned 0%-10% in one presentation (and the page also claimed that streams can actually speed up things in some cases). But I guess that depending on the hardware it could get worse than that.

Johnny, vertex declarations allow you to use streams, but don't force you to use them. That's a big distinction. A declaration can define exactly the same vertices that you defined with FVFs, but it gives you added flexibility to define things that can't be represented by an FVF, including the use of streams.
Ah I think I understand now, thanks.

Also I'm drawing different sets of dynamic vertices, with vertex streams, is it fine if I just use the one vb to draw all my dynamic content?
eg
//lock/unlock vb...insert vertices of VertexType1device->SetStreamSource(0, vb, 0, sizeof(VertexType1));device->SetVertexDeclaration(vertexDeclare1);//draw vertices from VertexType1//lock/unlock vb...insert vertices of VertexType2device->SetStreamSource(0, vb, 0, sizeof(VertexType2));device->SetVertexDeclaration(vertexDeclare2);//draw vertices from VertexType2//and so on?



Quote:Original post by ET3D
Quote:Original post by circlesoft
Be careful of using multiple vertex streams. It is a lot of overhead and causes a lot of performance loss - upwards of at least 25%.


ATI mentioned 0%-10% in one presentation (and the page also claimed that streams can actually speed up things in some cases). But I guess that depending on the hardware it could get worse than that.

Ah, you are correct. Now that I went back and looked at the slidedeck, I see that it is 10% [smile]
Dustin Franklin ( circlesoft :: KBase :: Mystic GD :: ApolloNL )
Quote:Original post by johnnyBravo
Also I'm drawing different sets of dynamic vertices, with vertex streams, is it fine if I just use the one vb to draw all my dynamic content?

You can put any data you want into any part of your buffer, and use it with a suitable stream offset. You can also use the same vertex buffer with different vertex declarations to reinterpret it -- although that's normally less useful.

However, your example seems to just reinterpret the same buffer as a different type with a different size, which is unlikely to work.
I just would like to add that there are situation where Vertex Streams are invaluable as a memory saver. I`m using character Keyframe animation in my engine. This means each frame you have to store all triangles of current frame. Storing texture coordinates would be horribly inefficient, since they`re same throughout all different animations. If you have 50 frames for all animations, that means that you would be storing UV 49 times more than necessary. If you have 3000 vertices per frame, that would be 24000 Bytes for frame and 1,15 MB per character. With 5 characters, that`s about 6 MB of duplicate data for a little performance hit (5% on average). If your game must run on HW with just 32 MB of VRAM, that`s a significant win.

Actually, each float is packed to just 2 Bytes in my implementation, but the point is the same whether your float is 4 bytes or 2 bytes.

VladR My 3rd person action RPG on GreenLight: http://steamcommunity.com/sharedfiles/filedetails/?id=92951596

Quote:Original post by VladR
I just would like to add that there are situation where Vertex Streams are invaluable as a memory saver. I`m using character Keyframe animation in my engine. This means each frame you have to store all triangles of current frame. Storing texture coordinates would be horribly inefficient, since they`re same throughout all different animations. If you have 50 frames for all animations, that means that you would be storing UV 49 times more than necessary. If you have 3000 vertices per frame, that would be 24000 Bytes for frame and 1,15 MB per character. With 5 characters, that`s about 6 MB of duplicate data for a little performance hit (5% on average). If your game must run on HW with just 32 MB of VRAM, that`s a significant win.

Actually, there is a nifty article about that here:

Vertex Tweening with D3D9

Even if you aren't really looking into animation, it's a good working example of streams, and it includes a MD2 loader.
Dustin Franklin ( circlesoft :: KBase :: Mystic GD :: ApolloNL )

This topic is closed to new replies.

Advertisement