This is a helper for drawing simple geometric shapes including texture coordinates and surface normals.
  • Cube
  • Sphere
  • Geodesic Sphere
  • Cylinder
  • Torus
  • Teapot

Initialization

The GeometryPrimitive class must be created from a factory method which takes the Direct3D 11 device context.

std::unique_ptr<GeometricPrimitive> shape(
GeometricPrimitive::CreateTeapot(deviceContext) );
For exception safety, it is recommended you make use of the C++ RAII pattern and use a std::unique_ptr or std::shared_ptr
  • CreateCube( deviceContext, float size = 1)
  • CreateSphere( deviceContext, float diameter = 1, size_t tessellation = 16)
  • CreateGeoSphere( deviceContext, float diameter = 1, size_t tessellation = 3)
  • CreateCylinder( deviceContext, float height = 1, float diameter = 1, size_t tessellation = 32)
  • CreateTorus( deviceContext, float diameter = 1, float thickness = 0.333f, size_t tessellation = 32)
  • CreateTeapot( deviceContext, float size = 1, size_t tessellation = 8)

Simple drawing

shape->Draw(world, view, projection, Colors::CornflowerBlue);
The draw method accepts an optional texture parameter, wireframe flag, and a callback function which can be used to override the default rendering state:

shape->Draw(world, view, projection, Colors::White, catTexture, false, [=]
{
    deviceContext->OMSetBlendState(...);
});
This makes use of a BasicEffect shared by all geometric primitives drawn on that device context.

Advanced drawing

This form of drawing makes use of a custom Effects instance. The caller is responsible for using an input layout that matches the effect.

IEffect* myeffect = ...

Microsoft::WRL::ComPtr<ID3D11InputLayout> inputLayout;
shape->CreateInputLayout( myeffect, &inputLayout );

shape->Draw( myeffect, inputLayout.Get() );
This takes an optional parameter for enabling alpha-blending, wireframe, and a callback function which can be used to override the default rendering state.

Coordinate systems

These geometric primitives (based on the XNA Game Studio conventions) use right-handed coordinates. They can be used with left-handed coordinates by setting the rhcoords parameter on the factory methods to 'false' to reverse the winding ordering (the parameter defaults to 'true').

std::unique_ptr<GeometricPrimitive> shape(
GeometricPrimitive::CreateTeapot( deviceContext, 1.f, 8, false ) );

Alpha blending

Alpha blending defaults to using premultiplied alpha. To make use of 'straight' alpha textures, override the blending mode via the optional callback:

CommonStates states(deviceContext);

shape->Draw(world, view, projection, Colors::White, catTexture, false, [=]
{
    deviceContext->OMSetBlendState( states.NonPremultiplied(), nullptr, 0xFFFFFFFF);
});

Feature Level Notes

In order to support all feature levels, the GeometricPrimitive implementation make use of 16-bit indices (DXGI_FORMAT_R16_UINT) which limits to a maximum of 65535 vertices. Feature Level 9.1 is limited to a maximum of 65535 primitives in a single draw.

Threading model

Each GeometricPrimitive instance only supports drawing from one thread at a time, but you can simultaneously submit primitives on multiple threads if you create a separate GeometricPrimitive instance per Direct3D 11 deferred context.
http://msdn.microsoft.com/en-us/library/windows/desktop/ff476892.aspx

Further Reading

http://msdn.microsoft.com/en-us/library/windows/desktop/ff476876.aspx

http://blogs.msdn.com/b/chuckw/archive/2012/06/20/direct3d-feature-levels.aspx

http://en.wikipedia.org/wiki/Cube
http://en.wikipedia.org/wiki/Sphere
http://en.wikipedia.org/wiki/Cylinder_(geometry)
http://en.wikipedia.org/wiki/Utah_teapot
http://en.wikipedia.org/wiki/Torus

Last edited May 22, 2013 at 11:32 PM by walbourn, version 31