yaze 0.3.2
Link to the Past ROM Editor
 
Loading...
Searching...
No Matches
canvas_rendering.cc
Go to the documentation of this file.
1#include "canvas_rendering.h"
2
3#include <algorithm>
4#include <cmath>
5
7
8namespace yaze {
9namespace gui {
10
11namespace {
12// Constants extracted from canvas.cc
13constexpr uint32_t kRectangleColor = IM_COL32(32, 32, 32, 255);
14constexpr uint32_t kWhiteColor = IM_COL32(255, 255, 255, 255);
15} // namespace
16
17void RenderCanvasBackground(ImDrawList* draw_list,
18 const CanvasGeometry& geometry) {
19 // Draw border and background color (extracted from Canvas::DrawBackground)
20 draw_list->AddRectFilled(geometry.canvas_p0, geometry.canvas_p1,
22 draw_list->AddRect(geometry.canvas_p0, geometry.canvas_p1, kWhiteColor);
23}
24
25void RenderCanvasGrid(ImDrawList* draw_list, const CanvasGeometry& geometry,
26 const CanvasConfig& config, int highlight_tile_id) {
27 if (!config.enable_grid) {
28 return;
29 }
30
31 // Create render context for utility functions (extracted from
32 // Canvas::DrawGrid)
34 .draw_list = draw_list,
35 .canvas_p0 = geometry.canvas_p0,
36 .canvas_p1 = geometry.canvas_p1,
37 .scrolling = geometry.scrolling,
38 .global_scale = config.global_scale,
39 .enable_grid = config.enable_grid,
40 .enable_hex_labels = config.enable_hex_labels,
41 .grid_step = config.grid_step};
42
43 // Use high-level utility function
44 CanvasUtils::DrawCanvasGrid(ctx, highlight_tile_id);
45}
46
47void RenderCanvasOverlay(ImDrawList* draw_list, const CanvasGeometry& geometry,
48 const CanvasConfig& config,
49 const ImVector<ImVec2>& points,
50 const ImVector<ImVec2>& selected_points) {
51 // Create render context for utility functions (extracted from
52 // Canvas::DrawOverlay)
54 .draw_list = draw_list,
55 .canvas_p0 = geometry.canvas_p0,
56 .canvas_p1 = geometry.canvas_p1,
57 .scrolling = geometry.scrolling,
58 .global_scale = config.global_scale,
59 .enable_grid = config.enable_grid,
60 .enable_hex_labels = config.enable_hex_labels,
61 .grid_step = config.grid_step};
62
63 // Use high-level utility function
64 CanvasUtils::DrawCanvasOverlay(ctx, points, selected_points);
65}
66
67void RenderCanvasLabels(ImDrawList* draw_list, const CanvasGeometry& geometry,
68 const CanvasConfig& config,
69 const ImVector<ImVector<std::string>>& labels,
70 int current_labels, int tile_id_offset) {
71 if (!config.enable_custom_labels || current_labels >= labels.size()) {
72 return;
73 }
74
75 // Push clip rect to prevent drawing outside canvas
76 draw_list->PushClipRect(geometry.canvas_p0, geometry.canvas_p1, true);
77
78 // Create render context for utility functions
80 .draw_list = draw_list,
81 .canvas_p0 = geometry.canvas_p0,
82 .canvas_p1 = geometry.canvas_p1,
83 .scrolling = geometry.scrolling,
84 .global_scale = config.global_scale,
85 .enable_grid = config.enable_grid,
86 .enable_hex_labels = config.enable_hex_labels,
87 .grid_step = config.grid_step};
88
89 // Use high-level utility function (extracted from Canvas::DrawInfoGrid)
90 CanvasUtils::DrawCanvasLabels(ctx, labels, current_labels, tile_id_offset);
91
92 draw_list->PopClipRect();
93}
94
95void RenderBitmapOnCanvas(ImDrawList* draw_list, const CanvasGeometry& geometry,
96 gfx::Bitmap& bitmap, int /*border_offset*/,
97 float scale) {
98 if (!bitmap.is_active() || !bitmap.texture()) {
99 return;
100 }
101
102 // Extracted from Canvas::DrawBitmap (border offset variant)
103 draw_list->AddImage((ImTextureID)(intptr_t)bitmap.texture(),
104 ImVec2(geometry.canvas_p0.x, geometry.canvas_p0.y),
105 ImVec2(geometry.canvas_p0.x + (bitmap.width() * scale),
106 geometry.canvas_p0.y + (bitmap.height() * scale)));
107 // NOTE: Canvas border is drawn once by RenderCanvasBackground().
108 // Do NOT draw border here - this function is called per-bitmap, which would
109 // cause N stacked border rectangles (e.g., 64 in overworld editor).
110}
111
112void RenderBitmapOnCanvas(ImDrawList* draw_list, const CanvasGeometry& geometry,
113 gfx::Bitmap& bitmap, int x_offset, int y_offset,
114 float scale, int alpha) {
115 if (!bitmap.is_active() || !bitmap.texture()) {
116 return;
117 }
118
119 // Calculate the actual rendered size including scale and offsets
120 // CRITICAL: Use scale parameter (NOT global_scale_) for per-bitmap scaling
121 // Extracted from Canvas::DrawBitmap (x/y offset variant)
122 ImVec2 rendered_size(bitmap.width() * scale, bitmap.height() * scale);
123
124 // CRITICAL FIX: Draw bitmap WITHOUT additional global_scale multiplication
125 // The scale parameter already contains the correct scale factor
126 // The scrolling should NOT be scaled - it's already in screen space
127 draw_list->AddImage(
128 (ImTextureID)(intptr_t)bitmap.texture(),
129 ImVec2(geometry.canvas_p0.x + x_offset + geometry.scrolling.x,
130 geometry.canvas_p0.y + y_offset + geometry.scrolling.y),
131 ImVec2(geometry.canvas_p0.x + x_offset + geometry.scrolling.x +
132 rendered_size.x,
133 geometry.canvas_p0.y + y_offset + geometry.scrolling.y +
134 rendered_size.y),
135 ImVec2(0, 0), ImVec2(1, 1), IM_COL32(255, 255, 255, alpha));
136}
137
138void RenderBitmapOnCanvas(ImDrawList* draw_list, const CanvasGeometry& geometry,
139 gfx::Bitmap& bitmap, ImVec2 dest_pos,
140 ImVec2 dest_size, ImVec2 src_pos, ImVec2 src_size) {
141 if (!bitmap.is_active() || !bitmap.texture()) {
142 return;
143 }
144
145 // Extracted from Canvas::DrawBitmap (custom source/dest regions variant)
146 draw_list->AddImage(
147 (ImTextureID)(intptr_t)bitmap.texture(),
148 ImVec2(geometry.canvas_p0.x + dest_pos.x,
149 geometry.canvas_p0.y + dest_pos.y),
150 ImVec2(geometry.canvas_p0.x + dest_pos.x + dest_size.x,
151 geometry.canvas_p0.y + dest_pos.y + dest_size.y),
152 ImVec2(src_pos.x / bitmap.width(), src_pos.y / bitmap.height()),
153 ImVec2((src_pos.x + src_size.x) / bitmap.width(),
154 (src_pos.y + src_size.y) / bitmap.height()));
155}
156
157void RenderBitmapGroup(ImDrawList* draw_list, const CanvasGeometry& geometry,
158 std::vector<int>& group, gfx::Tilemap& tilemap,
159 int tile_size, float scale, int local_map_size,
160 ImVec2 total_map_size) {
161 // Extracted from Canvas::DrawBitmapGroup (lines 1148-1264)
162 // This is used for multi-tile selection preview in overworld editor
163
164 if (group.empty()) {
165 return;
166 }
167
168 // OPTIMIZATION: Use optimized rendering for large groups to improve
169 // performance
170 bool use_optimized_rendering = group.size() > 128;
171
172 // Pre-calculate common values to avoid repeated computation
173 const float tile_scale = tile_size * scale;
174 const int atlas_tiles_per_row = tilemap.atlas.width() / tilemap.tile_size.x;
175
176 // Get selected points (note: this assumes selected_points are available in
177 // context) For now, we'll just render tiles at their grid positions The full
178 // implementation would need the selected_points passed in
179
180 int i = 0;
181 for (const auto tile_id : group) {
182 // Calculate grid position for this tile
183 int tiles_per_row = 32; // Default for standard maps
184 int x = i % tiles_per_row;
185 int y = i / tiles_per_row;
186
187 int tile_pos_x = x * tile_size * scale;
188 int tile_pos_y = y * tile_size * scale;
189
190 // Check if tile_id is within the range
191 auto tilemap_size = tilemap.map_size.x;
192 if (tile_id >= 0 && tile_id < tilemap_size) {
193 if (tilemap.atlas.is_active() && tilemap.atlas.texture() &&
194 atlas_tiles_per_row > 0) {
195 int atlas_tile_x =
196 (tile_id % atlas_tiles_per_row) * tilemap.tile_size.x;
197 int atlas_tile_y =
198 (tile_id / atlas_tiles_per_row) * tilemap.tile_size.y;
199
200 // Simple bounds check
201 if (atlas_tile_x >= 0 && atlas_tile_x < tilemap.atlas.width() &&
202 atlas_tile_y >= 0 && atlas_tile_y < tilemap.atlas.height()) {
203 // Calculate UV coordinates once for efficiency
204 const float atlas_width = static_cast<float>(tilemap.atlas.width());
205 const float atlas_height = static_cast<float>(tilemap.atlas.height());
206 ImVec2 uv0 =
207 ImVec2(atlas_tile_x / atlas_width, atlas_tile_y / atlas_height);
208 ImVec2 uv1 =
209 ImVec2((atlas_tile_x + tilemap.tile_size.x) / atlas_width,
210 (atlas_tile_y + tilemap.tile_size.y) / atlas_height);
211
212 // Calculate screen positions
213 float screen_x =
214 geometry.canvas_p0.x + geometry.scrolling.x + tile_pos_x;
215 float screen_y =
216 geometry.canvas_p0.y + geometry.scrolling.y + tile_pos_y;
217 float screen_w = tilemap.tile_size.x * scale;
218 float screen_h = tilemap.tile_size.y * scale;
219
220 // Use higher alpha for large selections to make them more visible
221 uint32_t alpha_color = use_optimized_rendering
222 ? IM_COL32(255, 255, 255, 200)
223 : IM_COL32(255, 255, 255, 150);
224
225 // Draw from atlas texture with optimized parameters
226 draw_list->AddImage((ImTextureID)(intptr_t)tilemap.atlas.texture(),
227 ImVec2(screen_x, screen_y),
228 ImVec2(screen_x + screen_w, screen_y + screen_h),
229 uv0, uv1, alpha_color);
230 }
231 }
232 }
233 i++;
234 }
235}
236
237} // namespace gui
238} // namespace yaze
Represents a bitmap image optimized for SNES ROM hacking.
Definition bitmap.h:67
TextureHandle texture() const
Definition bitmap.h:380
bool is_active() const
Definition bitmap.h:384
int height() const
Definition bitmap.h:374
int width() const
Definition bitmap.h:373
void DrawCanvasLabels(const CanvasRenderContext &ctx, const ImVector< ImVector< std::string > > &labels, int current_labels, int tile_id_offset)
void DrawCanvasOverlay(const CanvasRenderContext &ctx, const ImVector< ImVec2 > &points, const ImVector< ImVec2 > &selected_points)
void DrawCanvasGrid(const CanvasRenderContext &ctx, int highlight_tile_id)
constexpr uint32_t kWhiteColor
Definition canvas.cc:145
constexpr uint32_t kRectangleColor
Definition canvas.cc:144
void RenderBitmapGroup(ImDrawList *draw_list, const CanvasGeometry &geometry, std::vector< int > &group, gfx::Tilemap &tilemap, int tile_size, float scale, int local_map_size, ImVec2 total_map_size)
Render group of bitmaps from tilemap.
void RenderCanvasLabels(ImDrawList *draw_list, const CanvasGeometry &geometry, const CanvasConfig &config, const ImVector< ImVector< std::string > > &labels, int current_labels, int tile_id_offset)
Render canvas labels on grid.
void RenderCanvasBackground(ImDrawList *draw_list, const CanvasGeometry &geometry)
Render canvas background and border.
void RenderCanvasGrid(ImDrawList *draw_list, const CanvasGeometry &geometry, const CanvasConfig &config, int highlight_tile_id)
Render canvas grid with optional highlighting.
void RenderBitmapOnCanvas(ImDrawList *draw_list, const CanvasGeometry &geometry, gfx::Bitmap &bitmap, int, float scale)
Render bitmap on canvas (border offset variant)
void RenderCanvasOverlay(ImDrawList *draw_list, const CanvasGeometry &geometry, const CanvasConfig &config, const ImVector< ImVec2 > &points, const ImVector< ImVec2 > &selected_points)
Render canvas overlay (hover and selection points)
int y
Y coordinate or height.
Definition tilemap.h:21
int x
X coordinate or width.
Definition tilemap.h:20
Tilemap structure for SNES tile-based graphics management.
Definition tilemap.h:118
Pair tile_size
Size of individual tiles (8x8 or 16x16)
Definition tilemap.h:123
Pair map_size
Size of tilemap in tiles.
Definition tilemap.h:124
Bitmap atlas
Master bitmap containing all tiles.
Definition tilemap.h:119
Unified configuration for canvas display and interaction.
Canvas geometry calculated per-frame.