Render Quality
This commit is contained in:
@@ -35,6 +35,7 @@ redraw_throttle_ms: u32 = 50,
|
|||||||
frame_index: u64 = 0,
|
frame_index: u64 = 0,
|
||||||
|
|
||||||
_zoom: f32 = 1,
|
_zoom: f32 = 1,
|
||||||
|
_rendering_quality: f32 = 100.0,
|
||||||
_last_redraw_time_ms: i64 = 0, // Метка последней перерисовки чтобы ограничить частоту
|
_last_redraw_time_ms: i64 = 0, // Метка последней перерисовки чтобы ограничить частоту
|
||||||
_visible_rect: ?Rect_i = null,
|
_visible_rect: ?Rect_i = null,
|
||||||
_redraw_pending: bool = false,
|
_redraw_pending: bool = false,
|
||||||
@@ -59,9 +60,9 @@ pub fn deinit(self: *Canvas) void {
|
|||||||
fn redraw(self: *Canvas) !void {
|
fn redraw(self: *Canvas) !void {
|
||||||
const full = self.getZoomedImageSize();
|
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| {
|
if (self.texture) |tex| {
|
||||||
dvui.Texture.destroyLater(tex);
|
dvui.Texture.destroyLater(tex);
|
||||||
self.texture = null;
|
self.texture = null;
|
||||||
@@ -69,11 +70,42 @@ fn redraw(self: *Canvas) !void {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
const canvas_size: Size_i = .{ .w = full.w, .h = full.h };
|
// Качество рендеринга задаётся в процентах площади (1–100),
|
||||||
|
// при этом фактически уменьшаем ширину/высоту холста на корень из этой доли.
|
||||||
|
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)
|
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
|
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 (new_texture) |tex| {
|
||||||
if (self.texture) |old_tex| {
|
if (self.texture) |old_tex| {
|
||||||
@@ -114,6 +146,15 @@ pub fn getZoom(self: Canvas) f32 {
|
|||||||
return self._zoom;
|
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 {
|
pub fn requestRedraw(self: *Canvas) void {
|
||||||
self._redraw_pending = true;
|
self._redraw_pending = true;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -176,6 +176,18 @@ pub fn leftPanel(ctx: *WindowContext) void {
|
|||||||
canvas.requestRedraw();
|
canvas.requestRedraw();
|
||||||
}
|
}
|
||||||
if (dvui.checkbox(@src(), &canvas.show_render_stats, "Show stats", .{})) {}
|
if (dvui.checkbox(@src(), &canvas.show_render_stats, "Show stats", .{})) {}
|
||||||
|
{
|
||||||
|
dvui.label(@src(), "Rendering quality", .{}, .{});
|
||||||
|
var quality = canvas.getRenderingQuality();
|
||||||
|
if (dvui.sliderEntry(
|
||||||
|
@src(),
|
||||||
|
"{d:0.0}%",
|
||||||
|
.{ .value = &quality, .min = 1.0, .max = 100.0, .interval = 1.0 },
|
||||||
|
.{ .expand = .horizontal },
|
||||||
|
)) {
|
||||||
|
canvas.setRenderingQuality(quality);
|
||||||
|
}
|
||||||
|
}
|
||||||
if (!canvas.draw_document) {
|
if (!canvas.draw_document) {
|
||||||
if (dvui.button(@src(), if (doc.cpu_render.type == .Gradient) "Gradient" else "Squares", .{}, .{})) {
|
if (dvui.button(@src(), if (doc.cpu_render.type == .Gradient) "Gradient" else "Squares", .{}, .{})) {
|
||||||
if (doc.cpu_render.type == .Gradient) {
|
if (doc.cpu_render.type == .Gradient) {
|
||||||
|
|||||||
Reference in New Issue
Block a user