refactor: generalize renderer builtin post process
This commit is contained in:
@@ -357,14 +357,14 @@ add_library(XCEngine STATIC
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/include/XCEngine/Rendering/SceneRenderer.h
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/include/XCEngine/Rendering/Passes/BuiltinObjectIdPass.h
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/include/XCEngine/Rendering/Passes/BuiltinInfiniteGridPass.h
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/include/XCEngine/Rendering/Passes/BuiltinSceneViewPostPassPlan.h
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/include/XCEngine/Rendering/Passes/BuiltinSceneViewPostPassSequenceBuilder.h
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/include/XCEngine/Rendering/Passes/BuiltinPostProcessPassPlan.h
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/include/XCEngine/Rendering/Passes/BuiltinPostProcessPassSequenceBuilder.h
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/include/XCEngine/Rendering/Passes/BuiltinObjectIdOutlinePass.h
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/include/XCEngine/Rendering/Pipelines/BuiltinForwardPipeline.h
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/src/Rendering/CameraRenderer.cpp
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/src/Rendering/Passes/BuiltinObjectIdPass.cpp
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/src/Rendering/Passes/BuiltinInfiniteGridPass.cpp
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/src/Rendering/Passes/BuiltinSceneViewPostPassSequenceBuilder.cpp
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/src/Rendering/Passes/BuiltinPostProcessPassSequenceBuilder.cpp
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/src/Rendering/Passes/BuiltinObjectIdOutlinePass.cpp
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/src/Rendering/RenderSurface.cpp
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/src/Rendering/RenderSceneExtractor.cpp
|
||||
|
||||
@@ -32,14 +32,14 @@ struct ObjectIdRenderRequest {
|
||||
}
|
||||
};
|
||||
|
||||
struct BuiltinSceneViewPostProcessRequest {
|
||||
struct BuiltinPostProcessRequest {
|
||||
Passes::InfiniteGridPassData gridPassData = {};
|
||||
RHI::RHIResourceView* objectIdTextureView = nullptr;
|
||||
std::vector<uint64_t> selectedObjectIds = {};
|
||||
Passes::ObjectIdOutlineStyle outlineStyle = {};
|
||||
|
||||
bool IsRequested() const {
|
||||
return gridPassData.valid;
|
||||
return gridPassData.valid || !selectedObjectIds.empty();
|
||||
}
|
||||
};
|
||||
|
||||
@@ -49,7 +49,7 @@ struct CameraRenderRequest {
|
||||
RenderContext context;
|
||||
RenderSurface surface;
|
||||
ObjectIdRenderRequest objectId;
|
||||
BuiltinSceneViewPostProcessRequest builtinSceneViewPostProcess;
|
||||
BuiltinPostProcessRequest builtinPostProcess;
|
||||
float cameraDepth = 0.0f;
|
||||
uint8_t cameraStackOrder = 0;
|
||||
RenderClearFlags clearFlags = RenderClearFlags::All;
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
|
||||
#include <XCEngine/Rendering/CameraRenderRequest.h>
|
||||
#include <XCEngine/Rendering/ObjectIdPass.h>
|
||||
#include <XCEngine/Rendering/Passes/BuiltinSceneViewPostPassSequenceBuilder.h>
|
||||
#include <XCEngine/Rendering/Passes/BuiltinPostProcessPassSequenceBuilder.h>
|
||||
#include <XCEngine/Rendering/RenderPipeline.h>
|
||||
|
||||
#include <memory>
|
||||
@@ -44,7 +44,7 @@ private:
|
||||
std::shared_ptr<const RenderPipelineAsset> m_pipelineAsset;
|
||||
std::unique_ptr<RenderPipeline> m_pipeline;
|
||||
std::unique_ptr<ObjectIdPass> m_objectIdPass;
|
||||
Passes::BuiltinSceneViewPostPassSequenceBuilder m_builtinSceneViewPostProcessBuilder;
|
||||
Passes::BuiltinPostProcessPassSequenceBuilder m_builtinPostProcessBuilder;
|
||||
};
|
||||
|
||||
} // namespace Rendering
|
||||
|
||||
@@ -0,0 +1,91 @@
|
||||
#pragma once
|
||||
|
||||
#include <cstdint>
|
||||
#include <vector>
|
||||
|
||||
namespace XCEngine {
|
||||
namespace Rendering {
|
||||
namespace Passes {
|
||||
|
||||
enum class BuiltinPostProcessPassStep : uint8_t {
|
||||
ColorToRenderTarget,
|
||||
InfiniteGrid,
|
||||
SelectionOutline,
|
||||
ColorToShaderResource,
|
||||
SelectionMaskDebug
|
||||
};
|
||||
|
||||
struct BuiltinPostProcessPassPlanInput {
|
||||
bool hasGridOverlay = false;
|
||||
bool hasSelection = false;
|
||||
bool debugSelectionMask = false;
|
||||
bool hasObjectIdShaderView = false;
|
||||
};
|
||||
|
||||
struct BuiltinPostProcessPassPlan {
|
||||
bool valid = false;
|
||||
std::vector<BuiltinPostProcessPassStep> steps;
|
||||
};
|
||||
|
||||
inline BuiltinPostProcessPassPlan BuildBuiltinPostProcessPassPlan(
|
||||
const BuiltinPostProcessPassPlanInput& input) {
|
||||
BuiltinPostProcessPassPlan plan = {};
|
||||
plan.valid = true;
|
||||
|
||||
if (input.debugSelectionMask) {
|
||||
if (input.hasSelection && input.hasObjectIdShaderView) {
|
||||
plan.steps = {
|
||||
BuiltinPostProcessPassStep::ColorToRenderTarget,
|
||||
BuiltinPostProcessPassStep::SelectionMaskDebug,
|
||||
BuiltinPostProcessPassStep::ColorToShaderResource
|
||||
};
|
||||
return plan;
|
||||
}
|
||||
|
||||
if (input.hasGridOverlay) {
|
||||
plan.steps = {
|
||||
BuiltinPostProcessPassStep::ColorToRenderTarget,
|
||||
BuiltinPostProcessPassStep::ColorToShaderResource
|
||||
};
|
||||
return plan;
|
||||
}
|
||||
|
||||
plan.valid = false;
|
||||
return plan;
|
||||
}
|
||||
|
||||
if (input.hasGridOverlay && input.hasSelection && input.hasObjectIdShaderView) {
|
||||
plan.steps = {
|
||||
BuiltinPostProcessPassStep::ColorToRenderTarget,
|
||||
BuiltinPostProcessPassStep::InfiniteGrid,
|
||||
BuiltinPostProcessPassStep::SelectionOutline,
|
||||
BuiltinPostProcessPassStep::ColorToShaderResource
|
||||
};
|
||||
return plan;
|
||||
}
|
||||
|
||||
if (input.hasGridOverlay) {
|
||||
plan.steps = {
|
||||
BuiltinPostProcessPassStep::ColorToRenderTarget,
|
||||
BuiltinPostProcessPassStep::InfiniteGrid,
|
||||
BuiltinPostProcessPassStep::ColorToShaderResource
|
||||
};
|
||||
return plan;
|
||||
}
|
||||
|
||||
if (input.hasSelection && input.hasObjectIdShaderView) {
|
||||
plan.steps = {
|
||||
BuiltinPostProcessPassStep::ColorToRenderTarget,
|
||||
BuiltinPostProcessPassStep::SelectionOutline,
|
||||
BuiltinPostProcessPassStep::ColorToShaderResource
|
||||
};
|
||||
return plan;
|
||||
}
|
||||
|
||||
plan.valid = false;
|
||||
return plan;
|
||||
}
|
||||
|
||||
} // namespace Passes
|
||||
} // namespace Rendering
|
||||
} // namespace XCEngine
|
||||
@@ -11,26 +11,26 @@ namespace XCEngine {
|
||||
namespace Rendering {
|
||||
namespace Passes {
|
||||
|
||||
struct BuiltinSceneViewPostPassSequenceInput {
|
||||
struct BuiltinPostProcessPassSequenceInput {
|
||||
InfiniteGridPassData gridPassData = {};
|
||||
RHI::RHIResourceView* objectIdTextureView = nullptr;
|
||||
std::vector<uint64_t> selectedObjectIds = {};
|
||||
ObjectIdOutlineStyle outlineStyle = {};
|
||||
};
|
||||
|
||||
struct BuiltinSceneViewPostPassSequenceBuildResult {
|
||||
struct BuiltinPostProcessPassSequenceBuildResult {
|
||||
bool valid = false;
|
||||
bool missingObjectIdTextureViewForSelection = false;
|
||||
};
|
||||
|
||||
class BuiltinSceneViewPostPassSequenceBuilder {
|
||||
class BuiltinPostProcessPassSequenceBuilder {
|
||||
public:
|
||||
~BuiltinSceneViewPostPassSequenceBuilder();
|
||||
~BuiltinPostProcessPassSequenceBuilder();
|
||||
|
||||
void Shutdown();
|
||||
|
||||
BuiltinSceneViewPostPassSequenceBuildResult Build(
|
||||
const BuiltinSceneViewPostPassSequenceInput& input,
|
||||
BuiltinPostProcessPassSequenceBuildResult Build(
|
||||
const BuiltinPostProcessPassSequenceInput& input,
|
||||
RenderPassSequence& outSequence);
|
||||
|
||||
private:
|
||||
@@ -1,67 +0,0 @@
|
||||
#pragma once
|
||||
|
||||
#include <cstdint>
|
||||
#include <vector>
|
||||
|
||||
namespace XCEngine {
|
||||
namespace Rendering {
|
||||
namespace Passes {
|
||||
|
||||
enum class BuiltinSceneViewPostPassStep : uint8_t {
|
||||
ColorToRenderTarget,
|
||||
InfiniteGrid,
|
||||
SelectionOutline,
|
||||
ColorToShaderResource,
|
||||
SelectionMaskDebug
|
||||
};
|
||||
|
||||
struct BuiltinSceneViewPostPassPlanInput {
|
||||
bool overlayValid = false;
|
||||
bool hasSelection = false;
|
||||
bool debugSelectionMask = false;
|
||||
bool hasObjectIdShaderView = false;
|
||||
};
|
||||
|
||||
struct BuiltinSceneViewPostPassPlan {
|
||||
bool valid = false;
|
||||
std::vector<BuiltinSceneViewPostPassStep> steps;
|
||||
};
|
||||
|
||||
inline BuiltinSceneViewPostPassPlan BuildBuiltinSceneViewPostPassPlan(
|
||||
const BuiltinSceneViewPostPassPlanInput& input) {
|
||||
BuiltinSceneViewPostPassPlan plan = {};
|
||||
if (!input.overlayValid) {
|
||||
return plan;
|
||||
}
|
||||
|
||||
plan.valid = true;
|
||||
|
||||
if (input.debugSelectionMask) {
|
||||
plan.steps.push_back(BuiltinSceneViewPostPassStep::ColorToRenderTarget);
|
||||
if (input.hasSelection && input.hasObjectIdShaderView) {
|
||||
plan.steps.push_back(BuiltinSceneViewPostPassStep::SelectionMaskDebug);
|
||||
}
|
||||
plan.steps.push_back(BuiltinSceneViewPostPassStep::ColorToShaderResource);
|
||||
return plan;
|
||||
}
|
||||
|
||||
plan.steps.push_back(BuiltinSceneViewPostPassStep::ColorToRenderTarget);
|
||||
plan.steps.push_back(BuiltinSceneViewPostPassStep::InfiniteGrid);
|
||||
|
||||
if (input.hasSelection && input.hasObjectIdShaderView) {
|
||||
plan.steps = {
|
||||
BuiltinSceneViewPostPassStep::ColorToRenderTarget,
|
||||
BuiltinSceneViewPostPassStep::InfiniteGrid,
|
||||
BuiltinSceneViewPostPassStep::SelectionOutline,
|
||||
BuiltinSceneViewPostPassStep::ColorToShaderResource
|
||||
};
|
||||
return plan;
|
||||
}
|
||||
|
||||
plan.steps.push_back(BuiltinSceneViewPostPassStep::ColorToShaderResource);
|
||||
return plan;
|
||||
}
|
||||
|
||||
} // namespace Passes
|
||||
} // namespace Rendering
|
||||
} // namespace XCEngine
|
||||
@@ -86,7 +86,7 @@ CameraRenderer::~CameraRenderer() {
|
||||
if (m_objectIdPass != nullptr) {
|
||||
m_objectIdPass->Shutdown();
|
||||
}
|
||||
m_builtinSceneViewPostProcessBuilder.Shutdown();
|
||||
m_builtinPostProcessBuilder.Shutdown();
|
||||
}
|
||||
|
||||
void CameraRenderer::SetPipeline(std::unique_ptr<RenderPipeline> pipeline) {
|
||||
@@ -136,8 +136,8 @@ bool CameraRenderer::Render(
|
||||
!request.objectId.IsValid()) {
|
||||
return false;
|
||||
}
|
||||
if (request.builtinSceneViewPostProcess.IsRequested() &&
|
||||
request.builtinSceneViewPostProcess.objectIdTextureView != nullptr &&
|
||||
if (request.builtinPostProcess.IsRequested() &&
|
||||
request.builtinPostProcess.objectIdTextureView != nullptr &&
|
||||
!request.objectId.IsRequested()) {
|
||||
return false;
|
||||
}
|
||||
@@ -201,36 +201,36 @@ bool CameraRenderer::Render(
|
||||
return false;
|
||||
}
|
||||
|
||||
RenderPassSequence builtinSceneViewPostPasses = {};
|
||||
bool builtinSceneViewPostPassesInitialized = false;
|
||||
if (request.builtinSceneViewPostProcess.IsRequested()) {
|
||||
const Passes::BuiltinSceneViewPostPassSequenceBuildResult buildResult =
|
||||
m_builtinSceneViewPostProcessBuilder.Build(
|
||||
RenderPassSequence builtinPostProcessPasses = {};
|
||||
bool builtinPostProcessPassesInitialized = false;
|
||||
if (request.builtinPostProcess.IsRequested()) {
|
||||
const Passes::BuiltinPostProcessPassSequenceBuildResult buildResult =
|
||||
m_builtinPostProcessBuilder.Build(
|
||||
{
|
||||
request.builtinSceneViewPostProcess.gridPassData,
|
||||
request.builtinSceneViewPostProcess.objectIdTextureView,
|
||||
request.builtinSceneViewPostProcess.selectedObjectIds,
|
||||
request.builtinSceneViewPostProcess.outlineStyle
|
||||
request.builtinPostProcess.gridPassData,
|
||||
request.builtinPostProcess.objectIdTextureView,
|
||||
request.builtinPostProcess.selectedObjectIds,
|
||||
request.builtinPostProcess.outlineStyle
|
||||
},
|
||||
builtinSceneViewPostPasses);
|
||||
builtinPostProcessPasses);
|
||||
if (!buildResult.valid ||
|
||||
!InitializePassSequence(
|
||||
&builtinSceneViewPostPasses,
|
||||
&builtinPostProcessPasses,
|
||||
request.context,
|
||||
builtinSceneViewPostPassesInitialized)) {
|
||||
builtinPostProcessPassesInitialized)) {
|
||||
ShutdownPassSequence(request.postScenePasses, postScenePassesInitialized);
|
||||
ShutdownPassSequence(request.preScenePasses, preScenePassesInitialized);
|
||||
return false;
|
||||
}
|
||||
if (!builtinSceneViewPostPasses.Execute(passContext)) {
|
||||
ShutdownPassSequence(&builtinSceneViewPostPasses, builtinSceneViewPostPassesInitialized);
|
||||
if (!builtinPostProcessPasses.Execute(passContext)) {
|
||||
ShutdownPassSequence(&builtinPostProcessPasses, builtinPostProcessPassesInitialized);
|
||||
ShutdownPassSequence(request.postScenePasses, postScenePassesInitialized);
|
||||
ShutdownPassSequence(request.preScenePasses, preScenePassesInitialized);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
ShutdownPassSequence(&builtinSceneViewPostPasses, builtinSceneViewPostPassesInitialized);
|
||||
ShutdownPassSequence(&builtinPostProcessPasses, builtinPostProcessPassesInitialized);
|
||||
ShutdownPassSequence(request.postScenePasses, postScenePassesInitialized);
|
||||
ShutdownPassSequence(request.preScenePasses, preScenePassesInitialized);
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
#include "Rendering/Passes/BuiltinSceneViewPostPassSequenceBuilder.h"
|
||||
#include "Rendering/Passes/BuiltinPostProcessPassSequenceBuilder.h"
|
||||
|
||||
#include "Rendering/Passes/BuiltinSceneViewPostPassPlan.h"
|
||||
#include "Rendering/Passes/BuiltinPostProcessPassPlan.h"
|
||||
|
||||
#include <XCEngine/Core/Math/Color.h>
|
||||
#include <XCEngine/RHI/RHICommandList.h>
|
||||
@@ -47,19 +47,19 @@ std::unique_ptr<RenderPass> MakeLambdaRenderPass(const char* name, Callback&& ca
|
||||
|
||||
} // namespace
|
||||
|
||||
BuiltinSceneViewPostPassSequenceBuilder::~BuiltinSceneViewPostPassSequenceBuilder() {
|
||||
BuiltinPostProcessPassSequenceBuilder::~BuiltinPostProcessPassSequenceBuilder() {
|
||||
Shutdown();
|
||||
}
|
||||
|
||||
void BuiltinSceneViewPostPassSequenceBuilder::Shutdown() {
|
||||
void BuiltinPostProcessPassSequenceBuilder::Shutdown() {
|
||||
m_outlinePass.Shutdown();
|
||||
m_gridPass.Shutdown();
|
||||
}
|
||||
|
||||
BuiltinSceneViewPostPassSequenceBuildResult BuiltinSceneViewPostPassSequenceBuilder::Build(
|
||||
const BuiltinSceneViewPostPassSequenceInput& input,
|
||||
BuiltinPostProcessPassSequenceBuildResult BuiltinPostProcessPassSequenceBuilder::Build(
|
||||
const BuiltinPostProcessPassSequenceInput& input,
|
||||
RenderPassSequence& outSequence) {
|
||||
BuiltinSceneViewPostPassSequenceBuildResult result = {};
|
||||
BuiltinPostProcessPassSequenceBuildResult result = {};
|
||||
const bool hasSelection = !input.selectedObjectIds.empty();
|
||||
const bool hasObjectIdTextureView = input.objectIdTextureView != nullptr;
|
||||
|
||||
@@ -67,7 +67,7 @@ BuiltinSceneViewPostPassSequenceBuildResult BuiltinSceneViewPostPassSequenceBuil
|
||||
result.missingObjectIdTextureViewForSelection = true;
|
||||
}
|
||||
|
||||
const BuiltinSceneViewPostPassPlan plan = BuildBuiltinSceneViewPostPassPlan({
|
||||
const BuiltinPostProcessPassPlan plan = BuildBuiltinPostProcessPassPlan({
|
||||
input.gridPassData.valid,
|
||||
hasSelection,
|
||||
input.outlineStyle.debugSelectionMask,
|
||||
@@ -78,25 +78,25 @@ BuiltinSceneViewPostPassSequenceBuildResult BuiltinSceneViewPostPassSequenceBuil
|
||||
}
|
||||
|
||||
result.valid = true;
|
||||
for (const BuiltinSceneViewPostPassStep step : plan.steps) {
|
||||
for (const BuiltinPostProcessPassStep step : plan.steps) {
|
||||
switch (step) {
|
||||
case BuiltinSceneViewPostPassStep::ColorToRenderTarget:
|
||||
case BuiltinPostProcessPassStep::ColorToRenderTarget:
|
||||
AddColorToRenderTargetPass(outSequence);
|
||||
break;
|
||||
case BuiltinSceneViewPostPassStep::InfiniteGrid:
|
||||
case BuiltinPostProcessPassStep::InfiniteGrid:
|
||||
AddInfiniteGridPass(input.gridPassData, outSequence);
|
||||
break;
|
||||
case BuiltinSceneViewPostPassStep::SelectionOutline:
|
||||
case BuiltinPostProcessPassStep::SelectionOutline:
|
||||
AddSelectionOutlinePass(
|
||||
input.objectIdTextureView,
|
||||
input.selectedObjectIds,
|
||||
input.outlineStyle,
|
||||
outSequence);
|
||||
break;
|
||||
case BuiltinSceneViewPostPassStep::ColorToShaderResource:
|
||||
case BuiltinPostProcessPassStep::ColorToShaderResource:
|
||||
AddColorToShaderResourcePass(outSequence);
|
||||
break;
|
||||
case BuiltinSceneViewPostPassStep::SelectionMaskDebug:
|
||||
case BuiltinPostProcessPassStep::SelectionMaskDebug:
|
||||
AddSelectionMaskDebugPass(
|
||||
input.objectIdTextureView,
|
||||
input.selectedObjectIds,
|
||||
@@ -111,7 +111,7 @@ BuiltinSceneViewPostPassSequenceBuildResult BuiltinSceneViewPostPassSequenceBuil
|
||||
return result;
|
||||
}
|
||||
|
||||
void BuiltinSceneViewPostPassSequenceBuilder::AddColorToRenderTargetPass(
|
||||
void BuiltinPostProcessPassSequenceBuilder::AddColorToRenderTargetPass(
|
||||
RenderPassSequence& outSequence) {
|
||||
outSequence.AddPass(MakeLambdaRenderPass(
|
||||
"SceneColorToRenderTarget",
|
||||
@@ -129,7 +129,7 @@ void BuiltinSceneViewPostPassSequenceBuilder::AddColorToRenderTargetPass(
|
||||
}));
|
||||
}
|
||||
|
||||
void BuiltinSceneViewPostPassSequenceBuilder::AddInfiniteGridPass(
|
||||
void BuiltinPostProcessPassSequenceBuilder::AddInfiniteGridPass(
|
||||
const InfiniteGridPassData& gridPassData,
|
||||
RenderPassSequence& outSequence) {
|
||||
outSequence.AddPass(MakeLambdaRenderPass(
|
||||
@@ -142,7 +142,7 @@ void BuiltinSceneViewPostPassSequenceBuilder::AddInfiniteGridPass(
|
||||
}));
|
||||
}
|
||||
|
||||
void BuiltinSceneViewPostPassSequenceBuilder::AddSelectionOutlinePass(
|
||||
void BuiltinPostProcessPassSequenceBuilder::AddSelectionOutlinePass(
|
||||
RHI::RHIResourceView* objectIdTextureView,
|
||||
const std::vector<uint64_t>& selectedObjectIds,
|
||||
const ObjectIdOutlineStyle& outlineStyle,
|
||||
@@ -159,7 +159,7 @@ void BuiltinSceneViewPostPassSequenceBuilder::AddSelectionOutlinePass(
|
||||
}));
|
||||
}
|
||||
|
||||
void BuiltinSceneViewPostPassSequenceBuilder::AddColorToShaderResourcePass(
|
||||
void BuiltinPostProcessPassSequenceBuilder::AddColorToShaderResourcePass(
|
||||
RenderPassSequence& outSequence) {
|
||||
outSequence.AddPass(MakeLambdaRenderPass(
|
||||
"SceneColorToShaderResource",
|
||||
@@ -177,7 +177,7 @@ void BuiltinSceneViewPostPassSequenceBuilder::AddColorToShaderResourcePass(
|
||||
}));
|
||||
}
|
||||
|
||||
void BuiltinSceneViewPostPassSequenceBuilder::AddSelectionMaskDebugPass(
|
||||
void BuiltinPostProcessPassSequenceBuilder::AddSelectionMaskDebugPass(
|
||||
RHI::RHIResourceView* objectIdTextureView,
|
||||
const std::vector<uint64_t>& selectedObjectIds,
|
||||
const ObjectIdOutlineStyle& outlineStyle,
|
||||
Reference in New Issue
Block a user