mirror of
https://github.com/aharabada/glitchy-engine-beef.git
synced 2026-09-05 21:01:52 +00:00
Added constructor and SetData to Texture2D
obviously this has to be done for the other texture types as well at some point
This commit is contained in:
@@ -0,0 +1,62 @@
|
|||||||
|
using System;
|
||||||
|
|
||||||
|
namespace GlitchyEngine.Math
|
||||||
|
{
|
||||||
|
public struct ResourceBox
|
||||||
|
{
|
||||||
|
/// The x position of the left hand side of the box.
|
||||||
|
public uint32 Left;
|
||||||
|
/// The y position of the top of the box.
|
||||||
|
public uint32 Top;
|
||||||
|
/// The z position of the front of the box.
|
||||||
|
public uint32 Front;
|
||||||
|
/// The x position of the right hand side of the box.
|
||||||
|
public uint32 Right;
|
||||||
|
/// The y position of the bottom of the box.
|
||||||
|
public uint32 Bottom;
|
||||||
|
/// The z position of the back of the box.
|
||||||
|
public uint32 Back;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns true if the box is empty.
|
||||||
|
* A box is empty if the top value is greater than or equal to the bottom value,
|
||||||
|
* or the left value is greater than or equal to the right value,
|
||||||
|
* or the front value is greater than or equal to the back value.
|
||||||
|
*/
|
||||||
|
public bool IsEmpty => Top >= Bottom || Left >= Right || Front >= Back;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Instantiates a new instance of an uninitialized Box structure.
|
||||||
|
*/
|
||||||
|
public this()
|
||||||
|
{
|
||||||
|
this = default;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Instantiates a new instance of a Box structure that is initialized with the dimensions of a box.
|
||||||
|
*/
|
||||||
|
public this(uint32 left, uint32 top, uint32 front, uint32 right, uint32 bottom, uint32 back)
|
||||||
|
{
|
||||||
|
Left = left;
|
||||||
|
Top = top;
|
||||||
|
Front = front;
|
||||||
|
Right = right;
|
||||||
|
Bottom = bottom;
|
||||||
|
Back = back;
|
||||||
|
}
|
||||||
|
|
||||||
|
[Inline]
|
||||||
|
public static bool operator ==(ResourceBox l, ResourceBox r)
|
||||||
|
{
|
||||||
|
return l.Left == r.Left && l.Top == r.Top && l.Front == r.Front &&
|
||||||
|
l.Right == r.Right && l.Bottom == r.Bottom && l.Back == r.Back;
|
||||||
|
}
|
||||||
|
|
||||||
|
[Inline]
|
||||||
|
public static bool operator !=(ResourceBox l, ResourceBox r)
|
||||||
|
{
|
||||||
|
return !(l == r);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -2,6 +2,7 @@ using System;
|
|||||||
using DirectX.D3D11;
|
using DirectX.D3D11;
|
||||||
using DirectX.Common;
|
using DirectX.Common;
|
||||||
using DirectXTK;
|
using DirectXTK;
|
||||||
|
using GlitchyEngine.Math;
|
||||||
|
|
||||||
using internal GlitchyEngine.Renderer;
|
using internal GlitchyEngine.Renderer;
|
||||||
|
|
||||||
@@ -34,15 +35,15 @@ namespace GlitchyEngine.Renderer
|
|||||||
|
|
||||||
// TODO: missing options
|
// TODO: missing options
|
||||||
desc.SampleDesc = .(1, 0);
|
desc.SampleDesc = .(1, 0);
|
||||||
desc.Usage = .Immutable;
|
desc.Usage = (.)Usage;
|
||||||
desc.BindFlags = .ShaderResource;
|
desc.BindFlags = .ShaderResource;
|
||||||
desc.CpuAccessFlags = .None;
|
desc.CpuAccessFlags = (.)CpuAccess;
|
||||||
desc.MiscFlags = .None;
|
desc.MiscFlags = .None;
|
||||||
|
|
||||||
return desc;
|
return desc;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static implicit operator NativeTex2DDesc(Self desc) => desc.ToNative();
|
public static explicit operator NativeTex2DDesc(Self desc) => desc.ToNative();
|
||||||
}
|
}
|
||||||
|
|
||||||
extension Texture2D
|
extension Texture2D
|
||||||
@@ -84,7 +85,7 @@ namespace GlitchyEngine.Renderer
|
|||||||
nativeTexture?.Release();
|
nativeTexture?.Release();
|
||||||
nativeView?.Release();
|
nativeView?.Release();
|
||||||
|
|
||||||
nativeDesc = desc;
|
nativeDesc = (NativeTex2DDesc)desc;
|
||||||
SubresourceData resData = .(data, linePitch, 0);
|
SubresourceData resData = .(data, linePitch, 0);
|
||||||
|
|
||||||
var result = _context.[Friend]nativeDevice.CreateTexture2D(ref nativeDesc, &resData, &nativeTexture);
|
var result = _context.[Friend]nativeDevice.CreateTexture2D(ref nativeDesc, &resData, &nativeTexture);
|
||||||
@@ -95,6 +96,135 @@ namespace GlitchyEngine.Renderer
|
|||||||
|
|
||||||
Log.EngineLogger.Assert(result.Succeeded, scope $"Failed to create texture view. Error ({result.Underlying}): {result}");
|
Log.EngineLogger.Assert(result.Succeeded, scope $"Failed to create texture view. Error ({result.Underlying}): {result}");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void InternalCreateTexture(void* data, uint32 linePitch, uint32 slicePitch)
|
||||||
|
{
|
||||||
|
SubresourceData resData = .(data, linePitch, slicePitch);
|
||||||
|
|
||||||
|
// If data is null, set subresourceData null
|
||||||
|
SubresourceData* resDataPtr = data == null ? null : &resData;
|
||||||
|
|
||||||
|
var result = _context.nativeDevice.CreateTexture2D(ref nativeDesc, resDataPtr, &nativeTexture);
|
||||||
|
Log.EngineLogger.Assert(result.Succeeded, scope $"Failed to create texture 2D. Error ({result.Underlying}): {result}");
|
||||||
|
|
||||||
|
result = _context.[Friend]nativeDevice.CreateShaderResourceView(nativeTexture, null, &nativeView);
|
||||||
|
Log.EngineLogger.Assert(result.Succeeded, scope $"Failed to create texture view. Error ({result.Underlying}): {result}");
|
||||||
|
}
|
||||||
|
|
||||||
|
protected override void PrepareTexturePlatform(Texture2DDesc desc)
|
||||||
|
{
|
||||||
|
nativeTexture?.Release();
|
||||||
|
nativeTexture = null;
|
||||||
|
nativeView?.Release();
|
||||||
|
|
||||||
|
nativeDesc = (NativeTex2DDesc)desc;
|
||||||
|
}
|
||||||
|
|
||||||
|
// TODO: Update Texture Arrays!
|
||||||
|
protected override System.Result<void> PlatformSetData(void* data, uint32 elementSize, uint32 destX,
|
||||||
|
uint32 destY, uint32 destWidth, uint32 destHeight, uint32 arraySlice, uint32 mipLevel, GlitchyEngine.Renderer.MapType mapType)
|
||||||
|
{
|
||||||
|
if(nativeTexture == null)
|
||||||
|
{
|
||||||
|
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.
|
||||||
|
var rowPitch = elementSize * destWidth;
|
||||||
|
return InternalCreateTexture(data, rowPitch, rowPitch * destHeight);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// If we don't set the entire texture we need to create the texture with unknown content and set it manually
|
||||||
|
Log.EngineLogger.Assert(nativeDesc.Usage != .Immutable, "The entire immutable texture has to be initialized.");
|
||||||
|
InternalCreateTexture(null, 0, 0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//Log.EngineLogger.AssertDebug();
|
||||||
|
// TODO: Debug.Assert(dstByteOffset + byteLength <= _description.Size, "The destination offset and byte length are too long for the target buffer.");
|
||||||
|
|
||||||
|
uint32 subresourceIndex = D3D11.CalcSubresource(mipLevel, arraySlice, nativeDesc.MipLevels);
|
||||||
|
|
||||||
|
switch(nativeDesc.Usage)
|
||||||
|
{
|
||||||
|
case .Default:
|
||||||
|
Box dataBox = .(destX, destY, 0, destX + destWidth, destY + destHeight, 1);
|
||||||
|
var rowPitch = elementSize * destWidth;
|
||||||
|
_context.nativeContext.UpdateSubresource(nativeTexture, subresourceIndex, &dataBox, data, rowPitch, rowPitch * destHeight);
|
||||||
|
case .Dynamic:
|
||||||
|
Runtime.NotImplemented();
|
||||||
|
/*
|
||||||
|
Log.EngineLogger.Assert(mapType.CanWrite, "The map type has to have write access.");
|
||||||
|
// Todo: DoNotWaitFlag
|
||||||
|
MappedSubresource map = ?;
|
||||||
|
_context.nativeContext.Map(nativeBuffer, 0, (.)mapType, .None, &map);
|
||||||
|
Internal.MemCpy(((uint8*)map.Data) + dstByteOffset, data, byteLength);
|
||||||
|
_context.nativeContext.Unmap(nativeBuffer, 0);
|
||||||
|
*/
|
||||||
|
case .Immutable:
|
||||||
|
Log.EngineLogger.Error("Can't set the data of an immutable resource.");
|
||||||
|
return .Err;
|
||||||
|
default:
|
||||||
|
Log.EngineLogger.Error($"Unknown resource usage: {nativeDesc.Usage}");
|
||||||
|
return .Err;
|
||||||
|
}
|
||||||
|
|
||||||
|
return .Ok;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static override void CopySubresourceRegion(Texture2D source, Texture2D destination,
|
||||||
|
ResourceBox sourceBox = default, uint32 destX = 0, uint32 destY = 0,
|
||||||
|
uint32 srcArraySlice = 0, uint32 srcMipSlice = 0, uint32 destArraySlice = 0, uint32 destMipSlice = 0)
|
||||||
|
{
|
||||||
|
Log.EngineLogger.AssertDebug(source != destination || srcArraySlice != destArraySlice
|
||||||
|
|| srcMipSlice != destMipSlice, "Cannot copy from and to the same sub resource.");
|
||||||
|
|
||||||
|
Log.EngineLogger.AssertDebug(source.nativeDesc.Format == destination.nativeDesc.Format,
|
||||||
|
"Source and destination resources must have the same texel-format.");
|
||||||
|
|
||||||
|
var sourceBox;
|
||||||
|
|
||||||
|
if(sourceBox.Right == 0)
|
||||||
|
{
|
||||||
|
sourceBox.Right = source.Width;
|
||||||
|
sourceBox.Bottom = source.Height;
|
||||||
|
sourceBox.Back = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Make sure the destination was initialized
|
||||||
|
if(destination.nativeTexture == null)
|
||||||
|
destination.InternalCreateTexture(null, 0, 0);
|
||||||
|
|
||||||
|
source._context.nativeContext.CopySubresourceRegion(destination.nativeTexture,
|
||||||
|
D3D11.CalcSubresource(destMipSlice, destArraySlice, destination.MipLevels), destX, destY, 0,
|
||||||
|
source.nativeTexture, D3D11.CalcSubresource(srcMipSlice, srcArraySlice, source.MipLevels), (.)&sourceBox);
|
||||||
|
}
|
||||||
|
|
||||||
|
public override void CopyTo(Texture2D destination)
|
||||||
|
{
|
||||||
|
if(nativeTexture == null)
|
||||||
|
return;
|
||||||
|
|
||||||
|
Log.EngineLogger.AssertDebug(nativeDesc.Format == destination.nativeDesc.Format,
|
||||||
|
"Source and destination resources must have the same texel-format.");
|
||||||
|
|
||||||
|
// Make sure the destination was initialized
|
||||||
|
if(destination.nativeTexture == null)
|
||||||
|
destination.InternalCreateTexture(null, 0, 0);
|
||||||
|
|
||||||
|
uint32 arraySlices = Math.Min(ArraySize, destination.ArraySize);
|
||||||
|
uint32 mipSlices = Math.Min(MipLevels, destination.MipLevels);
|
||||||
|
|
||||||
|
for(uint32 arraySlice < arraySlices)
|
||||||
|
for(uint32 mipSlice < mipSlices)
|
||||||
|
{
|
||||||
|
Box sourceBox = .(0, 0, 0, Width, Height, 1);
|
||||||
|
|
||||||
|
_context.nativeContext.CopySubresourceRegion(destination.nativeTexture,
|
||||||
|
D3D11.CalcSubresource(mipSlice, arraySlice, destination.MipLevels), 0, 0, 0,
|
||||||
|
nativeTexture, D3D11.CalcSubresource(mipSlice, arraySlice, MipLevels), (.)&sourceBox);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
extension TextureCube
|
extension TextureCube
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
using System;
|
using System;
|
||||||
|
using GlitchyEngine.Math;
|
||||||
|
|
||||||
namespace GlitchyEngine.Renderer
|
namespace GlitchyEngine.Renderer
|
||||||
{
|
{
|
||||||
@@ -53,6 +54,8 @@ namespace GlitchyEngine.Renderer
|
|||||||
public uint32 ArraySize;
|
public uint32 ArraySize;
|
||||||
public uint32 MipLevels;
|
public uint32 MipLevels;
|
||||||
public Format Format;
|
public Format Format;
|
||||||
|
public Usage Usage;
|
||||||
|
public CPUAccessFlags CpuAccess;
|
||||||
}
|
}
|
||||||
|
|
||||||
public class Texture2D : Texture
|
public class Texture2D : Texture
|
||||||
@@ -73,9 +76,49 @@ namespace GlitchyEngine.Renderer
|
|||||||
LoadTexturePlatform();
|
LoadTexturePlatform();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public this(GraphicsContext context, Texture2DDesc desc) : base(context)
|
||||||
|
{
|
||||||
|
PrepareTexturePlatform(desc);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void SetData<T>(T* data, uint32 arraySlice = 0, uint32 mipSlice = 0)
|
||||||
|
{
|
||||||
|
PlatformSetData(data, (.)sizeof(T), 0, 0, Width, Height, arraySlice, mipSlice, .Write);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void SetData<T>(T* data, uint32 x, uint32 y, uint32 width, uint32 height, uint32 arraySlice = 0, uint32 mipSlice = 0)
|
||||||
|
{
|
||||||
|
PlatformSetData(data, (.)sizeof(T), x, y, width, height, arraySlice, mipSlice, .Write);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
uint32 width, uint32 height, Format format,
|
||||||
|
uint32 mipLevels = 1, uint32 arraySize = 1, Usage usage = .Default, CPUAccessFlags cpuAccess = .None
|
||||||
|
*/
|
||||||
|
|
||||||
protected extern void LoadTexturePlatform();
|
protected extern void LoadTexturePlatform();
|
||||||
|
|
||||||
protected extern void CreateTexturePlatform(Texture2DDesc desc, void* data, uint32 linePitch);
|
protected extern void CreateTexturePlatform(Texture2DDesc desc, void* data, uint32 linePitch);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Prepares the texture so that a call to SetData can successfully upload the data to the gpu.
|
||||||
|
*/
|
||||||
|
protected extern void PrepareTexturePlatform(Texture2DDesc desc);
|
||||||
|
|
||||||
|
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);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Copies the texel-data of this texture to the given destination texture.
|
||||||
|
*/
|
||||||
|
public static extern void CopySubresourceRegion(Texture2D source, Texture2D destination,
|
||||||
|
ResourceBox sourceBox = default, uint32 destX = 0, uint32 destY = 0,
|
||||||
|
uint32 srcArraySlice = 0, uint32 srcMipSlice = 0, uint32 destArraySlice = 0, uint32 destMipSlice = 0);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Copies the data to the given destination.
|
||||||
|
*/
|
||||||
|
public extern void CopyTo(Texture2D destination);
|
||||||
}
|
}
|
||||||
|
|
||||||
public class TextureCube : Texture
|
public class TextureCube : Texture
|
||||||
|
|||||||
Reference in New Issue
Block a user