FSlateShaderResourceProxy* FSlateD3DTextureManager::CreateDynamicTextureResource(FName ResourceName, uint32 Width, uint32 Height, const TArray< uint8 >& RawData) { // Bail out if we already have this texture loaded TSharedPtr<FDynamicTextureResource> TextureResource = DynamicTextureMap.FindRef(ResourceName); if (TextureResource.IsValid()) { return TextureResource->Proxy; } // Keep track of non-atlased textures so we can free their resources later FSlateD3DTexture* LoadedTexture = new FSlateD3DTexture(Width, Height); TextureResource = MakeShareable(new FDynamicTextureResource(LoadedTexture)); D3D11_SUBRESOURCE_DATA InitData; InitData.pSysMem = RawData.GetTypedData(); InitData.SysMemPitch = Width * 4; FNewTextureInfo Info; Info.bShouldAtlas = false; LoadedTexture->Init(Info.bSrgb ? DXGI_FORMAT_R8G8B8A8_UNORM_SRGB : DXGI_FORMAT_R8G8B8A8_UNORM, &InitData); TextureResource->Proxy->ActualSize = FIntPoint(Width, Height); TextureResource->Proxy->Resource = TextureResource->D3DTexture; // Map the new resource for the UTexture so we don't have to load again DynamicTextureMap.Add(ResourceName, TextureResource); return TextureResource->Proxy; }
FSlateUpdatableTexture* FSlateD3DRenderer::CreateUpdatableTexture(uint32 Width, uint32 Height) { FSlateD3DTexture* NewTexture = new FSlateD3DTexture(Width, Height); NewTexture->Init(DXGI_FORMAT_B8G8R8A8_UNORM_SRGB, NULL, D3D11_USAGE_DYNAMIC, D3D11_CPU_ACCESS_WRITE); return NewTexture; }
FSlateShaderResourceProxy* FSlateD3DTextureManager::GenerateTextureResource( const FNewTextureInfo& Info ) { FSlateShaderResourceProxy* NewProxy = NULL; const uint32 Width = Info.TextureData->GetWidth(); const uint32 Height = Info.TextureData->GetHeight(); if( Info.bShouldAtlas ) { const uint32 AtlasSize = 1024; // 4 bytes per pixel const uint32 AtlasStride = sizeof(uint8)*4; const uint8 Padding = 1; const FAtlasedTextureSlot* NewSlot = NULL; FSlateTextureAtlasD3D* Atlas = NULL; // Get the last atlas and find a slot for the texture for( int32 AtlasIndex = 0; AtlasIndex < TextureAtlases.Num(); ++AtlasIndex ) { Atlas = TextureAtlases[AtlasIndex]; NewSlot = Atlas->AddTexture( Width, Height, Info.TextureData->GetRawBytes() ); if( NewSlot ) { break; } } // No new slot was found in any atlas so we have to make another one if( !NewSlot ) { // A new slot in the atlas could not be found, make a new atlas and add the texture to it Atlas = new FSlateTextureAtlasD3D( AtlasSize, AtlasSize, AtlasStride, Padding ); TextureAtlases.Add( Atlas ); NewSlot = TextureAtlases.Last()->AddTexture( Width, Height, Info.TextureData->GetRawBytes() ); } check( Atlas && NewSlot ); // Create a proxy representing this texture in the atlas NewProxy = new FSlateShaderResourceProxy; NewProxy->Resource = Atlas->GetAtlasTexture(); // Compute the sub-uvs for the location of this texture in the atlas, accounting for padding NewProxy->StartUV = FVector2D( (float)(NewSlot->X+Padding) / Atlas->GetWidth(), (float)(NewSlot->Y+Padding) / Atlas->GetHeight() ); NewProxy->SizeUV = FVector2D( (float)(NewSlot->Width-Padding*2) / Atlas->GetWidth(), (float)(NewSlot->Height-Padding*2) / Atlas->GetHeight() ); NewProxy->ActualSize = FIntPoint( Width, Height ); } else { // The texture is not atlased create a new texture proxy and just point it to the actual texture NewProxy = new FSlateShaderResourceProxy; // Keep track of non-atlased textures so we can free their resources later FSlateD3DTexture* Texture = new FSlateD3DTexture( Width, Height ); NonAtlasedTextures.Add( Texture ); NewProxy->Resource = Texture; NewProxy->StartUV = FVector2D(0.0f,0.0f); NewProxy->SizeUV = FVector2D(1.0f, 1.0f); NewProxy->ActualSize = FIntPoint( Width, Height ); D3D11_SUBRESOURCE_DATA InitData; InitData.pSysMem = Info.TextureData->GetRawBytes().GetTypedData(); InitData.SysMemPitch = Width * 4; Texture->Init( Info.bSrgb ? DXGI_FORMAT_R8G8B8A8_UNORM_SRGB : DXGI_FORMAT_R8G8B8A8_UNORM, &InitData ); } return NewProxy; }