Files
esengine/packages/engine/src/renderer/material/manager.rs
YHH 63f006ab62 feat: 添加跨平台运行时、资产系统和UI适配功能 (#256)
* feat(platform-common): 添加WASM加载器和环境检测API

* feat(rapier2d): 新增Rapier2D WASM绑定包

* feat(physics-rapier2d): 添加跨平台WASM加载器

* feat(asset-system): 添加运行时资产目录和bundle格式

* feat(asset-system-editor): 新增编辑器资产管理包

* feat(editor-core): 添加构建系统和模块管理

* feat(editor-app): 重构浏览器预览使用import maps

* feat(platform-web): 添加BrowserRuntime和资产读取

* feat(engine): 添加材质系统和着色器管理

* feat(material): 新增材质系统和着色器编辑器

* feat(tilemap): 增强tilemap编辑器和动画系统

* feat(modules): 添加module.json配置

* feat(core): 添加module.json和类型定义更新

* chore: 更新依赖和构建配置

* refactor(plugins): 更新插件模板使用ModuleManifest

* chore: 添加第三方依赖库

* chore: 移除BehaviourTree-ai和ecs-astar子模块

* docs: 更新README和文档主题样式

* fix: 修复Rust文档测试和添加rapier2d WASM绑定

* fix(tilemap-editor): 修复画布高DPI屏幕分辨率适配问题

* feat(ui): 添加UI屏幕适配系统(CanvasScaler/SafeArea)

* fix(ecs-engine-bindgen): 添加缺失的ecs-framework-math依赖

* fix: 添加缺失的包依赖修复CI构建

* fix: 修复CodeQL检测到的代码问题

* fix: 修复构建错误和缺失依赖

* fix: 修复类型检查错误

* fix(material-system): 修复tsconfig配置支持TypeScript项目引用

* fix(editor-core): 修复Rollup构建配置添加tauri external

* fix: 修复CodeQL检测到的代码问题

* fix: 修复CodeQL检测到的代码问题
2025-12-03 22:15:22 +08:00

208 lines
7.0 KiB
Rust
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
//! Material manager for storing and retrieving materials.
//! 材质管理器,用于存储和检索材质。
use std::collections::HashMap;
use web_sys::WebGl2RenderingContext;
use super::material::{Material, BlendMode};
/// Reserved material IDs for built-in materials.
/// 内置材质的保留ID。
pub const MATERIAL_ID_DEFAULT: u32 = 0;
pub const MATERIAL_ID_ADDITIVE: u32 = 1;
pub const MATERIAL_ID_MULTIPLY: u32 = 2;
pub const MATERIAL_ID_UNLIT: u32 = 3;
/// Material manager for creating and caching materials.
/// 材质管理器,用于创建和缓存材质。
pub struct MaterialManager {
/// Stored materials indexed by ID.
/// 按ID索引的存储材质。
materials: HashMap<u32, Material>,
/// Next available material ID for custom materials.
/// 下一个可用的自定义材质ID。
next_material_id: u32,
}
impl MaterialManager {
/// Create a new material manager with built-in materials.
/// 创建带有内置材质的新材质管理器。
pub fn new() -> Self {
let mut manager = Self {
materials: HashMap::new(),
next_material_id: 100, // Reserve 0-99 for built-in materials
};
// Register built-in materials | 注册内置材质
manager.materials.insert(MATERIAL_ID_DEFAULT, Material::sprite());
manager.materials.insert(MATERIAL_ID_ADDITIVE, Material::additive());
manager.materials.insert(MATERIAL_ID_MULTIPLY, Material::multiply());
manager.materials.insert(MATERIAL_ID_UNLIT, Material::unlit());
log::info!("MaterialManager initialized with {} built-in materials | 材质管理器初始化完成,内置材质数量: {}",
manager.materials.len(), manager.materials.len());
manager
}
/// Register a custom material.
/// 注册自定义材质。
///
/// # Returns | 返回
/// The material ID for referencing this material | 用于引用此材质的ID
pub fn register_material(&mut self, material: Material) -> u32 {
let material_id = self.next_material_id;
self.next_material_id += 1;
log::debug!("Registered material '{}' with ID: {} | 注册材质 '{}' ID: {}",
material.name, material_id, material.name, material_id);
self.materials.insert(material_id, material);
material_id
}
/// Register a material with a specific ID.
/// 使用特定ID注册材质。
pub fn register_material_with_id(&mut self, material_id: u32, material: Material) {
log::debug!("Registered material '{}' with ID: {} | 注册材质 '{}' ID: {}",
material.name, material_id, material.name, material_id);
self.materials.insert(material_id, material);
// Update next_material_id if necessary
if material_id >= self.next_material_id {
self.next_material_id = material_id + 1;
}
}
/// Get a material by ID.
/// 按ID获取材质。
#[inline]
pub fn get_material(&self, material_id: u32) -> Option<&Material> {
self.materials.get(&material_id)
}
/// Get a mutable material by ID.
/// 按ID获取可变材质。
#[inline]
pub fn get_material_mut(&mut self, material_id: u32) -> Option<&mut Material> {
self.materials.get_mut(&material_id)
}
/// Get the default material.
/// 获取默认材质。
#[inline]
pub fn get_default_material(&self) -> &Material {
self.materials.get(&MATERIAL_ID_DEFAULT)
.expect("Default material should always exist | 默认材质应该始终存在")
}
/// Check if a material exists.
/// 检查材质是否存在。
#[inline]
pub fn has_material(&self, material_id: u32) -> bool {
self.materials.contains_key(&material_id)
}
/// Remove a material.
/// 移除材质。
///
/// Note: Cannot remove built-in materials (ID < 100).
/// 注意无法移除内置材质ID < 100
pub fn remove_material(&mut self, material_id: u32) -> bool {
if material_id < 100 {
log::warn!("Cannot remove built-in material: {} | 无法移除内置材质: {}", material_id, material_id);
return false;
}
self.materials.remove(&material_id).is_some()
}
/// Update a material's uniform value.
/// 更新材质的uniform值。
pub fn set_material_float(&mut self, material_id: u32, name: &str, value: f32) -> bool {
if let Some(material) = self.materials.get_mut(&material_id) {
material.uniforms.set_float(name, value);
true
} else {
false
}
}
/// Update a material's vec4 uniform.
/// 更新材质的vec4 uniform。
pub fn set_material_vec4(&mut self, material_id: u32, name: &str, x: f32, y: f32, z: f32, w: f32) -> bool {
if let Some(material) = self.materials.get_mut(&material_id) {
material.uniforms.set_vec4(name, x, y, z, w);
true
} else {
false
}
}
/// Apply blend mode to WebGL context.
/// 将混合模式应用到WebGL上下文。
pub fn apply_blend_mode(gl: &WebGl2RenderingContext, blend_mode: BlendMode) {
match blend_mode {
BlendMode::None => {
gl.disable(WebGl2RenderingContext::BLEND);
}
BlendMode::Alpha => {
gl.enable(WebGl2RenderingContext::BLEND);
gl.blend_func(
WebGl2RenderingContext::SRC_ALPHA,
WebGl2RenderingContext::ONE_MINUS_SRC_ALPHA,
);
}
BlendMode::Additive => {
gl.enable(WebGl2RenderingContext::BLEND);
gl.blend_func(
WebGl2RenderingContext::SRC_ALPHA,
WebGl2RenderingContext::ONE,
);
}
BlendMode::Multiply => {
gl.enable(WebGl2RenderingContext::BLEND);
gl.blend_func(
WebGl2RenderingContext::DST_COLOR,
WebGl2RenderingContext::ZERO,
);
}
BlendMode::Screen => {
gl.enable(WebGl2RenderingContext::BLEND);
gl.blend_func(
WebGl2RenderingContext::ONE,
WebGl2RenderingContext::ONE_MINUS_SRC_COLOR,
);
}
BlendMode::PremultipliedAlpha => {
gl.enable(WebGl2RenderingContext::BLEND);
gl.blend_func(
WebGl2RenderingContext::ONE,
WebGl2RenderingContext::ONE_MINUS_SRC_ALPHA,
);
}
}
}
/// Get all material IDs.
/// 获取所有材质ID。
pub fn material_ids(&self) -> Vec<u32> {
self.materials.keys().copied().collect()
}
/// Get material count.
/// 获取材质数量。
#[inline]
pub fn material_count(&self) -> usize {
self.materials.len()
}
}
impl Default for MaterialManager {
fn default() -> Self {
Self::new()
}
}