- Added TextureAtlas class to manage multiple textures packed into a single large texture, improving rendering performance and reducing GPU state changes. - Implemented methods for allocating regions, packing bitmaps, and drawing regions from the atlas. - Removed the DrawDungeonTabView function from DungeonCanvasViewer as it is no longer needed with the new EditorCard system. - Updated CMake configuration to include texture_atlas.cc in the build process. - Refactored Room class to eliminate dependency on Arena graphics sheets, transitioning to per-room graphics for rendering.
151 lines
4.3 KiB
C++
151 lines
4.3 KiB
C++
#ifndef YAZE_APP_GFX_TEXTURE_ATLAS_H
|
|
#define YAZE_APP_GFX_TEXTURE_ATLAS_H
|
|
|
|
#include <map>
|
|
#include <memory>
|
|
#include <vector>
|
|
|
|
#include "app/gfx/bitmap.h"
|
|
#include "absl/status/status.h"
|
|
|
|
namespace yaze {
|
|
namespace gfx {
|
|
|
|
/**
|
|
* @class TextureAtlas
|
|
* @brief Manages multiple textures packed into a single large texture for performance
|
|
*
|
|
* Future-proof infrastructure for combining multiple room textures into one atlas.
|
|
* This reduces GPU state changes and improves rendering performance when many rooms are open.
|
|
*
|
|
* Benefits:
|
|
* - Fewer texture binds per frame
|
|
* - Better memory locality
|
|
* - Reduced VRAM fragmentation
|
|
* - Easier batch rendering
|
|
*
|
|
* Usage (Future):
|
|
* TextureAtlas atlas(2048, 2048);
|
|
* auto region = atlas.AllocateRegion(room_id, 512, 512);
|
|
* atlas.PackBitmap(room.bg1_buffer().bitmap(), *region);
|
|
* atlas.DrawRegion(room_id, x, y);
|
|
*/
|
|
class TextureAtlas {
|
|
public:
|
|
/**
|
|
* @brief Region within the atlas texture
|
|
*/
|
|
struct AtlasRegion {
|
|
int x = 0; // X position in atlas
|
|
int y = 0; // Y position in atlas
|
|
int width = 0; // Region width
|
|
int height = 0; // Region height
|
|
int source_id = -1; // ID of source (e.g., room_id)
|
|
bool in_use = false; // Whether this region is allocated
|
|
};
|
|
|
|
/**
|
|
* @brief Construct texture atlas with specified dimensions
|
|
* @param width Atlas width in pixels (typically 2048 or 4096)
|
|
* @param height Atlas height in pixels (typically 2048 or 4096)
|
|
*/
|
|
explicit TextureAtlas(int width = 2048, int height = 2048);
|
|
|
|
/**
|
|
* @brief Allocate a region in the atlas for a source texture
|
|
* @param source_id Identifier for the source (e.g., room_id)
|
|
* @param width Required width in pixels
|
|
* @param height Required height in pixels
|
|
* @return Pointer to allocated region, or nullptr if no space
|
|
*
|
|
* Uses simple rect packing algorithm. Future: implement more efficient packing.
|
|
*/
|
|
AtlasRegion* AllocateRegion(int source_id, int width, int height);
|
|
|
|
/**
|
|
* @brief Pack a bitmap into an allocated region
|
|
* @param src Source bitmap to pack
|
|
* @param region Region to pack into (must be pre-allocated)
|
|
* @return Status of packing operation
|
|
*
|
|
* Copies pixel data from source bitmap into atlas at region coordinates.
|
|
*/
|
|
absl::Status PackBitmap(const Bitmap& src, const AtlasRegion& region);
|
|
|
|
/**
|
|
* @brief Draw a region from the atlas to screen coordinates
|
|
* @param source_id Source identifier (e.g., room_id)
|
|
* @param dest_x Destination X coordinate
|
|
* @param dest_y Destination Y coordinate
|
|
* @return Status of drawing operation
|
|
*
|
|
* Future: Integrate with renderer to draw atlas regions.
|
|
*/
|
|
absl::Status DrawRegion(int source_id, int dest_x, int dest_y);
|
|
|
|
/**
|
|
* @brief Free a region and mark it as available
|
|
* @param source_id Source identifier to free
|
|
*/
|
|
void FreeRegion(int source_id);
|
|
|
|
/**
|
|
* @brief Clear all regions and reset atlas
|
|
*/
|
|
void Clear();
|
|
|
|
/**
|
|
* @brief Get the atlas bitmap (contains all packed textures)
|
|
* @return Reference to atlas bitmap
|
|
*/
|
|
Bitmap& GetAtlasBitmap() { return atlas_bitmap_; }
|
|
const Bitmap& GetAtlasBitmap() const { return atlas_bitmap_; }
|
|
|
|
/**
|
|
* @brief Get region for a specific source
|
|
* @param source_id Source identifier
|
|
* @return Pointer to region, or nullptr if not found
|
|
*/
|
|
const AtlasRegion* GetRegion(int source_id) const;
|
|
|
|
/**
|
|
* @brief Get atlas dimensions
|
|
*/
|
|
int width() const { return width_; }
|
|
int height() const { return height_; }
|
|
|
|
/**
|
|
* @brief Get atlas utilization statistics
|
|
*/
|
|
struct AtlasStats {
|
|
int total_regions = 0;
|
|
int used_regions = 0;
|
|
int total_pixels = 0;
|
|
int used_pixels = 0;
|
|
float utilization = 0.0f; // Percentage of atlas in use
|
|
};
|
|
AtlasStats GetStats() const;
|
|
|
|
private:
|
|
int width_;
|
|
int height_;
|
|
Bitmap atlas_bitmap_; // Large combined bitmap
|
|
|
|
// Simple linear packing for now (future: more efficient algorithms)
|
|
int next_x_ = 0;
|
|
int next_y_ = 0;
|
|
int row_height_ = 0; // Current row height for packing
|
|
|
|
// Map source_id → region
|
|
std::map<int, AtlasRegion> regions_;
|
|
|
|
// Simple rect packing helper
|
|
bool TryPackRect(int width, int height, int& out_x, int& out_y);
|
|
};
|
|
|
|
} // namespace gfx
|
|
} // namespace yaze
|
|
|
|
#endif // YAZE_APP_GFX_TEXTURE_ATLAS_H
|
|
|