Add option to automatically generate mips for textures created from code
This commit is contained in:
@@ -47,6 +47,16 @@ namespace FlaxEngine
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
public int ArraySize;
|
public int ArraySize;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// If checked, the engine will generate automatic-mips based on the latest provided mip.
|
||||||
|
/// </summary>
|
||||||
|
public bool GenerateMips;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// If checked, the generated mips will use linear filter, otherwise it will use point filter. Linear filter is supported only for formats compatible with Color32.
|
||||||
|
/// </summary>
|
||||||
|
public bool GenerateMipsLinear;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// The mips levels data.
|
/// The mips levels data.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
@@ -108,7 +118,7 @@ namespace FlaxEngine
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Convert data to internal storage (don't allocate memory but pin the managed arrays)
|
// Convert data to internal storage (don't allocate memory but pin the managed arrays)
|
||||||
InternalInitData t = new InternalInitData
|
var t = new InternalInitData
|
||||||
{
|
{
|
||||||
Format = initData.Format,
|
Format = initData.Format,
|
||||||
Width = initData.Width,
|
Width = initData.Width,
|
||||||
@@ -116,6 +126,12 @@ namespace FlaxEngine
|
|||||||
ArraySize = initData.ArraySize,
|
ArraySize = initData.ArraySize,
|
||||||
MipLevels = initData.Mips.Length,
|
MipLevels = initData.Mips.Length,
|
||||||
};
|
};
|
||||||
|
if (initData.GenerateMips)
|
||||||
|
{
|
||||||
|
t.GenerateMips = 1;
|
||||||
|
if (initData.GenerateMipsLinear)
|
||||||
|
t.GenerateMips |= 2;
|
||||||
|
}
|
||||||
var emptyArray = Utils.GetEmptyArray<byte>();
|
var emptyArray = Utils.GetEmptyArray<byte>();
|
||||||
fixed (byte* data13 = (initData.Mips.Length > 13 ? initData.Mips[13].Data : emptyArray))
|
fixed (byte* data13 = (initData.Mips.Length > 13 ? initData.Mips[13].Data : emptyArray))
|
||||||
fixed (byte* data12 = (initData.Mips.Length > 12 ? initData.Mips[12].Data : emptyArray))
|
fixed (byte* data12 = (initData.Mips.Length > 12 ? initData.Mips[12].Data : emptyArray))
|
||||||
@@ -173,6 +189,7 @@ namespace FlaxEngine
|
|||||||
public int Height;
|
public int Height;
|
||||||
public int ArraySize;
|
public int ArraySize;
|
||||||
public int MipLevels;
|
public int MipLevels;
|
||||||
|
public int GenerateMips;
|
||||||
|
|
||||||
public int Data00RowPitch;
|
public int Data00RowPitch;
|
||||||
public int Data01RowPitch;
|
public int Data01RowPitch;
|
||||||
|
|||||||
@@ -11,6 +11,7 @@
|
|||||||
#include "Engine/Debug/Exceptions/InvalidOperationException.h"
|
#include "Engine/Debug/Exceptions/InvalidOperationException.h"
|
||||||
#include "Engine/Profiler/ProfilerCPU.h"
|
#include "Engine/Profiler/ProfilerCPU.h"
|
||||||
#include "Engine/Content/Factories/BinaryAssetFactory.h"
|
#include "Engine/Content/Factories/BinaryAssetFactory.h"
|
||||||
|
#include "Engine/Threading/Threading.h"
|
||||||
|
|
||||||
TextureMipData::TextureMipData()
|
TextureMipData::TextureMipData()
|
||||||
: RowPitch(0)
|
: RowPitch(0)
|
||||||
@@ -151,11 +152,13 @@ BytesContainer TextureBase::GetMipData(int32 mipIndex, int32& rowPitch, int32& s
|
|||||||
|
|
||||||
bool TextureBase::GetTextureData(TextureData& result, bool copyData)
|
bool TextureBase::GetTextureData(TextureData& result, bool copyData)
|
||||||
{
|
{
|
||||||
|
PROFILE_CPU_NAMED("Texture.GetTextureData");
|
||||||
if (!IsVirtual() && WaitForLoaded())
|
if (!IsVirtual() && WaitForLoaded())
|
||||||
{
|
{
|
||||||
LOG(Error, "Asset load failed.");
|
LOG(Error, "Asset load failed.");
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
auto dataLock = LockData();
|
||||||
|
|
||||||
// Setup description
|
// Setup description
|
||||||
result.Width = _texture.TotalWidth();
|
result.Width = _texture.TotalWidth();
|
||||||
@@ -202,7 +205,7 @@ bool TextureBase::Init(InitData* initData)
|
|||||||
// Validate state
|
// Validate state
|
||||||
if (!IsVirtual())
|
if (!IsVirtual())
|
||||||
{
|
{
|
||||||
Log::InvalidOperationException();
|
LOG(Error, "Texture must be virtual.");
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
if (initData->Format == PixelFormat::Unknown ||
|
if (initData->Format == PixelFormat::Unknown ||
|
||||||
@@ -214,6 +217,7 @@ bool TextureBase::Init(InitData* initData)
|
|||||||
Log::ArgumentOutOfRangeException();
|
Log::ArgumentOutOfRangeException();
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
ScopeLock lock(Locker);
|
||||||
|
|
||||||
// Release texture
|
// Release texture
|
||||||
_texture.UnloadTexture();
|
_texture.UnloadTexture();
|
||||||
@@ -243,6 +247,7 @@ bool TextureBase::Init(InitData* initData)
|
|||||||
|
|
||||||
bool TextureBase::Init(void* ptr)
|
bool TextureBase::Init(void* ptr)
|
||||||
{
|
{
|
||||||
|
PROFILE_CPU_NAMED("Texture.Init");
|
||||||
struct InternalInitData
|
struct InternalInitData
|
||||||
{
|
{
|
||||||
PixelFormat Format;
|
PixelFormat Format;
|
||||||
@@ -250,6 +255,7 @@ bool TextureBase::Init(void* ptr)
|
|||||||
int32 Height;
|
int32 Height;
|
||||||
int32 ArraySize;
|
int32 ArraySize;
|
||||||
int32 MipLevels;
|
int32 MipLevels;
|
||||||
|
int32 GenerateMips;
|
||||||
int32 DataRowPitch[14];
|
int32 DataRowPitch[14];
|
||||||
int32 DataSlicePitch[14];
|
int32 DataSlicePitch[14];
|
||||||
byte* Data[14];
|
byte* Data[14];
|
||||||
@@ -261,8 +267,9 @@ bool TextureBase::Init(void* ptr)
|
|||||||
initData->Width = initDataObj->Width;
|
initData->Width = initDataObj->Width;
|
||||||
initData->Height = initDataObj->Height;
|
initData->Height = initDataObj->Height;
|
||||||
initData->ArraySize = initDataObj->ArraySize;
|
initData->ArraySize = initDataObj->ArraySize;
|
||||||
initData->Mips.Resize(initDataObj->MipLevels);
|
initData->Mips.Resize(initDataObj->GenerateMips ? MipLevelsCount(initDataObj->Width, initDataObj->Height) : initDataObj->MipLevels);
|
||||||
|
|
||||||
|
// Copy source mips data
|
||||||
for (int32 mipIndex = 0; mipIndex < initDataObj->MipLevels; mipIndex++)
|
for (int32 mipIndex = 0; mipIndex < initDataObj->MipLevels; mipIndex++)
|
||||||
{
|
{
|
||||||
auto& mip = initData->Mips[mipIndex];
|
auto& mip = initData->Mips[mipIndex];
|
||||||
@@ -271,6 +278,12 @@ bool TextureBase::Init(void* ptr)
|
|||||||
mip.Data.Copy(initDataObj->Data[mipIndex], mip.SlicePitch * initData->ArraySize);
|
mip.Data.Copy(initDataObj->Data[mipIndex], mip.SlicePitch * initData->ArraySize);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Generate mips
|
||||||
|
for (int32 mipIndex = initDataObj->MipLevels; mipIndex < initData->Mips.Count(); mipIndex++)
|
||||||
|
{
|
||||||
|
initData->GenerateMip(mipIndex, initDataObj->GenerateMips & 2);
|
||||||
|
}
|
||||||
|
|
||||||
return Init(initData);
|
return Init(initData);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -462,7 +475,7 @@ bool TextureBase::InitData::GenerateMip(int32 mipIndex, bool linear)
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
default:
|
default:
|
||||||
LOG(Error, "Unsupported texture data format {0} for mip map generation.", (int32)Format);
|
LOG(Error, "Unsupported texture data format {0}.", (int32)Format);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -43,7 +43,7 @@ DECLARE_ASSET_HEADER(TextureBase);
|
|||||||
/// <param name="mipIndex">Index of the mip.</param>
|
/// <param name="mipIndex">Index of the mip.</param>
|
||||||
/// <param name="linear">True if use linear filer, otherwise point filtering.</param>
|
/// <param name="linear">True if use linear filer, otherwise point filtering.</param>
|
||||||
/// <returns>True if failed, otherwise false.</returns>
|
/// <returns>True if failed, otherwise false.</returns>
|
||||||
bool GenerateMip(int32 mipIndex, bool linear);
|
bool GenerateMip(int32 mipIndex, bool linear = false);
|
||||||
};
|
};
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
|
|||||||
Reference in New Issue
Block a user