diff options
| author | ReinUsesLisp <reinuseslisp@airmail.cc> | 2018-07-05 15:47:29 -0300 |
|---|---|---|
| committer | gdkchan <gab.dark.100@gmail.com> | 2018-07-05 15:47:29 -0300 |
| commit | 97ca974213ec9564ed4a9c57e998ca726dbbb64f (patch) | |
| tree | 5daf598d267d3ce05f3ef342621e7f93536fa554 /Ryujinx.Graphics/Gal/OpenGL | |
| parent | c99b2884e4eb9adfb5b893ee84d7678262d19b06 (diff) | |
Implement some GPU features (#209)
* Implement stencil testing
* Implement depth testing
* Implement face culling
* Implement front face
* Comparison functions now take OGL enums too
* Fix front facing when flipping was used
* Add depth and stencil clear values
Diffstat (limited to 'Ryujinx.Graphics/Gal/OpenGL')
| -rw-r--r-- | Ryujinx.Graphics/Gal/OpenGL/OGLEnumConverter.cs | 59 | ||||
| -rw-r--r-- | Ryujinx.Graphics/Gal/OpenGL/OGLRasterizer.cs | 53 |
2 files changed, 112 insertions, 0 deletions
diff --git a/Ryujinx.Graphics/Gal/OpenGL/OGLEnumConverter.cs b/Ryujinx.Graphics/Gal/OpenGL/OGLEnumConverter.cs index 349c695e..3a81150d 100644 --- a/Ryujinx.Graphics/Gal/OpenGL/OGLEnumConverter.cs +++ b/Ryujinx.Graphics/Gal/OpenGL/OGLEnumConverter.cs @@ -5,17 +5,76 @@ namespace Ryujinx.Graphics.Gal.OpenGL { static class OGLEnumConverter { + public static FrontFaceDirection GetFrontFace(GalFrontFace FrontFace) + { + switch (FrontFace) + { + case GalFrontFace.CW: return FrontFaceDirection.Cw; + case GalFrontFace.CCW: return FrontFaceDirection.Ccw; + } + + throw new ArgumentException(nameof(FrontFace)); + } + + public static CullFaceMode GetCullFace(GalCullFace CullFace) + { + switch (CullFace) + { + case GalCullFace.Front: return CullFaceMode.Front; + case GalCullFace.Back: return CullFaceMode.Back; + case GalCullFace.FrontAndBack: return CullFaceMode.FrontAndBack; + } + + throw new ArgumentException(nameof(CullFace)); + } + + public static StencilOp GetStencilOp(GalStencilOp Op) + { + switch (Op) + { + case GalStencilOp.Keep: return StencilOp.Keep; + case GalStencilOp.Zero: return StencilOp.Zero; + case GalStencilOp.Replace: return StencilOp.Replace; + case GalStencilOp.Incr: return StencilOp.Incr; + case GalStencilOp.Decr: return StencilOp.Decr; + case GalStencilOp.Invert: return StencilOp.Invert; + case GalStencilOp.IncrWrap: return StencilOp.IncrWrap; + case GalStencilOp.DecrWrap: return StencilOp.DecrWrap; + } + + throw new ArgumentException(nameof(Op)); + } + public static DepthFunction GetDepthFunc(GalComparisonOp Func) { + //Looks like the GPU can take it's own values (described in GalComparisonOp) and OpenGL values alike if ((int)Func >= (int)DepthFunction.Never && (int)Func <= (int)DepthFunction.Always) { return (DepthFunction)Func; } + switch (Func) + { + case GalComparisonOp.Never: return DepthFunction.Never; + case GalComparisonOp.Less: return DepthFunction.Less; + case GalComparisonOp.Equal: return DepthFunction.Equal; + case GalComparisonOp.Lequal: return DepthFunction.Lequal; + case GalComparisonOp.Greater: return DepthFunction.Greater; + case GalComparisonOp.NotEqual: return DepthFunction.Notequal; + case GalComparisonOp.Gequal: return DepthFunction.Gequal; + case GalComparisonOp.Always: return DepthFunction.Always; + } + throw new ArgumentException(nameof(Func)); } + public static StencilFunction GetStencilFunc(GalComparisonOp Func) + { + //OGL comparison values match, it's just an enum cast + return (StencilFunction)GetDepthFunc(Func); + } + public static DrawElementsType GetDrawElementsType(GalIndexFormat Format) { switch (Format) diff --git a/Ryujinx.Graphics/Gal/OpenGL/OGLRasterizer.cs b/Ryujinx.Graphics/Gal/OpenGL/OGLRasterizer.cs index 8bff6bb3..b9885711 100644 --- a/Ryujinx.Graphics/Gal/OpenGL/OGLRasterizer.cs +++ b/Ryujinx.Graphics/Gal/OpenGL/OGLRasterizer.cs @@ -106,6 +106,11 @@ namespace Ryujinx.Graphics.Gal.OpenGL return IboCache.TryGetSize(Key, out long Size) && Size == DataSize; } + public void SetFrontFace(GalFrontFace FrontFace) + { + GL.FrontFace(OGLEnumConverter.GetFrontFace(FrontFace)); + } + public void EnableCullFace() { GL.Enable(EnableCap.CullFace); @@ -116,6 +121,11 @@ namespace Ryujinx.Graphics.Gal.OpenGL GL.Disable(EnableCap.CullFace); } + public void SetCullFace(GalCullFace CullFace) + { + GL.CullFace(OGLEnumConverter.GetCullFace(CullFace)); + } + public void EnableDepthTest() { GL.Enable(EnableCap.DepthTest); @@ -131,6 +141,49 @@ namespace Ryujinx.Graphics.Gal.OpenGL GL.DepthFunc(OGLEnumConverter.GetDepthFunc(Func)); } + public void SetClearDepth(float Depth) + { + GL.ClearDepth(Depth); + } + + public void EnableStencilTest() + { + GL.Enable(EnableCap.StencilTest); + } + + public void DisableStencilTest() + { + GL.Disable(EnableCap.StencilTest); + } + + public void SetStencilFunction(bool IsFrontFace, GalComparisonOp Func, int Ref, int Mask) + { + GL.StencilFuncSeparate( + IsFrontFace ? StencilFace.Front : StencilFace.Back, + OGLEnumConverter.GetStencilFunc(Func), + Ref, + Mask); + } + + public void SetStencilOp(bool IsFrontFace, GalStencilOp Fail, GalStencilOp ZFail, GalStencilOp ZPass) + { + GL.StencilOpSeparate( + IsFrontFace ? StencilFace.Front : StencilFace.Back, + OGLEnumConverter.GetStencilOp(Fail), + OGLEnumConverter.GetStencilOp(ZFail), + OGLEnumConverter.GetStencilOp(ZPass)); + } + + public void SetStencilMask(bool IsFrontFace, int Mask) + { + GL.StencilMaskSeparate(IsFrontFace ? StencilFace.Front : StencilFace.Back, Mask); + } + + public void SetClearStencil(int Stencil) + { + GL.ClearStencil(Stencil); + } + public void CreateVbo(long Key, byte[] Buffer) { int Handle = GL.GenBuffer(); |
