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:
@@ -70,7 +70,7 @@ public struct float4
|
||||
public const float4 UnitZ = .(0f, 0f, 1f, 0f);
|
||||
public const float4 UnitW = .(0f, 0f, 0f, 1f);
|
||||
public const float4 One = .(1f, 1f, 1f, 1f);
|
||||
|
||||
|
||||
public static implicit operator int4(float4 value)
|
||||
{
|
||||
return int4((int32)value.X, (int32)value.Y, (int32)value.Z, (int32)value.W);
|
||||
|
||||
@@ -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.
|
||||
*/
|
||||
@@ -93,6 +120,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