-
Notifications
You must be signed in to change notification settings - Fork 411
EffectTextureFactory
DirectXTK | Effects |
---|
This is a helper object primarily used by the Model loader implementations to provide sharing of texture resources. This can be used standalone as well, and allows access to any existing textures definitions already loaded.
It uses a simple case-sensitive string-based (wide-character) map for finding effect instances that have already been created by the factory, which avoid duplication of resources in complex models and scenes.
#include <Effects.h>
classDiagram
direction LR
class IEffectTextureFactory{
<<Interface>>
+CreateTexture()
}
class EffectTextureFactory
EffectTextureFactory --> IEffectTextureFactory
The EffectTextureFactory constructor requires a Direct3D 12 device, a ResourceUploadBatch, and will create the required resource heap automatically.
std::unique_ptr<EffectTextureFactory> modelResources;
ResourceUploadBatch resourceUpload(device);
resourceUpload.Begin();
modelResources = std::make_unique<EffectTextureFactory>( device,
resourceUploadBatch,
numberOfDescriptors,
D3D12_DESCRIPTOR_HEAP_FLAG_NONE);
modelResources->CreateTexture(...);
auto uploadResourcesFinished = resourceUpload.End(m_deviceResources->GetCommandQueue());
// Wait for the upload thread to terminate
uploadResourcesFinished.wait();
If you already have created the required heaps, you can provide your own:
states = std::make_unique<CommonStates>(device);
resourceDescriptors = std::make_unique<DescriptorHeap>(device,
Descriptors::Count);
modelResources = std::make_unique<EffectFactory>( device,
resourceUploadBatch,
resourceDescriptors->Heap() );
For exception safety, it is recommended you make use of the C++ RAII pattern and use a std::unique_ptr
or std::shared_ptr
Textures are usually created through the LoadTextures
method of Model, but the factory can also be used directly.
modelResources->CreateTexture( L"mytexture.dds", Descriptors::MyTexture );
When drawing with texture resources, if you used the first constructor that create it's own heap, you must set it:
ID3D12DescriptorHeap* heaps[] = { modelResources->Heap(), states->Heap() };
commandList->SetDescriptorHeaps(static_cast<UINT>(std::size(heaps)), heaps);
Otherwise you need to use the usual method of setting a DescriptorHeap:
ID3D12DescriptorHeap* heaps[] = { resourceDescriptors->Heap(), states->Heap() };
commandList->SetDescriptorHeaps(static_cast<UINT>(std::size(heaps)), heaps);
For most built-in Effects you make use of heap texture samplers, which this code assumes is coming from CommonStates. If using
EffectTextureFactory
withSpriteBatch
and the default static sampler, you could omit setting the states heap.
To provide flexibility, setting the proper descriptor heaps to render with via
SetDescriptorHeaps
is left to the caller. You can create as many heaps as you wish in your application, but remember that you can have only a single texture descriptor heap and a single sampler descriptor heap active at a given time.
The CreateTexture method assumes the name given is the filename. By default, this is a relative path to the current working directory (CWD). To cause the factory to look in a specific directory path, use SetDirectory.
modelResources->SetDirectory( L".\\Assets" );
It will first look in the current working directory for the file, and then look in the specified path given in
SetDirectory
if set.
The EffectTextureFactory is a concrete implementation of the IEffectTextureFactory interface, and provides a default implementation and caching policy. This allows the developer to create their own custom version of the factory by deriving from IEffectTextureFactory, which can be used with Model loaders. This could be used for alternative caching policies, locating textures in packed archives, etc.
You can control the sharing cache with two methods that are implemented for EffectTextureFactory.
This method sets the sharing mode which defaults to true. By setting it to false, CreateTexture will always return a new instance rather than returning a cached instance.
modelResources->SetSharing( false );
This method clears the sharing cache, which might not release all the instances if they are referenced by other objects.
modelResources->ReleaseCache();
-
EnableForceSRGB is used to determine if textures have "force SRGB" set to true for the loaders or not. This defaults to false.
-
EnableAutoGenMips is used to determine if textures have generateMipsIfMissing / generateMips set to true for the loaders or not. This defaults to false. Keep in mind generating mipmaps at runtime will increase load times.
The method GetResource on EffectTextureFactory can be used to obtain the ID3D12Resource
object that's created internally by the texture factory. GetResourceCount returns the total number of ID3D12Resource
objects within the factory.
size_t slot = modelResources->CreateTexture(...);
ComPtr<ID3D12Resource> res;
bool isCubeMap;
modelResources->GetResource(slot, res.GetAddressOf(), &isCubeMap);
Each EffectTextureFactory requires a ResourceUploadBatch so it only supports submitting content from one thread at a time. You can load on multiple threads if you create a separate EffectTextureFactory instance per command-list.
All content and source code for this package are subject to the terms of the MIT License.
This project has adopted the Microsoft Open Source Code of Conduct. For more information see the Code of Conduct FAQ or contact [email protected] with any additional questions or comments.
- Universal Windows Platform apps
- Windows desktop apps
- Windows 11
- Windows 10
- Xbox One
- Xbox Series X|S
- x86
- x64
- ARM64
- Visual Studio 2022
- Visual Studio 2019 (16.11)
- clang/LLVM v12 - v18
- MinGW 12.2, 13.2
- CMake 3.20