Render Quality

This commit is contained in:
2026-03-02 22:43:09 +03:00
parent c399d285fb
commit e5b8e6735d
2 changed files with 58 additions and 5 deletions

View File

@@ -35,6 +35,7 @@ redraw_throttle_ms: u32 = 50,
frame_index: u64 = 0,
_zoom: f32 = 1,
_rendering_quality: f32 = 100.0,
_last_redraw_time_ms: i64 = 0, // Метка последней перерисовки чтобы ограничить частоту
_visible_rect: ?Rect_i = null,
_redraw_pending: bool = false,
@@ -59,9 +60,9 @@ pub fn deinit(self: *Canvas) void {
fn redraw(self: *Canvas) !void {
const full = self.getZoomedImageSize();
const vis: Rect_i = self._visible_rect orelse Rect_i{ .x = 0, .y = 0, .w = 0, .h = 0 };
const vis_full: Rect_i = self._visible_rect orelse Rect_i{ .x = 0, .y = 0, .w = 0, .h = 0 };
if (vis.w == 0 or vis.h == 0) {
if (vis_full.w == 0 or vis_full.h == 0) {
if (self.texture) |tex| {
dvui.Texture.destroyLater(tex);
self.texture = null;
@@ -69,11 +70,42 @@ fn redraw(self: *Canvas) !void {
return;
}
const canvas_size: Size_i = .{ .w = full.w, .h = full.h };
// Качество рендеринга задаётся в процентах площади (1100),
// при этом фактически уменьшаем ширину/высоту холста на корень из этой доли.
const quality_percent: f32 = self.getRenderingQuality();
const quality_area: f32 = quality_percent / 100.0;
const quality_side: f32 = std.math.sqrt(quality_area);
const scale: f32 = std.math.clamp(quality_side, 0.01, 1.0);
const canvas_size: Size_i = .{
.w = @max(@as(u32, 1), @as(u32, @intFromFloat(@as(f32, @floatFromInt(full.w)) * scale))),
.h = @max(@as(u32, 1), @as(u32, @intFromFloat(@as(f32, @floatFromInt(full.h)) * scale))),
};
var vis_scaled = Rect_i{
.x = @as(u32, @intFromFloat(@as(f32, @floatFromInt(vis_full.x)) * scale)),
.y = @as(u32, @intFromFloat(@as(f32, @floatFromInt(vis_full.y)) * scale)),
.w = @max(@as(u32, 1), @as(u32, @intFromFloat(@as(f32, @floatFromInt(vis_full.w)) * scale))),
.h = @max(@as(u32, 1), @as(u32, @intFromFloat(@as(f32, @floatFromInt(vis_full.h)) * scale))),
};
if (vis_scaled.x >= canvas_size.w or vis_scaled.y >= canvas_size.h) {
if (self.texture) |tex| {
dvui.Texture.destroyLater(tex);
self.texture = null;
}
return;
}
const max_vis_w: u32 = canvas_size.w - vis_scaled.x;
const max_vis_h: u32 = canvas_size.h - vis_scaled.y;
if (vis_scaled.w > max_vis_w) vis_scaled.w = max_vis_w;
if (vis_scaled.h > max_vis_h) vis_scaled.h = max_vis_h;
const new_texture = if (self.draw_document)
self.render_engine.render(self.document, canvas_size, vis) catch null
self.render_engine.render(self.document, canvas_size, vis_scaled) catch null
else
self.render_engine.example(canvas_size, vis) catch null;
self.render_engine.example(canvas_size, vis_scaled) catch null;
if (new_texture) |tex| {
if (self.texture) |old_tex| {
@@ -114,6 +146,15 @@ pub fn getZoom(self: Canvas) f32 {
return self._zoom;
}
pub fn setRenderingQuality(self: *Canvas, value: f32) void {
self._rendering_quality = std.math.clamp(value, 1.0, 100.0);
self.requestRedraw();
}
pub fn getRenderingQuality(self: Canvas) f32 {
return self._rendering_quality;
}
pub fn requestRedraw(self: *Canvas) void {
self._redraw_pending = true;
}