Переход на CpuRenderEngine
This commit is contained in:
@@ -42,8 +42,6 @@ pub fn deinit(self: *Canvas) void {
|
|||||||
/// Заполнить canvas градиентом
|
/// Заполнить canvas градиентом
|
||||||
pub fn redrawExample(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_h: u32 = full.h;
|
|
||||||
|
|
||||||
const vis: ImageRect = self._visible_rect orelse ImageRect{ .x = 0, .y = 0, .w = 0, .h = 0 };
|
const vis: ImageRect = self._visible_rect orelse ImageRect{ .x = 0, .y = 0, .w = 0, .h = 0 };
|
||||||
|
|
||||||
@@ -55,58 +53,20 @@ pub fn redrawExample(self: *Canvas) !void {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
const width: u32 = vis.w;
|
const new_texture = self.render_engine.example(.{ .w = full.w, .h = full.h }, vis) catch null;
|
||||||
const height: u32 = vis.h;
|
|
||||||
|
|
||||||
// const new_texture = self.render_engine.example(width, height);
|
if (new_texture) |tex| {
|
||||||
|
// Удалить старую текстуру
|
||||||
// Выделить буфер пиксельных данных
|
if (self.texture) |old_tex| {
|
||||||
const pixels = try self.allocator.alloc(Color.PMA, @as(usize, width) * height);
|
dvui.Texture.destroyLater(old_tex);
|
||||||
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;
|
|
||||||
while (x < width) : (x += 1) {
|
|
||||||
const gx: u32 = vis.x + x;
|
|
||||||
const gy: u32 = vis.y + y;
|
|
||||||
|
|
||||||
const denom_x: f32 = if (full_w > 1) @as(f32, @floatFromInt(full_w - 1)) else 1;
|
|
||||||
const denom_y: f32 = if (full_h > 1) @as(f32, @floatFromInt(full_h - 1)) else 1;
|
|
||||||
const fx: f32 = @as(f32, @floatFromInt(gx)) / denom_x;
|
|
||||||
const fy: f32 = @as(f32, @floatFromInt(gy)) / denom_y;
|
|
||||||
const factor: f32 = std.math.clamp((fx + fy) / 2, 0, 1);
|
|
||||||
|
|
||||||
const r_f: f32 = @as(f32, @floatFromInt(self.gradient_start.r)) + factor * (@as(f32, @floatFromInt(self.gradient_end.r)) - @as(f32, @floatFromInt(self.gradient_start.r)));
|
|
||||||
const g_f: f32 = @as(f32, @floatFromInt(self.gradient_start.g)) + factor * (@as(f32, @floatFromInt(self.gradient_end.g)) - @as(f32, @floatFromInt(self.gradient_start.g)));
|
|
||||||
const b_f: f32 = @as(f32, @floatFromInt(self.gradient_start.b)) + factor * (@as(f32, @floatFromInt(self.gradient_end.b)) - @as(f32, @floatFromInt(self.gradient_start.b)));
|
|
||||||
|
|
||||||
const r: u8 = @intFromFloat(std.math.clamp(r_f, 0, 255));
|
|
||||||
const g: u8 = @intFromFloat(std.math.clamp(g_f, 0, 255));
|
|
||||||
const b: u8 = @intFromFloat(std.math.clamp(b_f, 0, 255));
|
|
||||||
pixels[y * width + x] = .{ .r = r, .g = g, .b = b, .a = 255 };
|
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
// Удалить старую текстуру
|
self.texture = tex;
|
||||||
if (self.texture) |tex| {
|
|
||||||
dvui.Texture.destroyLater(tex);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Создать новую текстуру из пиксельных данных
|
|
||||||
self.texture = try dvui.textureCreate(pixels, width, height, .nearest);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Заполнить canvas случайным градиентом
|
// Ресетнуть example изображение в renderEngine
|
||||||
pub fn exampleReset(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 };
|
|
||||||
|
|
||||||
self.render_engine.exampleReset();
|
self.render_engine.exampleReset();
|
||||||
try self.redrawExample();
|
try self.redrawExample();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -7,6 +7,7 @@ const WindowContext = @This();
|
|||||||
allocator: std.mem.Allocator,
|
allocator: std.mem.Allocator,
|
||||||
canvas: Canvas,
|
canvas: Canvas,
|
||||||
cpu_render: *CpuRenderEngine,
|
cpu_render: *CpuRenderEngine,
|
||||||
|
frame_index: u64,
|
||||||
|
|
||||||
pub fn init(allocator: std.mem.Allocator) !WindowContext {
|
pub fn init(allocator: std.mem.Allocator) !WindowContext {
|
||||||
var self: WindowContext = undefined;
|
var self: WindowContext = undefined;
|
||||||
@@ -18,6 +19,8 @@ pub fn init(allocator: std.mem.Allocator) !WindowContext {
|
|||||||
|
|
||||||
self.canvas = Canvas.init(allocator, self.cpu_render.renderEngine());
|
self.canvas = Canvas.init(allocator, self.cpu_render.renderEngine());
|
||||||
|
|
||||||
|
self.frame_index = 0;
|
||||||
|
|
||||||
return self;
|
return self;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -33,7 +33,6 @@ pub fn main() !void {
|
|||||||
defer ctx.deinit();
|
defer ctx.deinit();
|
||||||
|
|
||||||
var interrupted = false;
|
var interrupted = false;
|
||||||
|
|
||||||
main_loop: while (true) {
|
main_loop: while (true) {
|
||||||
// beginWait coordinates with waitTime below to run frames only when needed
|
// beginWait coordinates with waitTime below to run frames only when needed
|
||||||
const nstime = win.beginWait(interrupted);
|
const nstime = win.beginWait(interrupted);
|
||||||
@@ -89,12 +88,12 @@ fn gui_frame(ctx: *WindowContext) bool {
|
|||||||
var left_panel = dvui.box(@src(), .{ .dir = .vertical }, .{ .expand = .vertical, .min_size_content = .{ .w = 200 }, .background = true });
|
var left_panel = dvui.box(@src(), .{ .dir = .vertical }, .{ .expand = .vertical, .min_size_content = .{ .w = 200 }, .background = true });
|
||||||
{
|
{
|
||||||
dvui.label(@src(), "Tools", .{}, .{});
|
dvui.label(@src(), "Tools", .{}, .{});
|
||||||
if (dvui.button(@src(), "Fill Random Color", .{}, .{})) {
|
if (dvui.button(@src(), "Fill Random Color", .{}, .{}) or ctx.frame_index == 0) {
|
||||||
canvas.exampleReset() 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 };
|
ctx.canvas.pos = .{ .x = 400, .y = 400 };
|
||||||
canvas.setZoom(dvui.windowNaturalScale());
|
ctx.canvas.setZoom(dvui.windowNaturalScale());
|
||||||
}
|
}
|
||||||
if (dvui.checkbox(@src(), &canvas.native_scaling, "Scaling", .{})) {}
|
if (dvui.checkbox(@src(), &canvas.native_scaling, "Scaling", .{})) {}
|
||||||
}
|
}
|
||||||
@@ -222,5 +221,7 @@ fn gui_frame(ctx: *WindowContext) bool {
|
|||||||
}
|
}
|
||||||
back.deinit();
|
back.deinit();
|
||||||
|
|
||||||
|
ctx.frame_index += 1;
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -35,10 +35,43 @@ pub fn exampleReset(self: *CpuRenderEngine) void {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub fn example(self: CpuRenderEngine, canvas_size: ImageSize, visible_rect: ImageRect) !?dvui.Texture {
|
pub fn example(self: CpuRenderEngine, canvas_size: ImageSize, visible_rect: ImageRect) !?dvui.Texture {
|
||||||
_ = self;
|
const full_w = canvas_size.w;
|
||||||
_ = canvas_size;
|
const full_h = canvas_size.h;
|
||||||
_ = visible_rect;
|
|
||||||
return null;
|
const width = visible_rect.w;
|
||||||
|
const height = visible_rect.h;
|
||||||
|
|
||||||
|
// Выделить буфер пиксельных данных
|
||||||
|
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;
|
||||||
|
while (x < width) : (x += 1) {
|
||||||
|
const gx: u32 = visible_rect.x + x;
|
||||||
|
const gy: u32 = visible_rect.y + y;
|
||||||
|
|
||||||
|
const denom_x: f32 = if (full_w > 1) @as(f32, @floatFromInt(full_w - 1)) else 1;
|
||||||
|
const denom_y: f32 = if (full_h > 1) @as(f32, @floatFromInt(full_h - 1)) else 1;
|
||||||
|
const fx: f32 = @as(f32, @floatFromInt(gx)) / denom_x;
|
||||||
|
const fy: f32 = @as(f32, @floatFromInt(gy)) / denom_y;
|
||||||
|
const factor: f32 = std.math.clamp((fx + fy) / 2, 0, 1);
|
||||||
|
|
||||||
|
const r_f: f32 = @as(f32, @floatFromInt(self.gradient_start.r)) + factor * (@as(f32, @floatFromInt(self.gradient_end.r)) - @as(f32, @floatFromInt(self.gradient_start.r)));
|
||||||
|
const g_f: f32 = @as(f32, @floatFromInt(self.gradient_start.g)) + factor * (@as(f32, @floatFromInt(self.gradient_end.g)) - @as(f32, @floatFromInt(self.gradient_start.g)));
|
||||||
|
const b_f: f32 = @as(f32, @floatFromInt(self.gradient_start.b)) + factor * (@as(f32, @floatFromInt(self.gradient_end.b)) - @as(f32, @floatFromInt(self.gradient_start.b)));
|
||||||
|
|
||||||
|
const r: u8 = @intFromFloat(std.math.clamp(r_f, 0, 255));
|
||||||
|
const g: u8 = @intFromFloat(std.math.clamp(g_f, 0, 255));
|
||||||
|
const b: u8 = @intFromFloat(std.math.clamp(b_f, 0, 255));
|
||||||
|
pixels[y * width + x] = .{ .r = r, .g = g, .b = b, .a = 255 };
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return try dvui.textureCreate(pixels, width, height, .nearest);
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn renderEngine(self: *CpuRenderEngine) RenderEngine {
|
pub fn renderEngine(self: *CpuRenderEngine) RenderEngine {
|
||||||
|
|||||||
Reference in New Issue
Block a user