Click or drag to resize

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.

Note Note

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

Basic Example

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

Java
GraphicsFont font = new GraphicsFont("MS Sans Serif", 12);

CentralBody earth = CentralBodiesFacet.getFromContext().getEarth();
ArrayList<Cartographic> positions = new ArrayList<Cartographic>();
positions.add(new Cartographic(Trig.degreesToRadians(-75.25), Trig.degreesToRadians(39.88), 0.0));
positions.add(new Cartographic(Trig.degreesToRadians(-77.04), Trig.degreesToRadians(38.85), 0.0));

ArrayList<String> strings = new ArrayList<String>();
strings.add("Philadelphia");
strings.add("Washington, D.C.");

TextBatchPrimitive textBatch = new TextBatchPrimitive(font, SetHint.INFREQUENT);
textBatch.setCartographic(earth, positions, strings);

SceneManager.getPrimitives().add(textBatch);
Text Batch Example
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.

Java
// Bold and outline font
GraphicsFont font = new GraphicsFont("MS Sans Serif", 12, FontStyle.BOLD, true);

CentralBody earth = CentralBodiesFacet.getFromContext().getEarth();
List<Cartographic> positions = new ArrayList<Cartographic>();
positions.add(new Cartographic(Trig.degreesToRadians(-75.25), Trig.degreesToRadians(39.88), 0.0));
positions.add(new Cartographic(Trig.degreesToRadians(-77.04), Trig.degreesToRadians(38.85), 0.0));

List<String> strings = new ArrayList<String>();
strings.add("Philadelphia");
strings.add("Washington, D.C.");

TextBatchPrimitive textBatch = new TextBatchPrimitive(font, SetHint.INFREQUENT);
textBatch.setCartographic(earth, positions, strings);
textBatch.setOutlineColor(Color.RED);
Text Batch Outline Example
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 primitive, as shown below:

Java
GraphicsFont font = new GraphicsFont("MS Sans Serif", 12, FontStyle.REGULAR, false);

CentralBody earth = CentralBodiesFacet.getFromContext().getEarth();
ArrayList<Cartographic> positions = new ArrayList<Cartographic>();
positions.add(new Cartographic(Trig.degreesToRadians(-75.25), Trig.degreesToRadians(39.88), 3000.0));
positions.add(new Cartographic(Trig.degreesToRadians(-77.04), Trig.degreesToRadians(38.85), 0.0));

ArrayList<String> strings = new ArrayList<String>();
strings.add("Philadelphia");
strings.add("Washington, D.C.");

ArrayList<Color> colors = new ArrayList<Color>();
colors.add(new Color(255, 0, 255, 255));
colors.add(new Color(255, 0, 255, 127));

TextBatchPrimitiveOptionalParameters parameters = new TextBatchPrimitiveOptionalParameters();
parameters.setColors(colors);

TextBatchPrimitive textBatch = new TextBatchPrimitive(font, SetHint.INFREQUENT);
textBatch.setCartographic(earth, positions, strings, parameters);

SceneManager.getPrimitives().add(textBatch);
Text Batch Colored Example
Origins

In many cases, text should be aligned be next to another primitive, such as a point, marker, or model. By default, a string's position defines the bottom left corner of the text. Using TextBatchPrimitiveOptionalParameters, the horizontal origin can be configured as left, center, or right, and the vertical origin as bottom, center, or top. Use the Origin (get / set) property to set the origin for every string in a batch, or use the setOrigins method to define origins per-string. The following code creates a text batch with several strings to demonstrate different origins:

Java
GraphicsFont font = new GraphicsFont("MS Sans Serif", 12, FontStyle.REGULAR, false);

CentralBody earth = CentralBodiesFacet.getFromContext().getEarth();
ArrayList<Cartographic> positions = new ArrayList<Cartographic>();
positions.add(new Cartographic(Trig.degreesToRadians(-75.25), Trig.degreesToRadians(39.88), 0.0));
positions.add(new Cartographic(Trig.degreesToRadians(-75.25), Trig.degreesToRadians(39.88), 0.0));
positions.add(new Cartographic(Trig.degreesToRadians(-75.25), Trig.degreesToRadians(39.88), 90000.0));
positions.add(new Cartographic(Trig.degreesToRadians(-75.25), Trig.degreesToRadians(39.88), 90000.0));

ArrayList<String> strings = new ArrayList<String>();
strings.add("Top Left Origin");
strings.add("Bottom Right Origin");
strings.add("Top Center Origin");
strings.add("Bottom Center Origin");

