Text Batch Primitive

The text batch primitive renders a group of strings with the same font. Each string can have a different position, color, horizontal origin, vertical origin, pixel offset, and eye offset. Using the text batch is similar to using the point batch, only strings are rendered instead of points.

Topic Description
Basic Example Use the text batch to render strings.
Fonts Change font properties, such as size, bold, and outline.
Per-String Color Use optional parameters to define a color per-string.
Horizontal and Vertical Origins Control the horizontal and vertical placement of a string relative to its position.
Pixel and Eye Offsets Optional offsets translate strings in pixel and/or eye space.
Unicode Support Use the text batch to render Unicode strings.
Dynamic Updates Set and SetPartial methods enable efficient dynamic updates.

Technical Details: The text batch uses a GPU-based rendering algorithm described in our blog.

Basic Example

The following example renders two strings with the MS Sans Serif font. A collection containing the strings and a parallel collection containing positions corresponding to each string are used to define the primitive.

[C#] Copy Code
IAgStkGraphicsSceneManager manager = ((IAgScenario)root.CurrentScenario).SceneManager;
IAgStkGraphicsGraphicsFont font = manager.Initializers.GraphicsFont.InitializeWithNameSize(
"MS Sans Serif", 12);

Array text = new object[]
{
     "Philadelphia",
     "Washington, D.C."
};

Array positions = new object[]
{
     39.88, -75.25, 0, // Philadelphia
     38.85, -77.04, 0 // Washington, D.C.
};

IAgStkGraphicsTextBatchPrimitive textBatch = manager.Initializers.TextBatchPrimitive.InitializeWithGraphicsFontAndSetHint(
font, AgEStkGraphicsSetHint.eStkGraphicsSetHintInfrequent);
textBatch.SetCartographic("Earth", ref positions, ref text);

manager.Primitives.Add((IAgStkGraphicsPrimitive)textBatch);

Fonts

GraphicsFont defines the font used to render a text batch. The constructor defines the font based on name, size, style, and outline. When a font is created with an outline, text is rendered with a colored outline as shown below.

[C#] Copy Code
IAgStkGraphicsSceneManager manager = ((IAgScenario)root.CurrentScenario).SceneManager;
// Bold and outline font
IAgStkGraphicsGraphicsFont font = manager.Initializers.GraphicsFont.InitializeWithNameSizeFontStyleOutline(
"MS Sans Serif", 12, AgEStkGraphicsFontStyle.eStkGraphicsFontStyleBold, true);

Array text = new object[]
{
     "Philadelphia",
     "Washington, D.C."
};

Array positions = new object[]
{
     39.88, -75.25, 0, // Philadelphia
     38.85, -77.04, 0 // Washington, D.C.
};

IAgStkGraphicsTextBatchPrimitive textBatch = manager.Initializers.TextBatchPrimitive.InitializeWithGraphicsFontAndSetHint(
font, AgEStkGraphicsSetHint.eStkGraphicsSetHintInfrequent);
textBatch.SetCartographic("Earth", ref positions, ref text);
textBatch.OutlineColor = Color.Red;

manager.Primitives.Add((IAgStkGraphicsPrimitive)textBatch);

Per-String Color

By default, text is white. The standard color and translucency properties are used to change the color of every string in the batch. For more flexibility, each string can have a unique color. This is done by creating a collection of colors, where each color corresponds to one string. The collection of colors is an optional parameter, so it is added to a TextBatchPrimitiveOptionalParameters object, which is then passed to the constructor as shown below.

[C#] Copy Code
IAgStkGraphicsSceneManager manager = ((IAgScenario)root.CurrentScenario).SceneManager;
IAgStkGraphicsGraphicsFont font = manager.Initializers.GraphicsFont.InitializeWithNameSizeFontStyleOutline(
"MS Sans Serif", 12, AgEStkGraphicsFontStyle.eStkGraphicsFontStyleRegular, false);

Array text = new object[]
{
     "Philadelphia",
     "Washington, D.C."
};

Array positions = new object[]
{
     39.88, -75.25, 0, // Philadelphia
     38.85, -77.04, 0 // Washington, D.C.
};

Array colors = new object[]
{
     Color.FromArgb(255, 255, 0, 255).ToArgb(),
     Color.FromArgb(127, 255, 0, 255).ToArgb()
};

IAgStkGraphicsTextBatchPrimitiveOptionalParameters parameters = manager.Initializers.TextBatchPrimitiveOptionalParameters.Initialize();
parameters.SetColors(ref colors);

IAgStkGraphicsTextBatchPrimitive textBatch = manager.Initializers.TextBatchPrimitive.InitializeWithGraphicsFontAndSetHint(
font, AgEStkGraphicsSetHint.eStkGraphicsSetHintInfrequent);
textBatch.SetCartographicWithOptionalParameters("Earth", ref positions, ref text, parameters);

manager.Primitives.Add((IAgStkGraphicsPrimitive)textBatch);

Origins

In many cases, text will be next to another primitive, such as a point, marker, or model. For example, the same positions collection used to initialize a text batch can be used to initialize a point batch as shown below.

[C#] Copy Code
IAgStkGraphicsPointBatchPrimitive pointBatch = manager.Initializers.PointBatchPrimitive.InitializeWithSetHint(
AgEStkGraphicsSetHint.eStkGraphicsSetHintInfrequent);
pointBatch.SetCartographic("Earth", ref positions);
pointBatch.PixelSize = 5;

By default, a string's position defines the bottom left corner of the text. Using TextBatchPrimitiveOptionalParameters, the position can define the horizontal origin as left, center, or right, and the vertical origin as bottom, center, or top. Use the Origin property to set the origin for every string in a batch, or use SetOrigins to define origins per-string. The following code creates a text batch with several strings to demonstrate the affects of different origins.

[C#] Copy Code
IAgStkGraphicsSceneManager manager = ((IAgScenario)root.CurrentScenario).SceneManager;
IAgStkGraphicsGraphicsFont font = manager.Initializers.GraphicsFont.InitializeWithNameSizeFontStyleOutline(
"MS Sans Serif", 12, AgEStkGraphicsFontStyle.eStkGraphicsFontStyleRegular, false);

Array positions = new object[]
{
     39.88, -75.25, 0.0,
     39.88, -75.25, 0.0,
     39.88, -75.25, 90000.0,
     39.88, -75.25, 90000.0
};

Array strings = new object[]
{
     "Top Left Origin",
     "Bottom Right Origin",
     "Top Center Origin",
     "Bottom Center Origin"
};

Array origins = new object[]
{
     AgEStkGraphicsOrigin.eStkGraphicsOriginTopLeft,
     AgEStkGraphicsOrigin.eStkGraphicsOriginBottomRight,
     AgEStkGraphicsOrigin.eStkGraphicsOriginTopCenter,
     AgEStkGraphicsOrigin.eStkGraphicsOriginBottomCenter
};

IAgStkGraphicsTextBatchPrimitiveOptionalParameters parameters = manager.Initializers.TextBatchPrimitiveOptionalParameters.Initialize();
parameters.SetOrigins(ref origins);

IAgStkGraphicsTextBatchPrimitive textBatch = manager.Initializers.TextBatchPrimitive.InitializeWithGraphicsFontAndSetHint(
font, AgEStkGraphicsSetHint.eStkGraphicsSetHintInfrequent);
textBatch.SetCartographicWithOptionalParameters("Earth", ref positions, ref strings, parameters);

IAgStkGraphicsPointBatchPrimitive pointBatch = manager.Initializers.PointBatchPrimitive.InitializeWithSetHint(
AgEStkGraphicsSetHint.eStkGraphicsSetHintInfrequent);
pointBatch.SetCartographic("Earth", ref positions);
pointBatch.PixelSize = 8;

manager.Primitives.Add((IAgStkGraphicsPrimitive)textBatch);
manager.Primitives.Add((IAgStkGraphicsPrimitive)pointBatch);

Pixel and Eye Offsets

Using TextBatchPrimitiveOptionalParameters, text can be offset from its position in either pixel or eye coordinates. In pixel coordinates, increasing x moves from the left toward the right side of the window, and increasing y moves from the bottom to the top. To move "Philadelphia" to the right so the "P" and the point do not overlap, apply a pixel offset of 10.

[C#] Copy Code
Array pixelOffsets = new object[]
{
     10, 0,
     0, 0
};

IAgStkGraphicsTextBatchPrimitiveOptionalParameters parameters = manager.Initializers.TextBatchPrimitiveOptionalParameters.Initialize();
parameters.SetPixelOffsets(ref pixelOffsets);

"Washington, D.C." has an offset of (0, 0) so it is not moved from its position. If every string in a batch will have the same offset, use PixelOffset instead of providing an collection to SetPixelOffsets.

In addition to pixel offsets, an eye space offset can be applied to each string using EyeOffset or SetEyeOffsets. Each unit in eye space is 1 meter. Positive x points towards the camera's right, positive y points up, and negative z points along the view vector. For example, a positive y offset may be applied to translate a string so it is always "on top" of a model primitive.

The following images demonstrate how applying an eye offset of (0, 100000, 0) affects the position of a string from different view points. Note that an eye offset is different from a pixel offset or a world translation (e.g. offset the altitude by ten meters).

From this view, the eye offset moves the strings approximately north.

From a different view, the offset moves the strings approximately along their surface normals.

Unicode Support

TextBatchPrimitive has support for Unicode. To use Unicode strings, initialize the TextBatchPrimitive with a GraphicsFont where the font family name is one that supports the Unicode characters used. If the file is formatted with a Unicode encoding, the string may be the actual Unicode glyphs; otherwise, the Unicode characters must be a '\u' followed by the hexadecimal encoding which is shown for every string in the code below.

[C#] Copy Code
IAgStkGraphicsSceneManager manager = ((IAgScenario)root.CurrentScenario).SceneManager;
//
// Create the strings
//
char[] german = { '\u0057', '\u0069', '\u006C', '\u006B', '\u006F', '\u006D', '\u006D', '\u0065', '\u006E' };
char[] french = { '\u0042', '\u0069', '\u0065', '\u006E', '\u0076', '\u0065', '\u006E', '\u0075', '\u0065', '\u0020' };
char[] portuguese = { '\u0042', '\u0065', '\u006D', '\u002D', '\u0076', '\u0069', '\u006E', '\u0064', '\u006F' };
char[] english = { '\u0057', '\u0065', '\u006C', '\u0063', '\u006F', '\u006D', '\u0065' };
char[] russian = { '\u0414', '\u043E', '\u0431', '\u0440', '\u043E', '\u0020', '\u043F', '\u043E',
'\u0436', '\u0430', '\u043B', '\u043E', '\u0432', '\u0430', '\u0442', '\u044A' };
char[] arabic = { '\u0623', '\u0647', '\u0644', '\u0627', '\u064B', '\u0020', '\u0648', '\u0020',
'\u0633', '\u0647', '\u0644', '\u0627', '\u064B' };

Array text = new object[]
{
     new string(german),
     new string(french),
     new string(portuguese),
     new string(english),
     new string(russian),
     new string(arabic)
};

//
// Create the positions
//
Array positions = new object[]
{
     51.00, 09.00, 0.0,
     46.00, 02.00, 0.0,
     39.50, -08.00, 0.0,
     38.00, -97.00, 0.0,
     60.00, 100.00, 0.0,
     25.00, 45.00, 0.0
};

IAgStkGraphicsGraphicsFont font = manager.Initializers.GraphicsFont.InitializeWithNameSizeFontStyleOutline("Unicode", 12,
AgEStkGraphicsFontStyle.eStkGraphicsFontStyleBold, true);
IAgStkGraphicsTextBatchPrimitive textBatch = manager.Initializers.TextBatchPrimitive.InitializeWithGraphicsFont(font);
textBatch.SetCartographic("Earth", ref positions, ref text);

Dynamic Updates

As explained in the dynamic updates overview, the text batch provides Set and SetPartial methods for efficient dynamic updates of positions, strings, and optional parameters, such as colors. Use Set to completely redefine the text batch. If this is done frequently (e.g. every few frames), initialize the text batch with SetHint.Frequent.

Use SetPartial to update a subset of strings in the text batch. Make sure to initialize the text batch with SetHint.Partial. SetPartial must modify either the string itself or its position. If optional parameters are not provided, the defaults are used. The following example updates the position of the second string in the text batch.

[C#] Copy Code
// textBatch was initialized with SetHint.Partial.

Array newPosition = new object[] { p1.X, p1.Y, p1.Z };
Array newText = new object[] { null };
Array indices = new object[] { 1 };

textBatch.SetPartial(ref newPosition, ref newText, ref indices);

Due to the text batch's vertex data layout, SetPartial has a few limitations:

STK Programming Interface 11.0.1