55 atlas.entries.emplace_back(atlas_id, uv_rect, bitmap.
texture(), bpp_format, bitmap.
width(), bitmap.
height());
74 ScopedTimer timer(
"atlas_add_bitmap_bpp_optimized");
80 if (current_bpp == target_bpp) {
107 for (
auto& atlas_entry : atlas->entries) {
108 if (atlas_entry.atlas_id == atlas_id) {
136 if (render_commands.empty()) {
143 std::unordered_map<int, std::vector<const RenderCommand*>> atlas_groups;
145 for (
const auto& cmd : render_commands) {
149 for (
size_t i = 0; i <
atlases_.size(); ++i) {
150 for (
const auto& entry :
atlases_[i]->entries) {
151 if (entry.atlas_id == cmd.atlas_id) {
152 atlas_groups[i].push_back(&cmd);
161 for (
const auto& [atlas_index, commands] : atlas_groups) {
162 if (commands.empty())
continue;
164 auto& atlas = *
atlases_[atlas_index];
170 for (
const auto* cmd : commands) {
177 SDL_Rect dest_rect = {
178 static_cast<int>(cmd->x),
179 static_cast<int>(cmd->y),
180 static_cast<int>(entry->
uv_rect.w * cmd->scale_x),
181 static_cast<int>(entry->
uv_rect.h * cmd->scale_y)
185 if (std::abs(cmd->rotation) > 0.001F) {
197 const std::unordered_map<
BppFormat, std::vector<int>>& bpp_groups) {
198 if (render_commands.empty()) {
202 ScopedTimer timer(
"atlas_batch_render_bpp_optimized");
205 for (
const auto& [bpp_format, command_indices] : bpp_groups) {
206 if (command_indices.empty())
continue;
209 std::unordered_map<int, std::vector<const RenderCommand*>> atlas_groups;
211 for (
int cmd_index : command_indices) {
212 if (cmd_index >= 0 && cmd_index <
static_cast<int>(render_commands.size())) {
213 const auto& cmd = render_commands[cmd_index];
215 if (it !=
atlas_lookup_.end() && it->second->in_use && it->second->bpp_format == bpp_format) {
217 for (
size_t i = 0; i <
atlases_.size(); ++i) {
218 for (
const auto& entry :
atlases_[i]->entries) {
219 if (entry.atlas_id == cmd.atlas_id) {
220 atlas_groups[i].push_back(&cmd);
230 for (
const auto& [atlas_index, commands] : atlas_groups) {
231 if (commands.empty())
continue;
233 auto& atlas = *
atlases_[atlas_index];
239 for (
const auto* cmd : commands) {
246 SDL_Rect dest_rect = {
247 static_cast<int>(cmd->x),
248 static_cast<int>(cmd->y),
249 static_cast<int>(entry->
uv_rect.w * cmd->scale_x),
250 static_cast<int>(entry->
uv_rect.h * cmd->scale_y)
254 if (std::abs(cmd->rotation) > 0.001F) {
269 for (
const auto& atlas :
atlases_) {
271 stats.
used_entries += std::count_if(atlas->entries.begin(), atlas->entries.end(),
272 [](
const AtlasEntry& entry) { return entry.in_use; });
290 atlas->entries.erase(
291 std::remove_if(atlas->entries.begin(), atlas->entries.end(),
292 [](
const AtlasEntry& entry) { return !entry.in_use; }),
293 atlas->entries.end());
303 if (atlas->texture) {
328 for (
const auto& atlas_entry : atlas->entries) {
329 if (atlas_entry.atlas_id == atlas_id) {
331 SDL_Rect dest_rect = {
334 static_cast<int>(entry->
uv_rect.w * scale_x),
335 static_cast<int>(entry->
uv_rect.h * scale_y)
353 return it->second->uv_rect;
357 int width = bitmap.
width();
358 int height = bitmap.
height();
362 if (free_rect.w == 0 || free_rect.h == 0) {
386 atlases_.push_back(std::make_unique<Atlas>(size));
393 if (!atlas.texture) {
394 SDL_Log(
"Failed to create atlas texture: %s", SDL_GetError());
407 for (
auto& entry : atlas.
entries) {
408 if (entry.in_use && entry.texture) {
419 for (
int y = 0; y <= atlas.
size - height; ++y) {
420 for (
int x = 0; x <= atlas.
size - width; ++x) {
424 for (
int dy = 0; dy < height && can_fit; ++dy) {
425 for (
int dx = 0; dx < width && can_fit; ++dx) {
426 int index = (y + dy) * atlas.
size + (x + dx);
434 return {x, y, width, height};
443 for (
int y = rect.y; y < rect.y + rect.h; ++y) {
444 for (
int x = rect.x; x < rect.x + rect.w; ++x) {
445 int index = y * atlas.
size + x;
446 if (index >= 0 && index <
static_cast<int>(atlas.
used_regions.size())) {
Atlas-based rendering system for efficient graphics operations.
SDL_Rect FindFreeRegion(Atlas &atlas, int width, int height)
AtlasStats GetStats() const
Get atlas statistics.
bool PackBitmap(Atlas &atlas, const Bitmap &bitmap, SDL_Rect &uv_rect)
void UpdateBitmap(int atlas_id, const Bitmap &bitmap)
Update a bitmap in the atlas.
std::vector< std::unique_ptr< Atlas > > atlases_
void RebuildAtlas(Atlas &atlas)
void Clear()
Clear all atlases.
int AddBitmapWithBppOptimization(const Bitmap &bitmap, BppFormat target_bpp)
Add a bitmap to the atlas with BPP format optimization.
void RenderBitmap(int atlas_id, float x, float y, float scale_x=1.0f, float scale_y=1.0f)
Render a single bitmap using atlas (convenience method)
void MarkRegionUsed(Atlas &atlas, const SDL_Rect &rect, bool used)
std::unordered_map< int, AtlasEntry * > atlas_lookup_
void RenderBatch(const std::vector< RenderCommand > &render_commands)
Render multiple bitmaps in a single draw call.
void RemoveBitmap(int atlas_id)
Remove a bitmap from the atlas.
void Defragment()
Defragment the atlas to reclaim space.
SDL_Rect GetUVCoordinates(int atlas_id) const
Get UV coordinates for a bitmap in the atlas.
int AddBitmap(const Bitmap &bitmap)
Add a bitmap to the atlas.
static AtlasRenderer & Get()
void Initialize(IRenderer *renderer, int initial_size=1024)
Initialize the atlas renderer.
void RenderBatchWithBppOptimization(const std::vector< RenderCommand > &render_commands, const std::unordered_map< BppFormat, std::vector< int > > &bpp_groups)
Render multiple bitmaps with BPP-aware batching.
Represents a bitmap image optimized for SNES ROM hacking.
const SnesPalette & palette() const
TextureHandle texture() const
const std::vector< uint8_t > & vector() const
void CreateTexture()
Creates the underlying SDL_Texture to be displayed.
Defines an abstract interface for all rendering operations.
virtual TextureHandle CreateTexture(int width, int height)=0
Creates a new, empty texture.
virtual void RenderCopy(TextureHandle texture, const SDL_Rect *srcrect, const SDL_Rect *dstrect)=0
Copies a portion of a texture to the current render target.
virtual void SetDrawColor(SDL_Color color)=0
Sets the color used for drawing operations (e.g., Clear).
virtual void Clear()=0
Clears the entire render target with the current draw color.
virtual void DestroyTexture(TextureHandle texture)=0
Destroys a texture and frees its associated resources.
virtual void SetRenderTarget(TextureHandle texture)=0
Sets the render target for subsequent drawing operations.
RAII timer for automatic timing management.
BppFormat
BPP format enumeration for SNES graphics.
Main namespace for the application.
std::vector< AtlasEntry > entries
std::vector< bool > used_regions
float utilization_percent