Skip to content

Commit 822af13

Browse files
author
kevyuu
committed
Merge branch 'master' into mesh_loaders_kevin
2 parents 83394e4 + 66e486c commit 822af13

File tree

8 files changed

+485
-199
lines changed

8 files changed

+485
-199
lines changed

09_GeometryCreator/main.cpp

Lines changed: 19 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -37,25 +37,32 @@ class GeometryCreatorApp final : public MonoWindowApplication, public BuiltinRes
3737
}
3838

3939
const uint32_t addtionalBufferOwnershipFamilies[] = {getGraphicsQueue()->getFamilyIndex()};
40-
// we want to use the vertex data through UTBs
41-
using usage_f = IGPUBuffer::E_USAGE_FLAGS;
42-
CAssetConverter::patch_t<asset::ICPUPolygonGeometry> patch = {};
43-
patch.positionBufferUsages = usage_f::EUF_UNIFORM_TEXEL_BUFFER_BIT;
44-
patch.indexBufferUsages = usage_f::EUF_INDEX_BUFFER_BIT;
45-
patch.otherBufferUsages = usage_f::EUF_UNIFORM_TEXEL_BUFFER_BIT;
4640
m_scene = CGeometryCreatorScene::create(
4741
{
4842
.transferQueue = getTransferUpQueue(),
4943
.utilities = m_utils.get(),
5044
.logger = m_logger.get(),
5145
.addtionalBufferOwnershipFamilies = addtionalBufferOwnershipFamilies
52-
},patch
46+
},
47+
CSimpleDebugRenderer::DefaultPolygonGeometryPatch // we want to use the vertex data through UTBs
5348
);
5449

5550
auto scRes = static_cast<CDefaultSwapchainFramebuffers*>(m_surface->getSwapchainResources());
56-
m_renderer = CSimpleDebugRenderer::create(m_assetMgr.get(),scRes->getRenderpass(),0,m_scene.get());
57-
if (!m_renderer)
51+
const auto& geometries = m_scene->getInitParams().geometries;
52+
m_renderer = CSimpleDebugRenderer::create(m_assetMgr.get(),scRes->getRenderpass(),0,{&geometries.front().get(),geometries.size()});
53+
if (!m_renderer || m_renderer->getGeometries().size() != geometries.size())
5854
return logFail("Could not create Renderer!");
55+
// special case
56+
{
57+
const auto& pipelines = m_renderer->getInitParams().pipelines;
58+
auto ix = 0u;
59+
for (const auto& name : m_scene->getInitParams().geometryNames)
60+
{
61+
if (name=="Cone")
62+
m_renderer->getGeometry(ix).pipeline = pipelines[CSimpleDebugRenderer::SInitParams::PipelineType::Cone];
63+
ix++;
64+
}
65+
}
5966
m_renderer->m_instances.resize(1);
6067
m_renderer->m_instances[0].world = float32_t3x4(
6168
float32_t4(1,0,0,0),
@@ -143,7 +150,7 @@ class GeometryCreatorApp final : public MonoWindowApplication, public BuiltinRes
143150
const auto viewParams = CSimpleDebugRenderer::SViewParams(viewMatrix,viewProjMatrix);
144151

145152
// tear down scene every frame
146-
m_renderer->m_instances[0].packedGeo = m_renderer->getInitParams().geoms.data()+gcIndex;
153+
m_renderer->m_instances[0].packedGeo = m_renderer->getGeometries().data()+gcIndex;
147154
m_renderer->render(cb,viewParams);
148155

149156
cb->endRenderPass();
@@ -185,7 +192,7 @@ class GeometryCreatorApp final : public MonoWindowApplication, public BuiltinRes
185192
std::string caption = "[Nabla Engine] Geometry Creator";
186193
{
187194
caption += ", displaying [";
188-
caption += m_scene->getGeometries()[gcIndex].name;
195+
caption += m_scene->getInitParams().geometryNames[gcIndex];
189196
caption += "]";
190197
m_window->setCaption(caption);
191198
}
@@ -258,7 +265,7 @@ class GeometryCreatorApp final : public MonoWindowApplication, public BuiltinRes
258265
if (ev.type==nbl::ui::SMouseEvent::EET_SCROLL && m_renderer)
259266
{
260267
gcIndex += int16_t(core::sign(ev.scrollEvent.verticalScroll));
261-
gcIndex = core::clamp(gcIndex,0ull,m_renderer->getInitParams().geoms.size()-1);
268+
gcIndex = core::clamp(gcIndex,0ull,m_renderer->getGeometries().size()-1);
262269
}
263270
}
264271
}

