Дополнительный буфер для отрисовки broken line
This commit is contained in:
@@ -45,6 +45,8 @@ pub const DrawContext = struct {
|
||||
scale_x: f32,
|
||||
scale_y: f32,
|
||||
transform: Transform = .{},
|
||||
/// Если true, blendPixelAtBuffer перезаписывает пиксель без бленда
|
||||
replace_mode: bool = false,
|
||||
|
||||
pub fn setTransform(self: *DrawContext, t: Transform) void {
|
||||
self.transform = t;
|
||||
@@ -111,12 +113,16 @@ pub const DrawContext = struct {
|
||||
};
|
||||
}
|
||||
|
||||
/// Смешивает цвет в пикселе буфера с учётом opacity трансформа.
|
||||
/// Смешивает цвет в пикселе буфера с учётом opacity трансформа. В replace_mode просто перезаписывает пиксель.
|
||||
pub fn blendPixelAtBuffer(self: *DrawContext, bx: u32, by: u32, color: Color.PMA) void {
|
||||
if (bx >= self.buf_width or by >= self.buf_height) return;
|
||||
const t = &self.transform;
|
||||
const idx = by * self.buf_width + bx;
|
||||
const dst = &self.pixels[idx];
|
||||
if (self.replace_mode) {
|
||||
dst.* = color;
|
||||
return;
|
||||
}
|
||||
const t = &self.transform;
|
||||
const a = @as(f32, @floatFromInt(color.a)) / 255.0 * t.opacity;
|
||||
const src_r = @as(f32, @floatFromInt(color.r)) * t.opacity;
|
||||
const src_g = @as(f32, @floatFromInt(color.g)) * t.opacity;
|
||||
@@ -128,6 +134,26 @@ pub const DrawContext = struct {
|
||||
dst.a = @intFromFloat(std.math.clamp(a * 255 + inv_a * @as(f32, @floatFromInt(dst.a)), 0, 255));
|
||||
}
|
||||
|
||||
/// Накладывает буфер другого контекста на этот с заданной прозрачностью (один бленд на пиксель). Размеры буферов должны совпадать.
|
||||
pub fn compositeDrawerContext(self: *DrawContext, other: *const DrawContext, opacity: f32) void {
|
||||
if (self.buf_width != other.buf_width or self.buf_height != other.buf_height) return;
|
||||
const n = self.buf_width * self.buf_height;
|
||||
for (0..n) |i| {
|
||||
const src = other.pixels[i];
|
||||
if (src.a == 0) continue;
|
||||
const dst = &self.pixels[i];
|
||||
const a = @as(f32, @floatFromInt(src.a)) / 255.0 * opacity;
|
||||
const src_r = @as(f32, @floatFromInt(src.r)) * opacity;
|
||||
const src_g = @as(f32, @floatFromInt(src.g)) * opacity;
|
||||
const src_b = @as(f32, @floatFromInt(src.b)) * opacity;
|
||||
const inv_a = 1.0 - a;
|
||||
dst.r = @intFromFloat(std.math.clamp(src_r + inv_a * @as(f32, @floatFromInt(dst.r)), 0, 255));
|
||||
dst.g = @intFromFloat(std.math.clamp(src_g + inv_a * @as(f32, @floatFromInt(dst.g)), 0, 255));
|
||||
dst.b = @intFromFloat(std.math.clamp(src_b + inv_a * @as(f32, @floatFromInt(dst.b)), 0, 255));
|
||||
dst.a = @intFromFloat(std.math.clamp(a * 255 + inv_a * @as(f32, @floatFromInt(dst.a)), 0, 255));
|
||||
}
|
||||
}
|
||||
|
||||
/// Пиксель в локальных координатах (трансформ + PMA).
|
||||
pub fn blendPixelLocal(self: *DrawContext, local_x: f32, local_y: f32, color: Color.PMA) void {
|
||||
const w = self.localToWorld(local_x, local_y);
|
||||
|
||||
Reference in New Issue
Block a user