mirror of
https://github.com/aharabada/glitchy-engine-beef.git
synced 2026-09-05 21:01:52 +00:00
Added SamplerState
This commit is contained in:
@@ -0,0 +1,123 @@
|
|||||||
|
using DirectX.D3D11;
|
||||||
|
using DirectX.Common;
|
||||||
|
|
||||||
|
namespace DirectX.D3D11
|
||||||
|
{
|
||||||
|
extension Filter
|
||||||
|
{
|
||||||
|
public static Filter SamplerToFilter(GlitchyEngine.Renderer.SamplerStateDescription samplerDesc)
|
||||||
|
{
|
||||||
|
/*
|
||||||
|
While I'm writing this Function it turns out that the numbers in the D3D11_FILTER-enum
|
||||||
|
aren't as random as I thought. One could even say they are quite clever.
|
||||||
|
|
||||||
|
Explanation:
|
||||||
|
If the Mip filter is Linear the first bit (LSB) will be 1 (Filter = 0x01)
|
||||||
|
If the Mag filter is Linear the third bit will be 1 (Filter = 0x04)
|
||||||
|
If the Min filter is Linear the fifth bit will be 1 (Filter = 0x10)
|
||||||
|
if any of them is Point their respective bit will be 0
|
||||||
|
|
||||||
|
If the filter is Anisotropic the Filter will be 0x0101'0101.
|
||||||
|
|
||||||
|
Comparison-, Minimum- and Maximum-Filter modes will also set their respective bit.
|
||||||
|
(0x80, 0x100 and 0x180 respectively)
|
||||||
|
*/
|
||||||
|
|
||||||
|
Filter output = .Min_Mag_Mip_Point;
|
||||||
|
|
||||||
|
// Mip filter
|
||||||
|
if(samplerDesc.MipFilter == .Linear)
|
||||||
|
{
|
||||||
|
output |= .Min_Mag_Point_Mip_Linear;
|
||||||
|
}
|
||||||
|
else if(samplerDesc.MipFilter == .Anisotropic)
|
||||||
|
{
|
||||||
|
output = .Anisotropic;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Min filter
|
||||||
|
if(samplerDesc.MagFilter == .Linear)
|
||||||
|
{
|
||||||
|
output |= .Min_Point_Mag_Linear_Mip_Point;
|
||||||
|
}
|
||||||
|
else if(samplerDesc.MagFilter == .Anisotropic)
|
||||||
|
{
|
||||||
|
output = .Anisotropic;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Mag filter
|
||||||
|
if(samplerDesc.MinFilter == .Linear)
|
||||||
|
{
|
||||||
|
output |= .Min_Linear_Mag_Mip_Point;
|
||||||
|
}
|
||||||
|
else if(samplerDesc.MagFilter == .Anisotropic)
|
||||||
|
{
|
||||||
|
output = .Anisotropic;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Sets filter mode bit
|
||||||
|
switch(samplerDesc.FilterMode)
|
||||||
|
{
|
||||||
|
case .Default:
|
||||||
|
output |= .Min_Mag_Mip_Point;
|
||||||
|
case .Comparison:
|
||||||
|
output |= .Comparison_Min_Mag_Mip_Point;
|
||||||
|
case .Minimum:
|
||||||
|
output |= .Minimum_Min_Mag_Mip_Point;
|
||||||
|
case .Maximum:
|
||||||
|
output |= .Maximum_Min_Mag_Mip_Point;
|
||||||
|
}
|
||||||
|
|
||||||
|
return output;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
using internal GlitchyEngine.Renderer;
|
||||||
|
|
||||||
|
namespace GlitchyEngine.Renderer
|
||||||
|
{
|
||||||
|
extension SamplerStateDescription
|
||||||
|
{
|
||||||
|
typealias NativeDesc = DirectX.D3D11.SamplerStateDescription;
|
||||||
|
|
||||||
|
public void ToNative(out NativeDesc samplerDesc)
|
||||||
|
{
|
||||||
|
samplerDesc.Filter = .SamplerToFilter(this);
|
||||||
|
|
||||||
|
samplerDesc.ComparisonFunc = (.)ComparisonFunction;
|
||||||
|
|
||||||
|
samplerDesc.AddressU = (.)AddressModeU;
|
||||||
|
samplerDesc.AddressV = (.)AddressModeV;
|
||||||
|
samplerDesc.AddressW = (.)AddressModeW;
|
||||||
|
|
||||||
|
samplerDesc.MipLODBias = MipLODBias;
|
||||||
|
samplerDesc.MinLOD = MipMinLOD;
|
||||||
|
samplerDesc.MaxLOD = MipMaxLOD;
|
||||||
|
|
||||||
|
samplerDesc.MaxAnisotropy = MaxAnisotropy;
|
||||||
|
|
||||||
|
samplerDesc.BorderColor = BorderColor;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
extension SamplerState
|
||||||
|
{
|
||||||
|
internal ID3D11SamplerState* nativeSamplerState ~ _?.Release();
|
||||||
|
|
||||||
|
protected override void PlatformCreateSamplerState()
|
||||||
|
{
|
||||||
|
_desc.ToNative(var nativeDesc);
|
||||||
|
|
||||||
|
HResult result = _context.nativeDevice.CreateSamplerState(ref nativeDesc, &nativeSamplerState);
|
||||||
|
|
||||||
|
Log.EngineLogger.Assert(result.Succeeded, scope $"Failed to create SamplerState. Error({(int)result}): {result}");
|
||||||
|
}
|
||||||
|
|
||||||
|
public override void Bind(uint32 slot)
|
||||||
|
{
|
||||||
|
_context.nativeContext.VertexShader.SetSamplers(slot, 1, &nativeSamplerState);
|
||||||
|
_context.nativeContext.PixelShader.SetSamplers(slot, 1, &nativeSamplerState);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,169 @@
|
|||||||
|
using System;
|
||||||
|
using GlitchyEngine.Math;
|
||||||
|
|
||||||
|
namespace GlitchyEngine.Renderer
|
||||||
|
{
|
||||||
|
public enum FilterFunction
|
||||||
|
{
|
||||||
|
/// Use point filtering (nearest neighbor) for sampling.
|
||||||
|
Point,
|
||||||
|
/// Use linear interpolation for sampling.
|
||||||
|
Linear,
|
||||||
|
/// Use anisotropic interpolation for sampling.
|
||||||
|
Anisotropic
|
||||||
|
}
|
||||||
|
|
||||||
|
public enum FilterMode
|
||||||
|
{
|
||||||
|
/// Just sample the texture.
|
||||||
|
Default,
|
||||||
|
/// Sample the texture and compares it with a comparison value.
|
||||||
|
Comparison,
|
||||||
|
/// Return the minimum value of the fetched texels.
|
||||||
|
Minimum,
|
||||||
|
/// Return the maximum value of the fetched texels.
|
||||||
|
Maximum
|
||||||
|
}
|
||||||
|
|
||||||
|
public enum ComparisonFunction
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* Never pass the comparison.
|
||||||
|
*/
|
||||||
|
Never = 1,
|
||||||
|
/**
|
||||||
|
* If the source data is less than the destination data, the comparison passes.
|
||||||
|
*/
|
||||||
|
Less = 2,
|
||||||
|
/**
|
||||||
|
* If the source data is equal to the destination data, the comparison passes.
|
||||||
|
*/
|
||||||
|
Equal = 3,
|
||||||
|
/**
|
||||||
|
* If the source data is less than or equal to the destination data, the comparison passes.
|
||||||
|
*/
|
||||||
|
LessOrEqual = 4,
|
||||||
|
/**
|
||||||
|
* If the source data is greater than the destination data, the comparison passes.
|
||||||
|
*/
|
||||||
|
Greater = 5,
|
||||||
|
/**
|
||||||
|
* If the source data is not equal to the destination data, the comparison passes.
|
||||||
|
*/
|
||||||
|
NotEqual = 6,
|
||||||
|
/**
|
||||||
|
* If the source data is greater than or equal to the destination data, the comparison passes.
|
||||||
|
*/
|
||||||
|
GreaterOrEqual = 7,
|
||||||
|
/**
|
||||||
|
* Always pass the comparison.
|
||||||
|
*/
|
||||||
|
Always = 8
|
||||||
|
}
|
||||||
|
|
||||||
|
public enum TextureAddressMode
|
||||||
|
{
|
||||||
|
/// Tile the texture at every (u,v) integer junction.
|
||||||
|
Wrap = 1,
|
||||||
|
/*
|
||||||
|
* Tile the texture at every (u,v) integer junction. However it is flipped every other tile.
|
||||||
|
* Example
|
||||||
|
* Between 0 and 1 the texture is addressed normally.
|
||||||
|
* Between 1 and 2 the texture is flipped.
|
||||||
|
* Between 2 and 3 the texture is addressed normally.
|
||||||
|
*/
|
||||||
|
Mirror,
|
||||||
|
/**
|
||||||
|
* Texture coordinates outside the range [0.0, 1.0] are set to the texture color at 0.0 or 1.0, respectively.
|
||||||
|
*/
|
||||||
|
Clamp,
|
||||||
|
/**
|
||||||
|
* Texture coordinates outside the range [0.0, 1.0] are set to the border color.
|
||||||
|
*/
|
||||||
|
Border,
|
||||||
|
/**
|
||||||
|
* Like a combination of Mirror and Clamp.
|
||||||
|
* Sample using the absolute value and clamp to 1.0.
|
||||||
|
*/
|
||||||
|
MirrorOnce
|
||||||
|
}
|
||||||
|
|
||||||
|
public struct SamplerStateDescription
|
||||||
|
{
|
||||||
|
public FilterFunction MinFilter = .Linear;
|
||||||
|
public FilterFunction MagFilter = .Linear;
|
||||||
|
public FilterFunction MipFilter = .Linear;
|
||||||
|
|
||||||
|
public FilterMode FilterMode = .Default;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The function that is used to compare the sampled data against the existing sampled data.
|
||||||
|
* Only applies if FilterMode is set to FilterMode.Comparison.
|
||||||
|
*/
|
||||||
|
public ComparisonFunction ComparisonFunction = .Never;
|
||||||
|
|
||||||
|
public TextureAddressMode AddressModeU = .Clamp;
|
||||||
|
public TextureAddressMode AddressModeV = .Clamp;
|
||||||
|
public TextureAddressMode AddressModeW = .Clamp;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Offset from the calculated mipmap level.
|
||||||
|
* For example, if Direct3D calculates that a texture should be sampled at mipmap level 3 and MipLODBias is 2, then the texture will be sampled at mipmap level 5.
|
||||||
|
*/
|
||||||
|
public float MipLODBias = 0;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Lower end of the mipmap range to clamp access to, where 0 is the largest and most detailed mipmap level and any level higher than that is less detailed.
|
||||||
|
*/
|
||||||
|
public float MipMinLOD = float.MinValue;
|
||||||
|
/**
|
||||||
|
* Upper end of the mipmap range to clamp access to, where 0 is the largest and most detailed mipmap level and any level higher than that is less detailed.
|
||||||
|
* This value must be greater than or equal to MinLOD. To have no upper limit on LOD set this to a large value such as float.MaxValue.
|
||||||
|
*/
|
||||||
|
public float MipMaxLOD = float.MaxValue;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Clamping value used if FilterMode.Anisotropic is specified in the Filters.
|
||||||
|
* Valid values are between 1 and 16.
|
||||||
|
*/
|
||||||
|
public uint32 MaxAnisotropy = 1; // TODO: we could use a smaller int
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Border color to use if TextureAddressMode.Border is specified for AddressModeU, AddressModeV, or AddressModeW.
|
||||||
|
*/
|
||||||
|
public ColorRGBA BorderColor = .White;
|
||||||
|
}
|
||||||
|
|
||||||
|
public class SamplerState : RefCounted
|
||||||
|
{
|
||||||
|
protected GraphicsContext _context ~ _?.ReleaseRef();
|
||||||
|
|
||||||
|
protected SamplerStateDescription _desc;
|
||||||
|
|
||||||
|
[Inline]
|
||||||
|
public FilterFunction MinificationFilter => _desc.MinFilter;
|
||||||
|
[Inline]
|
||||||
|
public FilterFunction MagnificationFilter => _desc.MagFilter;
|
||||||
|
[Inline]
|
||||||
|
public FilterFunction MipFilter => _desc.MipFilter;
|
||||||
|
[Inline]
|
||||||
|
public FilterMode FilterMode => _desc.FilterMode;
|
||||||
|
|
||||||
|
protected this(GraphicsContext context)
|
||||||
|
{
|
||||||
|
_context = context..AddRef();
|
||||||
|
}
|
||||||
|
|
||||||
|
public this(GraphicsContext context, SamplerStateDescription desc) : this(context)
|
||||||
|
{
|
||||||
|
_desc = desc;
|
||||||
|
|
||||||
|
PlatformCreateSamplerState();
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Creates the platform specific Sampler State
|
||||||
|
protected extern void PlatformCreateSamplerState();
|
||||||
|
|
||||||
|
public extern void Bind(uint32 slot = 0);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -69,6 +69,7 @@ namespace Sandbox
|
|||||||
GraphicsContext _context ~ _?.ReleaseRef();
|
GraphicsContext _context ~ _?.ReleaseRef();
|
||||||
|
|
||||||
Texture2D _texture ~ _?.ReleaseRef();
|
Texture2D _texture ~ _?.ReleaseRef();
|
||||||
|
SamplerState _sampler ~ _?.ReleaseRef();
|
||||||
|
|
||||||
private Vector3 CircleCoord(float angle)
|
private Vector3 CircleCoord(float angle)
|
||||||
{
|
{
|
||||||
@@ -193,6 +194,12 @@ namespace Sandbox
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
_texture = new Texture2D(_context, "content/Textures/Checkerboard.dds");
|
_texture = new Texture2D(_context, "content/Textures/Checkerboard.dds");
|
||||||
|
|
||||||
|
_sampler = new SamplerState(_context,
|
||||||
|
SamplerStateDescription()
|
||||||
|
{
|
||||||
|
MagFilter = .Point
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
public override void Update(GameTime gameTime)
|
public override void Update(GameTime gameTime)
|
||||||
@@ -262,6 +269,7 @@ namespace Sandbox
|
|||||||
_cBuffer.Update();
|
_cBuffer.Update();
|
||||||
|
|
||||||
_texture.Bind();
|
_texture.Bind();
|
||||||
|
_sampler.Bind();
|
||||||
|
|
||||||
Renderer.Submit(_geometryBinding, _effect);
|
Renderer.Submit(_geometryBinding, _effect);
|
||||||
Renderer.Submit(_quadGeometryBinding, _textureEffect, .Scaling(1.5f));
|
Renderer.Submit(_quadGeometryBinding, _textureEffect, .Scaling(1.5f));
|
||||||
|
|||||||
Reference in New Issue
Block a user