Batching

For raw rendering speed, use the least amount of primitives to represent as many objects as possible.

Topic Description
Triangle Mesh Combine TriangleMeshPrimitive objects that have the same color. When using indexed triangle lists as input, the triangles do not need to be adjacent. See the Triangle Mesh Overview to learn about indexed triangle lists.
Point Batch Instead of creating several PointBatchPrimitive objects, each with a single point, create one PointBatchPrimitive with many points.
Text Batch Use one TextBatchPrimitive object to render several strings. Although in many cases, rendering thousands of strings with a small number of objects will be as efficient as rendering with just one, and is likely to provide better culling.
Polyline Instead of creating several PolylinePrimitive objects with two positions each, create one PolylinePrimitive with several positions. Also, instead of creating several PolylinePrimitive objects, using PolylineType.LineStrip, create one PolylinePrimitive using PolylineType.Lines. This trades memory for better batching.

Triangle Mesh

By combining triangle mesh primitives that share the same color we can improve performance even though the number of pixels rendered remains the same. This batching relies on primitives sharing the same color so it is limited by the number of unique colors used. The following class can be used to combine triangle mesh primitives.

[C#] Copy Code
public class TriangleMeshBatch
{
    public TriangleMeshBatch(Color color, AgStkObjectRoot root)
    {
        m_color = color;
        m_positions = new List<object>();
        m_normals = new List<object>();
        m_indices = new List<object>();
        m_root = root;
        m_manager = ((IAgScenario)root.CurrentScenario).SceneManager;
    }

    /// <summary>
    /// Call this one or more times to add triangles to the mesh.
    /// </summary>
    public void Append(IAgStkGraphicsTriangulatorResult triangles)
    {
        for (int i = 0; i < triangles.Positions.Length; i++)
        {
            m_positions.Add(triangles.Positions.GetValue(i));
            m_normals.Add(triangles.Normals.GetValue(i));
        }
        for (int i = 0; i < triangles.Indices.Length; i++)
            m_indices.Add(triangles.Indices.GetValue(i));
    }

    /// <summary>
    /// Call this once after all calls to Append().
    /// </summary>
    public IAgStkGraphicsTriangleMeshPrimitive Commit(string centralBody, IAgStkGraphicsPrimitiveManager primitives)
    {
        IAgStkGraphicsTriangleMeshPrimitive mesh = m_manager.Initializers.TriangleMeshPrimitive.InitializeWithSetHint(
AgEStkGraphicsSetHint.eStkGraphicsSetHintInfrequent);
        Array positions = m_positions.ToArray();
        Array normals = m_normals.ToArray();
        Array indices = m_indices.ToArray();

        mesh.Set(ref positions, ref normals, ref indices);
        ((IAgStkGraphicsPrimitive)mesh).ReferenceFrame = m_root.CentralBodies[centralBody].Vgt.Systems["Fixed"];

        ((IAgStkGraphicsPrimitive)mesh).Color = m_color;
        ((IAgStkGraphicsPrimitive)mesh).Translucency = 0;
        primitives.Add((IAgStkGraphicsPrimitive)mesh);
        return mesh;
    }

    private readonly Color m_color;
    private readonly List<object> m_positions;
    private readonly List<object> m_normals;
    private readonly List<object> m_indices;
    private AgStkObjectRoot m_root;
    private IAgStkGraphicsSceneManager m_manager;
}

To use this class, first create an instance, specifying the color of the mesh. Then call Append one or more times to add triangles to the mesh. The triangulator objects do not need to be adjacent to each other. Finally, call Commit to create the primitive. An example that combines two extents is shown below.

[C#] Copy Code
IAgStkGraphicsSceneManager SceneManager = ((IAgScenario)root.CurrentScenario).SceneManager;
Array extent1 = new object[]
{
    0, 0, 1, 1
};
IAgStkGraphicsSurfaceTriangulatorResult result1 = SceneManager.Initializers.SurfaceExtentTriangulator.ComputeSimple("Earth", ref extent1);

Array extent2 = new object[]
{
    2, 0, 3, 1
};
IAgStkGraphicsSurfaceTriangulatorResult result2 = SceneManager.Initializers.SurfaceExtentTriangulator.ComputeSimple("Earth", ref extent2);

TriangleMeshBatch batch = new TriangleMeshBatch(Color.Green, root);
batch.Append((IAgStkGraphicsTriangulatorResult)result1);
batch.Append((IAgStkGraphicsTriangulatorResult)result2);
IAgStkGraphicsTriangleMeshPrimitive mesh = batch.Commit("Earth", SceneManager.Primitives);

Point Batch

For best performance, use large point batches. If a point batch is created for each point in the STK Area Targets for the United States, 13,691 primitives are created. Instead, if one point batch is created for each area target, only 134 primitives are created. The frame rate can be improved if only one point batch is used to represent every point.

In order to combine point batches, it may be necessary to use Set methods with arguments for colors if the orginial point batches have different colors. These methods allow each point in a point batch to have a unique color.

Text Batch

Text batches provide a great degree of flexibility to allow grouping several strings into one batch. Using TextBatchPrimitiveOptionalParameters, each string can have a unique color, horizontal origin, vertical origin, pixel offset, and eye offset. The main constraint is each string in a batch must share the same GraphicsFont.

Polyline

It is straightforward and beneficial to combine several polylines that use PolylineType.Lines into one polyline. It is also possible to combine several polylines that use PolylineType.LineStrip into a single primitive that uses PolylineType.Lines by duplicating positions, for example, rendering the boundary for each state using a separate primitive. If per-position color is used and the type is changed from line strips to individual lines, one polyline primitive can render the boundary for every state.

This uses a significant amount more memory and more than double the previous method. Be cautious with this technique because it may hurt performance when limited GPU memory is available. If too much memory is used, it will not all fit into GPU memory and will cause more bus traffic.

STK Programming Interface 11.0.1