Skip to content

Commit 288b823

Browse files
authored
Merge pull request #998 from Devsh-Graphics-Programming/Frustum
Add frustum debug draw extension
2 parents 295205e + d73216e commit 288b823

7 files changed

Lines changed: 773 additions & 1 deletion

File tree

Lines changed: 119 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,119 @@
1+
// Copyright (C) 2018-2026 - DevSH Graphics Programming Sp. z O.O.
2+
// This file is part of the "Nabla Engine".
3+
// For conditions of distribution and use, see copyright notice in nabla.h
4+
5+
#ifndef _NBL_EXT_FRUSTUM_DRAW_FRUSTUM_H_
6+
#define _NBL_EXT_FRUSTUM_DRAW_FRUSTUM_H_
7+
8+
#include "nbl/video/declarations.h"
9+
#include "nbl/builtin/hlsl/cpp_compat.hlsl"
10+
#include "nbl/builtin/hlsl/math/linalg/fast_affine.hlsl"
11+
#include "nbl/ext/Frustum/builtin/hlsl/common.hlsl"
12+
13+
namespace nbl::ext::frustum
14+
{
15+
class CDrawFrustum final : public core::IReferenceCounted
16+
{
17+
public:
18+
static constexpr inline uint32_t IndicesCount = 24u;
19+
20+
enum DrawMode : uint16_t
21+
{
22+
DM_SINGLE = 0b01,
23+
DM_BATCH = 0b10,
24+
DM_BOTH = 0b11
25+
};
26+
27+
struct SCachedCreationParameters
28+
{
29+
using streaming_buffer_t = video::StreamingTransientDataBufferST<core::allocator<uint8_t>>;
30+
static constexpr inline auto RequiredAllocateFlags = core::bitflag<video::IDeviceMemoryAllocation::E_MEMORY_ALLOCATE_FLAGS>(video::IDeviceMemoryAllocation::EMAF_DEVICE_ADDRESS_BIT);
31+
static constexpr inline auto RequiredUsageFlags = core::bitflag(asset::IBuffer::EUF_STORAGE_BUFFER_BIT) | asset::IBuffer::EUF_SHADER_DEVICE_ADDRESS_BIT;
32+
DrawMode drawMode = DM_BOTH;
33+
core::smart_refctd_ptr<video::IUtilities> utilities;
34+
core::smart_refctd_ptr<streaming_buffer_t> streamingBuffer = nullptr;
35+
};
36+
37+
struct SCreationParameters : SCachedCreationParameters
38+
{
39+
video::IQueue* transfer = nullptr;
40+
core::smart_refctd_ptr<asset::IAssetManager> assetManager = nullptr;
41+
42+
core::smart_refctd_ptr<video::IGPUPipelineLayout> singlePipelineLayout = nullptr;
43+
core::smart_refctd_ptr<video::IGPUPipelineLayout> batchPipelineLayout = nullptr;
44+
core::smart_refctd_ptr<video::IGPURenderpass> renderpass = nullptr;
45+
46+
inline bool validate() const
47+
{
48+
const auto validation = std::to_array
49+
({
50+
std::make_pair(bool(assetManager), "Invalid `creationParams.assetManager` is nullptr!"),
51+
std::make_pair(bool(utilities), "Invalid `creationParams.utilities` is nullptr!"),
52+
std::make_pair(bool(transfer), "Invalid `creationParams.transfer` is nullptr!"),
53+
std::make_pair(bool(renderpass), "Invalid `creationParams.renderpass` is nullptr!"),
54+
std::make_pair(bool(utilities->getLogicalDevice()->getPhysicalDevice()->getQueueFamilyProperties()[transfer->getFamilyIndex()].queueFlags.hasFlags(video::IQueue::FAMILY_FLAGS::TRANSFER_BIT)), "Invalid `creationParams.transfer` is not capable of transfer operations!")
55+
});
56+
system::logger_opt_ptr logger = utilities->getLogger();
57+
for (const auto& [ok, error] : validation)
58+
if (!ok)
59+
{
60+
logger.log(error, system::ILogger::ELL_ERROR);
61+
return false;
62+
}
63+
64+
assert(bool(assetManager->getSystem()));
65+
66+
return true;
67+
}
68+
};
69+
70+
struct DrawParameters
71+
{
72+
video::IGPUCommandBuffer* commandBuffer = nullptr;
73+
hlsl::float32_t4x4 viewProjectionMatrix;
74+
float lineWidth = 2.f;
75+
};
76+
77+
static core::smart_refctd_ptr<CDrawFrustum> create(SCreationParameters&& params);
78+
79+
static core::smart_refctd_ptr<video::IGPUPipelineLayout> createPipelineLayoutFromPCRange(video::ILogicalDevice* device, const asset::SPushConstantRange& pcRange);
80+
81+
static core::smart_refctd_ptr<video::IGPUPipelineLayout> createDefaultPipelineLayout(video::ILogicalDevice* device, DrawMode mode = DM_BATCH);
82+
83+
static const core::smart_refctd_ptr<system::IFileArchive> mount(core::smart_refctd_ptr<system::ILogger> logger, system::ISystem* system, video::ILogicalDevice* device, const std::string_view archiveAlias = "");
84+
85+
inline const SCachedCreationParameters& getCreationParameters() const { return m_cachedCreationParams; }
86+
87+
bool renderSingle(const DrawParameters& params, const hlsl::float32_t4x4& frustumTransform,const hlsl::float32_t4 & color);
88+
bool render(const DrawParameters& params, video::ISemaphore::SWaitInfo waitInfo, std::span<const InstanceData> frustumInstances);
89+
protected:
90+
91+
struct ConstructorParams
92+
{
93+
SCachedCreationParameters creationParams;
94+
core::smart_refctd_ptr<video::IGPUGraphicsPipeline> singlePipeline = nullptr;
95+
core::smart_refctd_ptr<video::IGPUGraphicsPipeline> batchPipeline = nullptr;
96+
core::smart_refctd_ptr<video::IGPUBuffer> indicesBuffer = nullptr;
97+
};
98+
99+
CDrawFrustum(ConstructorParams&& params) :
100+
m_cachedCreationParams(std::move(params.creationParams)),
101+
m_singlePipeline(std::move(params.singlePipeline)),
102+
m_batchPipeline(std::move(params.batchPipeline)),
103+
m_indicesBuffer(std::move(params.indicesBuffer))
104+
{}
105+
~CDrawFrustum() override {};
106+
private:
107+
static core::smart_refctd_ptr<video::IGPUGraphicsPipeline> createPipeline(SCreationParameters& params, const video::IGPUPipelineLayout* pipelineLayout, const DrawMode mode);
108+
static bool createStreamingBuffer(SCreationParameters& params);
109+
static core::smart_refctd_ptr<video::IGPUBuffer> createIndicesBuffer(SCreationParameters& params);
110+
111+
core::smart_refctd_ptr<video::IGPUBuffer> m_indicesBuffer;
112+
113+
SCachedCreationParameters m_cachedCreationParams;
114+
115+
core::smart_refctd_ptr<video::IGPUGraphicsPipeline> m_singlePipeline;
116+
core::smart_refctd_ptr<video::IGPUGraphicsPipeline> m_batchPipeline;
117+
};
118+
}
119+
#endif
Lines changed: 61 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,61 @@
1+
// Copyright (C) 2018-2026 - DevSH Graphics Programming Sp. z O.O.
2+
// This file is part of the "Nabla Engine".
3+
// For conditions of distribution and use, see copyright notice in nabla.h
4+
5+
#ifndef _NBL_EXT_FRUSTUM_BUILTIN_HLSL_COMMON_INCLUDED_
6+
#define _NBL_EXT_FRUSTUM_BUILTIN_HLSL_COMMON_INCLUDED_
7+
8+
#include "nbl/builtin/hlsl/cpp_compat.hlsl"
9+
#ifdef __HLSL_VERSION
10+
#include "nbl/builtin/hlsl/math/linalg/fast_affine.hlsl"
11+
#include "nbl/builtin/hlsl/glsl_compat/core.hlsl"
12+
#include "nbl/builtin/hlsl/bda/__ptr.hlsl"
13+
#endif
14+
15+
namespace nbl
16+
{
17+
namespace ext
18+
{
19+
namespace frustum
20+
{
21+
22+
struct InstanceData
23+
{
24+
hlsl::float32_t4x4 transform;
25+
hlsl::float32_t4 color;
26+
};
27+
28+
struct SSinglePC
29+
{
30+
InstanceData instance;
31+
};
32+
33+
struct SInstancedPC
34+
{
35+
uint64_t pInstanceBuffer;
36+
};
37+
38+
struct PushConstants
39+
{
40+
SSinglePC spc;
41+
SInstancedPC ipc;
42+
};
43+
#ifdef __HLSL_VERSION
44+
struct PSInput
45+
{
46+
float32_t4 position : SV_Position;
47+
nointerpolation float32_t4 color : TEXCOORD0;
48+
};
49+
50+
float32_t3 getNDCCubeVertex()
51+
{
52+
float32_t3 v = (hlsl::promote<uint32_t3>(hlsl::glsl::gl_VertexIndex()) >> uint32_t3(0,2,1)) & 0x1u;
53+
return v * float32_t3(2,2,1) + float32_t3(-1,-1,0);
54+
}
55+
#endif
56+
57+
}
58+
}
59+
}
60+
61+
#endif
Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
// Copyright (C) 2018-2026 - DevSH Graphics Programming Sp. z O.O.
2+
// This file is part of the "Nabla Engine".
3+
// For conditions of distribution and use, see copyright notice in nabla.h
4+
5+
#include "nbl/ext/Frustum/builtin/hlsl/common.hlsl"
6+
7+
using namespace nbl::hlsl;
8+
using namespace nbl::ext::frustum;
9+
// Push constants
10+
[[vk::push_constant]] PushConstants pc;
11+
12+
[shader("vertex")]
13+
PSInput frustum_vertex_single()
14+
{
15+
PSInput output;
16+
float32_t3 vertex = getNDCCubeVertex();
17+
18+
output.position = math::linalg::promoted_mul(pc.spc.instance.transform, vertex);
19+
output.color = pc.spc.instance.color;
20+
21+
return output;
22+
}
23+
// Vertex shader - batch mode (instanced)
24+
[shader("vertex")]
25+
PSInput frustum_vertex_instances()
26+
{
27+
PSInput output;
28+
const float32_t3 vertex = getNDCCubeVertex();
29+
InstanceData instance = vk::BufferPointer<InstanceData>(pc.ipc.pInstanceBuffer + sizeof(InstanceData) * glsl::gl_InstanceIndex()).Get();
30+
31+
output.position = math::linalg::promoted_mul(instance.transform, vertex);
32+
output.color = instance.color;
33+
34+
return output;
35+
}
36+
37+
[shader("pixel")]
38+
float32_t4 frustum_fragment(PSInput input) : SV_TARGET
39+
{
40+
float32_t4 outColor = input.color;
41+
42+
return outColor;
43+
}

src/nbl/ext/CMakeLists.txt

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -66,6 +66,16 @@ if(NBL_BUILD_DEBUG_DRAW)
6666
)
6767
endif()
6868

69+
add_subdirectory(frustum)
70+
set(NBL_EXT_FRUSTUM_INCLUDE_DIRS
71+
${NBL_EXT_FRUSTUM_INCLUDE_DIRS}
72+
PARENT_SCOPE
73+
)
74+
set(NBL_EXT_FRUSTUM_LIB
75+
${NBL_EXT_FRUSTUM_LIB}
76+
PARENT_SCOPE
77+
)
78+
6979
add_subdirectory(FullScreenTriangle)
7080
set(NBL_EXT_FULL_SCREEN_TRIANGLE_INCLUDE_DIRS
7181
${NBL_EXT_FULL_SCREEN_TRIANGLE_INCLUDE_DIRS}

0 commit comments

Comments
 (0)