@@ -32,14 +32,14 @@ namespace nbl
32
32
- depth buffer is placed under video::EFAP_DEPTH_ATTACHMENT attachment
33
33
*/
34
34
35
- nbl::video::IFrameBuffer* createDefaultFBOForScreenshoting (core::smart_refctd_ptr<IrrlichtDevice> device)
35
+ nbl::video::IFrameBuffer* createDefaultFBOForScreenshoting (core::smart_refctd_ptr<IrrlichtDevice> device, asset::E_FORMAT colorFormat=asset::EF_R8G8B8A8_SRGB )
36
36
{
37
37
auto driver = device->getVideoDriver ();
38
38
39
39
auto createAttachement = [&](bool colorBuffer)
40
40
{
41
41
asset::ICPUImage::SCreationParams imgInfo;
42
- imgInfo.format = colorBuffer ? asset::EF_R8G8B8A8_SRGB : asset::EF_D24_UNORM_S8_UINT;
42
+ imgInfo.format = colorBuffer ? colorFormat: asset::EF_D24_UNORM_S8_UINT;
43
43
imgInfo.type = asset::ICPUImage::ET_2D;
44
44
imgInfo.extent .width = driver->getScreenSize ().Width ;
45
45
imgInfo.extent .height = driver->getScreenSize ().Height ;
@@ -69,7 +69,7 @@ namespace nbl
69
69
70
70
asset::ICPUImageView::SCreationParams imgViewInfo;
71
71
imgViewInfo.image = std::move (image);
72
- imgViewInfo.format = colorBuffer ? asset::EF_R8G8B8A8_SRGB : asset::EF_D24_UNORM_S8_UINT;
72
+ imgViewInfo.format = colorBuffer ? colorFormat: asset::EF_D24_UNORM_S8_UINT;
73
73
imgViewInfo.viewType = asset::IImageView<asset::ICPUImage>::ET_2D;
74
74
imgViewInfo.flags = static_cast <asset::ICPUImageView::E_CREATE_FLAGS>(0u );
75
75
imgViewInfo.subresourceRange .baseArrayLayer = 0u ;
@@ -117,7 +117,7 @@ namespace nbl
117
117
/*
118
118
Create a ScreenShot with gpu image usage and save it to a file.
119
119
*/
120
- bool createScreenShot (video::IVideoDriver* driver, asset::IAssetManager* assetManager, const video::IGPUImageView* gpuImageView, const std::string& outFileName)
120
+ bool createScreenShot (video::IVideoDriver* driver, asset::IAssetManager* assetManager, const video::IGPUImageView* gpuImageView, const std::string& outFileName, asset::E_FORMAT convertToFormat=asset::EF_UNKNOWN )
121
121
{
122
122
auto fetchedImageViewParmas = gpuImageView->getCreationParameters ();
123
123
auto gpuImage = fetchedImageViewParmas.image ;
@@ -153,11 +153,65 @@ namespace nbl
153
153
auto texelBuffer = core::make_smart_refctd_ptr<asset::CCustomAllocatorCPUBuffer<core::null_allocator<uint8_t >>>(memoryRequirements.vulkanReqs .size , destinationBoundMemory->getMappedPointer (), core::adopt_memory);
154
154
155
155
image->setBufferAndRegions (std::move (texelBuffer), regions);
156
- auto newCreationParams = image->getCreationParameters ();
156
+
157
+ while (mapPointerGetterFence->waitCPU (1000ull , mapPointerGetterFence->canDeferredFlush ()) == video::EDFR_TIMEOUT_EXPIRED) {}
158
+
159
+ core::smart_refctd_ptr<asset::ICPUImage> convertedImage;
160
+ if (convertToFormat != asset::EF_UNKNOWN)
161
+ {
162
+ auto referenceImageParams = image->getCreationParameters ();
163
+ auto referenceBuffer = image->getBuffer ();
164
+ auto referenceRegions = image->getRegions ();
165
+ auto referenceRegion = referenceRegions.begin ();
166
+ const auto newTexelOrBlockByteSize = asset::getTexelOrBlockBytesize (convertToFormat);
167
+
168
+ auto newImageParams = referenceImageParams;
169
+ auto newCpuBuffer = core::make_smart_refctd_ptr<asset::ICPUBuffer>(referenceBuffer->getSize () * newTexelOrBlockByteSize);
170
+ auto newRegions = core::make_refctd_dynamic_array<core::smart_refctd_dynamic_array<asset::ICPUImage::SBufferCopy>>(referenceRegions.size ());
171
+
172
+ for (auto newRegion = newRegions->begin (); newRegion != newRegions->end (); ++newRegion)
173
+ {
174
+ *newRegion = *(referenceRegion++);
175
+ newRegion->bufferOffset = newRegion->bufferOffset * newTexelOrBlockByteSize;
176
+ }
177
+
178
+ newImageParams.format = convertToFormat;
179
+ convertedImage = asset::ICPUImage::create (std::move (newImageParams));
180
+ convertedImage->setBufferAndRegions (std::move (newCpuBuffer), newRegions);
181
+
182
+ // asset::CConvertFormatImageFilter TODO: use this one instead with a nice dither @Anastazluk, we could also get rid of a lot of code here, since there's a bunch of constraints
183
+ asset::CSwizzleAndConvertImageFilter<> convertFilter;
184
+ asset::CSwizzleAndConvertImageFilter<>::state_type state;
185
+
186
+ state.swizzle = {};
187
+ state.inImage = image.get ();
188
+ state.outImage = convertedImage.get ();
189
+ state.inOffset = { 0 , 0 , 0 };
190
+ state.inBaseLayer = 0 ;
191
+ state.outOffset = { 0 , 0 , 0 };
192
+ state.outBaseLayer = 0 ;
193
+ // state.dither = ;
194
+
195
+ for (auto itr = 0 ; itr < convertedImage->getCreationParameters ().mipLevels ; ++itr)
196
+ {
197
+ auto regionWithMipMap = convertedImage->getRegions (itr).begin ();
198
+
199
+ state.extent = regionWithMipMap->getExtent ();
200
+ state.layerCount = regionWithMipMap->imageSubresource .layerCount ;
201
+ state.inMipLevel = regionWithMipMap->imageSubresource .mipLevel ;
202
+ state.outMipLevel = regionWithMipMap->imageSubresource .mipLevel ;
203
+
204
+ const bool ok = convertFilter.execute (&state);
205
+ assert (ok);
206
+ }
207
+ }
208
+ else
209
+ convertedImage = image;
210
+ auto newCreationParams = convertedImage->getCreationParameters ();
157
211
158
212
asset::ICPUImageView::SCreationParams viewParams;
159
213
viewParams.flags = static_cast <asset::ICPUImageView::E_CREATE_FLAGS>(0u );
160
- viewParams.image = image ;
214
+ viewParams.image = convertedImage ;
161
215
viewParams.format = newCreationParams.format ;
162
216
viewParams.viewType = asset::ICPUImageView::ET_2D;
163
217
viewParams.subresourceRange .baseArrayLayer = 0u ;
@@ -172,10 +226,8 @@ namespace nbl
172
226
asset::IAssetWriter::SAssetWriteParams wparams (asset);
173
227
return assetManager->writeAsset (outFileName, wparams);
174
228
};
175
-
176
- while (mapPointerGetterFence->waitCPU (1000ull , mapPointerGetterFence->canDeferredFlush ()) == video::EDFR_TIMEOUT_EXPIRED) {}
177
229
178
- bool status = tryToWrite (image .get ());
230
+ bool status = tryToWrite (convertedImage .get ());
179
231
if (!status)
180
232
status = tryToWrite (imageView.get ());
181
233
0 commit comments