13
13
using namespace nbl ;
14
14
using namespace core ;
15
15
16
- // #define NBL_USE_STL_LOADER // Uncomment it to use STL loader, otherwise PLY will be in use
16
+ /*
17
+ Define below to write assets
18
+ */
19
+
20
+ // #define WRITE_ASSETS
17
21
18
22
int main ()
19
23
{
@@ -39,99 +43,118 @@ int main()
39
43
auto * driver = device->getVideoDriver ();
40
44
auto * smgr = device->getSceneManager ();
41
45
42
- auto loadAndGetCpuMesh = [&]() -> std::pair<core::smart_refctd_ptr<asset::ICPUMesh>, const asset::IAssetMetadata*>
46
+ auto loadAndGetCpuMesh = [&](std::string path ) -> std::pair<core::smart_refctd_ptr<asset::ICPUMesh>, const asset::IAssetMetadata*>
43
47
{
44
48
auto * am = device->getAssetManager ();
45
49
auto * fs = am->getFileSystem ();
46
50
47
51
asset::IAssetLoader::SAssetLoadParams lp;
48
52
49
- #ifdef NBL_USE_STL_LOADER
50
- auto meshes_bundle = am->getAsset (" ../../media/extrusionLogo_TEST_fixed.stl" , lp);
51
- #else
52
- auto meshes_bundle = am->getAsset (" ../../media/ply/Industrial_compressor.ply" , lp);
53
- #endif // NBL_USE_STL_LOADER
53
+ auto meshes_bundle = am->getAsset (path, lp);
54
54
55
55
assert (!meshes_bundle.getContents ().empty ());
56
56
57
57
return std::make_pair (core::smart_refctd_ptr_static_cast<asset::ICPUMesh>(meshes_bundle.getContents ().begin ()[0 ]), meshes_bundle.getMetadata ());
58
58
};
59
59
60
- auto & cpuBundleData = loadAndGetCpuMesh ();
61
- core::smart_refctd_ptr<asset::ICPUMesh> cpuMesh = cpuBundleData.first ;
62
- auto metadata = cpuBundleData.second ->selfCast <const asset::CPLYMetadata>();
60
+ auto & cpuBundlePLYData = loadAndGetCpuMesh (" ../../media/ply/Industrial_compressor.ply" );
61
+ auto & cpuBundleSTLData = loadAndGetCpuMesh (" ../../media/extrusionLogo_TEST_fixed.stl" );
63
62
64
- #ifdef NBL_USE_STL_LOADER
65
- // asset::IAssetWriter::SAssetWriteParams wp(cpuMesh.get());
66
- // device->getAssetManager()->writeAsset("TODO.stl", wp);
67
- #else
68
- asset::IAssetWriter::SAssetWriteParams wp (cpuMesh.get ());
69
- device->getAssetManager ()->writeAsset (" IndustrialWriteTest.ply" , wp);
70
- #endif // NBL_USE_STL_LOADER
63
+ core::smart_refctd_ptr<asset::ICPUMesh> cpuMeshPly = cpuBundlePLYData.first ;
64
+ auto metadataPly = cpuBundlePLYData.second ->selfCast <const asset::CPLYMetadata>();
71
65
72
-
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
73
80
74
81
/*
75
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)
76
83
*/
77
84
78
- asset::ICPUMeshBuffer* const firstMeshBuffer = cpuMesh->getMeshBuffers ().begin ()[0 ];
79
- asset::ICPUDescriptorSetLayout* ds1layout = firstMeshBuffer->getPipeline ()->getLayout ()->getDescriptorSetLayout (1u ); // ! DS1
80
- const asset::IRenderpassIndependentPipelineMetadata* pipelineMetadata = metadata->getAssetSpecificMetadata (firstMeshBuffer->getPipeline ());
81
-
82
- /*
83
- So we can create just one DescriptorSet
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*>;
85
86
86
- auto getDS1UboBinding = [&]()
87
+ auto getMeshDependentDrawData = [&](core::smart_refctd_ptr<asset::ICPUMesh> cpuMesh, bool isPLY) -> DependentDrawData
87
88
{
88
- uint32_t ds1UboBinding = 0u ;
89
- for ( const auto & bnd : ds1layout-> getBindings ())
90
- if (bnd. type == asset::EDT_UNIFORM_BUFFER)
91
- {
92
- ds1UboBinding = bnd. binding ;
93
- break ;
94
- }
95
- return ds1UboBinding ;
96
- };
89
+ asset::ICPUMeshBuffer* const firstMeshBuffer = cpuMesh-> getMeshBuffers (). begin ()[ 0 ] ;
90
+ 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
+ }
97
98
98
- const uint32_t ds1UboBinding = getDS1UboBinding ();
99
+ /*
100
+ So we can create just one DescriptorSet
101
+ */
99
102
100
- auto getNeededDS1UboByteSize = [&]()
101
- {
102
- size_t neededDS1UboSize = 0ull ;
103
+ auto getDS1UboBinding = [&]()
103
104
{
104
- for (const auto & shaderInputs : pipelineMetadata->getRequiredShaderInputs ())
105
- if (shaderInputs.descriptorSection .type == asset::IRenderpassIndependentPipelineMetadata::ShaderInput::ET_UNIFORM_BUFFER && shaderInputs.descriptorSection .uniformBufferObject .set == 1u && shaderInputs.descriptorSection .uniformBufferObject .binding == ds1UboBinding)
106
- neededDS1UboSize = std::max<size_t >(neededDS1UboSize, shaderInputs.descriptorSection .uniformBufferObject .relByteoffset + shaderInputs.descriptorSection .uniformBufferObject .bytesize );
107
- }
108
- return neededDS1UboSize;
109
- };
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->getRequiredShaderInputs ())
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
+ };
110
127
111
- const uint64_t uboDS1ByteSize = getNeededDS1UboByteSize ();
128
+ const uint64_t uboDS1ByteSize = getNeededDS1UboByteSize ();
112
129
113
- auto gpuds1layout = driver->getGPUObjectsFromAssets (&ds1layout, &ds1layout + 1 )->front ();
130
+ auto gpuds1layout = driver->getGPUObjectsFromAssets (&ds1layout, &ds1layout + 1 )->front ();
114
131
115
- auto gpuubo = driver->createDeviceLocalGPUBufferOnDedMem (uboDS1ByteSize);
116
- auto gpuds1 = driver->createGPUDescriptorSet (std::move (gpuds1layout));
117
- {
118
- video::IGPUDescriptorSet::SWriteDescriptorSet write;
119
- write.dstSet = gpuds1.get ();
120
- write.binding = ds1UboBinding;
121
- write.count = 1u ;
122
- write.arrayElement = 0u ;
123
- write.descriptorType = asset::EDT_UNIFORM_BUFFER;
124
- video::IGPUDescriptorSet::SDescriptorInfo info;
132
+ auto gpuubo = driver->createDeviceLocalGPUBufferOnDedMem (uboDS1ByteSize);
133
+ auto gpuds1 = driver->createGPUDescriptorSet (std::move (gpuds1layout));
125
134
{
126
- info.desc = gpuubo;
127
- info.buffer .offset = 0ull ;
128
- info.buffer .size = uboDS1ByteSize;
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 );
129
149
}
130
- write.info = &info;
131
- driver->updateDescriptorSets (1u , &write, 0u , nullptr );
132
- }
133
150
134
- auto gpuMesh = driver->getGPUObjectsFromAssets (&cpuMesh.get (), &cpuMesh.get () + 1 )->front ();
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 );
135
158
136
159
scene::ICameraSceneNode* camera = smgr->addCameraSceneNodeFPS (0 , 100 .0f , 0 .5f );
137
160
@@ -150,55 +173,77 @@ int main()
150
173
camera->OnAnimate (std::chrono::duration_cast<std::chrono::milliseconds>(device->getTimer ()->getTime ()).count ());
151
174
camera->render ();
152
175
153
- core::vector<uint8_t > uboData (gpuubo->getSize ());
154
- for (const auto & shaderInputs : pipelineMetadata->getRequiredShaderInputs ())
176
+ const auto viewProjection = camera->getConcatenatedMatrix ();
177
+
178
+ auto renderMesh = [&](DependentDrawData& drawData, uint32_t index)
155
179
{
156
- if (shaderInputs.descriptorSection .type == asset::IRenderpassIndependentPipelineMetadata::ShaderInput::ET_UNIFORM_BUFFER && shaderInputs.descriptorSection .uniformBufferObject .set == 1u && shaderInputs.descriptorSection .uniformBufferObject .binding == ds1UboBinding)
157
- {
158
- switch (shaderInputs.type )
159
- {
160
- case asset::IRenderpassIndependentPipelineMetadata::ECSI_WORLD_VIEW_PROJ:
161
- {
162
- core::matrix4SIMD mvp = camera->getConcatenatedMatrix ();
163
- memcpy (uboData.data () + shaderInputs.descriptorSection .uniformBufferObject .relByteoffset , mvp.pointer (), shaderInputs.descriptorSection .uniformBufferObject .bytesize );
164
- } break ;
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);
165
185
166
- case asset::IRenderpassIndependentPipelineMetadata::ECSI_WORLD_VIEW:
167
- {
168
- core::matrix3x4SIMD MV = camera->getViewMatrix ();
169
- memcpy (uboData.data () + shaderInputs.descriptorSection .uniformBufferObject .relByteoffset , MV.pointer (), shaderInputs.descriptorSection .uniformBufferObject .bytesize );
170
- } break ;
186
+ core::matrix3x4SIMD modelMatrix;
187
+ modelMatrix.setTranslation (nbl::core::vectorSIMDf (index * 5 , 0 , 0 , 0 ));
171
188
172
- case asset::IRenderpassIndependentPipelineMetadata::ECSI_WORLD_VIEW_INVERSE_TRANSPOSE:
189
+ core::matrix4SIMD mvp = core::concatenateBFollowedByA (viewProjection, modelMatrix);
190
+
191
+ core::vector<uint8_t > uboData (gpuubo->getSize ());
192
+ for (const auto & shaderInputs : pipelineMetadata->getRequiredShaderInputs ())
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 )
173
197
{
174
- core::matrix3x4SIMD MV = camera->getViewMatrix ();
175
- memcpy (uboData.data () + shaderInputs.descriptorSection .uniformBufferObject .relByteoffset , MV.pointer (), shaderInputs.descriptorSection .uniformBufferObject .bytesize );
176
- } break ;
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
+ }
177
215
}
178
216
}
179
- }
180
- driver->updateBufferRangeViaStagingBuffer (gpuubo.get (), 0ull , gpuubo->getSize (), uboData.data ());
217
+ driver->updateBufferRangeViaStagingBuffer (gpuubo.get (), 0ull , gpuubo->getSize (), uboData.data ());
181
218
182
- for (auto gpuMeshBuffer : gpuMesh->getMeshBuffers ())
183
- {
184
- const video::IGPURenderpassIndependentPipeline* gpuPipeline = gpuMeshBuffer->getPipeline ();
185
- const video::IGPUDescriptorSet* gpuds3 = gpuMeshBuffer->getAttachedDescriptorSet ();
219
+ for (auto gpuMeshBuffer : gpuMesh->getMeshBuffers ())
220
+ {
221
+ const video::IGPURenderpassIndependentPipeline* gpuPipeline = gpuMeshBuffer->getPipeline ();
222
+ const video::IGPUDescriptorSet* gpuds3 = gpuMeshBuffer->getAttachedDescriptorSet ();
186
223
187
- driver->bindGraphicsPipeline (gpuPipeline);
188
- const video::IGPUDescriptorSet* gpuds1_ptr = gpuds1.get ();
189
- driver->bindDescriptorSets (video::EPBP_GRAPHICS, gpuPipeline->getLayout (), 1u , 1u , &gpuds1_ptr, nullptr );
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 );
190
227
191
- if (gpuds3) // ! Execute if we have a texture attached as DS
192
- driver->bindDescriptorSets (video::EPBP_GRAPHICS, gpuPipeline->getLayout (), 3u , 1u , &gpuds3, nullptr );
193
- driver->pushConstants (gpuPipeline->getLayout (), video::IGPUSpecializedShader::ESS_FRAGMENT, 0u , gpuMeshBuffer->MAX_PUSH_CONSTANT_BYTESIZE , gpuMeshBuffer->getPushConstantsDataPtr ());
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 ());
194
231
195
- driver->drawMeshBuffer (gpuMeshBuffer);
196
- }
232
+ driver->drawMeshBuffer (gpuMeshBuffer);
233
+ }
234
+ };
235
+
236
+ /*
237
+ Render PLY and STL
238
+ */
239
+
240
+ renderMesh (plyDrawData, 0 );
241
+ renderMesh (stlDrawData, 20 );
197
242
198
243
driver->endScene ();
199
244
200
245
/*
201
- display frames per second in window title
246
+ Display frames per second in window title
202
247
*/
203
248
204
249
uint64_t time = device->getTimer ()->getRealTime ();
0 commit comments