12_MeshLoaders/CMakeLists.txt

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,18 @@
11
set(NBL_INCLUDE_SERACH_DIRECTORIES
22
"${CMAKE_CURRENT_SOURCE_DIR}/include"
33
)
4+
set(NBL_LIBRARIES)
5+
6+
if (NBL_BUILD_MITSUBA_LOADER)
7+
list(APPEND NBL_INCLUDE_SERACH_DIRECTORIES
8+
"${NBL_EXT_MITSUBA_LOADER_INCLUDE_DIRS}"
9+
)
10+
list(APPEND NBL_LIBRARIES
11+
"${NBL_EXT_MITSUBA_LOADER_LIB}"
12+
)
13+
endif()
414

515
# TODO; Arek I removed `NBL_EXECUTABLE_PROJECT_CREATION_PCH_TARGET` from the last parameter here, doesn't this macro have 4 arguments anyway !?
6-
nbl_create_executable_project("" "" "${NBL_INCLUDE_SERACH_DIRECTORIES}" "" "")
16+
nbl_create_executable_project("" "" "${NBL_INCLUDE_SERACH_DIRECTORIES}" "${NBL_LIBRARIES}")
717
# TODO: Arek temporarily disabled cause I haven't figured out how to make this target yet
818
# LINK_BUILTIN_RESOURCES_TO_TARGET(${EXECUTABLE_NAME} nblExamplesGeometrySpirvBRD)

12_MeshLoaders/main.cpp

Lines changed: 188 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,9 @@
55

66
#include "../3rdparty/portable-file-dialogs/portable-file-dialogs.h"
77

8+
#ifdef NBL_BUILD_MITSUBA_LOADER
9+
#include "nbl/ext/MitsubaLoader/CSerializedLoader.h"
10+
#endif
811

912
class MeshLoadersApp final : public MonoWindowApplication, public BuiltinResourcesApplication
1013
{
@@ -14,12 +17,15 @@ class MeshLoadersApp final : public MonoWindowApplication, public BuiltinResourc
1417
public:
1518
inline MeshLoadersApp(const path& _localInputCWD, const path& _localOutputCWD, const path& _sharedInputCWD, const path& _sharedOutputCWD)
1619
: IApplicationFramework(_localInputCWD, _localOutputCWD, _sharedInputCWD, _sharedOutputCWD),
17-
device_base_t({1280,720}, EF_UNKNOWN, _localInputCWD, _localOutputCWD, _sharedInputCWD, _sharedOutputCWD) {}
20+
device_base_t({1280,720}, EF_D32_SFLOAT, _localInputCWD, _localOutputCWD, _sharedInputCWD, _sharedOutputCWD) {}
1821

1922
inline bool onAppInitialized(smart_refctd_ptr<ISystem>&& system) override
2023
{
2124
if (!asset_base_t::onAppInitialized(smart_refctd_ptr(system)))
2225
return false;
26+
#ifdef NBL_BUILD_MITSUBA_LOADER
27+
m_assetMgr->addAssetLoader(make_smart_refctd_ptr<ext::MitsubaLoader::CSerializedLoader>());
28+
#endif
2329
if (!device_base_t::onAppInitialized(smart_refctd_ptr(system)))
2430
return false;
2531

@@ -36,32 +42,15 @@ class MeshLoadersApp final : public MonoWindowApplication, public BuiltinResourc
3642
return logFail("Couldn't create Command Buffer!");
3743
}
3844

39-
//! cache results -- speeds up mesh generation on second run
40-
m_qnc->loadCacheFromFile<EF_R8G8B8_SNORM>(m_system.get(),sharedOutputCWD/"../../tmp/normalCache888.sse");
45+
46+
auto scRes = static_cast<CDefaultSwapchainFramebuffers*>(m_surface->getSwapchainResources());
47+
m_renderer = CSimpleDebugRenderer::create(m_assetMgr.get(),scRes->getRenderpass(),0,{});
48+
if (!m_renderer)
49+
return logFail("Failed to create renderer!");
4150

4251
//
4352
if (!reloadModel())
4453
return false;
45-
#if 0
46-
const uint32_t addtionalBufferOwnershipFamilies[] = {getGraphicsQueue()->getFamilyIndex()};
47-
// we want to use the vertex data through UTBs
48-
using usage_f = IGPUBuffer::E_USAGE_FLAGS;
49-
CAssetConverter::patch_t<asset::ICPUPolygonGeometry> patch = {};
50-
patch.positionBufferUsages = usage_f::EUF_UNIFORM_TEXEL_BUFFER_BIT;
51-
patch.indexBufferUsages = usage_f::EUF_INDEX_BUFFER_BIT;
52-
patch.otherBufferUsages = usage_f::EUF_UNIFORM_TEXEL_BUFFER_BIT;
53-
m_scene = CGeometryCreatorScene::create(
54-
{
55-
.transferQueue = getTransferUpQueue(),
56-
.utilities = m_utils.get(),
57-
.logger = m_logger.get(),
58-
.addtionalBufferOwnershipFamilies = addtionalBufferOwnershipFamilies
59-
},patch
60-
);
61-
#endif
62-
63-
auto scRes = static_cast<CDefaultSwapchainFramebuffers*>(m_surface->getSwapchainResources());
64-
m_renderer = CSimpleDebugRenderer::create(m_assetMgr.get(),scRes->getRenderpass(),0,nullptr);
6554

6655
camera.mapKeysToArrows();
6756

@@ -114,15 +103,21 @@ class MeshLoadersApp final : public MonoWindowApplication, public BuiltinResourc
114103
}
115104
// late latch input
116105
{
106+
bool reload = false;
117107
camera.beginInputProcessing(nextPresentationTimestamp);
118108
mouse.consumeEvents([&](const IMouseEventChannel::range_t& events) -> void { camera.mouseProcess(events); }, m_logger.get());
119109
keyboard.consumeEvents([&](const IKeyboardEventChannel::range_t& events) -> void
120110
{
111+
for (const auto& event : events)
112+
if (event.keyCode==E_KEY_CODE::EKC_R && event.action==SKeyboardEvent::ECA_RELEASED)
113+
reload = true;
121114
camera.keyboardProcess(events);
122115
},
123116
m_logger.get()
124117
);
125118
camera.endInputProcessing(nextPresentationTimestamp);
119+
if (reload)
120+
reloadModel();
126121
}
127122
// draw scene
128123
{
@@ -139,8 +134,6 @@ class MeshLoadersApp final : public MonoWindowApplication, public BuiltinResourc
139134
}
140135
cb->end();
141136

