DrawIndexedPrimitive arguments

Started by
5 comments, last by 21st Century Moose 10 years, 8 months ago

So,DrawIndexedPrimitive looks like this:

HRESULT DrawIndexedPrimitive(
[in] D3DPRIMITIVETYPE Type,
[in] INT BaseVertexIndex,
[in] UINT MinIndex,
[in] UINT NumVertices,
[in] UINT StartIndex,
[in] UINT PrimitiveCount
);

So if I use a BaseVertexIndex argument of 10,the first 10 vertices in the vertex buffer will be skipped,instead only the rest of them will be used.

How about MinIndex? And StartIndex? I have a very hard time understanding these offsets,can someone give an example like: "you have 100 indices,only the last 50 will be used etc..." based on all of these offsets?

Advertisement

http://msdn.microsoft.com/en-us/library/windows/desktop/bb174369(v=vs.85).aspx

NumVertices [in]

Type: UINT

Number of vertices used during this call. The first vertex is located at index: BaseVertexIndex + MinIndex.

So that meas that the MinIndex is just another helper value that describes '1st' vertex you use .

Confusing huh?

BaseVertexIndex is a constant that is added to each value in the index buffer prior to use. If a given value in your index buffer is n then the actual vertex that gets used is n+BaseVertexIndex. Typically this value is set to zero. I've only used it once when aggressively repurposing auto generated index buffers to reduce the total number of permutations required for geo mip mapping.

MinIndex and NumVertices come as a pair and are used by the GPU to determine what vertices in your vertex buffer your index buffer will reference. Choose them as follows:


MinIndex    = minimum of { n + BaseVertexIndex }
NumVertices = maximum of { n + BaseVertexIndex } - MinIndex + 1

Where n is any value stored in the index buffer that will get used.

StartIndex is just the offset into the index buffer to start reading from. Suppose you are drawing a triangle list and your index buffer has 9 elements in it but you only care about the last 2 triangles. In that case StartIndex would be 3.

PrimitiveCount is the number of primitives to draw and when combined with the primitive type specifies how many indices to consume.

Is this true? "when using a hardware vertex-processing device the MinIndex and NumVertices are ignored",because the gpu has it's own optimizations,those are used only on software rendering.


Is this true? "when using a hardware vertex-processing device the MinIndex and NumVertices are ignored",because the gpu has it's own optimizations,those are used only on software rendering.

Where have you got that from? No, of course this is not true, that would be horrible! MinIndex and NumVertices are extremely useful, for rendering only portions of a buffer (sprite render, static batched geometry). You can also try it out yourself, fill in some garbage value, for example 0 for NumVertices, and it won't draw.

I think it is. E.g. my NVidia draws fine with NumVertices = 0. Make sure to read mhagains follow-up post for details. Nonetheless, I would still use sensible/legal values ever.

Yes, it is true; you can put any old junk into them and with hardware VP you'll most likely still draw correctly. With software you'll possibly crash, or draw triangles-on-LSD, or something else interesting, however. It is important to get them right with software VP as they define a range of the vertex buffer that is used in the draw call (if the params had been named otherwise it would have helped understanding a lot), which suggests that software VP operates in two passes, the first being to run your vertex shader (or other transforms/etc) on the defined range, the second being to take the results of that and transfer it to the GPU - without the ability to define a range the software VP engine doesn't know in advance how much of the vertex buffer is going to be used, so it may pre-emptively transform the full thing.

I definitely second the recommendation to get them right anyway despite this; even if you think right now that you'll never need software VP you may find yourself using it as a fallback at some time in the future.

As an interesting aside, this is exactly analogous to OpenGL's glDrawRangeElements, and suggests that the same behaviour applies there too and that with hardware T&L glDrawRangeElements is no advantage over glDrawElements - which my own informal benchmarking confirms.

Note that these two params were removed from the D3D10+ variant with the rationale being that they're not needed and that most drivers ignored them anyway. There's an MS document floating around somewhere that explains this.

Direct3D has need of instancing, but we do not. We have plenty of glVertexAttrib calls.

This topic is closed to new replies.

Advertisement