Переход к RenderEngine

This commit is contained in:
2025-12-21 17:26:19 +03:00
parent 6f58967049
commit 3ac35a5046
11 changed files with 138 additions and 33 deletions

7
.vscode/settings.json vendored Normal file
View File

@@ -0,0 +1,7 @@
{
"zig.testArgs": [
"build",
"test",
"-Dtest-filter=${filter}"
]
}

View File

@@ -34,7 +34,16 @@ pub fn build(b: *std.Build) void {
}
const exe_tests = b.addTest(.{
.root_module = exe.root_module,
.root_module = b.createModule(.{
.root_source_file = b.path("src/tests.zig"),
.target = target,
.optimize = optimize,
.imports = &.{
.{ .name = "dvui", .module = dvui_dep.module("dvui_sdl3") },
.{ .name = "sdl-backend", .module = dvui_dep.module("sdl3") },
},
}),
});
const run_exe_tests = b.addRunArtifact(exe_tests);

View File

@@ -1,18 +1,14 @@
const std = @import("std");
const builtin = @import("builtin");
const dvui = @import("dvui");
const Document = @import("models/Document.zig");
const RenderEngine = @import("render/RenderEngine.zig").RenderEngine;
const ImageRect = @import("models/rasterization_models.zig").ImageRect;
const Size = dvui.Size;
const Color = dvui.Color;
const Canvas = @This();
pub const ImageRect = struct {
x: u32,
y: u32,
w: u32,
h: u32,
};
allocator: std.mem.Allocator,
texture: ?dvui.Texture = null,
size: Size = .{ .w = 800, .h = 600 },
@@ -24,11 +20,16 @@ scroll: dvui.ScrollInfo = .{
native_scaling: bool = false,
gradient_start: Color.PMA = .{ .r = 0, .g = 0, .b = 0, .a = 255 },
gradient_end: Color.PMA = .{ .r = 255, .g = 255, .b = 255, .a = 255 },
document: ?*Document = null,
render_engine: RenderEngine,
_visible_rect: ?ImageRect = null,
_zoom: f32 = 1,
pub fn init(allocator: std.mem.Allocator) Canvas {
return .{ .allocator = allocator };
pub fn init(allocator: std.mem.Allocator, engine: RenderEngine) Canvas {
return .{
.allocator = allocator,
.render_engine = engine,
};
}
pub fn deinit(self: *Canvas) void {
@@ -39,7 +40,7 @@ pub fn deinit(self: *Canvas) void {
}
/// Заполнить canvas градиентом
pub fn redrawGradient(self: *Canvas) !void {
pub fn redrawExample(self: *Canvas) !void {
const full = self.getScaledImageSize();
const full_w: u32 = full.w;
const full_h: u32 = full.h;
@@ -57,10 +58,14 @@ pub fn redrawGradient(self: *Canvas) !void {
const width: u32 = vis.w;
const height: u32 = vis.h;
// const new_texture = self.render_engine.example(width, height);
// Выделить буфер пиксельных данных
const pixels = try self.allocator.alloc(Color.PMA, @as(usize, width) * height);
defer self.allocator.free(pixels);
std.debug.print("w={any}, fw={any};\th={any}, fh={any}\n", .{ width, full_w, height, full_h });
var y: u32 = 0;
while (y < height) : (y += 1) {
var x: u32 = 0;
@@ -95,14 +100,15 @@ pub fn redrawGradient(self: *Canvas) !void {
}
/// Заполнить canvas случайным градиентом
pub fn fillRandomGradient(self: *Canvas) !void {
pub fn exampleReset(self: *Canvas) !void {
// Сгенерировать случайные цвета градиента
var prng = std.Random.DefaultPrng.init(@intCast(std.time.microTimestamp()));
const random = prng.random();
self.gradient_start = Color.PMA{ .r = random.int(u8), .g = random.int(u8), .b = random.int(u8), .a = 255 };
self.gradient_end = Color.PMA{ .r = random.int(u8), .g = random.int(u8), .b = random.int(u8), .a = 255 };
try self.redrawGradient();
self.render_engine.exampleReset();
try self.redrawExample();
}
pub fn setZoom(self: *Canvas, value: f32) void {
@@ -136,7 +142,7 @@ pub fn updateVisibleImageRect(self: *Canvas, viewport: dvui.Rect, scroll_offset:
}
self._visible_rect = next;
if (changed or self.texture == null) {
try self.redrawGradient();
try self.redrawExample();
}
}
@@ -194,10 +200,3 @@ fn floatToClampedU32(value: f32, max_inclusive: u32) u32 {
if (value >= max_f) return max_inclusive;
return @intFromFloat(value);
}
/// Отобразить canvas в UI
pub fn render(self: Canvas, rect: dvui.RectScale) !void {
if (self.texture) |texture| {
try dvui.renderTexture(texture, rect, .{});
}
}

View File

@@ -1,19 +1,27 @@
const std = @import("std");
const dvui = @import("dvui");
const Canvas = @import("Canvas.zig");
const CpuRenderEngine = @import("render/CpuRenderEngine.zig");
const WindowContext = @This();
allocator: std.mem.Allocator,
canvas: Canvas,
cpu_render: *CpuRenderEngine,
pub fn init(allocator: std.mem.Allocator) WindowContext {
return .{
.allocator = allocator,
.canvas = Canvas.init(allocator),
};
pub fn init(allocator: std.mem.Allocator) !WindowContext {
var self: WindowContext = undefined;
self.allocator = allocator;
self.cpu_render = try allocator.create(CpuRenderEngine);
errdefer allocator.destroy(self.cpu_render);
self.cpu_render.* = CpuRenderEngine.init(allocator, .Gradient);
self.canvas = Canvas.init(allocator, self.cpu_render.renderEngine());
return self;
}
pub fn deinit(self: *WindowContext) void {
self.canvas.deinit();
self.allocator.destroy(self.cpu_render);
}

View File

@@ -1,9 +1,9 @@
const std = @import("std");
const builtin = @import("builtin");
const dvui = @import("dvui");
const dvui_ext = @import("./ui/dvui_ext.zig");
const dvui_ext = @import("ui/dvui_ext.zig");
const SDLBackend = @import("sdl-backend");
const Document = @import("Document.zig");
const Document = @import("models/Document.zig");
const WindowContext = @import("WindowContext.zig");
const sdl_c = SDLBackend.c;
const Allocator = std.mem.Allocator;
@@ -29,7 +29,7 @@ pub fn main() !void {
});
defer win.deinit();
var ctx = WindowContext.init(allocator);
var ctx = try WindowContext.init(allocator);
defer ctx.deinit();
var interrupted = false;
@@ -90,7 +90,7 @@ fn gui_frame(ctx: *WindowContext) bool {
{
dvui.label(@src(), "Tools", .{}, .{});
if (dvui.button(@src(), "Fill Random Color", .{}, .{})) {
canvas.fillRandomGradient() catch |err| {
canvas.exampleReset() catch |err| {
std.debug.print("Error filling canvas: {}\n", .{err});
};
canvas.pos = .{ .x = 400, .y = 400 };
@@ -198,7 +198,7 @@ fn gui_frame(ctx: *WindowContext) bool {
switch (action) {
.wheel_y => |y| {
canvas.addZoom(y / 1000);
canvas.redrawGradient() catch {};
canvas.redrawExample() catch {};
},
else => {},
}

View File

@@ -0,0 +1,11 @@
pub const ImageRect = struct {
x: u32,
y: u32,
w: u32,
h: u32,
};
pub const ImageSize = struct {
w: u32,
h: u32,
};

View File

@@ -0,0 +1,46 @@
const std = @import("std");
const builtin = @import("builtin");
const dvui = @import("dvui");
const RenderEngine = @import("RenderEngine.zig").RenderEngine;
const rast_models = @import("../models/rasterization_models.zig");
const ImageSize = rast_models.ImageSize;
const ImageRect = rast_models.ImageRect;
const Allocator = std.mem.Allocator;
const Color = dvui.Color;
const CpuRenderEngine = @This();
const Type = enum {
Gradient,
Squares,
};
type: Type,
_allocator: Allocator,
gradient_start: Color.PMA = .{ .r = 0, .g = 0, .b = 0, .a = 255 },
gradient_end: Color.PMA = .{ .r = 255, .g = 255, .b = 255, .a = 255 },
pub fn init(allocator: Allocator, render_type: Type) CpuRenderEngine {
return .{
._allocator = allocator,
.type = render_type,
};
}
pub fn exampleReset(self: *CpuRenderEngine) void {
// Сгенерировать случайные цвета градиента
var prng = std.Random.DefaultPrng.init(@intCast(std.time.microTimestamp()));
const random = prng.random();
self.gradient_start = Color.PMA{ .r = random.int(u8), .g = random.int(u8), .b = random.int(u8), .a = 255 };
self.gradient_end = Color.PMA{ .r = random.int(u8), .g = random.int(u8), .b = random.int(u8), .a = 255 };
}
pub fn example(self: CpuRenderEngine, canvas_size: ImageSize, visible_rect: ImageRect) !?dvui.Texture {
_ = self;
_ = canvas_size;
_ = visible_rect;
return null;
}
pub fn renderEngine(self: *CpuRenderEngine) RenderEngine {
return .{ .cpu = self };
}

View File

@@ -1 +0,0 @@
// Интерфейс для рендеринга документа

View File

@@ -0,0 +1,20 @@
// Интерфейс для рендеринга документа
const dvui = @import("dvui");
const CpuRenderEngine = @import("CpuRenderEngine.zig");
const rast_models = @import("../models/rasterization_models.zig");
pub const RenderEngine = union(enum) {
cpu: *CpuRenderEngine,
pub fn exampleReset(self: RenderEngine) void {
switch (self) {
.cpu => |cpu_r| cpu_r.exampleReset(),
}
}
pub fn example(self: RenderEngine, canvas_size: rast_models.ImageSize, visible_rect: rast_models.ImageRect) !?dvui.Texture {
return switch (self) {
.cpu => |cpu_r| cpu_r.example(canvas_size, visible_rect),
};
}
};

6
src/tests.zig Normal file
View File

@@ -0,0 +1,6 @@
// Test root for `zig build test`.
// Import modules here to ensure their `test` blocks are discovered.
test "module test discovery" {
_ = @import("render/CpuRenderEngine.zig");
}