mirror of
https://github.com/aharabada/glitchy-engine-beef.git
synced 2026-09-05 13:01:52 +00:00
Texture importer now supports mip maps
This commit is contained in:
@@ -48,7 +48,10 @@ static class DdsImporter
|
||||
{
|
||||
Unknown,
|
||||
WrongMagicWord,
|
||||
StreamReadFailed
|
||||
StreamReadFailed,
|
||||
InvalidArraySize,
|
||||
WrongDimensions,
|
||||
IncompleteCubemap
|
||||
}
|
||||
|
||||
private enum HeaderFlags : uint32
|
||||
@@ -274,45 +277,91 @@ static class DdsImporter
|
||||
DdsPixelFormat pixelFormat = header.PixelFormat;
|
||||
|
||||
// Currently supports only basic dxgi formats.
|
||||
if (pixelFormat.SurfaceType.HasFlag(.RGBA))
|
||||
{
|
||||
switch (pixelFormat.RGBBitCount)
|
||||
{
|
||||
case 32:
|
||||
if (IsBitMask(pixelFormat, 0xFF, 0xFF00, 0xFF0000, 0xFF000000))
|
||||
return isSrgb ? .R8G8B8A8_UNorm_SRGB : .R8G8B8A8_UNorm;
|
||||
|
||||
if (IsBitMask(pixelFormat, 0xffff, 0xffff0000, 0x0, 0x0))
|
||||
return .R16G16_UNorm;
|
||||
|
||||
if (IsBitMask(pixelFormat, 0x3ff, 0xffc00, 0x3ff00000, 0x0))
|
||||
return .R10G10B10A2_UNorm;
|
||||
case 16:
|
||||
if (IsBitMask(pixelFormat, 0x7c00, 0x3e0, 0x1f, 0x8000))
|
||||
return .B5G5R5A1_UNorm;
|
||||
default:
|
||||
return .Unknown;
|
||||
}
|
||||
}
|
||||
|
||||
//if (pixelFormat.SurfaceType.HasFlag(.RGBA))
|
||||
if (pixelFormat.SurfaceType.HasFlag(.RGB))
|
||||
{
|
||||
switch (pixelFormat.RGBBitCount)
|
||||
{
|
||||
case 32:
|
||||
if (IsBitMask(pixelFormat, 0xffff, 0xffff0000, 0x0, 0x0))
|
||||
if (IsBitMask(pixelFormat, 0x000000FF, 0x0000FF00, 0x00FF0000, 0xFF000000))
|
||||
return isSrgb ? .R8G8B8A8_UNorm_SRGB : .R8G8B8A8_UNorm;
|
||||
|
||||
if (IsBitMask(pixelFormat, 0x00FF0000, 0x0000FF00, 0x000000FF, 0xFF000000))
|
||||
return isSrgb ? .B8G8R8A8_UNorm_SRGB : .B8G8R8A8_UNorm;
|
||||
|
||||
if (IsBitMask(pixelFormat, 0x00FF0000, 0x0000FF00, 0x000000FF, 0))
|
||||
return isSrgb ? .B8G8R8X8_UNorm_SRGB : .B8G8R8X8_UNorm;
|
||||
|
||||
if (IsBitMask(pixelFormat, 0x000003FF, 0x000FFc00, 0x3FF00000, 0))
|
||||
return .R10G10B10A2_UNorm;
|
||||
|
||||
if (IsBitMask(pixelFormat, 0x3FF00000, 0x000FFc00, 0x000003FF, 0))
|
||||
return .R10G10B10A2_UNorm;
|
||||
|
||||
if (IsBitMask(pixelFormat, 0x0000FFFF, 0xFFFF0000, 0, 0))
|
||||
return .R16G16_UNorm;
|
||||
break;
|
||||
|
||||
if (IsBitMask(pixelFormat, 0xFFFFFFFF, 0, 0, 0))
|
||||
return .R32_Float;
|
||||
|
||||
case 24:
|
||||
// NO 24 bit formats
|
||||
return .Unknown;
|
||||
|
||||
case 16:
|
||||
if (IsBitMask(pixelFormat, 0xf800, 0x7e0, 0x1f, 0x0))
|
||||
if (IsBitMask(pixelFormat, 0x7C00, 0x03E0, 0x001F, 0x8000))
|
||||
return .B5G5R5A1_UNorm;
|
||||
|
||||
if (IsBitMask(pixelFormat, 0xF800, 0x07E0, 0x001F, 0))
|
||||
return .B5G6R5_UNorm;
|
||||
break;
|
||||
|
||||
if (IsBitMask(pixelFormat, 0x0F00, 0x00F0, 0x000F, 0xF000))
|
||||
return .B4G4R4A4_UNORM;
|
||||
|
||||
if (IsBitMask(pixelFormat, 0x00FF, 0, 0, 0xFF00))
|
||||
return .R8G8_UNorm;
|
||||
|
||||
if (IsBitMask(pixelFormat, 0xFFFF, 0, 0, 0))
|
||||
return .R16_UNorm;
|
||||
|
||||
case 8:
|
||||
if (IsBitMask(pixelFormat, 0xFF, 0, 0, 0))
|
||||
return .R8_UNorm;
|
||||
|
||||
default:
|
||||
return .Unknown;
|
||||
}
|
||||
}
|
||||
else if (pixelFormat.SurfaceType.HasFlag(.Luminance))
|
||||
{
|
||||
switch (pixelFormat.RGBBitCount)
|
||||
{
|
||||
case 16:
|
||||
if (IsBitMask(pixelFormat, 0xFFFF, 0, 0, 0))
|
||||
return .R16_UNorm;
|
||||
|
||||
if (pixelFormat.SurfaceType.HasFlag(.FourCC))
|
||||
if (IsBitMask(pixelFormat, 0x00FF, 0, 0, 0xFF00))
|
||||
return .R8G8_UNorm;
|
||||
|
||||
case 8:
|
||||
if (IsBitMask(pixelFormat, 0xFF, 0, 0, 0))
|
||||
return .R8_UNorm;
|
||||
|
||||
if (IsBitMask(pixelFormat, 0x00FF, 0, 0, 0xFF00))
|
||||
return .R8G8_UNorm; // Some DDS writers assume the bitcount should be 8 instead of 16
|
||||
|
||||
default:
|
||||
return .Unknown;
|
||||
}
|
||||
}
|
||||
else if (pixelFormat.SurfaceType.HasFlag(.Luminance))
|
||||
{
|
||||
if (pixelFormat.RGBBitCount == 8)
|
||||
{
|
||||
return .A8_UNorm;
|
||||
}
|
||||
}
|
||||
else if (pixelFormat.SurfaceType.HasFlag(.FourCC))
|
||||
{
|
||||
switch (pixelFormat.FourCC)
|
||||
{
|
||||
@@ -322,15 +371,30 @@ static class DdsImporter
|
||||
return isSrgb ? .BC2_UNorm_SRGB : .BC2_UNorm;
|
||||
case MakeFourCC('D', 'X', 'T', '5'):
|
||||
return isSrgb ? .BC3_UNorm_SRGB : .BC3_UNorm;
|
||||
|
||||
// Legacy compression formats.
|
||||
case MakeFourCC('D', 'X', 'T', '2'):
|
||||
return isSrgb ? .BC2_UNorm_SRGB : .BC2_UNorm;
|
||||
case MakeFourCC('D', 'X', 'T', '4'):
|
||||
return isSrgb ? .BC3_UNorm_SRGB : .BC3_UNorm;
|
||||
|
||||
case MakeFourCC('B', 'C', '4', 'U'), MakeFourCC('A', 'T', 'I', '1'):
|
||||
return .BC4_UNorm;
|
||||
case MakeFourCC('A', 'T', 'I', '2'):
|
||||
case MakeFourCC('B', 'C', '4', 'S'):
|
||||
return .BC4_SNorm;
|
||||
case MakeFourCC('B', 'C', '5', 'U'), MakeFourCC('A', 'T', 'I', '2'):
|
||||
return .BC5_UNorm;
|
||||
case MakeFourCC('B', 'C', '5', 'S'):
|
||||
return .BC5_SNorm;
|
||||
|
||||
case MakeFourCC('R', 'G', 'B', 'G'):
|
||||
return .R8G8_B8G8_UNorm;
|
||||
case MakeFourCC('G', 'R', 'G', 'B'):
|
||||
return .G8R8_G8B8_UNorm;
|
||||
|
||||
case MakeFourCC('Y', 'U', 'Y', '2'):
|
||||
return .YUY2;
|
||||
|
||||
case 36:
|
||||
return .R16G16B16A16_UNorm;
|
||||
case 111:
|
||||
@@ -353,8 +417,137 @@ static class DdsImporter
|
||||
return .Unknown;
|
||||
}
|
||||
|
||||
public static void GetPitch(uint32 width, uint32 height, DirectX.DXGI.Format format, out uint32 rowBytes, out uint32 numRows, out uint64 numBytes)
|
||||
{
|
||||
rowBytes = 0;
|
||||
numRows = 0;
|
||||
numBytes = 0;
|
||||
|
||||
bool bc = false;
|
||||
bool packed = false;
|
||||
bool planar = false;
|
||||
uint32 bpe = 0;
|
||||
|
||||
switch (format)
|
||||
{
|
||||
case .BC1_Typeless, .BC1_UNorm, .BC1_UNorm_SRGB,
|
||||
.BC4_Typeless, .BC4_UNorm, .BC4_SNorm:
|
||||
bc = true;
|
||||
bpe = 8;
|
||||
break;
|
||||
|
||||
case .BC2_Typeless, .BC2_UNorm, .BC2_UNorm_SRGB,
|
||||
.BC3_Typeless, .BC3_UNorm, .BC3_UNorm_SRGB,
|
||||
.BC5_Typeless, .BC5_UNorm, .BC5_SNorm,
|
||||
.BC6H_Typeless, .BC6H_UF16, .BC6H_SF16,
|
||||
.BC7_Typeless, .BC7_UNorm, .BC7_UNorm_SRGB:
|
||||
bc = true;
|
||||
bpe = 16;
|
||||
break;
|
||||
|
||||
case .R8G8_B8G8_UNorm, .G8R8_G8B8_UNorm, .YUY2:
|
||||
packed = true;
|
||||
bpe = 4;
|
||||
break;
|
||||
|
||||
case .Y210, .Y216:
|
||||
packed = true;
|
||||
bpe = 8;
|
||||
break;
|
||||
|
||||
case .NV12, .P208, .OPAQUE_420:
|
||||
planar = true;
|
||||
bpe = 2;
|
||||
break;
|
||||
|
||||
case .P010, .P016:
|
||||
planar = true;
|
||||
bpe = 4;
|
||||
break;
|
||||
|
||||
/*
|
||||
case .D16_UNORM_S8_UINT:
|
||||
case .R16_UNORM_X8_TYPELESS:
|
||||
case .X16_TYPELESS_G8_UINT:
|
||||
planar = true;
|
||||
bpe = 4;
|
||||
break;
|
||||
*/
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
if (bc)
|
||||
{
|
||||
uint32 numBlocksWide = 0;
|
||||
if (width > 0)
|
||||
{
|
||||
numBlocksWide = Math.Max(1, (width + 3u) / 4u);
|
||||
}
|
||||
uint32 numBlocksHigh = 0;
|
||||
if (height > 0)
|
||||
{
|
||||
numBlocksHigh = Math.Max(1, (height + 3u) / 4u);
|
||||
}
|
||||
rowBytes = numBlocksWide * bpe;
|
||||
numRows = numBlocksHigh;
|
||||
numBytes = rowBytes * numBlocksHigh;
|
||||
}
|
||||
else if (packed)
|
||||
{
|
||||
rowBytes = (((uint32)width + 1u) >> 1) * bpe;
|
||||
numRows = height;
|
||||
numBytes = rowBytes * height;
|
||||
}
|
||||
else if (format == .NV11)
|
||||
{
|
||||
rowBytes = ((width + 3u) >> 2) * 4u;
|
||||
numRows = height * 2u; // Direct3D makes this simplifying assumption, although it is larger than the 4:1:1 data
|
||||
numBytes = rowBytes * numRows;
|
||||
}
|
||||
else if (planar)
|
||||
{
|
||||
rowBytes = ((width + 1u) >> 1) * bpe;
|
||||
numBytes = (rowBytes * height) + ((rowBytes * height + 1u) >> 1);
|
||||
numRows = height + ((height + 1u) >> 1);
|
||||
}
|
||||
else
|
||||
{
|
||||
uint32 bpp = format.BitsPerPixel();// BitsPerPixel(format);
|
||||
if (bpp == 0)
|
||||
return;
|
||||
|
||||
rowBytes = (width * bpp + 7u) / 8u; // round up to nearest byte
|
||||
numRows = height;
|
||||
numBytes = rowBytes * height;
|
||||
}
|
||||
|
||||
//#if defined(_M_IX86) || defined(_M_ARM) || defined(_M_HYBRID_X86_ARM64)
|
||||
/*static_assert(sizeof(size_t) == 4, "Not a 32-bit platform!");
|
||||
if (numBytes > UINT32_MAX || rowBytes > UINT32_MAX || numRows > UINT32_MAX)
|
||||
return HRESULT_FROM_WIN32(ERROR_ARITHMETIC_OVERFLOW);*/
|
||||
/*#else
|
||||
static_assert(sizeof(size_t) == 8, "Not a 64-bit platform!");
|
||||
#endif*/
|
||||
|
||||
/*if (outNumBytes)
|
||||
{
|
||||
*outNumBytes = static_cast<size_t>(numBytes);
|
||||
}
|
||||
if (outRowBytes)
|
||||
{
|
||||
*outRowBytes = static_cast<size_t>(rowBytes);
|
||||
}
|
||||
if (outNumRows)
|
||||
{
|
||||
*outNumRows = static_cast<size_t>(numRows);
|
||||
}*/
|
||||
}
|
||||
|
||||
public static Result<void, LoadError> LoadDds(Stream data, bool isSrgb, List<LoadedSurface> surfaces, out LoadedTextureInfo textureInfo)
|
||||
{
|
||||
// TODO: Care about alpha mode
|
||||
|
||||
textureInfo = .();
|
||||
|
||||
var headerResult = DecodeHeader(data, let header, let extendedHeader);
|
||||
@@ -384,6 +577,9 @@ static class DdsImporter
|
||||
{
|
||||
textureInfo.ArraySize = extendedHeader.Value.ArraySize;
|
||||
surfaceCount *= textureInfo.ArraySize;
|
||||
|
||||
if (textureInfo.ArraySize == 0)
|
||||
return .Err(.InvalidArraySize);
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -409,15 +605,28 @@ static class DdsImporter
|
||||
{
|
||||
case .Texture1D:
|
||||
textureInfo.Dimension = .Texture1D;
|
||||
|
||||
if (header.Flags.HasFlag(.DDSD_HEIGHT) && header.Height != 1)
|
||||
return .Err(.WrongDimensions);
|
||||
|
||||
textureInfo.Height = 1;
|
||||
textureInfo.Depth = 1;
|
||||
|
||||
case .Texture2D:
|
||||
textureInfo.Dimension = .Texture2D;
|
||||
|
||||
textureInfo.Depth = 1;
|
||||
|
||||
case .Texture3D:
|
||||
textureInfo.Dimension = .Texture3D;
|
||||
case null:
|
||||
if (header.Flags.HasFlag(.DDSD_DEPTH))
|
||||
textureInfo.Dimension = .Texture3D;
|
||||
else
|
||||
{
|
||||
textureInfo.Dimension = .Texture2D;
|
||||
textureInfo.Depth = 1;
|
||||
}
|
||||
}
|
||||
|
||||
// Make sure we have enough space in the list (avoid allocations later)
|
||||
@@ -425,7 +634,7 @@ static class DdsImporter
|
||||
|
||||
uint32 scanLineSize = 0;
|
||||
uint32 slicePitch = 0;
|
||||
uint32 numBytes = 0;
|
||||
uint64 numBytes = 0;
|
||||
uint32 blockSize = 0; // Block size in bytes.
|
||||
|
||||
switch (textureInfo.PixelFormat)
|
||||
@@ -459,7 +668,7 @@ static class DdsImporter
|
||||
|
||||
for (uint32 mipLevel = 0; mipLevel < textureInfo.MipMapCount; ++mipLevel)
|
||||
{
|
||||
// This will recalculate te pitch of the main image as well.
|
||||
/*// This will recalculate te pitch of the main image as well.
|
||||
if (header.Flags.HasFlag(.DDSD_LINEARSIZE))
|
||||
{
|
||||
// compressed textures
|
||||
@@ -473,13 +682,22 @@ static class DdsImporter
|
||||
scanLineSize = (width * header.PixelFormat.RGBBitCount + 7u) / 8u;
|
||||
numBytes = scanLineSize * height;
|
||||
}
|
||||
else
|
||||
{
|
||||
scanLineSize = header.PitchOrLinearSize;
|
||||
numBytes = scanLineSize * height;
|
||||
}*/
|
||||
|
||||
GetPitch(width, height, textureInfo.PixelFormat, out scanLineSize, let numRows, out numBytes);
|
||||
|
||||
|
||||
LoadedSurface surface = .();
|
||||
// We don't know how large data-array is, so we don't have one yet.
|
||||
// Only save the offset, we will adjust the pointer later.
|
||||
surface.Data = Span<uint8>((uint8*)(void*)offset, numBytes);
|
||||
surface.Data = Span<uint8>((uint8*)(void*)offset, (int)numBytes);
|
||||
surface.Pitch = scanLineSize;
|
||||
surface.SlicePitch = slicePitch;
|
||||
//surface.SlicePitch = slicePitch;
|
||||
surface.SlicePitch = scanLineSize * numRows;
|
||||
|
||||
surface.ArrayIndex = arrayIndex;
|
||||
surface.CubeFace = cubeFace;
|
||||
|
||||
@@ -9,6 +9,7 @@ using GlitchyEngine.Math;
|
||||
using DirectXTK;
|
||||
using ImGui;
|
||||
using GlitchyEditor.Assets.Importers;
|
||||
using System.Diagnostics;
|
||||
|
||||
namespace GlitchyEditor.Assets;
|
||||
|
||||
@@ -165,6 +166,9 @@ class EditorTextureAssetLoaderConfig : AssetLoaderConfig
|
||||
}
|
||||
}
|
||||
|
||||
using internal GlitchyEngine.Renderer;
|
||||
using internal GlitchyEngine.Platform.DX11;
|
||||
|
||||
class EditorTextureAssetLoader : IAssetLoader//, IReloadingAssetLoader
|
||||
{
|
||||
private static readonly List<StringView> _fileExtensions = new .(){".png", ".dds"} ~ delete _; // ".jpg", ".bmp"
|
||||
@@ -231,6 +235,35 @@ class EditorTextureAssetLoader : IAssetLoader//, IReloadingAssetLoader
|
||||
return .Unknown;
|
||||
}
|
||||
|
||||
/** \brief Loads the texture from the specified path.
|
||||
* @param path The path of the texture to load.
|
||||
* @param texture The reference to the pointer that will hold the texture.
|
||||
* @returns true if the texture was loaded successfully; false otherwise.
|
||||
*/
|
||||
protected static bool LoadDdsResourcePlatform(Stream stream)
|
||||
{
|
||||
Debug.Profiler.ProfileResourceFunction!();
|
||||
|
||||
uint8[] ddsData = new:ScopedAlloc! uint8[stream.Length];
|
||||
|
||||
var result = stream.TryRead(ddsData);
|
||||
|
||||
if (result case .Err(let err))
|
||||
{
|
||||
Log.EngineLogger.Error($"Failed to read texture data from stream. Error: {err}");
|
||||
}
|
||||
|
||||
DirectX.D3D11.ID3D11Texture2D* texture = null;
|
||||
DirectX.D3D11.ID3D11ShaderResourceView* view = null;
|
||||
|
||||
DirectX.Common.HResult loadResult = DDSTextureLoader.CreateDDSTextureFromMemory(GlitchyEngine.Platform.DX11.NativeDevice,
|
||||
ddsData.Ptr, (uint)ddsData.Count, (.)&texture, &view);
|
||||
|
||||
view.Release();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
private static Texture LoadTexture(Stream data, EditorTextureAssetLoaderConfig config)
|
||||
{
|
||||
Debug.Profiler.ProfileResourceFunction!();
|
||||
@@ -245,6 +278,13 @@ class EditorTextureAssetLoader : IAssetLoader//, IReloadingAssetLoader
|
||||
switch(GetTextureType(data))
|
||||
{
|
||||
case .DDS:
|
||||
|
||||
var v = data.Position;
|
||||
|
||||
//LoadDdsResourcePlatform(data);
|
||||
|
||||
data.Position = v;
|
||||
|
||||
Result<void> result = LoadDds(data, config, surfaces, out textureInfo);
|
||||
|
||||
if (result case .Err)
|
||||
@@ -261,6 +301,12 @@ class EditorTextureAssetLoader : IAssetLoader//, IReloadingAssetLoader
|
||||
return null;
|
||||
}
|
||||
|
||||
// Make the format SRGB or non-SRGB
|
||||
if (config.IsSRGB)
|
||||
textureInfo.PixelFormat = textureInfo.PixelFormat.GetSRGB();
|
||||
else
|
||||
textureInfo.PixelFormat = textureInfo.PixelFormat.GetNonSRGB();
|
||||
|
||||
Texture texture = CreateTexture(surfaces, textureInfo);
|
||||
|
||||
if (texture != null)
|
||||
@@ -274,6 +320,15 @@ class EditorTextureAssetLoader : IAssetLoader//, IReloadingAssetLoader
|
||||
|
||||
private static Texture CreateTexture(List<LoadedSurface> surfaces, LoadedTextureInfo textureInfo)
|
||||
{
|
||||
TextureSliceData[] slices = scope TextureSliceData[surfaces.Count];
|
||||
|
||||
for (int i < slices.Count)
|
||||
{
|
||||
slices[i] = .(surfaces[i].Data.Ptr, surfaces[i].Pitch, surfaces[i].SlicePitch);
|
||||
}
|
||||
|
||||
//slices[0].SlicePitch = (.)(surfaces[0].Pitch * textureInfo.Height);
|
||||
|
||||
switch (textureInfo.Dimension)
|
||||
{
|
||||
//case .Texture1D:
|
||||
@@ -296,6 +351,8 @@ class EditorTextureAssetLoader : IAssetLoader//, IReloadingAssetLoader
|
||||
|
||||
TextureCube cubeTexture = new TextureCube(staging);
|
||||
|
||||
//cubeTexture.SetData();
|
||||
|
||||
for (let surface in surfaces)
|
||||
{
|
||||
cubeTexture.SetData(surface.Data.Ptr, surface.Pitch / staging.Width, (TextureCubeFace)surface.CubeFace, (.)surface.ArrayIndex, (.)surface.MipLevel);
|
||||
@@ -317,14 +374,16 @@ class EditorTextureAssetLoader : IAssetLoader//, IReloadingAssetLoader
|
||||
|
||||
// TODO: allow enabling read/write
|
||||
staging.CpuAccess = .None;
|
||||
staging.Usage = .Default;
|
||||
staging.Usage = .Immutable;
|
||||
|
||||
Texture2D stagingTexture = new Texture2D(staging);
|
||||
|
||||
for (let surface in surfaces)
|
||||
stagingTexture.SetData(slices);
|
||||
|
||||
/*for (let surface in surfaces)
|
||||
{
|
||||
stagingTexture.[Friend]PlatformSetData(surface.Data.Ptr, surface.Pitch / staging.Width, 0, 0, staging.Width, staging.Height, (.)surface.ArrayIndex, (.)surface.MipLevel, .Write);
|
||||
}
|
||||
}*/
|
||||
|
||||
return stagingTexture;
|
||||
}
|
||||
|
||||
@@ -201,31 +201,6 @@ class TexturererViewerer
|
||||
ColorChannelSwizzle _swizzleB = .B;
|
||||
ColorChannelSwizzle _swizzleA = .A;
|
||||
|
||||
public void ViewTexture(RenderTargetGroup texture)
|
||||
{
|
||||
ShowSettings(texture.Width, texture.Height, texture.MipLevels - 1, texture.ArraySize - 1, texture);
|
||||
|
||||
UpdateInput();
|
||||
|
||||
var viewportSize = ImGui.GetContentRegionAvail();
|
||||
|
||||
viewportSize.x = Math.Max(viewportSize.x, 1);
|
||||
viewportSize.y = Math.Max(viewportSize.y, 1);
|
||||
|
||||
if(_target == null || viewportSize.x != _target.Width || viewportSize.y != _target.Height)
|
||||
{
|
||||
_target?.ReleaseRef();
|
||||
_target = new RenderTarget2D(.(.R8G8B8A8_UNorm, (.)viewportSize.x, (.)viewportSize.y));
|
||||
_target.SamplerState = SamplerStateManager.PointClamp;
|
||||
_depth?.ReleaseRef();
|
||||
_depth = new DepthStencilTarget((.)viewportSize.x, (.)viewportSize.y, .D16_UNorm);
|
||||
}
|
||||
|
||||
RenderTexture(texture);
|
||||
|
||||
ImGui.Image(_target, viewportSize);
|
||||
}
|
||||
|
||||
public void ShowSettings(float width, float height, int maxMips, int arraySize, RenderTargetGroup rtGroup)
|
||||
{
|
||||
char8*[] items = scope .("White", "Black", "Pink", "Checkerboard", "Custom Color");
|
||||
@@ -382,6 +357,38 @@ class TexturererViewerer
|
||||
}
|
||||
}
|
||||
|
||||
public void ViewTexture(RenderTargetGroup texture)
|
||||
{
|
||||
ShowSettings(texture.Width, texture.Height, texture.MipLevels - 1, texture.ArraySize - 1, texture);
|
||||
|
||||
if (ImGui.BeginChild("imageChild"))
|
||||
{
|
||||
UpdateInput();
|
||||
|
||||
var viewportSize = ImGui.GetContentRegionAvail();
|
||||
|
||||
viewportSize.x = Math.Max(viewportSize.x, 1);
|
||||
viewportSize.y = Math.Max(viewportSize.y, 1);
|
||||
|
||||
if(_target == null || viewportSize.x != _target.Width || viewportSize.y != _target.Height)
|
||||
{
|
||||
_target?.ReleaseRef();
|
||||
_target = new RenderTarget2D(.(.R8G8B8A8_UNorm_SRGB, (.)viewportSize.x, (.)viewportSize.y));
|
||||
_target.SamplerState = SamplerStateManager.PointClamp;
|
||||
_depth?.ReleaseRef();
|
||||
_depth = new DepthStencilTarget((.)viewportSize.x, (.)viewportSize.y, .D16_UNorm);
|
||||
}
|
||||
|
||||
RenderBackground();
|
||||
|
||||
RenderTexture(texture);
|
||||
|
||||
ImGui.Image(_target, viewportSize);
|
||||
|
||||
ImGui.EndChild();
|
||||
}
|
||||
}
|
||||
|
||||
public void ViewTexture(Texture texture)
|
||||
{
|
||||
ShowSettings(texture.Width, texture.Height, texture.MipLevels - 1, texture.ArraySize - 1, null);
|
||||
@@ -398,12 +405,14 @@ class TexturererViewerer
|
||||
if(_target == null || viewportSize.x != _target.Width || viewportSize.y != _target.Height)
|
||||
{
|
||||
_target?.ReleaseRef();
|
||||
_target = new RenderTarget2D(.(.R8G8B8A8_UNorm, (.)viewportSize.x, (.)viewportSize.y));
|
||||
_target = new RenderTarget2D(.(.R8G8B8A8_UNorm_SRGB, (.)viewportSize.x, (.)viewportSize.y));
|
||||
_target.SamplerState = SamplerStateManager.PointClamp;
|
||||
_depth?.ReleaseRef();
|
||||
_depth = new DepthStencilTarget((.)viewportSize.x, (.)viewportSize.y, .D16_UNorm);
|
||||
}
|
||||
|
||||
RenderBackground();
|
||||
|
||||
RenderTexture(texture);
|
||||
|
||||
ImGui.Image(_target, viewportSize);
|
||||
@@ -461,7 +470,7 @@ class TexturererViewerer
|
||||
|
||||
OrthographicCamera _camera = new OrthographicCamera() ~ delete _;
|
||||
|
||||
private void RenderTexture(RenderTargetGroup viewedTexture)
|
||||
private void RenderBackground()
|
||||
{
|
||||
Viewport vp = .(0, 0, _target.Width, _target.Height);
|
||||
RenderCommand.SetViewport(vp);
|
||||
@@ -475,9 +484,6 @@ class TexturererViewerer
|
||||
RenderCommand.SetDepthStencilTarget(_depth);
|
||||
RenderCommand.BindRenderTargets();
|
||||
|
||||
float2 textureSize = float2(viewedTexture.Width, viewedTexture.Height);
|
||||
float2 zoomedTextureSize = textureSize * _zoom;
|
||||
|
||||
float2 targetSize = float2(_target.Width, _target.Height);
|
||||
|
||||
_camera.Left = 0;
|
||||
@@ -516,6 +522,17 @@ class TexturererViewerer
|
||||
}
|
||||
|
||||
Renderer2D.EndScene();
|
||||
}
|
||||
|
||||
private void RenderTexture(TextureViewBinding viewedTexture, float2 textureSize, Format format)
|
||||
{
|
||||
float2 mippedTextureSize = float2((int)textureSize.X >> _mipLevel, (int)textureSize.X >> _mipLevel);
|
||||
|
||||
// Sicherstellen, dass die Auflösung nicht 0 wird
|
||||
mippedTextureSize = max(mippedTextureSize, 1);
|
||||
|
||||
//float2 textureSize = float2(viewedTexture.Width, viewedTexture.Height);
|
||||
float2 zoomedTextureSize = textureSize * _zoom;
|
||||
|
||||
// TODO: Sampler state for rt group
|
||||
//var sampler = viewedTexture.SamplerState;
|
||||
@@ -542,34 +559,35 @@ class TexturererViewerer
|
||||
_renderTargetEffect.Variables["AlphaOffset"].SetData(_alphaOffset);
|
||||
_renderTargetEffect.Variables["AlphaScale"].SetData(_alphaScale);
|
||||
|
||||
_renderTargetEffect.Variables["Texels"].SetData(float2(viewedTexture.Width, viewedTexture.Height));
|
||||
_renderTargetEffect.Variables["Texels"].SetData(mippedTextureSize);
|
||||
|
||||
_renderTargetEffect.Variables["MipLevel"].SetData((float)_mipLevel);
|
||||
|
||||
_renderTargetEffect.Variables["Swizzle"].SetData(int4((int32)_swizzleR, (int32)_swizzleG, (int32)_swizzleB, (int32)_swizzleA));
|
||||
|
||||
var desc = _groupIndex >= 0 ? viewedTexture.[Friend]_colorTargetDescriptions[_groupIndex] : viewedTexture.[Friend]_depthTargetDescription;
|
||||
|
||||
if (desc.Format.IsInt())
|
||||
if (format.IsInt())
|
||||
{
|
||||
// Int Texture
|
||||
_renderTargetEffect.Variables["Mode"].SetData(1);
|
||||
_renderTargetEffect.SetTexture("IntTexture", viewedTexture.GetViewBinding(_groupIndex));
|
||||
_renderTargetEffect.SetTexture("IntTexture", viewedTexture);
|
||||
_renderTargetEffect.SetTexture("UIntTexture", null);
|
||||
_renderTargetEffect.SetTexture("Texture", null);
|
||||
}
|
||||
else if (desc.Format.IsUInt())
|
||||
else if (format.IsUInt())
|
||||
{
|
||||
// UInt Texture
|
||||
_renderTargetEffect.Variables["Mode"].SetData(2);
|
||||
_renderTargetEffect.SetTexture("IntTexture", null);
|
||||
_renderTargetEffect.SetTexture("UIntTexture", viewedTexture.GetViewBinding(_groupIndex));
|
||||
_renderTargetEffect.SetTexture("UIntTexture", viewedTexture);
|
||||
_renderTargetEffect.SetTexture("Texture", null);
|
||||
}
|
||||
else
|
||||
{
|
||||
// Float Texture
|
||||
_renderTargetEffect.Variables["Mode"].SetData(0);
|
||||
_renderTargetEffect.SetTexture("IntTexture", null);
|
||||
_renderTargetEffect.SetTexture("UIntTexture", null);
|
||||
_renderTargetEffect.SetTexture("Texture", viewedTexture.GetViewBinding(_groupIndex));
|
||||
_renderTargetEffect.SetTexture("Texture", viewedTexture);
|
||||
}
|
||||
|
||||
_renderTargetEffect.Variables["Swizzle"].SetData(int4((int32)_swizzleR, (int32)_swizzleG, (int32)_swizzleB, (int32)_swizzleA));
|
||||
@@ -580,84 +598,15 @@ class TexturererViewerer
|
||||
Quad.Draw();
|
||||
}
|
||||
|
||||
private void RenderTexture(RenderTargetGroup viewedTexture)
|
||||
{
|
||||
var desc = _groupIndex >= 0 ? viewedTexture.[Friend]_colorTargetDescriptions[_groupIndex] : viewedTexture.[Friend]_depthTargetDescription;
|
||||
|
||||
RenderTexture(viewedTexture.GetViewBinding(_groupIndex), float2(viewedTexture.Width, viewedTexture.Height), desc.Format.GetShaderViewFormat());
|
||||
}
|
||||
|
||||
private void RenderTexture(Texture viewedTexture)
|
||||
{
|
||||
Viewport vp = .(0, 0, _target.Width, _target.Height);
|
||||
RenderCommand.SetViewport(vp);
|
||||
|
||||
// TODO: don't clear pink!
|
||||
RenderCommand.Clear(_target, .Pink);
|
||||
RenderCommand.Clear(_depth, .Depth, 1.0f, 0);
|
||||
|
||||
//_target.Bind();
|
||||
RenderCommand.SetRenderTarget(_target);
|
||||
RenderCommand.SetDepthStencilTarget(_depth);
|
||||
RenderCommand.BindRenderTargets();
|
||||
|
||||
float2 textureSize = float2(viewedTexture.Width, viewedTexture.Height);
|
||||
float2 zoomedTextureSize = textureSize * _zoom;
|
||||
|
||||
float2 targetSize = float2(_target.Width, _target.Height);
|
||||
|
||||
_effect.Variables["ColorOffset"].SetData(_colorOffset);
|
||||
_effect.Variables["ColorScale"].SetData(_colorScale);
|
||||
_effect.Variables["AlphaOffset"].SetData(_alphaOffset);
|
||||
_effect.Variables["AlphaScale"].SetData(_alphaScale);
|
||||
|
||||
_camera.Left = 0;
|
||||
_camera.Top = 0;
|
||||
_camera.Right = targetSize.X;
|
||||
_camera.Bottom = -targetSize.Y;
|
||||
_camera.NearPlane = -5;
|
||||
_camera.FarPlane = 5;
|
||||
_camera.Update();
|
||||
|
||||
Renderer2D.BeginScene(_camera);
|
||||
|
||||
switch(_backgroundMode)
|
||||
{
|
||||
case .Black:
|
||||
Renderer2D.DrawQuadPivotCorner(float3(0, 0, 1), targetSize, 0, .Black);
|
||||
case .White:
|
||||
Renderer2D.DrawQuadPivotCorner(float3(0, 0, 1), targetSize, 0, .White);
|
||||
case .Pink:
|
||||
Renderer2D.DrawQuadPivotCorner(float3(0, 0, 1), targetSize, 0, .HotPink);
|
||||
case .CustomColor:
|
||||
Renderer2D.DrawQuadPivotCorner(float3(0, 0, 1), targetSize, 0, _backgroundColor);
|
||||
case .Checkerboard:
|
||||
float quadSize = 50.0f;
|
||||
|
||||
float2 numQuads = (targetSize / 500f) * 10f;
|
||||
|
||||
for(float x = 0; x < numQuads.X; x++)
|
||||
{
|
||||
for(float y = 0; y < numQuads.Y; y++)
|
||||
{
|
||||
Renderer2D.DrawQuadPivotCorner(float3(x * quadSize, -y * quadSize, 1), quadSize.XX, 0, ((x + y) % 2 == 0) ? .White : .Gray);
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
Renderer2D.EndScene();
|
||||
|
||||
var sampler = viewedTexture.SamplerState..AddRef();
|
||||
|
||||
switch(_sampleMode)
|
||||
{
|
||||
case .Point:
|
||||
viewedTexture.SamplerState = SamplerStateManager.PointClamp;
|
||||
case .Linear:
|
||||
viewedTexture.SamplerState = SamplerStateManager.LinearClamp;
|
||||
}
|
||||
|
||||
Renderer2D.BeginScene(_camera, .SortByTexture, _effect);
|
||||
|
||||
Renderer2D.DrawQuad(float3(_position * .(1, -1), 0), zoomedTextureSize, 0, viewedTexture);
|
||||
|
||||
Renderer2D.EndScene();
|
||||
|
||||
viewedTexture.SamplerState = sampler;
|
||||
sampler.ReleaseRef();
|
||||
RenderTexture(viewedTexture.GetViewBinding(), float2(viewedTexture.Width, viewedTexture.Height), viewedTexture.Format);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -56,31 +56,65 @@ namespace GlitchyEngine.Renderer
|
||||
public override uint32 Height => nativeDesc.Height;
|
||||
public override uint32 ArraySize => nativeDesc.ArraySize;
|
||||
public override uint32 MipLevels => nativeDesc.MipLevels;
|
||||
public override Format Format => nativeDesc.Format;
|
||||
|
||||
protected override void CreateTexturePlatform(Texture2DDesc desc, bool isRenderTarget, void* data, uint32 linePitch)
|
||||
|
||||
/*protected override void CreateTexturePlatform(Texture2DDesc desc, bool isRenderTarget, void* data, uint32 linePitch)
|
||||
{
|
||||
Debug.Profiler.ProfileResourceFunction!();
|
||||
|
||||
PrepareTexturePlatform(desc, isRenderTarget);
|
||||
InternalCreateTexture(data, linePitch, 0);
|
||||
}
|
||||
}*/
|
||||
|
||||
private void InternalCreateTexture(void* data, uint32 linePitch, uint32 slicePitch)
|
||||
/// Creates the native texture. Initializes it, if slices is not null and has enough Entries to fill all slices.
|
||||
/// @returns true if the texture has been initialized; false otherwise.
|
||||
private bool InternalCreateTexture(Span<TextureSliceData> slices)
|
||||
{
|
||||
Debug.Profiler.ProfileResourceFunction!();
|
||||
|
||||
SubresourceData resData = .(data, linePitch, slicePitch);
|
||||
SubresourceData[] data = null;
|
||||
|
||||
// If data is null, set subresourceData null
|
||||
SubresourceData* resDataPtr = data == null ? null : &resData;
|
||||
if (slices.Length == MipLevels * ArraySize)
|
||||
{
|
||||
data = scope:: SubresourceData[slices.Length];
|
||||
|
||||
var result = NativeDevice.CreateTexture2D(ref nativeDesc, resDataPtr, &nativeTexture);
|
||||
for (int i < slices.Length)
|
||||
{
|
||||
TextureSliceData slice = slices[i];
|
||||
|
||||
data[i] = .(slice.Data, slice.LinePitch, slice.SlicePitch);
|
||||
}
|
||||
}
|
||||
|
||||
var result = NativeDevice.CreateTexture2D(ref nativeDesc, data?.Ptr, &nativeTexture);
|
||||
Log.EngineLogger.Assert(result.Succeeded, scope $"Failed to create texture 2D. Error ({result.Underlying}): {result}");
|
||||
|
||||
result = NativeDevice.CreateShaderResourceView(nativeTexture, null, &_nativeResourceView);
|
||||
Log.EngineLogger.Assert(result.Succeeded, scope $"Failed to create texture view. Error ({result.Underlying}): {result}");
|
||||
|
||||
// If Data is non-null the texture got initialized with data.
|
||||
return (data != null);
|
||||
}
|
||||
|
||||
/*private void InternalCreateTexture(void* data, uint32 linePitch, uint32 slicePitch)
|
||||
{
|
||||
Debug.Profiler.ProfileResourceFunction!();
|
||||
|
||||
/*SubresourceData resData = .(data, linePitch, slicePitch);
|
||||
|
||||
// If data is null, set subresourceData null
|
||||
SubresourceData* resDataPtr = data == null ? null : &resData;*/
|
||||
|
||||
SubresourceData[2] resData = .(.(data, linePitch, slicePitch), .(null, 0, 0));
|
||||
|
||||
var result = NativeDevice.CreateTexture2D(ref nativeDesc, &resData, &nativeTexture);
|
||||
Log.EngineLogger.Assert(result.Succeeded, scope $"Failed to create texture 2D. Error ({result.Underlying}): {result}");
|
||||
|
||||
result = NativeDevice.CreateShaderResourceView(nativeTexture, null, &_nativeResourceView);
|
||||
Log.EngineLogger.Assert(result.Succeeded, scope $"Failed to create texture view. Error ({result.Underlying}): {result}");
|
||||
}*/
|
||||
|
||||
protected override void PrepareTexturePlatform(Texture2DDesc desc, bool isRenderTarget)
|
||||
{
|
||||
Debug.Profiler.ProfileResourceFunction!();
|
||||
@@ -96,6 +130,26 @@ namespace GlitchyEngine.Renderer
|
||||
nativeDesc.BindFlags |= .RenderTarget;
|
||||
}
|
||||
|
||||
protected override Result<void> PlatformSetData(Span<TextureSliceData> slices)
|
||||
{
|
||||
Debug.Profiler.ProfileResourceFunction!();
|
||||
|
||||
if(nativeTexture == null)
|
||||
{
|
||||
if (InternalCreateTexture(slices))
|
||||
return .Ok;
|
||||
}
|
||||
|
||||
Runtime.NotImplemented();
|
||||
|
||||
/*int index = firstArraySlice;
|
||||
|
||||
for (TextureSliceData slice in slices)
|
||||
{
|
||||
|
||||
}*/
|
||||
}
|
||||
|
||||
// TODO: Update Texture Arrays!
|
||||
protected override Result<void> PlatformSetData(void* data, uint32 elementSize, uint32 destX,
|
||||
uint32 destY, uint32 destWidth, uint32 destHeight, uint32 arraySlice, uint32 mipLevel, GlitchyEngine.Renderer.MapType mapType)
|
||||
@@ -104,6 +158,21 @@ namespace GlitchyEngine.Renderer
|
||||
|
||||
if(nativeTexture == null)
|
||||
{
|
||||
if(destX == 0 && destY == 0 && destWidth == nativeDesc.Width && destHeight == nativeDesc.Height &&
|
||||
arraySlice == 0 && mipLevel == 0 && ArraySize == 1 && MipLevels == 1)
|
||||
{
|
||||
TextureSliceData[1] dataSlice = .(.(data, elementSize * destWidth, elementSize * destWidth * destHeight));
|
||||
|
||||
// Turns out we need to initialize all slices at once or none... so... tough shit, we cant early out here.
|
||||
if (InternalCreateTexture(dataSlice))
|
||||
return .Ok;
|
||||
}
|
||||
else
|
||||
{
|
||||
InternalCreateTexture(null);
|
||||
}
|
||||
|
||||
/* Old shit follows...
|
||||
if(destX == 0 && destY == 0 && destWidth == nativeDesc.Width && destHeight == nativeDesc.Height)
|
||||
{
|
||||
// We can pass the data while creating the buffer, so we can return here.
|
||||
@@ -116,6 +185,7 @@ namespace GlitchyEngine.Renderer
|
||||
Log.EngineLogger.Assert(nativeDesc.Usage != .Immutable, "The entire immutable texture has to be initialized.");
|
||||
InternalCreateTexture(null, 0, 0);
|
||||
}
|
||||
*/
|
||||
}
|
||||
|
||||
//Log.EngineLogger.AssertDebug();
|
||||
@@ -178,7 +248,7 @@ namespace GlitchyEngine.Renderer
|
||||
|
||||
// Make sure the destination was initialized
|
||||
if(destination.nativeTexture == null)
|
||||
destination.InternalCreateTexture(null, 0, 0);
|
||||
destination.InternalCreateTexture(null);
|
||||
|
||||
using (ContextMonitor.Enter())
|
||||
{
|
||||
@@ -200,7 +270,7 @@ namespace GlitchyEngine.Renderer
|
||||
|
||||
// Make sure the destination was initialized
|
||||
if(destination.nativeTexture == null)
|
||||
destination.InternalCreateTexture(null, 0, 0);
|
||||
destination.InternalCreateTexture(null);
|
||||
|
||||
uint32 arraySlices = Math.Min(ArraySize, destination.ArraySize);
|
||||
uint32 mipSlices = Math.Min(MipLevels, destination.MipLevels);
|
||||
@@ -234,6 +304,7 @@ namespace GlitchyEngine.Renderer
|
||||
public override uint32 Height => nativeDesc.Height;
|
||||
public override uint32 ArraySize => nativeDesc.ArraySize / 6;
|
||||
public override uint32 MipLevels => nativeDesc.MipLevels;
|
||||
public override Format Format => nativeDesc.Format;
|
||||
|
||||
protected override void CreateTexturePlatform(Texture2DDesc desc, bool isRenderTarget, void* data, uint32 linePitch)
|
||||
{
|
||||
|
||||
@@ -1,6 +1,139 @@
|
||||
using System;
|
||||
using GlitchyEngine.Core;
|
||||
|
||||
namespace DirectX.DXGI
|
||||
{
|
||||
public extension Format
|
||||
{
|
||||
public bool IsInt()
|
||||
{
|
||||
switch(this)
|
||||
{
|
||||
case R32G32B32A32_SInt, R32G32B32_SInt, R16G16B16A16_SInt, R32G32_SInt, R8G8B8A8_SInt, R16G16_SInt,
|
||||
R32_SInt, R8G8_SInt, R16_SInt, R8_SInt:
|
||||
return true;
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
public bool IsUInt()
|
||||
{
|
||||
switch(this)
|
||||
{
|
||||
case R32G32B32A32_UInt, R32G32B32_UInt, R16G16B16A16_UInt, R32G32_UInt, R10G10B10A2_UInt, R8G8B8A8_UInt, R16G16_UInt,
|
||||
R32_UInt, R8G8_UInt, R16_UInt, R8_UInt:
|
||||
return true;
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
public uint32 BitsPerPixel()
|
||||
{
|
||||
switch (this)
|
||||
{
|
||||
case .R32G32B32A32_Typeless,.R32G32B32A32_Float,.R32G32B32A32_UInt,.R32G32B32A32_SInt:
|
||||
return 128;
|
||||
|
||||
case .R32G32B32_Typeless,.R32G32B32_Float,.R32G32B32_UInt,.R32G32B32_SInt:
|
||||
return 96;
|
||||
|
||||
case .R16G16B16A16_Typeless,.R16G16B16A16_Float,.R16G16B16A16_UNorm,.R16G16B16A16_UInt,.R16G16B16A16_SNorm,.R16G16B16A16_SInt,.R32G32_Typeless,.R32G32_Float,.R32G32_UInt,.R32G32_SInt,.R32G8X24_Typeless,.D32_Float_S8X24_UInt,.R32_Float_X8X24_Typeless,.X32_Typeless_G8X24_UInt,.Y416,.Y210,.Y216:
|
||||
return 64;
|
||||
|
||||
case .R10G10B10A2_Typeless,.R10G10B10A2_UNorm,.R10G10B10A2_UInt,.R11G11B10_Float,.R8G8B8A8_Typeless,.R8G8B8A8_UNorm,.R8G8B8A8_UNorm_SRGB,.R8G8B8A8_UInt,.R8G8B8A8_SNorm,.R8G8B8A8_SInt,.R16G16_Typeless,.R16G16_Float,.R16G16_UNorm,.R16G16_UInt,.R16G16_SNorm,.R16G16_SInt,.R32_Typeless,.D32_Float,.R32_Float,.R32_UInt,.R32_SInt,.R24G8_Typeless,.D24_UNorm_S8_UInt,.R24_UNorm_X8_Typeless,.X24_Typeless_G8_UInt,.R9G9B9E5_SHAREDEXP,.R8G8_B8G8_UNorm,.G8R8_G8B8_UNorm,.B8G8R8A8_UNorm,.B8G8R8X8_UNorm,.R10G10B10_XR_BIAS_A2_UNorm,.B8G8R8A8_Typeless,.B8G8R8A8_UNorm_SRGB,.B8G8R8X8_Typeless,.B8G8R8X8_UNorm_SRGB,.AYUV,.Y410,.YUY2:
|
||||
//#if (defined(_XBOX_ONE) && defined(_TITLE)) || defined(_GAMING_XBOX)
|
||||
//case .R10G10B10_7E3_A2_Float,.R10G10B10_6E4_A2_Float,.R10G10B10_SNorm_A2_UNorm:
|
||||
//#endif
|
||||
return 32;
|
||||
|
||||
case .P010,.P016, .V408:
|
||||
/*#if (_WIN32_WINNT >= _WIN32_WINNT_WIN10)
|
||||
case .V408:
|
||||
#endif
|
||||
#if (defined(_XBOX_ONE) && defined(_TITLE)) || defined(_GAMING_XBOX)
|
||||
case .D16_UNorm_S8_UInt,.R16_UNorm_X8_Typeless,.X16_Typeless_G8_UInt:
|
||||
#endif*/
|
||||
return 24;
|
||||
|
||||
case .R8G8_Typeless,.R8G8_UNorm,.R8G8_UInt,.R8G8_SNorm,.R8G8_SInt,.R16_Typeless,.R16_Float,.D16_UNorm,.R16_UNorm,.R16_UInt,.R16_SNorm,.R16_SInt,.B5G6R5_UNorm,.B5G5R5A1_UNorm,.A8P8,.B4G4R4A4_UNORM, .P208,.V208:
|
||||
/*#if (_WIN32_WINNT >= _WIN32_WINNT_WIN10)
|
||||
case .P208,.V208:
|
||||
#endif*/
|
||||
return 16;
|
||||
|
||||
case .NV12,.OPAQUE_420,.NV11:
|
||||
return 12;
|
||||
|
||||
case .R8_Typeless,.R8_UNorm,.R8_UInt,.R8_SNorm,.R8_SInt,.A8_UNorm,.BC2_Typeless,.BC2_UNorm,.BC2_UNorm_SRGB,.BC3_Typeless,.BC3_UNorm,.BC3_UNorm_SRGB,.BC5_Typeless,.BC5_UNorm,.BC5_SNorm,.BC6H_Typeless,.BC6H_UF16,.BC6H_SF16,.BC7_Typeless,.BC7_UNorm,.BC7_UNorm_SRGB,.AI44,.IA44,.P8:
|
||||
/*#if (defined(_XBOX_ONE) && defined(_TITLE)) || defined(_GAMING_XBOX)
|
||||
case .R4G4_UNorm:
|
||||
#endif*/
|
||||
return 8;
|
||||
|
||||
case .R1_UNorm:
|
||||
return 1;
|
||||
|
||||
case .BC1_Typeless,.BC1_UNorm,.BC1_UNorm_SRGB,.BC4_Typeless,.BC4_UNorm,.BC4_SNorm:
|
||||
return 4;
|
||||
|
||||
//case .Unknown,.FORCE_UInt:
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
/// Returns the SRGB-Format for the given Format, or the Format itself, if no SRGB-variant exists.
|
||||
public Format GetSRGB()
|
||||
{
|
||||
switch (this)
|
||||
{
|
||||
case .BC1_UNorm:
|
||||
return .BC1_UNorm_SRGB;
|
||||
case .BC2_UNorm:
|
||||
return .BC2_UNorm_SRGB;
|
||||
case .BC3_UNorm:
|
||||
return .BC3_UNorm_SRGB;
|
||||
case .BC7_UNorm:
|
||||
return .BC7_UNorm_SRGB;
|
||||
case .R8G8B8A8_UNorm:
|
||||
return .R8G8B8A8_UNorm_SRGB;
|
||||
case .B8G8R8A8_UNorm:
|
||||
return .B8G8R8A8_UNorm_SRGB;
|
||||
case .B8G8R8X8_UNorm:
|
||||
return .B8G8R8X8_UNorm_SRGB;
|
||||
default:
|
||||
return this;
|
||||
}
|
||||
}
|
||||
|
||||
/// Returns the non-SRGB-Format for the given Format.
|
||||
public Format GetNonSRGB()
|
||||
{
|
||||
switch (this)
|
||||
{
|
||||
case .BC1_UNorm_SRGB:
|
||||
return .BC1_UNorm;
|
||||
case .BC2_UNorm_SRGB:
|
||||
return .BC2_UNorm;
|
||||
case .BC3_UNorm_SRGB:
|
||||
return .BC3_UNorm;
|
||||
case .BC7_UNorm_SRGB:
|
||||
return .BC7_UNorm;
|
||||
case .R8G8B8A8_UNorm_SRGB:
|
||||
return .R8G8B8A8_UNorm;
|
||||
case .B8G8R8A8_UNorm_SRGB:
|
||||
return .B8G8R8A8_UNorm;
|
||||
case .B8G8R8X8_UNorm_SRGB:
|
||||
return .B8G8R8X8_UNorm;
|
||||
default:
|
||||
return this;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
namespace GlitchyEngine.Renderer
|
||||
{
|
||||
/**
|
||||
@@ -29,6 +162,7 @@ namespace GlitchyEngine.Renderer
|
||||
|
||||
typealias Format = DirectX.DXGI.Format;
|
||||
|
||||
|
||||
public struct BufferDescription
|
||||
{
|
||||
/**
|
||||
|
||||
@@ -48,6 +48,7 @@ namespace GlitchyEngine.Renderer
|
||||
public override uint32 Depth => 1;
|
||||
public override uint32 ArraySize => _description.ArraySize;
|
||||
public override uint32 MipLevels => _description.MipLevels;
|
||||
public override Format Format => _description.PixelFormat;
|
||||
|
||||
protected internal DepthStencilTarget _depthStenilTarget ~ _?.ReleaseRef();
|
||||
|
||||
|
||||
@@ -368,7 +368,9 @@ namespace GlitchyEngine.Renderer
|
||||
s_whiteTexture = new Texture2D(tex2Ddesc);
|
||||
|
||||
Color color = .White;
|
||||
s_whiteTexture.SetData(&color);
|
||||
|
||||
TextureSliceData[1] data = .(.(&color, sizeof(Color), sizeof(Color)));
|
||||
s_whiteTexture.SetData(data);
|
||||
|
||||
// Create the default sampler for the white texture
|
||||
SamplerState sampler = SamplerStateManager.GetSampler(SamplerStateDescription());
|
||||
|
||||
@@ -29,6 +29,8 @@ namespace GlitchyEngine.Renderer
|
||||
public abstract uint32 ArraySize {get;}
|
||||
public abstract uint32 MipLevels {get;}
|
||||
|
||||
public abstract Format Format {get;}
|
||||
|
||||
public abstract TextureViewBinding GetViewBinding();
|
||||
}
|
||||
|
||||
@@ -56,6 +58,22 @@ namespace GlitchyEngine.Renderer
|
||||
}
|
||||
}
|
||||
|
||||
/// Represents the Data of one Texture Slice (a specific mip-level of a array-slice of the texture)
|
||||
/// @remarks Basically works like described here: https://learn.microsoft.com/en-us/windows/win32/api/d3d11/ns-d3d11-d3d11_subresource_data
|
||||
public struct TextureSliceData
|
||||
{
|
||||
public void* Data;
|
||||
public uint32 LinePitch;
|
||||
public uint32 SlicePitch;
|
||||
|
||||
public this(void* data, uint32 linePitch, uint32 slicePitch)
|
||||
{
|
||||
Data = data;
|
||||
LinePitch = linePitch;
|
||||
SlicePitch = slicePitch;
|
||||
}
|
||||
}
|
||||
|
||||
public class Texture2D : Texture
|
||||
{
|
||||
//public override extern uint32 Width {get;}
|
||||
@@ -69,6 +87,17 @@ namespace GlitchyEngine.Renderer
|
||||
PrepareTexturePlatform(desc, false);
|
||||
}
|
||||
|
||||
public Result<void> SetData(Span<TextureSliceData> slices)
|
||||
{
|
||||
if (slices.Length != ArraySize * MipLevels)
|
||||
{
|
||||
Log.EngineLogger.Error("Not enough slices provided to initialize texture.");
|
||||
return .Err;
|
||||
}
|
||||
|
||||
return PlatformSetData(slices);
|
||||
}
|
||||
|
||||
public void SetData<T>(T* data, uint32 arraySlice = 0, uint32 mipSlice = 0)
|
||||
{
|
||||
PlatformSetData(data, (.)sizeof(T), 0, 0, Width, Height, arraySlice, mipSlice, .Write);
|
||||
@@ -84,8 +113,6 @@ namespace GlitchyEngine.Renderer
|
||||
uint32 mipLevels = 1, uint32 arraySize = 1, Usage usage = .Default, CPUAccessFlags cpuAccess = .None
|
||||
*/
|
||||
|
||||
protected extern void CreateTexturePlatform(Texture2DDesc desc, bool isRenderTarget, void* data, uint32 linePitch);
|
||||
|
||||
/**
|
||||
* Prepares the texture so that a call to SetData can successfully upload the data to the gpu.
|
||||
*/
|
||||
@@ -94,6 +121,8 @@ namespace GlitchyEngine.Renderer
|
||||
protected extern Result<void> PlatformSetData(void* data, uint32 elementSize, uint32 destX,
|
||||
uint32 destY, uint32 destWidth, uint32 destHeight, uint32 arraySlice, uint32 mipLevel, GlitchyEngine.Renderer.MapType mapType);
|
||||
|
||||
protected extern Result<void> PlatformSetData(Span<TextureSliceData> slices);
|
||||
|
||||
/**
|
||||
* Copies the texel-data of this texture to the given destination texture.
|
||||
*/
|
||||
|
||||
Reference in New Issue
Block a user