Formalize render object id contract

This commit is contained in:
2026-04-10 01:57:15 +08:00
parent 4debbbea1f
commit b5ba985831
12 changed files with 282 additions and 102 deletions

View File

@@ -2,6 +2,7 @@
#include <XCEngine/Core/Math/Matrix4.h>
#include <XCEngine/Core/Types.h>
#include <XCEngine/Rendering/Picking/ObjectIdCodec.h>
#include <XCEngine/Resources/Mesh/Mesh.h>
namespace XCEngine {
@@ -19,6 +20,7 @@ struct VisibleRenderItem {
Components::MeshRendererComponent* meshRenderer = nullptr;
Resources::Mesh* mesh = nullptr;
const Resources::Material* material = nullptr;
RenderObjectId renderObjectId = kInvalidRenderObjectId;
Core::uint32 materialIndex = 0;
Core::uint32 sectionIndex = 0;
bool hasSection = false;

View File

@@ -43,11 +43,15 @@ private:
RHI::RHIDescriptorSet* set = nullptr;
};
bool EnsureInitialized(const RenderContext& context);
bool CreateResources(const RenderContext& context);
bool EnsureInitialized(
const RenderContext& context,
const RenderSurface& surface);
bool CreateResources(
const RenderContext& context,
const RenderSurface& surface);
void DestroyResources();
RHI::RHIDescriptorSet* GetOrCreatePerObjectSet(uint64_t objectId);
RHI::RHIDescriptorSet* GetOrCreatePerObjectSet(RenderObjectId objectId);
void DestroyOwnedDescriptorSet(OwnedDescriptorSet& descriptorSet);
bool DrawVisibleItem(
const RenderContext& context,
@@ -61,9 +65,12 @@ private:
PassResourceBindingLocation m_perObjectBinding = {};
BuiltinPassSetLayoutMetadata m_perObjectSetLayout = {};
Core::uint32 m_firstDescriptorSet = 0;
RHI::Format m_renderTargetFormat = RHI::Format::Unknown;
RHI::Format m_depthStencilFormat = RHI::Format::Unknown;
uint32_t m_renderTargetSampleCount = 1u;
Resources::ResourceHandle<Resources::Shader> m_builtinObjectIdShader;
RenderResourceCache m_resourceCache;
std::unordered_map<uint64_t, OwnedDescriptorSet> m_perObjectSets;
std::unordered_map<RenderObjectId, OwnedDescriptorSet> m_perObjectSets;
};
} // namespace Passes

View File

@@ -1,6 +1,7 @@
#pragma once
#include <XCEngine/Rendering/Passes/BuiltinDepthStylePassBase.h>
#include <XCEngine/Rendering/Picking/ObjectIdCodec.h>
#include <cstdint>
#include <vector>
@@ -32,7 +33,7 @@ protected:
bool ShouldRenderVisibleItem(const VisibleRenderItem& visibleItem) const override;
private:
std::vector<uint64_t> m_selectedObjectIds = {};
std::vector<RenderObjectId> m_selectedObjectIds = {};
};
} // namespace Passes

View File

@@ -3,27 +3,51 @@
#include <XCEngine/Core/Math/Vector4.h>
#include <XCEngine/Core/Types.h>
#include <limits>
namespace XCEngine {
namespace Rendering {
using EncodedObjectId = Core::uint32;
using RenderObjectId = Core::uint32;
using EncodedObjectId = RenderObjectId;
// Object-id render targets store only the low 32 bits of a runtime object id.
// This codec is for editor/runtime picking surfaces, not for persistent ids.
inline bool CanEncodeObjectIdWithoutLoss(Core::uint64 objectId) {
return (objectId & 0xFFFFFFFF00000000ull) == 0ull;
static constexpr RenderObjectId kInvalidRenderObjectId = 0u;
inline bool IsValidRenderObjectId(RenderObjectId renderObjectId) {
return renderObjectId != kInvalidRenderObjectId;
}
inline EncodedObjectId EncodeObjectIdToEncodedId(Core::uint64 objectId) {
return static_cast<EncodedObjectId>(objectId & 0xFFFFFFFFull);
inline bool CanConvertRuntimeObjectIdToRenderObjectId(Core::uint64 runtimeObjectId) {
return runtimeObjectId != 0u &&
runtimeObjectId <= static_cast<Core::uint64>(std::numeric_limits<RenderObjectId>::max());
}
inline EncodedObjectId EncodeObjectIdToUInt32(Core::uint64 objectId) {
return EncodeObjectIdToEncodedId(objectId);
inline bool TryConvertRuntimeObjectIdToRenderObjectId(
Core::uint64 runtimeObjectId,
RenderObjectId& outRenderObjectId) {
outRenderObjectId = kInvalidRenderObjectId;
if (!CanConvertRuntimeObjectIdToRenderObjectId(runtimeObjectId)) {
return false;
}
outRenderObjectId = static_cast<RenderObjectId>(runtimeObjectId);
return true;
}
inline Math::Vector4 EncodeObjectIdToColor(Core::uint64 objectId) {
const EncodedObjectId encodedId = EncodeObjectIdToEncodedId(objectId);
inline Core::uint64 ConvertRenderObjectIdToRuntimeObjectId(RenderObjectId renderObjectId) {
return static_cast<Core::uint64>(renderObjectId);
}
inline EncodedObjectId EncodeRenderObjectIdToEncodedId(RenderObjectId renderObjectId) {
return renderObjectId;
}
inline EncodedObjectId EncodeRenderObjectIdToUInt32(RenderObjectId renderObjectId) {
return EncodeRenderObjectIdToEncodedId(renderObjectId);
}
inline Math::Vector4 EncodeRenderObjectIdToColor(RenderObjectId renderObjectId) {
const EncodedObjectId encodedId = EncodeRenderObjectIdToEncodedId(renderObjectId);
constexpr float kInv255 = 1.0f / 255.0f;
return Math::Vector4(
static_cast<float>((encodedId >> 0) & 0xFFu) * kInv255,
@@ -43,12 +67,12 @@ inline EncodedObjectId DecodeEncodedObjectIdFromColor(
(static_cast<EncodedObjectId>(a) << 24u);
}
inline Core::uint64 DecodeObjectIdFromColor(
inline RenderObjectId DecodeRenderObjectIdFromColor(
Core::uint8 r,
Core::uint8 g,
Core::uint8 b,
Core::uint8 a) {
return static_cast<Core::uint64>(DecodeEncodedObjectIdFromColor(r, g, b, a));
return DecodeEncodedObjectIdFromColor(r, g, b, a);
}
} // namespace Rendering