资产浏览器可视化改造 + 材质缩略图 GPU 烘焙 + 纹理上传批式化
- 资产浏览器可视化与配色:面板重构(网格/列表/缩略图)、AssetKind 分类、 EditorColors 统一配色、AssetItemView 抽出条目绘制;HierarchyPanel/ MaterialEditorPanel 同步调整 - 材质缩略图改走 GPU 回读烘焙:MaterialPreviewPass 新增 bake pass (SDR atlas → host staging copyImageToBuffer)、Renderer 提供 Request/PollMaterialPreviewBake(无 waitIdle,依赖 per-slot fence), Editor 每帧排空后注入 ThumbnailCache——脱离预览 tile 池,消除"滚出视野 即失效/池耗尽"两问题 - 缩略图失效:BakedIdentity(serial, editVersion) 与当前材质身份比对, 换贴图槽(重载新 serial)/调参数(editVersion++)不符即 Invalidate 重烘, 修"修改材质后资产浏览器缩略图不更新" - 材质加载闸门:每帧至多 1 个 + 按实测耗时冷却,替代固定 2/帧 - 纹理上传批式化:VulkanAssetUploader 新增路径纹理缓存(跨材质去重, 同一贴图只解码/上传一次)+ 同批新纹理合并为单 cmd/单 submit/单 fence; Texture 抽出 RecordPixelsUpload/CreateDeferred/ReleasePendingStaging, 析构兜底释放 staging;MaterialAsset 纹理所有权移交 uploader 缓存—— 修大材质目录首次打开卡顿
This commit is contained in:
@@ -8,6 +8,7 @@
|
||||
|
||||
#include "HierarchyPanel.h"
|
||||
#include "AssetBrowserPanel.h" // kPrefabDragPayload(Content Browser 源)
|
||||
#include "EditorColors.h" // 实体名/组件徽标配色
|
||||
#include "Engine/ECS/Components.h"
|
||||
#include "Engine/ECS/EntityHandle.h" // CreateEntity 返回完整 EntityHandle
|
||||
#include "Engine/Serialization/SceneSerializer.h"
|
||||
@@ -73,6 +74,25 @@ namespace {
|
||||
return static_cast<entt::entity>(e);
|
||||
}
|
||||
|
||||
// 主组件 → 实体名颜色(优先级高者胜,用于 Outliner 可读性)
|
||||
ImVec4 PrimaryColor(const entt::registry& reg, entt::entity e)
|
||||
{
|
||||
using namespace Engine::ECS;
|
||||
if (reg.all_of<CameraComponent>(e)) return EditorColors::kCamera;
|
||||
if (reg.all_of<LightComponent>(e)) return EditorColors::kLight;
|
||||
if (reg.all_of<SkyboxComponent>(e) ||
|
||||
reg.all_of<SkyLightComponent>(e)) return EditorColors::kSky;
|
||||
if (reg.all_of<MeshRendererComponent>(e)) return EditorColors::kMesh;
|
||||
if (reg.all_of<AnimationComponent>(e)) return EditorColors::kAnimB;
|
||||
if (reg.all_of<ScriptComponent>(e)) return EditorColors::kScript;
|
||||
if (reg.all_of<RigidBodyComponent>(e) ||
|
||||
reg.all_of<CharacterControllerComponent>(e))
|
||||
{
|
||||
return EditorColors::kPhysics;
|
||||
}
|
||||
return EditorColors::kEntityNeutral;
|
||||
}
|
||||
|
||||
// 实体名 → 合法文件名(路径分隔符/保留符净化;空名兜底)
|
||||
std::string PrefabFileName(std::string name)
|
||||
{
|
||||
@@ -120,7 +140,10 @@ namespace {
|
||||
(kids.empty() ? ImGuiTreeNodeFlags_Leaf : 0) |
|
||||
(selected == e ? ImGuiTreeNodeFlags_Selected : 0);
|
||||
|
||||
// 实体名按主组件着色(无组件 = 中性色)
|
||||
ImGui::PushStyleColor(ImGuiCol_Text, PrimaryColor(reg, e));
|
||||
const bool opened = ImGui::TreeNodeEx(label.c_str(), flags);
|
||||
ImGui::PopStyleColor();
|
||||
const bool toggled = ImGui::IsItemToggledOpen();
|
||||
if (ImGui::IsItemClicked(ImGuiMouseButton_Left) && !toggled) {
|
||||
selected = e;
|
||||
@@ -208,20 +231,36 @@ namespace {
|
||||
ImGui::EndPopup();
|
||||
}
|
||||
|
||||
// ---- 组件徽标(与行内同级显示)----
|
||||
std::string badge;
|
||||
if (reg.all_of<Engine::ECS::MeshRendererComponent>(e)) badge += "[M]";
|
||||
if (reg.all_of<Engine::ECS::AnimationComponent>(e)) badge += "[A]";
|
||||
if (reg.all_of<Engine::ECS::CameraComponent>(e)) badge += "[C]";
|
||||
if (reg.all_of<Engine::ECS::LightComponent>(e)) badge += "[L]";
|
||||
if (reg.all_of<Engine::ECS::RigidBodyComponent>(e)) badge += "[P]";
|
||||
if (!badge.empty()) {
|
||||
ImGui::SameLine();
|
||||
ImGui::TextDisabled("%s", badge.c_str());
|
||||
if (ImGui::IsItemHovered()) {
|
||||
ImGui::SetTooltip(
|
||||
"M=Mesh A=Animation C=Camera L=Light P=Physics");
|
||||
}
|
||||
// ---- 组件徽标(逐组件着色,与行内同级显示)----
|
||||
bool anyBadge = false;
|
||||
auto badge = [&](const char* text, const ImVec4& col)
|
||||
{
|
||||
ImGui::SameLine(0.0f, 6.0f);
|
||||
ImGui::PushStyleColor(ImGuiCol_Text, col);
|
||||
ImGui::TextUnformatted(text);
|
||||
ImGui::PopStyleColor();
|
||||
anyBadge = true;
|
||||
};
|
||||
if (reg.all_of<Engine::ECS::MeshRendererComponent>(e))
|
||||
badge("M", EditorColors::kMesh);
|
||||
if (reg.all_of<Engine::ECS::AnimationComponent>(e))
|
||||
badge("A", EditorColors::kAnimB);
|
||||
if (reg.all_of<Engine::ECS::CameraComponent>(e))
|
||||
badge("C", EditorColors::kCamera);
|
||||
if (reg.all_of<Engine::ECS::LightComponent>(e))
|
||||
badge("L", EditorColors::kLight);
|
||||
if (reg.all_of<Engine::ECS::RigidBodyComponent>(e) ||
|
||||
reg.all_of<Engine::ECS::CharacterControllerComponent>(e))
|
||||
badge("P", EditorColors::kPhysics);
|
||||
if (reg.all_of<Engine::ECS::ScriptComponent>(e))
|
||||
badge("S", EditorColors::kScript);
|
||||
if (reg.all_of<Engine::ECS::SkyboxComponent>(e) ||
|
||||
reg.all_of<Engine::ECS::SkyLightComponent>(e))
|
||||
badge("K", EditorColors::kSky);
|
||||
if (anyBadge && ImGui::IsItemHovered()) {
|
||||
ImGui::SetTooltip(
|
||||
"M=Mesh A=Animation C=Camera L=Light P=Physics "
|
||||
"S=Script K=Sky");
|
||||
}
|
||||
|
||||
if (opened) {
|
||||
|
||||
Reference in New Issue
Block a user