142-
//updateGUIDescriptorSet();
143-
144137
IQueue::SSubmitInfo::SSemaphoreInfo retval =
145138
{
146139
.semaphore = m_semaphore.get(),
@@ -224,37 +217,193 @@ class MeshLoadersApp final : public MonoWindowApplication, public BuiltinResourc
224217
}
225218

226219
private:
227-
inline bool reloadModel()
220+
// TODO: standardise this across examples, and take from `argv`
221+
bool m_nonInteractiveTest = false;
222+
223+
bool reloadModel()
228224
{
229-
pfd::open_file file("Choose a supported Model File", "../../media", { "All Supported Formats", "*.ply *.stl *.serialized *.obj",
230-
"TODO (.ply)", "*.ply",
231-
"TODO (.stl)", "*.stl",
232-
"Mitsuba 0.6 Serialized (.serialized)", "*.serialized",
233-
"Wavefront Object (.obj)", "*.obj"
234-
});
235-
if (file.result().empty())
236-
return false;
237-
m_modelPath = file.result()[0];
225+
if (m_nonInteractiveTest) // TODO: maybe also take from argv and argc
226+
m_modelPath = (sharedInputCWD/"ply/Spanner-ply.ply").string();
227+
else
228+
{
229+
pfd::open_file file("Choose a supported Model File", sharedInputCWD.string(),
230+
{
231+
"All Supported Formats", "*.ply *.stl *.serialized *.obj",
232+
"TODO (.ply)", "*.ply",
233+
"TODO (.stl)", "*.stl",
234+
"Mitsuba 0.6 Serialized (.serialized)", "*.serialized",
235+
"Wavefront Object (.obj)", "*.obj"
236+
},
237+
false
238+
);
239+
if (file.result().empty())
240+
return false;
241+
m_modelPath = file.result()[0];
242+
}
238243

239244
// free up
245+
m_renderer->m_instances.clear();
246+
m_renderer->clearGeometries({.semaphore=m_semaphore.get(),.value=m_realFrameIx});
240247
m_assetMgr->clearAllAssetCache();
241248

242249
//! load the geometry
243250
IAssetLoader::SAssetLoadParams params = {};
244-
params.meshManipulatorOverride = nullptr; // TODO
251+
params.logger = m_logger.get();
245252
auto bundle = m_assetMgr->getAsset(m_modelPath,params);
246253
if (bundle.getContents().empty())
247254
return false;
248-
//! cache results -- speeds up mesh generation on second run
249-
m_qnc->saveCacheToFile<EF_R8G8B8_SNORM>(m_system.get(),sharedOutputCWD/"../../tmp/normalCache888.sse");
255+
256+
//
257+
core::vector<smart_refctd_ptr<const ICPUPolygonGeometry>> geometries;
258+
switch (bundle.getAssetType())
259+
{
260+
case IAsset::E_TYPE::ET_GEOMETRY:
261+
for (const auto& item : bundle.getContents())
262+
if (auto polyGeo=IAsset::castDown<ICPUPolygonGeometry>(item); polyGeo)
263+
geometries.push_back(polyGeo);
264+
break;
265+
default:
266+
m_logger->log("Asset loaded but not a supported type (ET_GEOMETRY,ET_GEOMETRY_COLLECTION)",ILogger::ELL_ERROR);
267+
break;
268+
}
269+
if (geometries.empty())
270+
return false;
271+
272+
using aabb_t = hlsl::shapes::AABB<3,double>;
273+
auto printAABB = [&](const aabb_t& aabb, const char* extraMsg="")->void
274+
{
275+
m_logger->log("%s AABB is (%f,%f,%f) -> (%f,%f,%f)",ILogger::ELL_INFO,extraMsg,aabb.minVx.x,aabb.minVx.y,aabb.minVx.z,aabb.maxVx.x,aabb.maxVx.y,aabb.maxVx.z);
276+
};
277+
auto bound = aabb_t::create();
278+
// convert the geometries
279+
{
280+
smart_refctd_ptr<CAssetConverter> converter = CAssetConverter::create({.device=m_device.get()});
281+
282+
const auto transferFamily = getTransferUpQueue()->getFamilyIndex();
283+
284+
struct SInputs : CAssetConverter::SInputs
285+
{
286+
virtual inline std::span<const uint32_t> getSharedOwnershipQueueFamilies(const size_t groupCopyID, const asset::ICPUBuffer* buffer, const CAssetConverter::patch_t<asset::ICPUBuffer>& patch) const
287+
{
288+
return sharedBufferOwnership;
289+
}
290+
291+
core::vector<uint32_t> sharedBufferOwnership;
292+
} inputs = {};
293+
core::vector<CAssetConverter::patch_t<ICPUPolygonGeometry>> patches(geometries.size(),CSimpleDebugRenderer::DefaultPolygonGeometryPatch);
294+
{
295+
inputs.logger = m_logger.get();
296+
std::get<CAssetConverter::SInputs::asset_span_t<ICPUPolygonGeometry>>(inputs.assets) = {&geometries.front().get(),geometries.size()};
297+
std::get<CAssetConverter::SInputs::patch_span_t<ICPUPolygonGeometry>>(inputs.patches) = patches;
298+
// set up shared ownership so we don't have to
299+
core::unordered_set<uint32_t> families;
300+
families.insert(transferFamily);
301+
families.insert(getGraphicsQueue()->getFamilyIndex());
302+
if (families.size()>1)
303+
for (const auto fam : families)
304+
inputs.sharedBufferOwnership.push_back(fam);
305+
}
306+
307+
// reserve
308+
auto reservation = converter->reserve(inputs);
309+
if (!reservation)
310+
{
311+
m_logger->log("Failed to reserve GPU objects for CPU->GPU conversion!",ILogger::ELL_ERROR);
312+
return false;
313+
}
314+
315+
// convert
316+
{
317+
auto semaphore = m_device->createSemaphore(0u);
318+
319+
constexpr auto MultiBuffering = 2;
320+
std::array<smart_refctd_ptr<IGPUCommandBuffer>,MultiBuffering> commandBuffers = {};
321+
{
322+
auto pool = m_device->createCommandPool(transferFamily,IGPUCommandPool::CREATE_FLAGS::RESET_COMMAND_BUFFER_BIT|IGPUCommandPool::CREATE_FLAGS::TRANSIENT_BIT);
323+
pool->createCommandBuffers(IGPUCommandPool::BUFFER_LEVEL::PRIMARY,commandBuffers,smart_refctd_ptr(m_logger));
324+
}
325+
commandBuffers.front()->begin(IGPUCommandBuffer::USAGE::ONE_TIME_SUBMIT_BIT);
326+
327+
std::array<IQueue::SSubmitInfo::SCommandBufferInfo,MultiBuffering> commandBufferSubmits;
328+
for (auto i=0; i<MultiBuffering; i++)
329+
commandBufferSubmits[i].cmdbuf = commandBuffers[i].get();
330+
331+
SIntendedSubmitInfo transfer = {};
332+
transfer.queue = getTransferUpQueue();
333+
transfer.scratchCommandBuffers = commandBufferSubmits;
334+
transfer.scratchSemaphore = {
335+
.semaphore = semaphore.get(),
336+
.value = 0u,
337+
.stageMask = PIPELINE_STAGE_FLAGS::ALL_TRANSFER_BITS
338+
};
339+
340+
CAssetConverter::SConvertParams cpar = {};
341+
cpar.utilities = m_utils.get();
342+
cpar.transfer = &transfer;
343+
344+
// basically it records all data uploads and submits them right away
345+
auto future = reservation.convert(cpar);
346+
if (future.copy()!=IQueue::RESULT::SUCCESS)
347+
{
348+
m_logger->log("Failed to await submission feature!", ILogger::ELL_ERROR);
349+
return false;
350+
}
351+
}
352+
353+
auto tmp = hlsl::float32_t4x3(
354+
hlsl::float32_t3(1,0,0),
355+
hlsl::float32_t3(0,1,0),
356+
hlsl::float32_t3(0,0,1),
357+
hlsl::float32_t3(0,0,0)
358+
);
359+
core::vector<hlsl::float32_t3x4> worldTforms;
360+
const auto& converted = reservation.getGPUObjects<ICPUPolygonGeometry>();
361+
for (const auto& geom : converted)
362+
{
363+
const auto promoted = geom.value->getAABB<aabb_t>();
364+
printAABB(promoted,"Geometry");
365+
tmp[3].x += promoted.getExtent().x;
366+
const auto promotedWorld = hlsl::float64_t3x4(worldTforms.emplace_back(hlsl::transpose(tmp)));
367+
const auto transformed = hlsl::shapes::util::transform(promotedWorld,promoted);
368+
printAABB(transformed,"Transformed");
369+
bound = hlsl::shapes::util::union_(transformed,bound);
370+
}
371+
printAABB(bound,"Total");
372+
if (!m_renderer->addGeometries({ &converted.front().get(),converted.size() }))
373+
return false;
374+
375+
auto worlTformsIt = worldTforms.begin();
376+
for (const auto& geo : m_renderer->getGeometries())
377+
m_renderer->m_instances.push_back({
378+
.world = *(worlTformsIt++),
379+
.packedGeo = &geo
380+
});
381+
}
382+
383+
// get scene bounds and reset camera
384+
{
385+
const double distance = 0.05;
386+
const auto diagonal = bound.getExtent();
387+
{
388+
const auto measure = hlsl::length(diagonal);
389+
const auto aspectRatio = float(m_window->getWidth())/float(m_window->getHeight());
390+
camera.setProjectionMatrix(core::matrix4SIMD::buildProjectionMatrixPerspectiveFovRH(1.2f,aspectRatio,distance*measure*0.1,measure*4.0));
391+
camera.setMoveSpeed(measure*0.04);
392+
}
393+
const auto pos = bound.maxVx+diagonal*distance;
394+
camera.setPosition(vectorSIMDf(pos.x,pos.y,pos.z));
395+
const auto center = (bound.minVx+bound.maxVx)*0.5;
396+
camera.setTarget(vectorSIMDf(center.x,center.y,center.z));
397+
}
398+
399+
// TODO: write out the geometry
250400

251401
return true;
252402
}
253403

254404
// Maximum frames which can be simultaneously submitted, used to cycle through our per-frame resources like command buffers
255405
constexpr static inline uint32_t MaxFramesInFlight = 3u;
256406
//
257-
smart_refctd_ptr<CQuantNormalCache> m_qnc;
258407
smart_refctd_ptr<CSimpleDebugRenderer> m_renderer;
259408
//
260409
smart_refctd_ptr<ISemaphore> m_semaphore;

0 commit comments

Comments
 (0)