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检测到的代码问题
This commit is contained in:
@@ -8,7 +8,8 @@ use crate::core::error::Result;
|
||||
use crate::resource::TextureManager;
|
||||
use super::batch::SpriteBatch;
|
||||
use super::camera::Camera2D;
|
||||
use super::shader::{ShaderProgram, SPRITE_VERTEX_SHADER, SPRITE_FRAGMENT_SHADER};
|
||||
use super::shader::ShaderManager;
|
||||
use super::material::MaterialManager;
|
||||
|
||||
/// 2D renderer with batched sprite rendering.
|
||||
/// 带批处理精灵渲染的2D渲染器。
|
||||
@@ -20,9 +21,13 @@ pub struct Renderer2D {
|
||||
/// 精灵批处理渲染器。
|
||||
sprite_batch: SpriteBatch,
|
||||
|
||||
/// Sprite shader program.
|
||||
/// 精灵Shader程序。
|
||||
shader: ShaderProgram,
|
||||
/// Shader manager.
|
||||
/// 着色器管理器。
|
||||
shader_manager: ShaderManager,
|
||||
|
||||
/// Material manager.
|
||||
/// 材质管理器。
|
||||
material_manager: MaterialManager,
|
||||
|
||||
/// 2D camera.
|
||||
/// 2D相机。
|
||||
@@ -31,6 +36,16 @@ pub struct Renderer2D {
|
||||
/// Clear color (RGBA).
|
||||
/// 清除颜色 (RGBA)。
|
||||
clear_color: [f32; 4],
|
||||
|
||||
/// Current active shader ID.
|
||||
/// 当前激活的着色器ID。
|
||||
#[allow(dead_code)]
|
||||
current_shader_id: u32,
|
||||
|
||||
/// Current active material ID.
|
||||
/// 当前激活的材质ID。
|
||||
#[allow(dead_code)]
|
||||
current_material_id: u32,
|
||||
}
|
||||
|
||||
impl Renderer2D {
|
||||
@@ -42,7 +57,8 @@ impl Renderer2D {
|
||||
/// * `max_sprites` - Maximum sprites per batch | 每批次最大精灵数
|
||||
pub fn new(gl: &WebGl2RenderingContext, max_sprites: usize) -> Result<Self> {
|
||||
let sprite_batch = SpriteBatch::new(gl, max_sprites)?;
|
||||
let shader = ShaderProgram::new(gl, SPRITE_VERTEX_SHADER, SPRITE_FRAGMENT_SHADER)?;
|
||||
let shader_manager = ShaderManager::new(gl)?;
|
||||
let material_manager = MaterialManager::new();
|
||||
|
||||
// Get canvas size for camera | 获取canvas尺寸用于相机
|
||||
let canvas = gl.canvas()
|
||||
@@ -59,9 +75,12 @@ impl Renderer2D {
|
||||
|
||||
Ok(Self {
|
||||
sprite_batch,
|
||||
shader,
|
||||
shader_manager,
|
||||
material_manager,
|
||||
camera,
|
||||
clear_color: [0.1, 0.1, 0.12, 1.0],
|
||||
current_shader_id: 0,
|
||||
current_material_id: 0,
|
||||
})
|
||||
}
|
||||
|
||||
@@ -73,6 +92,7 @@ impl Renderer2D {
|
||||
/// * `texture_ids` - Texture ID for each sprite | 每个精灵的纹理ID
|
||||
/// * `uvs` - UV coordinates for each sprite | 每个精灵的UV坐标
|
||||
/// * `colors` - Packed color for each sprite | 每个精灵的打包颜色
|
||||
/// * `material_ids` - Material ID for each sprite (0 = default) | 每个精灵的材质ID(0 = 默认)
|
||||
/// * `texture_manager` - Texture manager | 纹理管理器
|
||||
pub fn submit_batch(
|
||||
&mut self,
|
||||
@@ -80,6 +100,7 @@ impl Renderer2D {
|
||||
texture_ids: &[u32],
|
||||
uvs: &[f32],
|
||||
colors: &[u32],
|
||||
material_ids: &[u32],
|
||||
texture_manager: &TextureManager,
|
||||
) -> Result<()> {
|
||||
self.sprite_batch.add_sprites(
|
||||
@@ -87,6 +108,7 @@ impl Renderer2D {
|
||||
texture_ids,
|
||||
uvs,
|
||||
colors,
|
||||
material_ids,
|
||||
texture_manager,
|
||||
)
|
||||
}
|
||||
@@ -94,34 +116,61 @@ impl Renderer2D {
|
||||
/// Render the current frame.
|
||||
/// 渲染当前帧。
|
||||
pub fn render(&mut self, gl: &WebGl2RenderingContext, texture_manager: &TextureManager) -> Result<()> {
|
||||
use super::batch::BatchKey;
|
||||
|
||||
if self.sprite_batch.sprite_count() == 0 {
|
||||
return Ok(());
|
||||
}
|
||||
|
||||
// Bind shader | 绑定Shader
|
||||
self.shader.bind(gl);
|
||||
|
||||
// Set projection matrix | 设置投影矩阵
|
||||
let projection = self.camera.projection_matrix();
|
||||
self.shader.set_uniform_mat3(gl, "u_projection", &projection.to_cols_array());
|
||||
|
||||
// Set texture sampler | 设置纹理采样器
|
||||
self.shader.set_uniform_i32(gl, "u_texture", 0);
|
||||
|
||||
// Render each texture batch | 渲染每个纹理批次
|
||||
// Only collect non-empty batches | 只收集非空批次
|
||||
let texture_ids: Vec<u32> = self.sprite_batch.texture_batches()
|
||||
// Collect non-empty batch keys | 收集非空批次键
|
||||
let batch_keys: Vec<BatchKey> = self.sprite_batch.batches()
|
||||
.iter()
|
||||
.filter(|(_, vertices)| !vertices.is_empty())
|
||||
.map(|(id, _)| *id)
|
||||
.map(|(key, _)| *key)
|
||||
.collect();
|
||||
|
||||
for texture_id in texture_ids {
|
||||
// Bind texture for this batch | 绑定此批次的纹理
|
||||
texture_manager.bind_texture(texture_id, 0);
|
||||
// Track current state to minimize state changes | 跟踪当前状态以最小化状态切换
|
||||
let mut current_material_id: u32 = u32::MAX;
|
||||
let mut current_texture_id: u32 = u32::MAX;
|
||||
|
||||
// Flush this texture's sprites | 刷新此纹理的精灵
|
||||
self.sprite_batch.flush_for_texture(gl, texture_id);
|
||||
// Get projection matrix once | 一次性获取投影矩阵
|
||||
let projection = self.camera.projection_matrix();
|
||||
|
||||
for batch_key in batch_keys {
|
||||
// Switch material if needed | 如需切换材质
|
||||
if batch_key.material_id != current_material_id {
|
||||
current_material_id = batch_key.material_id;
|
||||
|
||||
// Get material (fallback to default if not found) | 获取材质(未找到则回退到默认)
|
||||
let material = self.material_manager.get_material(batch_key.material_id)
|
||||
.unwrap_or_else(|| self.material_manager.get_default_material());
|
||||
|
||||
// Bind shader | 绑定Shader
|
||||
let shader = self.shader_manager.get_shader(material.shader_id)
|
||||
.unwrap_or_else(|| self.shader_manager.get_default_shader());
|
||||
shader.bind(gl);
|
||||
|
||||
// Apply blend mode | 应用混合模式
|
||||
MaterialManager::apply_blend_mode(gl, material.blend_mode);
|
||||
|
||||
// Set projection matrix | 设置投影矩阵
|
||||
shader.set_uniform_mat3(gl, "u_projection", &projection.to_cols_array());
|
||||
|
||||
// Set texture sampler | 设置纹理采样器
|
||||
shader.set_uniform_i32(gl, "u_texture", 0);
|
||||
|
||||
// Apply material uniforms | 应用材质uniform
|
||||
material.uniforms.apply_to_shader(gl, shader);
|
||||
}
|
||||
|
||||
// Switch texture if needed | 如需切换纹理
|
||||
if batch_key.texture_id != current_texture_id {
|
||||
current_texture_id = batch_key.texture_id;
|
||||
texture_manager.bind_texture(batch_key.texture_id, 0);
|
||||
}
|
||||
|
||||
// Flush this batch | 刷新此批次
|
||||
self.sprite_batch.flush_for_batch(gl, &batch_key);
|
||||
}
|
||||
|
||||
// Clear batch for next frame | 清空批处理以供下一帧使用
|
||||
@@ -161,4 +210,123 @@ impl Renderer2D {
|
||||
pub fn resize(&mut self, width: f32, height: f32) {
|
||||
self.camera.set_viewport(width, height);
|
||||
}
|
||||
|
||||
// ============= Shader Management =============
|
||||
// ============= 着色器管理 =============
|
||||
|
||||
/// Compile and register a custom shader.
|
||||
/// 编译并注册自定义着色器。
|
||||
///
|
||||
/// # Returns | 返回
|
||||
/// The shader ID for referencing this shader | 用于引用此着色器的ID
|
||||
pub fn compile_shader(
|
||||
&mut self,
|
||||
gl: &WebGl2RenderingContext,
|
||||
vertex_source: &str,
|
||||
fragment_source: &str,
|
||||
) -> Result<u32> {
|
||||
self.shader_manager.compile_shader(gl, vertex_source, fragment_source)
|
||||
}
|
||||
|
||||
/// Compile a shader with a specific ID.
|
||||
/// 使用特定ID编译着色器。
|
||||
pub fn compile_shader_with_id(
|
||||
&mut self,
|
||||
gl: &WebGl2RenderingContext,
|
||||
shader_id: u32,
|
||||
vertex_source: &str,
|
||||
fragment_source: &str,
|
||||
) -> Result<()> {
|
||||
self.shader_manager.compile_shader_with_id(gl, shader_id, vertex_source, fragment_source)
|
||||
}
|
||||
|
||||
/// Check if a shader exists.
|
||||
/// 检查着色器是否存在。
|
||||
pub fn has_shader(&self, shader_id: u32) -> bool {
|
||||
self.shader_manager.has_shader(shader_id)
|
||||
}
|
||||
|
||||
/// Remove a shader.
|
||||
/// 移除着色器。
|
||||
pub fn remove_shader(&mut self, shader_id: u32) -> bool {
|
||||
self.shader_manager.remove_shader(shader_id)
|
||||
}
|
||||
|
||||
/// Get shader manager reference.
|
||||
/// 获取着色器管理器引用。
|
||||
pub fn shader_manager(&self) -> &ShaderManager {
|
||||
&self.shader_manager
|
||||
}
|
||||
|
||||
/// Get mutable shader manager reference.
|
||||
/// 获取可变着色器管理器引用。
|
||||
pub fn shader_manager_mut(&mut self) -> &mut ShaderManager {
|
||||
&mut self.shader_manager
|
||||
}
|
||||
|
||||
// ============= Material Management =============
|
||||
// ============= 材质管理 =============
|
||||
|
||||
/// Register a custom material.
|
||||
/// 注册自定义材质。
|
||||
///
|
||||
/// # Returns | 返回
|
||||
/// The material ID for referencing this material | 用于引用此材质的ID
|
||||
pub fn register_material(&mut self, material: super::material::Material) -> u32 {
|
||||
self.material_manager.register_material(material)
|
||||
}
|
||||
|
||||
/// Register a material with a specific ID.
|
||||
/// 使用特定ID注册材质。
|
||||
pub fn register_material_with_id(&mut self, material_id: u32, material: super::material::Material) {
|
||||
self.material_manager.register_material_with_id(material_id, material);
|
||||
}
|
||||
|
||||
/// Get a material by ID.
|
||||
/// 按ID获取材质。
|
||||
pub fn get_material(&self, material_id: u32) -> Option<&super::material::Material> {
|
||||
self.material_manager.get_material(material_id)
|
||||
}
|
||||
|
||||
/// Get a mutable material by ID.
|
||||
/// 按ID获取可变材质。
|
||||
pub fn get_material_mut(&mut self, material_id: u32) -> Option<&mut super::material::Material> {
|
||||
self.material_manager.get_material_mut(material_id)
|
||||
}
|
||||
|
||||
/// Check if a material exists.
|
||||
/// 检查材质是否存在。
|
||||
pub fn has_material(&self, material_id: u32) -> bool {
|
||||
self.material_manager.has_material(material_id)
|
||||
}
|
||||
|
||||
/// Remove a material.
|
||||
/// 移除材质。
|
||||
pub fn remove_material(&mut self, material_id: u32) -> bool {
|
||||
self.material_manager.remove_material(material_id)
|
||||
}
|
||||
|
||||
/// Set a material's float uniform.
|
||||
/// 设置材质的浮点uniform。
|
||||
pub fn set_material_float(&mut self, material_id: u32, name: &str, value: f32) -> bool {
|
||||
self.material_manager.set_material_float(material_id, name, value)
|
||||
}
|
||||
|
||||
/// Set 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 {
|
||||
self.material_manager.set_material_vec4(material_id, name, x, y, z, w)
|
||||
}
|
||||
|
||||
/// Get material manager reference.
|
||||
/// 获取材质管理器引用。
|
||||
pub fn material_manager(&self) -> &MaterialManager {
|
||||
&self.material_manager
|
||||
}
|
||||
|
||||
/// Get mutable material manager reference.
|
||||
/// 获取可变材质管理器引用。
|
||||
pub fn material_manager_mut(&mut self) -> &mut MaterialManager {
|
||||
&mut self.material_manager
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user