GroveEngine/modules/BgfxRenderer/Text/BitmapFont.h
StillHammer 613283d75c feat(BgfxRenderer): Phase 7-8 - Text, Tilemap, Multi-texture, Resize
Phase 7 - Text Rendering:
- Add BitmapFont with embedded 8x8 CP437 font (ASCII 32-126)
- Add TextPass for instanced glyph rendering
- Fix SceneCollector::parseText() to copy strings to FrameAllocator

Phase 8A - Multi-texture Support:
- Add numeric texture ID system in ResourceCache
- SpritePass sorts by textureId and batches per texture
- Flush batch on texture change for efficient rendering

Phase 8B - Tilemap Rendering:
- Add TilemapPass for grid-based tile rendering
- Support tileData as comma-separated string
- Tiles rendered as instanced quads

Window Resize:
- Handle window resize via process() input
- Call bgfx::reset() on size change

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-11-27 22:09:48 +08:00

102 lines
2.8 KiB
C++

#pragma once
#include "../RHI/RHITypes.h"
#include <cstdint>
#include <string>
#include <unordered_map>
namespace grove {
namespace rhi { class IRHIDevice; }
// ============================================================================
// Glyph Info - Metrics for a single character
// ============================================================================
struct GlyphInfo {
float u0, v0, u1, v1; // UV coordinates in atlas
float width, height; // Glyph size in pixels
float offsetX, offsetY; // Offset from cursor position
float advance; // Cursor advance after this glyph
};
// ============================================================================
// BitmapFont - Simple bitmap font for text rendering
// ============================================================================
class BitmapFont {
public:
BitmapFont() = default;
~BitmapFont() = default;
// Non-copyable
BitmapFont(const BitmapFont&) = delete;
BitmapFont& operator=(const BitmapFont&) = delete;
/**
* @brief Initialize with embedded 8x8 monospace font
* @param device RHI device for texture creation
* @return true on success
*/
bool initDefault(rhi::IRHIDevice& device);
/**
* @brief Load font from BMFont format (.fnt + .png)
* @param device RHI device for texture creation
* @param fntPath Path to .fnt file
* @param pngPath Path to .png atlas
* @return true on success
*/
bool loadBMFont(rhi::IRHIDevice& device, const std::string& fntPath, const std::string& pngPath);
/**
* @brief Cleanup GPU resources
*/
void shutdown(rhi::IRHIDevice& device);
/**
* @brief Get glyph info for a character
* @param codepoint Unicode codepoint (ASCII for now)
* @return Glyph info, or default space if not found
*/
const GlyphInfo& getGlyph(uint32_t codepoint) const;
/**
* @brief Get font atlas texture
*/
rhi::TextureHandle getTexture() const { return m_texture; }
/**
* @brief Get line height (for multi-line text)
*/
float getLineHeight() const { return m_lineHeight; }
/**
* @brief Get base font size (pixels)
*/
float getBaseSize() const { return m_baseSize; }
/**
* @brief Calculate text width in pixels
*/
float measureWidth(const char* text) const;
/**
* @brief Check if font is loaded
*/
bool isValid() const { return m_texture.isValid(); }
private:
void generateDefaultGlyphs();
rhi::TextureHandle m_texture;
std::unordered_map<uint32_t, GlyphInfo> m_glyphs;
GlyphInfo m_defaultGlyph;
float m_lineHeight = 8.0f;
float m_baseSize = 8.0f;
uint16_t m_atlasWidth = 128;
uint16_t m_atlasHeight = 64;
};
} // namespace grove