BillboardBatch

Easy3D / Data & Batching / BillboardBatch

Easy3D::BillboardBatch collects billboards — camera-facing quads — for later drawing. The intended use is rendering sprites (such as Blupi) as billboards from existing 2D frames. Add() stores one BillboardItem per call; Items() exposes them so a future CPU-side vertex builder / CNA draw path can consume them once that phase starts. This class does no GPU work itself.

#include <Easy3D/BillboardBatch.hpp>

namespace Easy3D
{
    struct BillboardItem;
    class  BillboardBatch;
}
Queueing is pure data storage, but constructing the CNA Vector3/Vector2 values you pass in calls CNA's compiled constructors — so executables using this class link CNA in practice. See Building & CMake.

BillboardItem

One queued camera-facing quad:

FieldTypeDefaultMeaning
PositionVector3World position of the billboard.
SizeVector2Quad width and height in world units.
UvUvRect{0, 0, 1, 1}Texture-atlas region to sample (see TextureAtlas::GetUv/GetUvOrDefault). Defaults to the full texture.
OriginVector2{0.5, 0.5}Pivot origin, normalized — the default is the quad's center. {0.5, 1.0} would pivot at the bottom-center (useful for characters standing on the ground).
RotationRadiansfloat0In-plane rotation around the origin, in radians.

Type aliases

AliasRefers to
BillboardBatch::Vector3Microsoft::Xna::Framework::Vector3
BillboardBatch::Vector2Microsoft::Xna::Framework::Vector2

API

void Begin() noexcept
Discard any queued billboards, starting a fresh batch.
void Add(const Vector3& position, const Vector2& size)
Queue one billboard at position with the given size, full-texture UV, centered origin, and no rotation.
void Add(const Vector3& position, const Vector2& size, const UvRect& uv)
Queue one billboard sampling the atlas region uv (centered origin, no rotation).
void Add(const BillboardItem& item)
Queue a fully specified billboard item (custom origin and rotation included).
void End() noexcept
Flush queued billboards — currently a no-op (no GPU work yet). Exists so call sites already have the final Begin()/Add()/End() shape.
void Clear() noexcept
Discard any queued billboards (equivalent to Begin()).
[[nodiscard]] bool Empty() const noexcept
[[nodiscard]] std::size_t Count() const noexcept
Whether the queue is empty / how many items are queued.
[[nodiscard]] const std::vector<BillboardItem>& Items() const noexcept
The queued billboards, in Add() order. This is the hand-off point for a future vertex builder or your own draw code.

Example — sprite frames as billboards

#include <Easy3D/BillboardBatch.hpp>
#include <Easy3D/TextureAtlas.hpp>

using Vector3 = Easy3D::BillboardBatch::Vector3;

Easy3D::TextureAtlas atlas(256, 256);
atlas.AddGrid("blupi_walk", 32, 48, 8, 1);

Easy3D::BillboardBatch billboards;
billboards.Begin();

// A simple walking animation: pick the frame by time.
const int frame = static_cast<int>(totalSeconds * 10.0f) % 8;
Easy3D::BillboardItem blupi;
blupi.Position = Vector3(2.0f, 0.75f, 5.0f);
blupi.Size     = {1.0f, 1.5f};
blupi.Uv       = atlas.GetUv("blupi_walk_" + std::to_string(frame));
blupi.Origin   = {0.5f, 1.0f};   // pivot at the feet
billboards.Add(blupi);

billboards.End();

// Later: hand billboards.Items() to your draw code (Phase 4 will add CNA adapters).

Lifecycle pattern

The expected per-frame usage mirrors XNA's SpriteBatch shape:

billboards.Begin();      // clear last frame's items
// ... Add() everything visible this frame ...
billboards.End();        // future: flush; today: no-op

Rendering the queued items is a later roadmap phase — see the Roadmap (Phase 3 builds CPU-side vertices, Phase 4 adds CNA draw adapters). Until then, Items() gives you everything needed to draw them yourself with CNA.