ArrayList<Origin> origins = new ArrayList<Origin>();
origins.add(Origin.TOP_LEFT);
origins.add(Origin.BOTTOM_RIGHT);
origins.add(Origin.TOP_CENTER);
origins.add(Origin.BOTTOM_CENTER);

TextBatchPrimitiveOptionalParameters parameters = new TextBatchPrimitiveOptionalParameters();
parameters.setOrigins(origins);

TextBatchPrimitive textBatch = new TextBatchPrimitive(font, SetHint.INFREQUENT);
textBatch.setCartographic(earth, positions, strings, parameters);

PointBatchPrimitive pointBatch = new PointBatchPrimitive(SetHint.INFREQUENT);
pointBatch.setCartographic(earth, positions);
pointBatch.setPixelSize(8.0f);

SceneManager.getPrimitives().add(textBatch);
SceneManager.getPrimitives().add(pointBatch);
Text Batch Horizontal and Vertical Origins
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, the following code example applies a pixel offset of 10:

Java
ArrayList<PointF> pixelOffsets = new ArrayList<PointF>();
pixelOffsets.add(new PointF(10.0f, 0.0f));
pixelOffsets.add(new PointF(0.0f, 0.0f));

TextBatchPrimitiveOptionalParameters parameters = new TextBatchPrimitiveOptionalParameters();
parameters.setPixelOffsets(pixelOffsets);
Text Batch Offset Example

In the above example, "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 the PixelOffset (get / set) property instead of the setPixelOffsets method.

In addition to pixel offsets, an eye space offset can be applied to each string using EyeOffset (get / set) 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 than a pixel offset or a world translation (e.g. offset the altitude by ten meters).

Text Batch Eye Offset
From this view, the eye offset moves the strings approximately north.
Text Batch Eye Offset
From a different view, the offset moves the strings approximately along their surface normals.
Unicode Support

TextBatchPrimitive has support for Unicode text. 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 can be the actual Unicode glyphs. Otherwise, the Unicode characters can be encoded with a '\u' followed by the hexadecimal encoding, as seen in the code example below:

Java
ArrayList<String> text = new ArrayList<String>();
text.add("Wilkommen");
text.add("Bienvenue");
text.add("Bem-vindo");
text.add("Welcome");
text.add("\u0623\u0647\u0644\u0627\u064b \u0648 \u0633\u0647\u0644\u0627\u064b");
text.add("\u0414\u043e\u0431\u0440\u043e \u043f\u043e\u0436\u0430\u043b\u043e\u0432\u0430\u0442\u044a");

CentralBody earth = CentralBodiesFacet.getFromContext().getEarth();
ArrayList<Cartographic> positions = new ArrayList<Cartographic>();
positions.add(new Cartographic(Trig.degreesToRadians(9.0), Trig.degreesToRadians(51.0), 0.0));
positions.add(new Cartographic(Trig.degreesToRadians(2.0), Trig.degreesToRadians(46.0), 0.0));
positions.add(new Cartographic(Trig.degreesToRadians(-8.0), Trig.degreesToRadians(39.5), 0.0));
positions.add(new Cartographic(Trig.degreesToRadians(-97.0), Trig.degreesToRadians(38.0), 0.0));
positions.add(new Cartographic(Trig.degreesToRadians(45.0), Trig.degreesToRadians(25.0), 0.0));
positions.add(new Cartographic(Trig.degreesToRadians(100.0), Trig.degreesToRadians(60.0), 0.0));

GraphicsFont font = new GraphicsFont(new Font("Arial", Font.PLAIN, 12), true);
TextBatchPrimitive textBatch = new TextBatchPrimitive(font, SetHint.INFREQUENT);
textBatch.setCartographic(earth, positions, text);
Text Batch Unicode
Dynamic Updates

As explained in the Dynamic Updates topic, 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. The following example updates the position of the second string in the text batch:

Java
// textBatch was initialized with SetHint.PARTIAL.

ArrayList<Cartesian> newPosition = new ArrayList<Cartesian>();
newPosition.add(new Cartesian(p1.getX(), p1.getY(), p1.getZ()));
ArrayList<Integer> indices = new ArrayList<Integer>();
indices.add(1);

textBatch.setPartial(newPosition, null, indices);

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

  • If the length of a string increases (e.g. changes from "0.1" to "0.12"), the new length cannot be longer than the length defined by MaximumStringLength (get / set). It is recommended to set this property to the anticipated length of the longest string when initializing a text batch.

  • The string's text must also be passed in order to modify the string's horizontal or vertical origin.