Переход к RenderEngine
This commit is contained in:
7
.vscode/settings.json
vendored
Normal file
7
.vscode/settings.json
vendored
Normal file
@@ -0,0 +1,7 @@
|
|||||||
|
{
|
||||||
|
"zig.testArgs": [
|
||||||
|
"build",
|
||||||
|
"test",
|
||||||
|
"-Dtest-filter=${filter}"
|
||||||
|
]
|
||||||
|
}
|
||||||
11
build.zig
11
build.zig
@@ -34,7 +34,16 @@ pub fn build(b: *std.Build) void {
|
|||||||
}
|
}
|
||||||
|
|
||||||
const exe_tests = b.addTest(.{
|
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);
|
const run_exe_tests = b.addRunArtifact(exe_tests);
|
||||||
|
|||||||
@@ -1,18 +1,14 @@
|
|||||||
const std = @import("std");
|
const std = @import("std");
|
||||||
const builtin = @import("builtin");
|
const builtin = @import("builtin");
|
||||||
const dvui = @import("dvui");
|
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 Size = dvui.Size;
|
||||||
const Color = dvui.Color;
|
const Color = dvui.Color;
|
||||||
|
|
||||||
const Canvas = @This();
|
const Canvas = @This();
|
||||||
|
|
||||||
pub const ImageRect = struct {
|
|
||||||
x: u32,
|
|
||||||
y: u32,
|
|
||||||
w: u32,
|
|
||||||
h: u32,
|
|
||||||
};
|
|
||||||
|
|
||||||
allocator: std.mem.Allocator,
|
allocator: std.mem.Allocator,
|
||||||
texture: ?dvui.Texture = null,
|
texture: ?dvui.Texture = null,
|
||||||
size: Size = .{ .w = 800, .h = 600 },
|
size: Size = .{ .w = 800, .h = 600 },
|
||||||
@@ -24,11 +20,16 @@ scroll: dvui.ScrollInfo = .{
|
|||||||
native_scaling: bool = false,
|
native_scaling: bool = false,
|
||||||
gradient_start: Color.PMA = .{ .r = 0, .g = 0, .b = 0, .a = 255 },
|
gradient_start: Color.PMA = .{ .r = 0, .g = 0, .b = 0, .a = 255 },
|
||||||
gradient_end: Color.PMA = .{ .r = 255, .g = 255, .b = 255, .a = 255 },
|
gradient_end: Color.PMA = .{ .r = 255, .g = 255, .b = 255, .a = 255 },
|
||||||
|
document: ?*Document = null,
|
||||||
|
render_engine: RenderEngine,
|
||||||
_visible_rect: ?ImageRect = null,
|
_visible_rect: ?ImageRect = null,
|
||||||
_zoom: f32 = 1,
|
_zoom: f32 = 1,
|
||||||
|
|
||||||
pub fn init(allocator: std.mem.Allocator) Canvas {
|
pub fn init(allocator: std.mem.Allocator, engine: RenderEngine) Canvas {
|
||||||
return .{ .allocator = allocator };
|
return .{
|
||||||
|
.allocator = allocator,
|
||||||
|
.render_engine = engine,
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn deinit(self: *Canvas) void {
|
pub fn deinit(self: *Canvas) void {
|
||||||
@@ -39,7 +40,7 @@ pub fn deinit(self: *Canvas) void {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Заполнить canvas градиентом
|
/// Заполнить canvas градиентом
|
||||||
pub fn redrawGradient(self: *Canvas) !void {
|
pub fn redrawExample(self: *Canvas) !void {
|
||||||
const full = self.getScaledImageSize();
|
const full = self.getScaledImageSize();
|
||||||
const full_w: u32 = full.w;
|
const full_w: u32 = full.w;
|
||||||
const full_h: u32 = full.h;
|
const full_h: u32 = full.h;
|
||||||
@@ -57,10 +58,14 @@ pub fn redrawGradient(self: *Canvas) !void {
|
|||||||
const width: u32 = vis.w;
|
const width: u32 = vis.w;
|
||||||
const height: u32 = vis.h;
|
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);
|
const pixels = try self.allocator.alloc(Color.PMA, @as(usize, width) * height);
|
||||||
defer self.allocator.free(pixels);
|
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;
|
var y: u32 = 0;
|
||||||
while (y < height) : (y += 1) {
|
while (y < height) : (y += 1) {
|
||||||
var x: u32 = 0;
|
var x: u32 = 0;
|
||||||
@@ -95,14 +100,15 @@ pub fn redrawGradient(self: *Canvas) !void {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Заполнить canvas случайным градиентом
|
/// Заполнить canvas случайным градиентом
|
||||||
pub fn fillRandomGradient(self: *Canvas) !void {
|
pub fn exampleReset(self: *Canvas) !void {
|
||||||
// Сгенерировать случайные цвета градиента
|
// Сгенерировать случайные цвета градиента
|
||||||
var prng = std.Random.DefaultPrng.init(@intCast(std.time.microTimestamp()));
|
var prng = std.Random.DefaultPrng.init(@intCast(std.time.microTimestamp()));
|
||||||
const random = prng.random();
|
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_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 };
|
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 {
|
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;
|
self._visible_rect = next;
|
||||||
if (changed or self.texture == null) {
|
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;
|
if (value >= max_f) return max_inclusive;
|
||||||
return @intFromFloat(value);
|
return @intFromFloat(value);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Отобразить canvas в UI
|
|
||||||
pub fn render(self: Canvas, rect: dvui.RectScale) !void {
|
|
||||||
if (self.texture) |texture| {
|
|
||||||
try dvui.renderTexture(texture, rect, .{});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|||||||
@@ -1,19 +1,27 @@
|
|||||||
const std = @import("std");
|
const std = @import("std");
|
||||||
const dvui = @import("dvui");
|
|
||||||
const Canvas = @import("Canvas.zig");
|
const Canvas = @import("Canvas.zig");
|
||||||
|
const CpuRenderEngine = @import("render/CpuRenderEngine.zig");
|
||||||
|
|
||||||
const WindowContext = @This();
|
const WindowContext = @This();
|
||||||
|
|
||||||
allocator: std.mem.Allocator,
|
allocator: std.mem.Allocator,
|
||||||
canvas: Canvas,
|
canvas: Canvas,
|
||||||
|
cpu_render: *CpuRenderEngine,
|
||||||
|
|
||||||
pub fn init(allocator: std.mem.Allocator) WindowContext {
|
pub fn init(allocator: std.mem.Allocator) !WindowContext {
|
||||||
return .{
|
var self: WindowContext = undefined;
|
||||||
.allocator = allocator,
|
self.allocator = allocator;
|
||||||
.canvas = Canvas.init(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 {
|
pub fn deinit(self: *WindowContext) void {
|
||||||
self.canvas.deinit();
|
self.canvas.deinit();
|
||||||
|
self.allocator.destroy(self.cpu_render);
|
||||||
}
|
}
|
||||||
|
|||||||
10
src/main.zig
10
src/main.zig
@@ -1,9 +1,9 @@
|
|||||||
const std = @import("std");
|
const std = @import("std");
|
||||||
const builtin = @import("builtin");
|
const builtin = @import("builtin");
|
||||||
const dvui = @import("dvui");
|
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 SDLBackend = @import("sdl-backend");
|
||||||
const Document = @import("Document.zig");
|
const Document = @import("models/Document.zig");
|
||||||
const WindowContext = @import("WindowContext.zig");
|
const WindowContext = @import("WindowContext.zig");
|
||||||
const sdl_c = SDLBackend.c;
|
const sdl_c = SDLBackend.c;
|
||||||
const Allocator = std.mem.Allocator;
|
const Allocator = std.mem.Allocator;
|
||||||
@@ -29,7 +29,7 @@ pub fn main() !void {
|
|||||||
});
|
});
|
||||||
defer win.deinit();
|
defer win.deinit();
|
||||||
|
|
||||||
var ctx = WindowContext.init(allocator);
|
var ctx = try WindowContext.init(allocator);
|
||||||
defer ctx.deinit();
|
defer ctx.deinit();
|
||||||
|
|
||||||
var interrupted = false;
|
var interrupted = false;
|
||||||
@@ -90,7 +90,7 @@ fn gui_frame(ctx: *WindowContext) bool {
|
|||||||
{
|
{
|
||||||
dvui.label(@src(), "Tools", .{}, .{});
|
dvui.label(@src(), "Tools", .{}, .{});
|
||||||
if (dvui.button(@src(), "Fill Random Color", .{}, .{})) {
|
if (dvui.button(@src(), "Fill Random Color", .{}, .{})) {
|
||||||
canvas.fillRandomGradient() catch |err| {
|
canvas.exampleReset() catch |err| {
|
||||||
std.debug.print("Error filling canvas: {}\n", .{err});
|
std.debug.print("Error filling canvas: {}\n", .{err});
|
||||||
};
|
};
|
||||||
canvas.pos = .{ .x = 400, .y = 400 };
|
canvas.pos = .{ .x = 400, .y = 400 };
|
||||||
@@ -198,7 +198,7 @@ fn gui_frame(ctx: *WindowContext) bool {
|
|||||||
switch (action) {
|
switch (action) {
|
||||||
.wheel_y => |y| {
|
.wheel_y => |y| {
|
||||||
canvas.addZoom(y / 1000);
|
canvas.addZoom(y / 1000);
|
||||||
canvas.redrawGradient() catch {};
|
canvas.redrawExample() catch {};
|
||||||
},
|
},
|
||||||
else => {},
|
else => {},
|
||||||
}
|
}
|
||||||
|
|||||||
11
src/models/rasterization_models.zig
Normal file
11
src/models/rasterization_models.zig
Normal 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,
|
||||||
|
};
|
||||||
46
src/render/CpuRenderEngine.zig
Normal file
46
src/render/CpuRenderEngine.zig
Normal 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 };
|
||||||
|
}
|
||||||
@@ -1 +0,0 @@
|
|||||||
// Интерфейс для рендеринга документа
|
|
||||||
20
src/render/RenderEngine.zig
Normal file
20
src/render/RenderEngine.zig
Normal 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
6
src/tests.zig
Normal 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");
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user