Skip to content

Commit 00e89af

Browse files
Merge pull request #66 from AnastaZIuk/loadersFix
STL & PLY
2 parents a3d588d + 29d45f4 commit 00e89af

26 files changed

+893
-1788
lines changed
Lines changed: 261 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,261 @@
1+
// Copyright (C) 2018-2020 - 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+
#define _NBL_STATIC_LIB_
6+
#include <iostream>
7+
#include <cstdio>
8+
#include <nabla.h>
9+
10+
#include "../common/QToQuitEventReceiver.h"
11+
#include "nbl/ext/ScreenShot/ScreenShot.h"
12+
13+
using namespace nbl;
14+
using namespace core;
15+
16+
/*
17+
Define below to write assets
18+
*/
19+
20+
// #define WRITE_ASSETS
21+
22+
int main()
23+
{
24+
nbl::SIrrlichtCreationParameters params;
25+
params.Bits = 24;
26+
params.ZBufferBits = 24;
27+
params.DriverType = video::EDT_OPENGL;
28+
params.WindowSize = dimension2d<uint32_t>(1280, 720);
29+
params.Fullscreen = false;
30+
params.Vsync = true;
31+
params.Doublebuffer = true;
32+
params.Stencilbuffer = false;
33+
auto device = createDeviceEx(params);
34+
35+
if (!device)
36+
return 1;
37+
38+
device->getCursorControl()->setVisible(false);
39+
40+
QToQuitEventReceiver receiver;
41+
device->setEventReceiver(&receiver);
42+
43+
auto* driver = device->getVideoDriver();
44+
auto* smgr = device->getSceneManager();
45+
46+
auto loadAndGetCpuMesh = [&](std::string path) -> std::pair<core::smart_refctd_ptr<asset::ICPUMesh>, const asset::IAssetMetadata*>
47+
{
48+
auto* am = device->getAssetManager();
49+
auto* fs = am->getFileSystem();
50+
51+
asset::IAssetLoader::SAssetLoadParams lp;
52+
53+
auto meshes_bundle = am->getAsset(path, lp);
54+
55+
assert(!meshes_bundle.getContents().empty());
56+
57+
return std::make_pair(core::smart_refctd_ptr_static_cast<asset::ICPUMesh>(meshes_bundle.getContents().begin()[0]), meshes_bundle.getMetadata());
58+
};
59+
60+
auto& cpuBundlePLYData = loadAndGetCpuMesh("../../media/ply/Industrial_compressor.ply");
61+
auto& cpuBundleSTLData = loadAndGetCpuMesh("../../media/extrusionLogo_TEST_fixed.stl");
62+
63+
core::smart_refctd_ptr<asset::ICPUMesh> cpuMeshPly = cpuBundlePLYData.first;
64+
auto metadataPly = cpuBundlePLYData.second->selfCast<const asset::CPLYMetadata>();
65+
66+
core::smart_refctd_ptr<asset::ICPUMesh> cpuMeshStl = cpuBundleSTLData.first;
67+
auto metadataStl = cpuBundleSTLData.second->selfCast<const asset::CSTLMetadata>();
68+
69+
#ifdef WRITE_ASSETS
70+
{
71+
asset::IAssetWriter::SAssetWriteParams wp(cpuMeshStl.get());
72+
device->getAssetManager()->writeAsset("extrusionLogo_TEST_fixedTest.stl", wp);
73+
}
74+
75+
{
76+
asset::IAssetWriter::SAssetWriteParams wp(cpuMeshPly.get());
77+
device->getAssetManager()->writeAsset("IndustrialWriteTest.ply", wp);
78+
}
79+
#endif // WRITE_ASSETS
80+
81+
/*
82+
For the testing puposes we can safely assume all meshbuffers within mesh loaded from PLY & STL has same DS1 layout (used for camera-specific data)
83+
*/
84+
85+
using DependentDrawData = std::tuple<core::smart_refctd_ptr<video::IGPUMesh>, core::smart_refctd_ptr<video::IGPUBuffer>, core::smart_refctd_ptr<video::IGPUDescriptorSet>, uint32_t, const asset::IRenderpassIndependentPipelineMetadata*>;
86+
87+
auto getMeshDependentDrawData = [&](core::smart_refctd_ptr<asset::ICPUMesh> cpuMesh, bool isPLY) -> DependentDrawData
88+
{
89+
const asset::ICPUMeshBuffer* const firstMeshBuffer = cpuMesh->getMeshBuffers().begin()[0];
90+
const asset::ICPUDescriptorSetLayout* ds1layout = firstMeshBuffer->getPipeline()->getLayout()->getDescriptorSetLayout(1u); //! DS1
91+
const asset::IRenderpassIndependentPipelineMetadata* pipelineMetadata;
92+
{
93+
if(isPLY)
94+
pipelineMetadata = metadataPly->getAssetSpecificMetadata(firstMeshBuffer->getPipeline());
95+
else
96+
pipelineMetadata = metadataStl->getAssetSpecificMetadata(firstMeshBuffer->getPipeline());
97+
}
98+
99+
/*
100+
So we can create just one DescriptorSet
101+
*/
102+
103+
auto getDS1UboBinding = [&]()
104+
{
105+
uint32_t ds1UboBinding = 0u;
106+
for (const auto& bnd : ds1layout->getBindings())
107+
if (bnd.type == asset::EDT_UNIFORM_BUFFER)
108+
{
109+
ds1UboBinding = bnd.binding;
110+
break;
111+
}
112+
return ds1UboBinding;
113+
};
114+
115+
const uint32_t ds1UboBinding = getDS1UboBinding();
116+
117+
auto getNeededDS1UboByteSize = [&]()
118+
{
119+
size_t neededDS1UboSize = 0ull;
120+
{
121+
for (const auto& shaderInputs : pipelineMetadata->m_inputSemantics)
122+
if (shaderInputs.descriptorSection.type == asset::IRenderpassIndependentPipelineMetadata::ShaderInput::ET_UNIFORM_BUFFER && shaderInputs.descriptorSection.uniformBufferObject.set == 1u && shaderInputs.descriptorSection.uniformBufferObject.binding == ds1UboBinding)
123+
neededDS1UboSize = std::max<size_t>(neededDS1UboSize, shaderInputs.descriptorSection.uniformBufferObject.relByteoffset + shaderInputs.descriptorSection.uniformBufferObject.bytesize);
124+
}
125+
return neededDS1UboSize;
126+
};
127+
128+
const uint64_t uboDS1ByteSize = getNeededDS1UboByteSize();
129+
130+
auto gpuds1layout = driver->getGPUObjectsFromAssets(&ds1layout, &ds1layout + 1)->front();
131+
132+
auto gpuubo = driver->createDeviceLocalGPUBufferOnDedMem(uboDS1ByteSize);
133+
auto gpuds1 = driver->createGPUDescriptorSet(std::move(gpuds1layout));
134+
{
135+
video::IGPUDescriptorSet::SWriteDescriptorSet write;
136+
write.dstSet = gpuds1.get();
137+
write.binding = ds1UboBinding;
138+
write.count = 1u;
139+
write.arrayElement = 0u;
140+
write.descriptorType = asset::EDT_UNIFORM_BUFFER;
141+
video::IGPUDescriptorSet::SDescriptorInfo info;
142+
{
143+
info.desc = gpuubo;
144+
info.buffer.offset = 0ull;
145+
info.buffer.size = uboDS1ByteSize;
146+
}
147+
write.info = &info;
148+
driver->updateDescriptorSets(1u, &write, 0u, nullptr);
149+
}
150+
151+
auto gpuMesh = driver->getGPUObjectsFromAssets(&cpuMesh.get(), &cpuMesh.get() + 1)->front();
152+
153+
return std::make_tuple(gpuMesh, gpuubo, gpuds1, ds1UboBinding, pipelineMetadata);
154+
};
155+
156+
auto& plyDrawData = getMeshDependentDrawData(cpuMeshPly, true);
157+
auto& stlDrawData = getMeshDependentDrawData(cpuMeshStl, false);
158+
159+
scene::ICameraSceneNode* camera = smgr->addCameraSceneNodeFPS(0, 100.0f, 0.5f);
160+
161+
camera->setPosition(core::vector3df(-4, 0, 0));
162+
camera->setTarget(core::vector3df(0, 0, 0));
163+
camera->setNearValue(1.f);
164+
camera->setFarValue(5000.0f);
165+
166+
smgr->setActiveCamera(camera);
167+
168+
uint64_t lastFPSTime = 0;
169+
while (device->run() && receiver.keepOpen())
170+
{
171+
driver->beginScene(true, true, video::SColor(255, 255, 255, 255));
172+
173+
camera->OnAnimate(std::chrono::duration_cast<std::chrono::milliseconds>(device->getTimer()->getTime()).count());
174+
camera->render();
175+
176+
const auto viewProjection = camera->getConcatenatedMatrix();
177+
178+
auto renderMesh = [&](DependentDrawData& drawData, uint32_t index)
179+
{
180+
core::smart_refctd_ptr<video::IGPUMesh> gpuMesh = std::get<0>(drawData);
181+
core::smart_refctd_ptr<video::IGPUBuffer> gpuubo = std::get<1>(drawData);
182+
core::smart_refctd_ptr<video::IGPUDescriptorSet> gpuds1 = std::get<2>(drawData);
183+
uint32_t ds1UboBinding = std::get<3>(drawData);
184+
const asset::IRenderpassIndependentPipelineMetadata* pipelineMetadata = std::get<4>(drawData);
185+
186+
core::matrix3x4SIMD modelMatrix;
187+
modelMatrix.setTranslation(nbl::core::vectorSIMDf(index * 5, 0, 0, 0));
188+
189+
core::matrix4SIMD mvp = core::concatenateBFollowedByA(viewProjection, modelMatrix);
190+
191+
core::vector<uint8_t> uboData(gpuubo->getSize());
192+
for (const auto& shaderInputs : pipelineMetadata->m_inputSemantics)
193+
{
194+
if (shaderInputs.descriptorSection.type == asset::IRenderpassIndependentPipelineMetadata::ShaderInput::ET_UNIFORM_BUFFER && shaderInputs.descriptorSection.uniformBufferObject.set == 1u && shaderInputs.descriptorSection.uniformBufferObject.binding == ds1UboBinding)
195+
{
196+
switch (shaderInputs.type)
197+
{
198+
case asset::IRenderpassIndependentPipelineMetadata::ECSI_WORLD_VIEW_PROJ:
199+
{
200+
memcpy(uboData.data() + shaderInputs.descriptorSection.uniformBufferObject.relByteoffset, mvp.pointer(), shaderInputs.descriptorSection.uniformBufferObject.bytesize);
201+
} break;
202+
203+
case asset::IRenderpassIndependentPipelineMetadata::ECSI_WORLD_VIEW:
204+
{
205+
core::matrix3x4SIMD MV = camera->getViewMatrix();
206+
memcpy(uboData.data() + shaderInputs.descriptorSection.uniformBufferObject.relByteoffset, MV.pointer(), shaderInputs.descriptorSection.uniformBufferObject.bytesize);
207+
} break;
208+
209+
case asset::IRenderpassIndependentPipelineMetadata::ECSI_WORLD_VIEW_INVERSE_TRANSPOSE:
210+
{
211+
core::matrix3x4SIMD MV = camera->getViewMatrix();
212+
memcpy(uboData.data() + shaderInputs.descriptorSection.uniformBufferObject.relByteoffset, MV.pointer(), shaderInputs.descriptorSection.uniformBufferObject.bytesize);
213+
} break;
214+
}
215+
}
216+
}
217+
driver->updateBufferRangeViaStagingBuffer(gpuubo.get(), 0ull, gpuubo->getSize(), uboData.data());
218+
219+
for (auto gpuMeshBuffer : gpuMesh->getMeshBuffers())
220+
{
221+
const video::IGPURenderpassIndependentPipeline* gpuPipeline = gpuMeshBuffer->getPipeline();
222+
const video::IGPUDescriptorSet* gpuds3 = gpuMeshBuffer->getAttachedDescriptorSet();
223+
224+
driver->bindGraphicsPipeline(gpuPipeline);
225+
const video::IGPUDescriptorSet* gpuds1_ptr = gpuds1.get();
226+
driver->bindDescriptorSets(video::EPBP_GRAPHICS, gpuPipeline->getLayout(), 1u, 1u, &gpuds1_ptr, nullptr);
227+
228+
if (gpuds3) //! Execute if we have a texture attached as DS
229+
driver->bindDescriptorSets(video::EPBP_GRAPHICS, gpuPipeline->getLayout(), 3u, 1u, &gpuds3, nullptr);
230+
driver->pushConstants(gpuPipeline->getLayout(), video::IGPUSpecializedShader::ESS_FRAGMENT, 0u, gpuMeshBuffer->MAX_PUSH_CONSTANT_BYTESIZE, gpuMeshBuffer->getPushConstantsDataPtr());
231+
232+
driver->drawMeshBuffer(gpuMeshBuffer);
233+
}
234+
};
235+
236+
/*
237+
Render PLY and STL
238+
*/
239+
240+
renderMesh(plyDrawData, 0);
241+
renderMesh(stlDrawData, 20);
242+
243+
driver->endScene();
244+
245+
/*
246+
Display frames per second in window title
247+
*/
248+
249+
uint64_t time = device->getTimer()->getRealTime();
250+
if (time - lastFPSTime > 1000)
251+
{
252+
std::wostringstream str;
253+
str << L"PLY & STL Test Demo - Nabla Engine [" << driver->getName() << "] FPS:" << driver->getFPS() << " PrimitvesDrawn:" << driver->getPrimitiveCountDrawn();
254+
255+
device->setWindowCaption(str.str().c_str());
256+
lastFPSTime = time;
257+
}
258+
}
259+
260+
return 0;
261+
}
-10.5 KB
Binary file not shown.

examples_tests/27.PointCloud/createComputeShader.h

Lines changed: 0 additions & 87 deletions
This file was deleted.

0 commit comments

Comments
 (0)