DirectXTK PrimitiveBatch helper makes it easy to draw user primitives with D3D11

The latest version of DirectXTK adds a PrimitiveBatch helper, for easily and efficiently drawing dynamically generated geometry such as lines or triangles.  This fills the same role as the legacy D3D9 APIs DrawPrimitiveUP and DrawIndexedPrimitiveUP.  PrimitiveBatch manages the vertex and index buffers for you, using DISCARD and NO_OVERWRITE hints to avoid stalling the GPU pipeline.  It automatically merges adjacent draw requests, so if you call DrawLine 100 times in a row, only a single GPU draw call will be generated.

PrimitiveBatch is responsible for setting the vertex buffer, index buffer, and primitive topology, then issuing the final draw call. Unlike the higher level SpriteBatch helper, it does not provide shaders, set the input layout, or set any state objects. PrimitiveBatch is often used in conjunction with BasicEffect and the structures from VertexTypes.h, but it can work with any other shader or vertex formats of your own.

To initialize a PrimitiveBatch for drawing VertexPositionColor data:

    std::unique_ptr<PrimitiveBatch<VertexPositionColor>> primitiveBatch(new PrimitiveBatch<VertexPositionColor>(deviceContext));

To draw a line:



    primitiveBatch->DrawLine(VertexPositionColor(...), VertexPositionColor(...));

PrimitiveBatch provides five drawing methods:

  • DrawLine(v1, v2)
  • DrawTriangle(v1, v2, v3)
  • DrawQuad(v1, v2, v3, v4)
  • Draw(topology, vertices, vertexCount)
  • DrawIndexed(topology, indices, indexCount, vertices, vertexCount)

Comments (15)

  1. Andy says:

    No DrawTeapot?

  2. Teapots are a GeometricPrimitive, not a PrimitiveBatch feature.  But of course they are supported by DirectXTK!  This is a quality helper lib we are making here, and full teapot support is an important part of 3D graphics 🙂

  3. Daniel says:

    Any chance to get a Visual Studio solution? I am having problems with all the setup that is required (yes, I am a noob!). Thanks.

  4. Daniel,

    There are three solutions in the DirectXTK zip – one for VS 2010, another for VS 2012, and finally one for making Win8 Store apps.

  5. Hi Shawn,

    I was trying to port this to GL application, the problem is that baseVertex can be set only on GL 3.2 or higher and with usage of glDrawElementsBaseVertex method, anyway to perform drawing without DrawIndexed with baseVertex?

  6. Bug says:

    Couldn't you just give OpenGL an offset to the base vertex using glVertexPointer() or glVertexAttribPointer()?

  7. Amer says:

    Bug I think directX base Vertex means which offset to add when performing index drawing, so it means start from 5, 6, 7, 8 instead of default one which would be 0, 1, 2, 3 etc.

  8. josh says:

    how about a polygon that matches the windows size for image processing as a Geometric Primitive.

  9. > how about a polygon that matches the windows size for image processing as a Geometric Primitive.

    For image processing, SpriteBatch is a better choice than PrimitiveBatch or one of the GeometricPrimitives.h helpers.  What more would you want to see there compared to the current SpriteBatch API?

  10. josh says:

    oh okay I haven't looked into SpriteBatch just yet. Can I use compute shaders with it?

    Also how about a Grid (with adjustable divisions in u and v direction) as Geometric Primitive. Could be useful for groundplanes.

  11. You can use SpriteBatch with a custom pixel shader. Compute shaders are different: they don't involve any actual geometry being rendered so use entirely different APIs to any of this shape drawing stuff.

    What would be the benefit of tessellating a ground plane grid, as opposed to just drawing a single larger quad?

  12. josh says:

    ah, thanks you are right … my d3d knowledge is a little rusty 🙂

    a tessellated groundplane might be useful for simple vertexshader displaced terrains and flat & slightly deformed objects like leafs.

  13. Pirlo says:

    Is it means that we can't control vertexOffset or indexOffset like this

                " public void DrawUserIndexedPrimitives<T>(PrimitiveType primitiveType, T[] vertexData, int vertexOffset, int numVertices, short[] indexData, int indexOffset, int primitiveCount) where T : struct, IVertexType;"

    in xna?

  14. Pirlo – you are thinking like a C# developer 🙂  There is no need for offset parameters in C++, because you pass the actual data as a pointer rather than an array container, so you can offset that pointer to directly reference whatever sub-block of data you like.

  15. Pirlo says:

    Shawn you give me a pleasantly surprised by replaying me so quick.I think I should start to learn c++.

    I have learn much in your blog and thank you so much!