feat(renderer): 添加遮罩支持,优化绘制流程和背景渐变

This commit is contained in:
2026-07-09 00:11:48 +08:00
parent 547085c819
commit 514fca6000
3 changed files with 470 additions and 32 deletions

View File

@@ -11,6 +11,8 @@ use std::path::Path;
/// 一个 drawable 的渲染所需数据快照
#[derive(Clone)]
pub struct DrawableSnapshot {
/// 在 Core drawable 数组中的原始索引(用于查 mask 引用)
pub index: usize,
pub texture_index: i32,
pub draw_order: i32,
pub render_order: i32,
@@ -23,6 +25,8 @@ pub struct DrawableSnapshot {
pub indices: Vec<u16>,
pub multiply_color: [f32; 4],
pub screen_color: [f32; 4],
/// 本 drawable 依赖的 mask drawable 索引(空表示无遮罩)
pub mask_indices: Vec<i32>,
pub mask_counts: i32,
}
@@ -148,8 +152,8 @@ impl CubismModel {
};
println!(
"[Live2D] 模型加载成功: 参数={} drawable={} canvas={:?}x{:.0}ppu",
param_count, drawable_count, canvas.size, canvas.pixels_per_unit
"[Live2D] 模型加载成功: 参数={} drawable={} canvas={:?} origin=({:.1},{:.1})x{:.0}ppu",
param_count, drawable_count, canvas.size, canvas.origin[0], canvas.origin[1], canvas.pixels_per_unit
);
Ok(Self {
@@ -254,6 +258,7 @@ impl CubismModel {
let indices = (core.csm_get_drawable_indices)(self.model);
let multiply_colors = (core.csm_get_drawable_multiply_colors)(self.model);
let screen_colors = (core.csm_get_drawable_screen_colors)(self.model);
let masks = (core.csm_get_drawable_masks)(self.model);
// 先收集每个 drawable 的原始索引
let mut items: Vec<(usize, i32)> = (0..count)
@@ -287,7 +292,18 @@ impl CubismModel {
let mc = *multiply_colors.add(i);
let sc = *screen_colors.add(i);
// 取出本 drawable 的 mask 索引列表
let mk = *mask_counts.add(i) as usize;
let mut mask_indices: Vec<i32> = Vec::with_capacity(mk);
if mk > 0 {
let mptr = *masks.add(i);
for k in 0..mk {
mask_indices.push(*mptr.add(k));
}
}
DrawableSnapshot {
index: i,
texture_index: *texture_indices.add(i),
draw_order: *draw_orders.add(i),
render_order: ro,
@@ -300,7 +316,8 @@ impl CubismModel {
indices: idx_vec,
multiply_color: [mc.x, mc.y, mc.z, mc.w],
screen_color: [sc.x, sc.y, sc.z, sc.w],
mask_counts: *mask_counts.add(i),
mask_indices,
mask_counts: mk as i32,
}
})
.collect()