Divide Framework 0.1
A free and open-source 3D Framework under heavy development
Loading...
Searching...
No Matches
Texture.cpp
Go to the documentation of this file.
1
2
3#include "Headers/Texture.h"
4
13
14namespace Divide
15{
16
17 constexpr U16 BYTE_BUFFER_VERSION = 1u;
18
19 [[nodiscard]] bool IsEmpty( const TextureLayoutChanges& changes ) noexcept
20 {
21 for ( const TextureLayoutChange& it : changes )
22 {
23 if ( it._targetView._srcTexture != nullptr &&
24 it._targetLayout != ImageUsage::COUNT &&
25 it._sourceLayout != it._targetLayout )
26 {
27 return false;
28 }
29 }
30
31 return true;
32 }
33
34 Str<64> Texture::s_missingTextureFileName( "missing_texture.jpg" );
35
36 SamplerDescriptor Texture::s_defaultSampler;
37 Handle<Texture> Texture::s_defaultTexture2D = INVALID_HANDLE<Texture>;
38 Handle<Texture> Texture::s_defaultTexture2DArray = INVALID_HANDLE<Texture>;
39 bool Texture::s_useDDSCache = true;
40
42 {
43 ImageTools::OnStartup( gfx.renderAPI() != RenderAPI::OpenGL );
44
45 TextureDescriptor textureDescriptor{};
46 textureDescriptor._dataType = GFXDataFormat::UNSIGNED_BYTE;
47 textureDescriptor._baseFormat = GFXImageFormat::RGBA;
48
49 {
50 s_defaultTexture2D = CreateResource( ResourceDescriptor<Texture>( "defaultEmptyTexture2D", textureDescriptor ) );
51 }
52 {
53 textureDescriptor._texType = TextureType::TEXTURE_2D_ARRAY;
54 s_defaultTexture2DArray = CreateResource( ResourceDescriptor<Texture>( "defaultEmptyTexture2DArray", textureDescriptor ) );
55 }
56
57 Byte defaultTexData[1u * 1u * 4];
58 defaultTexData[0] = defaultTexData[1] = defaultTexData[2] = to_byte( 0u ); //RGB: black
59 defaultTexData[3] = to_byte( 1u ); //Alpha: 1
60
61 ImageTools::ImageData imgDataDefault = {};
62 if ( !imgDataDefault.loadFromMemory( defaultTexData, 4, 1u, 1u, 1u, 4 ) )
63 {
65 }
66 Get(s_defaultTexture2D)->createWithData( imgDataDefault, {});
67 Get(s_defaultTexture2DArray)->createWithData( imgDataDefault, {});
68
76 }
77
78 void Texture::OnShutdown() noexcept
79 {
83 }
84
86 {
87 return s_useDDSCache;
88 }
89
91 {
92 return s_defaultTexture2D;
93 }
94
96 {
98 }
99
101 {
102 return s_defaultSampler;
103 }
104
105 U8 Texture::GetBytesPerPixel( const GFXDataFormat format, const GFXImageFormat baseFormat, const GFXImagePacking packing ) noexcept
106 {
107 if ( packing == GFXImagePacking::RGB_565 || packing == GFXImagePacking::RGBA_4444 )
108 {
109 return 2u;
110 }
111
112 U8 bytesPerChannel = 1u;
113 switch ( format )
114 {
117 case GFXDataFormat::FLOAT_16: bytesPerChannel = 2u; break;
118
121 case GFXDataFormat::FLOAT_32: bytesPerChannel = 4u; break;
122 default: break;
123 };
124
125 return NumChannels( baseFormat ) * bytesPerChannel;
126 }
127
129 : CachedResource( descriptor, "Texture" )
130 , GraphicsResource( context.gfx(), Type::TEXTURE, getGUID(), _ID( resourceName() ) )
131 , _descriptor( descriptor._propertyDescriptor )
132 {
133 DIVIDE_ASSERT( descriptor.enumValue() < to_base( TextureType::COUNT ) );
134 DIVIDE_ASSERT(_descriptor._packing != GFXImagePacking::COUNT &&
135 _descriptor._baseFormat != GFXImageFormat::COUNT &&
136 _descriptor._dataType != GFXDataFormat::COUNT);
137
138 _loadedFromFile = !descriptor.assetName().empty();
139
140 if ( _loadedFromFile )
141 {
142 if ( assetLocation().empty() )
143 {
144 assetLocation( Paths::g_texturesLocation );
145 }
146
147 DIVIDE_ASSERT( assetLocation().string().find(',' ) == string::npos, "TextureLoaderImpl error: All textures for a single array must be loaded from the same location!" );
148
149 const bool isCubeMap = IsCubeTexture( _descriptor._texType );
150
151 const U16 numCommas = to_U16( std::count( std::cbegin( descriptor.assetName() ), std::cend( descriptor.assetName() ), ',' ) );
152 if ( numCommas > 0u )
153 {
154 const U16 targetLayers = numCommas + 1u;
155
156 if ( isCubeMap )
157 {
158 // Each layer needs 6 images
159 DIVIDE_ASSERT( targetLayers >= 6u && targetLayers % 6u == 0u, "TextureLoaderImpl error: Invalid number of source textures specified for cube map!" );
160
161 if ( _descriptor._layerCount == 0u )
162 {
163 _descriptor._layerCount = targetLayers % 6;
164 }
165
166 DIVIDE_ASSERT( _descriptor._layerCount == targetLayers % 6 );
167
168 // We only use cube arrays to simplify some logic in the texturing code
169 if ( _descriptor._texType == TextureType::TEXTURE_CUBE_MAP )
170 {
171 _descriptor._texType = TextureType::TEXTURE_CUBE_ARRAY;
172 }
173 }
174 else
175 {
176 if ( _descriptor._layerCount == 0u )
177 {
178 _descriptor._layerCount = targetLayers;
179 }
180
181 DIVIDE_ASSERT( _descriptor._layerCount == targetLayers, "TextureLoaderImpl error: Invalid number of source textures specified for texture array!" );
182 }
183 }
184
185 }
186
187 if ( _descriptor._layerCount == 0u )
188 {
189 _descriptor._layerCount = 1u;
190 }
191
192 }
193
195 {
196 }
197
199 {
200 if (!loadInternal())
201 {
202 Console::errorfn( LOCALE_STR( "ERROR_TEXTURE_LOADER_FILE" ),
203 assetLocation(),
204 assetName(),
205 resourceName() );
206 return false;
207 }
208
210 }
211
213 {
215 }
216
219 {
221
222 if ( _loadedFromFile )
223 {
224 const GFXDataFormat requestedFormat = _descriptor._dataType;
225 assert( requestedFormat == GFXDataFormat::UNSIGNED_BYTE || // Regular image format
226 requestedFormat == GFXDataFormat::UNSIGNED_SHORT || // 16Bit
227 requestedFormat == GFXDataFormat::FLOAT_16 || // 16Bit
228 requestedFormat == GFXDataFormat::FLOAT_32 || // HDR
229 requestedFormat == GFXDataFormat::COUNT ); // Auto
230
231 // Each texture face/layer must be in a comma separated list
232 istringstream textureFileList( assetName().c_str() );
233
234 ImageTools::ImageData dataStorage = {};
235 dataStorage.requestedFormat( requestedFormat );
236
237 bool hasValidEntries = false;
238 // We loop over every texture in the above list and store it in this temporary string
239 const ResourcePath currentTextureFullPath = assetLocation().empty() ? Paths::g_texturesLocation : assetLocation();
240
241 string currentTextureFile;
242 while ( Util::GetLine( textureFileList, currentTextureFile, ',' ) )
243 {
244 // Skip invalid entries
245 if ( currentTextureFile.empty() )
246 {
247 continue;
248 }
249
250 // Attempt to load the current entry
251 if ( !loadFile( currentTextureFullPath, Util::Trim(currentTextureFile), dataStorage ) )
252 {
253 // Invalid texture files are not handled yet, so stop loading
254 continue;
255 }
256
257 hasValidEntries = true;
258 }
259
260 if ( hasValidEntries )
261 {
262 // Create a new Rendering API-dependent texture object
263 _descriptor._baseFormat = dataStorage.format();
264 _descriptor._dataType = dataStorage.dataType();
265 // Uploading to the GPU dependents on the rendering API
266 createWithData( dataStorage, {});
267
268 if ( IsCubeTexture( _descriptor._texType ) && ( dataStorage.layerCount() % 6 != 0 || dataStorage.layerCount() / 6 != depth()) )
269 {
270 Console::errorfn( LOCALE_STR( "ERROR_TEXTURE_LOADER_CUBMAP_INIT_COUNT" ), resourceName().c_str() );
271 }
272 else if ( IsArrayTexture( _descriptor._texType ) && !IsCubeTexture( _descriptor._texType ) && dataStorage.layerCount() != depth() )
273 {
274 Console::errorfn( LOCALE_STR( "ERROR_TEXTURE_LOADER_ARRAY_INIT_COUNT" ), resourceName().c_str() );
275 }
276 }
277 }
278
279 return true;
280 }
281
282 U8 Texture::numChannels() const noexcept
283 {
284 switch ( _descriptor._baseFormat )
285 {
286 case GFXImageFormat::RED: return 1u;
287 case GFXImageFormat::RG: return 2u;
288 case GFXImageFormat::RGB: return 3u;
289 case GFXImageFormat::RGBA: return 4u;
290 default: break;
291 }
292
293 return 0u;
294 }
295
296 bool Texture::loadFile( const ResourcePath& path, const std::string_view name, ImageTools::ImageData& fileData )
297 {
298 const bool srgb = _descriptor._packing == GFXImagePacking::NORMALIZED_SRGB;
299
300
301 if ( !fileExists( path / name ) || !fileData.loadFromFile( _context.context(), srgb, _width, _height, path, name, _descriptor._textureOptions ) )
302 {
303 if ( fileData.layerCount() > 0 )
304 {
305 Console::errorfn( LOCALE_STR( "ERROR_TEXTURE_LAYER_LOAD" ), name );
306 return false;
307 }
308
309 Console::errorfn( LOCALE_STR( "ERROR_TEXTURE_LOAD" ), name );
310 // missing_texture.jpg must be something that really stands out
311 if ( !fileData.loadFromFile( _context.context(), srgb, _width, _height, Paths::g_texturesLocation, s_missingTextureFileName ) )
312 {
314 }
315 }
316 else
317 {
318 return checkTransparency( path, name, fileData );
319 }
320
321 return true;
322 }
323
324 void Texture::prepareTextureData( const U16 width, const U16 height, const U16 depth, [[maybe_unused]] const bool emptyAllocation )
325 {
326 _width = width;
327 _height = height;
328 _depth = depth;
329 DIVIDE_ASSERT( _width > 0 && _height > 0 && _depth > 0, "Texture error: Invalid texture dimensions!" );
330
332 }
333
334 void Texture::createWithData( const Byte* data, size_t dataSize, const vec2<U16>& dimensions, const PixelAlignment& pixelUnpackAlignment )
335 {
336 createWithData(data, dataSize, vec3<U16>{dimensions.width, dimensions.height, _descriptor._layerCount}, pixelUnpackAlignment);
337 }
338
340 {
341 NOP();
342 }
343
344 void Texture::createWithData( const Byte* data, const size_t dataSize, const vec3<U16>& dimensions, const PixelAlignment& pixelUnpackAlignment )
345 {
347
348 // This should never be called for compressed textures
349 DIVIDE_ASSERT( !IsCompressed( _descriptor._baseFormat ) );
350
351 const U16 slices = IsCubeTexture( _descriptor._texType ) ? dimensions.depth * 6u : dimensions.depth;
352
353 const bool emptyAllocation = dataSize == 0u || data == nullptr;
354 prepareTextureData( dimensions.width, dimensions.height, slices, emptyAllocation );
355
356 // We can't manually specify data for msaa textures.
357 DIVIDE_ASSERT( _descriptor._msaaSamples == 0u || data == nullptr );
358
359 if ( !emptyAllocation )
360 {
361 ImageTools::ImageData imgData{};
362 if ( imgData.loadFromMemory( data, dataSize, dimensions.width, dimensions.height, 1, GetBytesPerPixel( _descriptor._dataType, _descriptor._baseFormat, _descriptor._packing ) ) )
363 {
364 loadDataInternal( imgData, vec3<U16>(0u), pixelUnpackAlignment);
365 }
366 }
367
369 }
370
371 void Texture::replaceData( const Byte* data, const size_t dataSize, const vec3<U16>& offset, const vec3<U16>& range, const PixelAlignment& pixelUnpackAlignment )
372 {
374
375 if ( data == nullptr || dataSize == 0u )
376 {
377 return;
378 }
379
380 if ( offset.x == 0u && offset.y == 0u && offset.z == 0u && (range.x > _width || range.y > _height || range.z > _depth) )
381 {
382 createWithData(data, dataSize, range, pixelUnpackAlignment);
383 }
384 else
385 {
386 DIVIDE_ASSERT( offset.width + range.width <= _width &&
387 offset.height + range.height <= _height &&
388 offset.depth + range.depth <= _depth);
389
390 loadDataInternal( data, dataSize, 0u, offset, range, pixelUnpackAlignment );
391 }
392 }
393
394 void Texture::createWithData( const ImageTools::ImageData& imageData, const PixelAlignment& pixelUnpackAlignment )
395 {
397
398 U16 slices = imageData.layerCount();
399 if ( IsCubeTexture( _descriptor._texType ) )
400 {
401 DIVIDE_ASSERT(slices >= 6u && slices % 6u == 0u);
402 slices = slices / 6u;
403 }
404 else if ( Is3DTexture( _descriptor._texType ) )
405 {
406 slices = imageData.dimensions( 0u, 0u ).depth;
407 }
408
409 prepareTextureData( imageData.dimensions( 0u, 0u ).width, imageData.dimensions( 0u, 0u ).height, slices, false );
410
411 if ( IsCompressed( _descriptor._baseFormat ) &&
412 _descriptor._mipMappingState == MipMappingState::AUTO )
413 {
414 _descriptor._mipMappingState = MipMappingState::MANUAL;
415 }
416
417 loadDataInternal( imageData, vec3<U16>(0u), pixelUnpackAlignment);
418
420 }
421
422 bool Texture::checkTransparency( const ResourcePath& path, const std::string_view name, ImageTools::ImageData& fileData )
423 {
425
426 if ( fileData.ignoreAlphaChannelTransparency() || fileData.hasDummyAlphaChannel() )
427 {
428 _hasTransparency = false;
429 _hasTranslucency = false;
430 return true;
431 }
432
433 const U32 layer = to_U32( fileData.layerCount() - 1 );
434
435 // Extract width, height and bit depth
436 const U16 width = fileData.dimensions( layer, 0u ).width;
437 const U16 height = fileData.dimensions( layer, 0u ).height;
438 // If we have an alpha channel, we must check for translucency/transparency
439
440 const ResourcePath cachePath = Paths::Textures::g_metadataLocation / path;
441 const string cacheName = string(name) + ".cache";
442
443 ByteBuffer metadataCache;
444 bool skip = false;
445 if ( metadataCache.loadFromFile( cachePath, cacheName ) )
446 {
447 auto tempVer = decltype(BYTE_BUFFER_VERSION){0};
448 metadataCache >> tempVer;
449 if ( tempVer == BYTE_BUFFER_VERSION )
450 {
451 metadataCache >> _hasTransparency;
452 metadataCache >> _hasTranslucency;
453 skip = true;
454 }
455 else
456 {
457 metadataCache.clear();
458 }
459 }
460
461 if ( !skip )
462 {
463 if ( HasAlphaChannel( fileData.format() ) )
464 {
465 bool hasTransulenctOrOpaquePixels = false;
466 // Allow about 4 pixels per partition to be ignored
467 constexpr U32 transparentPixelsSkipCount = 4u;
468
469 std::atomic_uint transparentPixelCount = 0u;
470
471 ParallelForDescriptor descriptor = {};
472 descriptor._iterCount = width;
473 descriptor._partitionSize = std::max( 16u, to_U32( width / 10 ) );
474 descriptor._useCurrentThread = true;
475 Parallel_For( _context.context().taskPool( TaskPoolType::HIGH_PRIORITY ), descriptor, [&]( const Task* /*parent*/, const U32 start, const U32 end )
476 {
477 U8 tempA = 0u;
478 for ( U32 i = start; i < end; ++i )
479 {
480 for ( I32 j = 0; j < height; ++j )
481 {
482 if ( _hasTransparency && (_hasTranslucency || hasTransulenctOrOpaquePixels) )
483 {
484 return;
485 }
486 fileData.getAlpha( i, j, tempA, layer );
487 if ( IS_IN_RANGE_INCLUSIVE( tempA, 0, 250 ) )
488 {
489 if ( transparentPixelCount.fetch_add( 1u ) >= transparentPixelsSkipCount )
490 {
491 _hasTransparency = true;
492 _hasTranslucency = tempA > 1;
493 if ( _hasTranslucency )
494 {
495 hasTransulenctOrOpaquePixels = true;
496 return;
497 }
498 }
499 }
500 else if ( tempA > 250 )
501 {
502 hasTransulenctOrOpaquePixels = true;
503 }
504 }
505 }
506 });
507 if ( _hasTransparency && !_hasTranslucency && !hasTransulenctOrOpaquePixels )
508 {
509 // All the alpha values are 0, so this channel is useless.
510 _hasTransparency = _hasTranslucency = false;
511 }
512
513 metadataCache << BYTE_BUFFER_VERSION;
514 metadataCache << _hasTransparency;
515 metadataCache << _hasTranslucency;
516 if ( !metadataCache.dumpToFile( cachePath, cacheName ) )
517 {
519 }
520 }
521 }
522
523 Console::printfn( LOCALE_STR( "TEXTURE_HAS_TRANSPARENCY_TRANSLUCENCY" ),
524 name,
525 _hasTransparency ? "yes" : "no",
526 _hasTranslucency ? "yes" : "no" );
527
528 return true;
529 }
530
531 void Texture::setSampleCount( U8 newSampleCount )
532 {
533 CLAMP( newSampleCount, U8_ZERO, DisplayManager::MaxMSAASamples() );
534 if ( _descriptor._msaaSamples != newSampleCount )
535 {
536 _descriptor._msaaSamples = newSampleCount;
537 createWithData( nullptr, 0u, { width(), height(), depth() }, {});
538 }
539 }
540
541 void Texture::validateDescriptor()
542 {
543 if ( _descriptor._packing == GFXImagePacking::NORMALIZED_SRGB )
544 {
545 bool valid = false;
546 switch ( _descriptor._baseFormat )
547 {
548 case GFXImageFormat::RGB:
549 case GFXImageFormat::BGR:
550 case GFXImageFormat::RGBA:
551 case GFXImageFormat::BGRA:
552 case GFXImageFormat::BC1:
553 case GFXImageFormat::BC1a:
554 case GFXImageFormat::BC2:
555 case GFXImageFormat::BC3:
556 case GFXImageFormat::BC7:
557 {
558 valid = _descriptor._dataType == GFXDataFormat::UNSIGNED_BYTE;
559 } break;
560
561 case GFXImageFormat::RED:
562 case GFXImageFormat::RG:
563 case GFXImageFormat::BC3n:
564 case GFXImageFormat::BC4s:
565 case GFXImageFormat::BC4u:
566 case GFXImageFormat::BC5s:
567 case GFXImageFormat::BC5u:
568 case GFXImageFormat::BC6s:
569 case GFXImageFormat::BC6u: break;
570
571 case GFXImageFormat::COUNT:
572 default: DIVIDE_UNEXPECTED_CALL(); break;
573 }
574
575 DIVIDE_ASSERT(valid, "SRGB textures are only supported for RGB/BGR(A) normalized formats!" );
576 }
577 else if ( IsDepthTexture( _descriptor._packing) )
578 {
579 DIVIDE_ASSERT( _descriptor._baseFormat == GFXImageFormat::RED, "Depth textures only supported for single channel formats");
580 }
581
582 // We may have a 1D texture
583 DIVIDE_ASSERT( _width > 0u && _height > 0u );
584 {
585 //http://www.opengl.org/registry/specs/ARB/texture_non_power_of_two.txt
586 if ( _descriptor._mipMappingState != MipMappingState::OFF )
587 {
588 _mipCount = to_U16( std::floorf( std::log2f( std::fmaxf( to_F32( _width ), to_F32( _height ) ) ) ) ) + 1;
589 }
590 else
591 {
592 _mipCount = 1u;
593 }
594 }
595 }
596
597 ImageView Texture::getView() const noexcept
598 {
599 const U16 layerCount = _descriptor._texType == TextureType::TEXTURE_3D ? 1u : _depth;
600
601 ImageView view{};
602 view._srcTexture = this;
603 view._descriptor._msaaSamples = _descriptor._msaaSamples;
604 view._descriptor._dataType = _descriptor._dataType;
605 view._descriptor._baseFormat = _descriptor._baseFormat;
606 view._descriptor._packing = _descriptor._packing;
607 view._subRange._layerRange._count = layerCount;
608 view._subRange._mipLevels._count = _mipCount;
609
610 return view;
611 }
612
613 ImageView Texture::getView( const TextureType targetType ) const noexcept
614 {
615 ImageView ret = getView();
616 ret._targetType = targetType;
617 return ret;
618 }
619
620 ImageView Texture::getView( const SubRange mipRange ) const noexcept
621 {
622 ImageView ret = getView();
623 ret._subRange._mipLevels = { mipRange._offset, std::min( mipRange._count, ret._subRange._mipLevels._count) };
624 return ret;
625 }
626
627 ImageView Texture::getView( const SubRange mipRange, const SubRange layerRange ) const noexcept
628 {
629 ImageView ret = getView( mipRange );
630 ret._subRange._layerRange = { layerRange._offset, std::min(layerRange._count, ret._subRange._layerRange._count) };
631 return ret;
632 }
633
634 ImageView Texture::getView( const TextureType targetType, const SubRange mipRange ) const noexcept
635 {
636 ImageView ret = getView( targetType );
637 ret._subRange._mipLevels = { mipRange._offset, std::min( mipRange._count, ret._subRange._mipLevels._count ) };
638 return ret;
639 }
640
641 ImageView Texture::getView( const TextureType targetType, const SubRange mipRange, const SubRange layerRange ) const noexcept
642 {
643 ImageView ret = getView( targetType, mipRange );
644 ret._subRange._layerRange = { layerRange._offset, std::min( layerRange._count, ret._subRange._layerRange._count ) };
645 return ret;
646 }
647};
#define LOCALE_STR(X)
Definition: Localization.h:91
#define DIVIDE_ASSERT(...)
#define DIVIDE_UNEXPECTED_CALL()
#define NOP()
#define PROFILE_SCOPE_AUTO(CATEGORY)
Definition: Profiler.h:87
bool loadFromFile(const ResourcePath &path, std::string_view fileName, const U8 version=BUFFER_FORMAT_VERSION)
Definition: ByteBuffer.cpp:57
void clear() noexcept
Resets the entire storage and the read and write positions.
Definition: ByteBuffer.cpp:28
bool dumpToFile(const ResourcePath &path, std::string_view fileName, const U8 version=BUFFER_FORMAT_VERSION)
Saves the entire buffer contents to file. Always appends the version at the end of the file.
Definition: ByteBuffer.cpp:47
virtual bool postLoad()
Definition: Resource.cpp:60
virtual bool load(PlatformContext &context)
Loading and unloading interface.
Definition: Resource.cpp:55
Rough around the edges Adapter pattern abstracting the actual rendering API and access to the GPU.
Definition: GFXDevice.h:215
GFXDevice & context() const noexcept
PlatformContext & context() noexcept
TaskPool & taskPool(const TaskPoolType type) noexcept
virtual void submitTextureData()
Definition: Texture.cpp:339
bool checkTransparency(const ResourcePath &path, std::string_view name, ImageTools::ImageData &fileData)
Definition: Texture.cpp:422
Texture(PlatformContext &context, const ResourceDescriptor< Texture > &descriptor)
Definition: Texture.cpp:128
static void OnShutdown() noexcept
Definition: Texture.cpp:78
bool loadInternal()
Load texture data using the specified file name.
Definition: Texture.cpp:218
static Handle< Texture > DefaultTexture2DArray() noexcept
Definition: Texture.cpp:95
bool load(PlatformContext &context) override
Loading and unloading interface.
Definition: Texture.cpp:198
static const SamplerDescriptor DefaultSampler() noexcept
Definition: Texture.cpp:100
virtual void prepareTextureData(U16 width, U16 height, U16 depth, bool emptyAllocation)
Definition: Texture.cpp:324
static SamplerDescriptor s_defaultSampler
Definition: Texture.h:156
U8 numChannels() const noexcept
Definition: Texture.cpp:282
static Handle< Texture > s_defaultTexture2D
Definition: Texture.h:157
static void OnStartup(GFXDevice &gfx)
Definition: Texture.cpp:41
static U8 GetBytesPerPixel(GFXDataFormat format, GFXImageFormat baseFormat, GFXImagePacking packing) noexcept
Definition: Texture.cpp:105
static Str< 64 > s_missingTextureFileName
Definition: Texture.h:159
static Handle< Texture > s_defaultTexture2DArray
Definition: Texture.h:158
void validateDescriptor()
Definition: Texture.cpp:541
static Handle< Texture > DefaultTexture2D() noexcept
Definition: Texture.cpp:90
bool postLoad() override
Definition: Texture.cpp:212
virtual ~Texture() override
Definition: Texture.cpp:194
void createWithData(const ImageTools::ImageData &imageData, const PixelAlignment &pixelUnpackAlignment)
API-dependent loading function that uploads ptr data to the GPU using the specified parameters.
Definition: Texture.cpp:394
static bool UseTextureDDSCache() noexcept
Definition: Texture.cpp:85
static bool s_useDDSCache
Definition: Texture.h:155
bool loadFile(const ResourcePath &path, std::string_view name, ImageTools::ImageData &fileData)
Use STB to load a file into a Texture Object.
Definition: Texture.cpp:296
void replaceData(const Byte *data, size_t dataSize, const vec3< U16 > &offset, const vec3< U16 > &range, const PixelAlignment &pixelUnpackAlignment)
Definition: Texture.cpp:371
virtual void loadDataInternal(const ImageTools::ImageData &imageData, const vec3< U16 > &offset, const PixelAlignment &pixelUnpackAlignment)=0
void OnStartup(bool upperLeftOrigin)
Definition: ImageTools.cpp:186
constexpr Optick::Category::Type Streaming
Definition: Profiler.h:65
constexpr Optick::Category::Type Graphics
Definition: Profiler.h:60
bool GetLine(istringstream &input, T_str &line, char delimiter='\n')
T_str & Trim(T_str &s)
Handle console commands that start with a forward slash.
Definition: AIProcessor.cpp:7
std::byte Byte
constexpr U32 to_U32(const T value)
FORCE_INLINE void DestroyResource(Handle< T > &handle, const bool immediate=false)
constexpr U16 to_U16(const T value)
uint8_t U8
constexpr F32 to_F32(const T value)
bool IsCubeTexture(TextureType texType) noexcept
bool IsArrayTexture(TextureType texType) noexcept
eastl::fixed_vector< TextureLayoutChange, 6, true > TextureLayoutChanges
Definition: Texture.h:77
bool Is3DTexture(TextureType texType) noexcept
constexpr U16 BYTE_BUFFER_VERSION
bool IsDepthTexture(GFXImagePacking packing) noexcept
uint16_t U16
constexpr U64 _ID(const char *const str, const U64 value=val_64_const) noexcept
constexpr Byte to_byte(const T value)
std::basic_istringstream< char, std::char_traits< char >, dvd_allocator< char > > istringstream
Definition: STLString.h:47
FORCE_INLINE Handle< T > CreateResource(const ResourceDescriptor< T > &descriptor, bool &wasInCache, std::atomic_uint &taskCounter)
bool IsEmpty(const BufferLocks &locks) noexcept
Definition: BufferLocks.cpp:8
std::basic_string< char, std::char_traits< char >, dvd_allocator< char > > string
Definition: STLString.h:41
::value constexpr void CLAMP(T &n, T min, T max) noexcept
Clamps value n between min and max.
Definition: MathHelper.inl:114
void Parallel_For(TaskPool &pool, const ParallelForDescriptor &descriptor, const DELEGATE< void, const Task *, U32, U32 > &cbk)
Definition: TaskPool.cpp:428
bool fileExists(const ResourcePath &filePathAndName)
U8 NumChannels(GFXImageFormat format) noexcept
bool IsCompressed(GFXImageFormat format) noexcept
FORCE_INLINE T * Get(const Handle< T > handle)
bool HasAlphaChannel(GFXImageFormat format) noexcept
uint32_t U32
constexpr U8 U8_ZERO
constexpr auto to_base(const Type value) -> Type
float floorf(const float in)
static NO_INLINE void errorfn(const char *format, T &&... args)
static NO_INLINE void printfn(const char *format, T &&... args)
const vec3< U16 > & dimensions(const U32 layer, const U8 mipLevel=0u) const
image width, height and depth
Definition: ImageTools.h:141
GFXDataFormat dataType() const noexcept
Definition: ImageTools.h:159
bool loadFromMemory(const Byte *data, size_t size, U16 width, U16 height, U16 depth, U8 numComponents)
Definition: ImageTools.cpp:206
GFXImageFormat format() const noexcept
the image format as given by STB
Definition: ImageTools.h:157
bool loadFromFile(PlatformContext &context, bool srgb, U16 refWidth, U16 refHeight, const ResourcePath &path, std::string_view name)
creates this image instance from the specified data
Definition: ImageTools.cpp:212
U16 layerCount() const noexcept
get the total number of image layers
Definition: ImageTools.h:151
void requestedFormat(const GFXDataFormat format) noexcept
image origin information
Definition: ImageTools.h:124
TextureType _targetType
ImageSubRange _subRange
const Texture * _srcTexture
U32 _partitionSize
How many elements should we process per async task.
Definition: TaskPool.h:45
bool _useCurrentThread
If true, we'll process a for partition on the calling thread.
Definition: TaskPool.h:51
U32 _iterCount
For loop iteration count.
Definition: TaskPool.h:43
bool empty() const noexcept
TextureFilter _minFilter
Texture filtering mode.
TextureWrap _wrapU
Texture wrap mode (Or S-R-T)
U8 _anisotropyLevel
The value must be in the range [0...255] and is automatically clamped by the max HW supported level.
TextureMipSampling _mipSampling