aboutsummaryrefslogtreecommitdiff
path: root/Ryujinx.Graphics/Gal/OpenGL
diff options
context:
space:
mode:
authorgdkchan <gab.dark.100@gmail.com>2018-04-13 15:12:58 -0300
committerGitHub <noreply@github.com>2018-04-13 15:12:58 -0300
commitc8c86a3854fb3c96e65eca6b59d6058270a21a17 (patch)
tree0f280e0b595d953ca081e493eda41d884fb34ef6 /Ryujinx.Graphics/Gal/OpenGL
parent262b5b80541d23ed248d5b4f2220a479a35d5969 (diff)
Fix for current framebuffer issues (#78)
[GPU] Fix some of the current framebuffer issues
Diffstat (limited to 'Ryujinx.Graphics/Gal/OpenGL')
-rw-r--r--Ryujinx.Graphics/Gal/OpenGL/FrameBuffer.cs250
-rw-r--r--Ryujinx.Graphics/Gal/OpenGL/OGLEnumConverter.cs61
-rw-r--r--Ryujinx.Graphics/Gal/OpenGL/OGLFrameBuffer.cs203
-rw-r--r--Ryujinx.Graphics/Gal/OpenGL/OGLTexture.cs20
-rw-r--r--Ryujinx.Graphics/Gal/OpenGL/OpenGLRenderer.cs89
5 files changed, 281 insertions, 342 deletions
diff --git a/Ryujinx.Graphics/Gal/OpenGL/FrameBuffer.cs b/Ryujinx.Graphics/Gal/OpenGL/FrameBuffer.cs
deleted file mode 100644
index 7e7725d6..00000000
--- a/Ryujinx.Graphics/Gal/OpenGL/FrameBuffer.cs
+++ /dev/null
@@ -1,250 +0,0 @@
-using OpenTK;
-using OpenTK.Graphics.OpenGL;
-using System;
-
-namespace Ryujinx.Graphics.Gal.OpenGL
-{
- unsafe class FrameBuffer
- {
- public int WindowWidth { get; set; }
- public int WindowHeight { get; set; }
-
- private int VtxShaderHandle;
- private int FragShaderHandle;
- private int PrgShaderHandle;
-
- private int TexHandle;
- private int TexWidth;
- private int TexHeight;
-
- private int VaoHandle;
- private int VboHandle;
-
- private int[] Pixels;
-
- private byte* FbPtr;
-
- private object FbPtrLock;
-
- public FrameBuffer(int Width, int Height)
- {
- if (Width < 0)
- {
- throw new ArgumentOutOfRangeException(nameof(Width));
- }
-
- if (Height < 0)
- {
- throw new ArgumentOutOfRangeException(nameof(Height));
- }
-
- FbPtrLock = new object();
-
- TexWidth = Width;
- TexHeight = Height;
-
- WindowWidth = Width;
- WindowHeight = Height;
-
- SetupShaders();
- SetupTexture();
- SetupVertex();
- }
-
- private void SetupShaders()
- {
- VtxShaderHandle = GL.CreateShader(ShaderType.VertexShader);
- FragShaderHandle = GL.CreateShader(ShaderType.FragmentShader);
-
- string VtxShaderSource = EmbeddedResource.GetString("GlFbVtxShader");
- string FragShaderSource = EmbeddedResource.GetString("GlFbFragShader");
-
- GL.ShaderSource(VtxShaderHandle, VtxShaderSource);
- GL.ShaderSource(FragShaderHandle, FragShaderSource);
- GL.CompileShader(VtxShaderHandle);
- GL.CompileShader(FragShaderHandle);
-
- PrgShaderHandle = GL.CreateProgram();
-
- GL.AttachShader(PrgShaderHandle, VtxShaderHandle);
- GL.AttachShader(PrgShaderHandle, FragShaderHandle);
- GL.LinkProgram(PrgShaderHandle);
- GL.UseProgram(PrgShaderHandle);
-
- int TexUniformLocation = GL.GetUniformLocation(PrgShaderHandle, "tex");
-
- GL.Uniform1(TexUniformLocation, 0);
-
- int WindowSizeUniformLocation = GL.GetUniformLocation(PrgShaderHandle, "window_size");
-
- GL.Uniform2(WindowSizeUniformLocation, new Vector2(1280.0f, 720.0f));
- }
-
- private void SetupTexture()
- {
- Pixels = new int[TexWidth * TexHeight];
-
- if (TexHandle == 0)
- {
- TexHandle = GL.GenTexture();
- }
-
- GL.BindTexture(TextureTarget.Texture2D, TexHandle);
- GL.TexParameter(TextureTarget.Texture2D, TextureParameterName.TextureMinFilter, (int)TextureMinFilter.Linear);
- GL.TexParameter(TextureTarget.Texture2D, TextureParameterName.TextureMagFilter, (int)TextureMagFilter.Linear);
- GL.TexImage2D(TextureTarget.Texture2D,
- 0,
- PixelInternalFormat.Rgba,
- TexWidth,
- TexHeight,
- 0,
- PixelFormat.Rgba,
- PixelType.UnsignedByte,
- IntPtr.Zero);
- }
-
- private void SetupVertex()
- {
- VaoHandle = GL.GenVertexArray();
- VboHandle = GL.GenBuffer();
-
- float[] Buffer = new float[]
- {
- -1, 1, 0, 0,
- 1, 1, 1, 0,
- -1, -1, 0, 1,
- 1, -1, 1, 1
- };
-
- IntPtr Length = new IntPtr(Buffer.Length * 4);
-
- GL.BindBuffer(BufferTarget.ArrayBuffer, VboHandle);
- GL.BufferData(BufferTarget.ArrayBuffer, Length, Buffer, BufferUsageHint.StreamDraw);
- GL.BindBuffer(BufferTarget.ArrayBuffer, 0);
-
- GL.BindVertexArray(VaoHandle);
-
- GL.EnableVertexAttribArray(0);
-
- GL.BindBuffer(BufferTarget.ArrayBuffer, VboHandle);
-
- GL.VertexAttribPointer(0, 2, VertexAttribPointerType.Float, false, 16, 0);
-
- GL.EnableVertexAttribArray(1);
-
- GL.BindBuffer(BufferTarget.ArrayBuffer, VboHandle);
-
- GL.VertexAttribPointer(1, 2, VertexAttribPointerType.Float, false, 16, 8);
-
- GL.BindVertexArray(0);
- }
-
- public unsafe void Set(byte* Fb, int Width, int Height, Matrix2 Transform, Vector2 Offs)
- {
- if (Fb == null)
- {
- throw new ArgumentNullException(nameof(Fb));
- }
-
- if (Width < 0)
- {
- throw new ArgumentOutOfRangeException(nameof(Width));
- }
-
- if (Height < 0)
- {
- throw new ArgumentOutOfRangeException(nameof(Height));
- }
-
- lock (FbPtrLock)
- {
- FbPtr = Fb;
- }
-
- if (Width != TexWidth ||
- Height != TexHeight)
- {
- TexWidth = Width;
- TexHeight = Height;
-
- SetupTexture();
- }
-
- GL.UseProgram(PrgShaderHandle);
-
- int TransformUniformLocation = GL.GetUniformLocation(PrgShaderHandle, "transform");
-
- GL.UniformMatrix2(TransformUniformLocation, false, ref Transform);
-
- int WindowSizeUniformLocation = GL.GetUniformLocation(PrgShaderHandle, "window_size");
-
- GL.Uniform2(WindowSizeUniformLocation, new Vector2(WindowWidth, WindowHeight));
-
- int OffsetUniformLocation = GL.GetUniformLocation(PrgShaderHandle, "offset");
-
- GL.Uniform2(OffsetUniformLocation, Offs);
- }
-
- public void Reset()
- {
- lock (FbPtrLock)
- {
- FbPtr = null;
- }
- }
-
- public void Render()
- {
- lock (FbPtrLock)
- {
- if (FbPtr == null)
- {
- return;
- }
-
- for (int Y = 0; Y < TexHeight; Y++)
- for (int X = 0; X < TexWidth; X++)
- {
- Pixels[X + Y * TexWidth] = *((int*)(FbPtr + GetSwizzleOffset(X, Y)));
- }
- }
-
- GL.BindTexture(TextureTarget.Texture2D, TexHandle);
- GL.TexSubImage2D(TextureTarget.Texture2D,
- 0,
- 0,
- 0,
- TexWidth,
- TexHeight,
- PixelFormat.Rgba,
- PixelType.UnsignedByte,
- Pixels);
-
- GL.ActiveTexture(TextureUnit.Texture0);
-
- GL.BindVertexArray(VaoHandle);
-
- GL.UseProgram(PrgShaderHandle);
-
- GL.DrawArrays(PrimitiveType.TriangleStrip, 0, 4);
- }
-
- private int GetSwizzleOffset(int X, int Y)
- {
- int Pos;
-
- Pos = (Y & 0x7f) >> 4;
- Pos += (X >> 4) << 3;
- Pos += (Y >> 7) * ((TexWidth >> 4) << 3);
- Pos *= 1024;
- Pos += ((Y & 0xf) >> 3) << 9;
- Pos += ((X & 0xf) >> 3) << 8;
- Pos += ((Y & 0x7) >> 1) << 6;
- Pos += ((X & 0x7) >> 2) << 5;
- Pos += ((Y & 0x1) >> 0) << 4;
- Pos += ((X & 0x3) >> 0) << 2;
-
- return Pos;
- }
- }
-} \ No newline at end of file
diff --git a/Ryujinx.Graphics/Gal/OpenGL/OGLEnumConverter.cs b/Ryujinx.Graphics/Gal/OpenGL/OGLEnumConverter.cs
index 17bf6291..4cc0a039 100644
--- a/Ryujinx.Graphics/Gal/OpenGL/OGLEnumConverter.cs
+++ b/Ryujinx.Graphics/Gal/OpenGL/OGLEnumConverter.cs
@@ -127,17 +127,72 @@ namespace Ryujinx.Graphics.Gal.OpenGL
public static BlendEquationMode GetBlendEquation(GalBlendEquation BlendEquation)
{
- return (BlendEquationMode)BlendEquation;
+ switch (BlendEquation)
+ {
+ case GalBlendEquation.FuncAdd: return BlendEquationMode.FuncAdd;
+ case GalBlendEquation.FuncSubtract: return BlendEquationMode.FuncSubtract;
+ case GalBlendEquation.FuncReverseSubtract: return BlendEquationMode.FuncReverseSubtract;
+ case GalBlendEquation.Min: return BlendEquationMode.Min;
+ case GalBlendEquation.Max: return BlendEquationMode.Max;
+ }
+
+ throw new ArgumentException(nameof(BlendEquation));
}
public static BlendingFactorSrc GetBlendFactorSrc(GalBlendFactor BlendFactor)
{
- return (BlendingFactorSrc)(BlendFactor - 0x4000);
+ switch (BlendFactor)
+ {
+ case GalBlendFactor.Zero: return BlendingFactorSrc.Zero;
+ case GalBlendFactor.One: return BlendingFactorSrc.One;
+ case GalBlendFactor.SrcColor: return BlendingFactorSrc.SrcColor;
+ case GalBlendFactor.OneMinusSrcColor: return BlendingFactorSrc.OneMinusSrcColor;
+ case GalBlendFactor.DstColor: return BlendingFactorSrc.DstColor;
+ case GalBlendFactor.OneMinusDstColor: return BlendingFactorSrc.OneMinusDstColor;
+ case GalBlendFactor.SrcAlpha: return BlendingFactorSrc.SrcAlpha;
+ case GalBlendFactor.OneMinusSrcAlpha: return BlendingFactorSrc.OneMinusSrcAlpha;
+ case GalBlendFactor.DstAlpha: return BlendingFactorSrc.DstAlpha;
+ case GalBlendFactor.OneMinusDstAlpha: return BlendingFactorSrc.OneMinusDstAlpha;
+ case GalBlendFactor.ConstantColor: return BlendingFactorSrc.ConstantColor;
+ case GalBlendFactor.OneMinusConstantColor: return BlendingFactorSrc.OneMinusConstantColor;
+ case GalBlendFactor.ConstantAlpha: return BlendingFactorSrc.ConstantAlpha;
+ case GalBlendFactor.OneMinusConstantAlpha: return BlendingFactorSrc.OneMinusConstantAlpha;
+ case GalBlendFactor.SrcAlphaSaturate: return BlendingFactorSrc.SrcAlphaSaturate;
+ case GalBlendFactor.Src1Color: return BlendingFactorSrc.Src1Color;
+ case GalBlendFactor.OneMinusSrc1Color: return BlendingFactorSrc.OneMinusSrc1Color;
+ case GalBlendFactor.Src1Alpha: return BlendingFactorSrc.Src1Alpha;
+ case GalBlendFactor.OneMinusSrc1Alpha: return BlendingFactorSrc.OneMinusSrc1Alpha;
+ }
+
+ throw new ArgumentException(nameof(BlendFactor));
}
public static BlendingFactorDest GetBlendFactorDst(GalBlendFactor BlendFactor)
{
- return (BlendingFactorDest)(BlendFactor - 0x4000);
+ switch (BlendFactor)
+ {
+ case GalBlendFactor.Zero: return BlendingFactorDest.Zero;
+ case GalBlendFactor.One: return BlendingFactorDest.One;
+ case GalBlendFactor.SrcColor: return BlendingFactorDest.SrcColor;
+ case GalBlendFactor.OneMinusSrcColor: return BlendingFactorDest.OneMinusSrcColor;
+ case GalBlendFactor.DstColor: return BlendingFactorDest.DstColor;
+ case GalBlendFactor.OneMinusDstColor: return BlendingFactorDest.OneMinusDstColor;
+ case GalBlendFactor.SrcAlpha: return BlendingFactorDest.SrcAlpha;
+ case GalBlendFactor.OneMinusSrcAlpha: return BlendingFactorDest.OneMinusSrcAlpha;
+ case GalBlendFactor.DstAlpha: return BlendingFactorDest.DstAlpha;
+ case GalBlendFactor.OneMinusDstAlpha: return BlendingFactorDest.OneMinusDstAlpha;
+ case GalBlendFactor.ConstantColor: return BlendingFactorDest.ConstantColor;
+ case GalBlendFactor.OneMinusConstantColor: return BlendingFactorDest.OneMinusConstantColor;
+ case GalBlendFactor.ConstantAlpha: return BlendingFactorDest.ConstantAlpha;
+ case GalBlendFactor.OneMinusConstantAlpha: return BlendingFactorDest.OneMinusConstantAlpha;
+ case GalBlendFactor.SrcAlphaSaturate: return BlendingFactorDest.SrcAlphaSaturate;
+ case GalBlendFactor.Src1Color: return BlendingFactorDest.Src1Color;
+ case GalBlendFactor.OneMinusSrc1Color: return BlendingFactorDest.OneMinusSrc1Color;
+ case GalBlendFactor.Src1Alpha: return BlendingFactorDest.Src1Alpha;
+ case GalBlendFactor.OneMinusSrc1Alpha: return BlendingFactorDest.OneMinusSrc1Alpha;
+ }
+
+ throw new ArgumentException(nameof(BlendFactor));
}
}
} \ No newline at end of file
diff --git a/Ryujinx.Graphics/Gal/OpenGL/OGLFrameBuffer.cs b/Ryujinx.Graphics/Gal/OpenGL/OGLFrameBuffer.cs
index f9c42ae0..818af3b3 100644
--- a/Ryujinx.Graphics/Gal/OpenGL/OGLFrameBuffer.cs
+++ b/Ryujinx.Graphics/Gal/OpenGL/OGLFrameBuffer.cs
@@ -1,16 +1,30 @@
using OpenTK;
using OpenTK.Graphics.OpenGL;
using System;
+using System.Collections.Generic;
namespace Ryujinx.Graphics.Gal.OpenGL
{
class OGLFrameBuffer
{
- private struct FrameBuffer
+ private class FrameBuffer
{
- public int FbHandle;
- public int RbHandle;
- public int TexHandle;
+ public int Width { get; set; }
+ public int Height { get; set; }
+
+ public int Handle { get; private set; }
+ public int RbHandle { get; private set; }
+ public int TexHandle { get; private set; }
+
+ public FrameBuffer(int Width, int Height)
+ {
+ this.Width = Width;
+ this.Height = Height;
+
+ Handle = GL.GenFramebuffer();
+ RbHandle = GL.GenRenderbuffer();
+ TexHandle = GL.GenTexture();
+ }
}
private struct ShaderProgram
@@ -20,83 +34,175 @@ namespace Ryujinx.Graphics.Gal.OpenGL
public int FpHandle;
}
- private FrameBuffer[] Fbs;
+ private Dictionary<long, FrameBuffer> Fbs;
private ShaderProgram Shader;
private bool IsInitialized;
+ private int RawFbTexWidth;
+ private int RawFbTexHeight;
+ private int RawFbTexHandle;
+
+ private int CurrFbHandle;
+ private int CurrTexHandle;
+
private int VaoHandle;
private int VboHandle;
public OGLFrameBuffer()
{
- Fbs = new FrameBuffer[16];
+ Fbs = new Dictionary<long, FrameBuffer>();
Shader = new ShaderProgram();
}
- public void Set(int Index, int Width, int Height)
+ public void Create(long Tag, int Width, int Height)
{
- if (Fbs[Index].FbHandle != 0)
+ if (Fbs.TryGetValue(Tag, out FrameBuffer Fb))
{
- return;
- }
+ if (Fb.Width != Width ||
+ Fb.Height != Height)
+ {
+ SetupTexture(Fb.TexHandle, Width, Height);
- Fbs[Index].FbHandle = GL.GenFramebuffer();
- Fbs[Index].RbHandle = GL.GenRenderbuffer();
- Fbs[Index].TexHandle = GL.GenTexture();
+ Fb.Width = Width;
+ Fb.Height = Height;
+ }
- GL.BindFramebuffer(FramebufferTarget.Framebuffer, Fbs[Index].FbHandle);
+ return;
+ }
- GL.BindRenderbuffer(RenderbufferTarget.Renderbuffer, Fbs[Index].RbHandle);
+ Fb = new FrameBuffer(Width, Height);
- GL.RenderbufferStorage(RenderbufferTarget.Renderbuffer, RenderbufferStorage.Depth24Stencil8, 1280, 720);
+ SetupTexture(Fb.TexHandle, Width, Height);
- GL.FramebufferRenderbuffer(FramebufferTarget.Framebuffer, FramebufferAttachment.DepthStencilAttachment, RenderbufferTarget.Renderbuffer, Fbs[Index].RbHandle);
+ GL.BindFramebuffer(FramebufferTarget.Framebuffer, Fb.Handle);
- GL.BindTexture(TextureTarget.Texture2D, Fbs[Index].TexHandle);
+ GL.BindRenderbuffer(RenderbufferTarget.Renderbuffer, Fb.RbHandle);
- GL.TexParameter(TextureTarget.Texture2D, TextureParameterName.TextureMinFilter, (int)TextureMinFilter.Linear);
- GL.TexParameter(TextureTarget.Texture2D, TextureParameterName.TextureMagFilter, (int)TextureMagFilter.Linear);
+ GL.RenderbufferStorage(
+ RenderbufferTarget.Renderbuffer,
+ RenderbufferStorage.Depth24Stencil8,
+ Width,
+ Height);
- GL.TexImage2D(TextureTarget.Texture2D, 0, PixelInternalFormat.Rgba, 1280, 720, 0, PixelFormat.Rgba, PixelType.UnsignedByte, IntPtr.Zero);
+ GL.FramebufferRenderbuffer(
+ FramebufferTarget.Framebuffer,
+ FramebufferAttachment.DepthStencilAttachment,
+ RenderbufferTarget.Renderbuffer,
+ Fb.RbHandle);
- GL.FramebufferTexture(FramebufferTarget.Framebuffer, FramebufferAttachment.ColorAttachment0, Fbs[Index].TexHandle, 0);
+ GL.FramebufferTexture(
+ FramebufferTarget.Framebuffer,
+ FramebufferAttachment.ColorAttachment0,
+ Fb.TexHandle,
+ 0);
GL.DrawBuffer(DrawBufferMode.ColorAttachment0);
+
+ Fbs.Add(Tag, Fb);
}
- public void Bind(int Index)
+ public void Bind(long Tag)
{
- if (Fbs[Index].FbHandle == 0)
+ if (Fbs.TryGetValue(Tag, out FrameBuffer Fb))
{
- return;
+ GL.BindFramebuffer(FramebufferTarget.Framebuffer, Fb.Handle);
+
+ CurrFbHandle = Fb.Handle;
}
+ }
- GL.BindFramebuffer(FramebufferTarget.Framebuffer, Fbs[Index].FbHandle);
+ public void BindTexture(long Tag, int Index)
+ {
+ if (Fbs.TryGetValue(Tag, out FrameBuffer Fb))
+ {
+ GL.ActiveTexture(TextureUnit.Texture0 + Index);
+
+ GL.BindTexture(TextureTarget.Texture2D, Fb.TexHandle);
+ }
}
- public void Draw(int Index)
+ public void Set(long Tag)
{
- if (Fbs[Index].FbHandle == 0)
+ if (Fbs.TryGetValue(Tag, out FrameBuffer Fb))
{
- return;
+ CurrTexHandle = Fb.TexHandle;
}
+ }
- EnsureInitialized();
+ public void Set(byte[] Data, int Width, int Height)
+ {
+ if (RawFbTexHandle == 0)
+ {
+ RawFbTexHandle = GL.GenTexture();
+ }
- GL.BindFramebuffer(FramebufferTarget.Framebuffer, 0);
+ if (RawFbTexWidth != Width ||
+ RawFbTexHeight != Height)
+ {
+ SetupTexture(RawFbTexHandle, Width, Height);
- GL.BindTexture(TextureTarget.Texture2D, Fbs[Index].TexHandle);
+ RawFbTexWidth = Width;
+ RawFbTexHeight = Height;
+ }
GL.ActiveTexture(TextureUnit.Texture0);
- GL.BindVertexArray(VaoHandle);
+ GL.BindTexture(TextureTarget.Texture2D, RawFbTexHandle);
+
+ (PixelFormat Format, PixelType Type) = OGLEnumConverter.GetTextureFormat(GalTextureFormat.A8B8G8R8);
+
+ GL.TexSubImage2D(TextureTarget.Texture2D, 0, 0, 0, Width, Height, Format, Type, Data);
+
+ CurrTexHandle = RawFbTexHandle;
+ }
+
+ public void SetTransform(Matrix2 Transform, Vector2 Offs)
+ {
+ EnsureInitialized();
+
+ int CurrentProgram = GL.GetInteger(GetPName.CurrentProgram);
GL.UseProgram(Shader.Handle);
- GL.DrawArrays(PrimitiveType.TriangleStrip, 0, 4);
+ int TransformUniformLocation = GL.GetUniformLocation(Shader.Handle, "transform");
+
+ GL.UniformMatrix2(TransformUniformLocation, false, ref Transform);
+
+ int OffsetUniformLocation = GL.GetUniformLocation(Shader.Handle, "offset");
+
+ GL.Uniform2(OffsetUniformLocation, ref Offs);
+
+ GL.UseProgram(CurrentProgram);
+ }
+
+ public void Render()
+ {
+ if (CurrTexHandle != 0)
+ {
+ EnsureInitialized();
+
+ GL.ActiveTexture(TextureUnit.Texture0);
+
+ GL.BindTexture(TextureTarget.Texture2D, CurrTexHandle);
+
+ int CurrentProgram = GL.GetInteger(GetPName.CurrentProgram);
+
+ GL.BindFramebuffer(FramebufferTarget.Framebuffer, 0);
+
+ GL.BindVertexArray(VaoHandle);
+
+ GL.UseProgram(Shader.Handle);
+
+ GL.DrawArrays(PrimitiveType.TriangleStrip, 0, 4);
+
+ //Restore the original state.
+ GL.BindFramebuffer(FramebufferTarget.Framebuffer, CurrFbHandle);
+
+ GL.UseProgram(CurrentProgram);
+ }
}
private void EnsureInitialized()
@@ -130,7 +236,7 @@ namespace Ryujinx.Graphics.Gal.OpenGL
GL.LinkProgram(Shader.Handle);
GL.UseProgram(Shader.Handle);
- Matrix2 Transform = Matrix2.CreateScale(1, -1);
+ Matrix2 Transform = Matrix2.Identity;
int TexUniformLocation = GL.GetUniformLocation(Shader.Handle, "tex");
@@ -178,5 +284,32 @@ namespace Ryujinx.Graphics.Gal.OpenGL
GL.VertexAttribPointer(1, 2, VertexAttribPointerType.Float, false, 16, 8);
}
+
+ private void SetupTexture(int Handle, int Width, int Height)
+ {
+ GL.BindTexture(TextureTarget.Texture2D, Handle);
+
+ GL.TexParameter(TextureTarget.Texture2D, TextureParameterName.TextureMinFilter, (int)TextureMinFilter.Linear);
+
+ GL.TexParameter(TextureTarget.Texture2D, TextureParameterName.TextureMagFilter, (int)TextureMagFilter.Linear);
+
+ (PixelFormat Format, PixelType Type) = OGLEnumConverter.GetTextureFormat(GalTextureFormat.A8B8G8R8);
+
+ const PixelInternalFormat InternalFmt = PixelInternalFormat.Rgba;
+
+ const int Level = 0;
+ const int Border = 0;
+
+ GL.TexImage2D(
+ TextureTarget.Texture2D,
+ Level,
+ InternalFmt,
+ Width,
+ Height,
+ Border,
+ Format,
+ Type,
+ IntPtr.Zero);
+ }
}
} \ No newline at end of file
diff --git a/Ryujinx.Graphics/Gal/OpenGL/OGLTexture.cs b/Ryujinx.Graphics/Gal/OpenGL/OGLTexture.cs
index b7c8999e..9ea25056 100644
--- a/Ryujinx.Graphics/Gal/OpenGL/OGLTexture.cs
+++ b/Ryujinx.Graphics/Gal/OpenGL/OGLTexture.cs
@@ -15,10 +15,9 @@ namespace Ryujinx.Graphics.Gal.OpenGL
{
GL.ActiveTexture(TextureUnit.Texture0 + Index);
- int Handle = EnsureTextureInitialized(Index);
-
- GL.BindTexture(TextureTarget.Texture2D, Handle);
+ Bind(Index);
+ const int Level = 0; //TODO: Support mipmap textures.
const int Border = 0;
if (IsCompressedTextureFormat(Texture.Format))
@@ -27,7 +26,7 @@ namespace Ryujinx.Graphics.Gal.OpenGL
GL.CompressedTexImage2D(
TextureTarget.Texture2D,
- 0,
+ Level,
InternalFmt,
Texture.Width,
Texture.Height,
@@ -39,27 +38,30 @@ namespace Ryujinx.Graphics.Gal.OpenGL
{
const PixelInternalFormat InternalFmt = PixelInternalFormat.Rgba;
- (PixelFormat, PixelType) Format = OGLEnumConverter.GetTextureFormat(Texture.Format);
+ (PixelFormat Format, PixelType Type) = OGLEnumConverter.GetTextureFormat(Texture.Format);
GL.TexImage2D(
TextureTarget.Texture2D,
- 0,
+ Level,
InternalFmt,
Texture.Width,
Texture.Height,
Border,
- Format.Item1,
- Format.Item2,
+ Format,
+ Type,
Texture.Data);
}
}
- public void Set(int Index, GalTextureSampler Sampler)
+ public void Bind(int Index)
{
int Handle = EnsureTextureInitialized(Index);
GL.BindTexture(TextureTarget.Texture2D, Handle);
+ }
+ public static void Set(GalTextureSampler Sampler)
+ {
int WrapS = (int)OGLEnumConverter.GetTextureWrapMode(Sampler.AddressU);
int WrapT = (int)OGLEnumConverter.GetTextureWrapMode(Sampler.AddressV);
diff --git a/Ryujinx.Graphics/Gal/OpenGL/OpenGLRenderer.cs b/Ryujinx.Graphics/Gal/OpenGL/OpenGLRenderer.cs
index 0b7bf92a..b3ccae5f 100644
--- a/Ryujinx.Graphics/Gal/OpenGL/OpenGLRenderer.cs
+++ b/Ryujinx.Graphics/Gal/OpenGL/OpenGLRenderer.cs
@@ -19,8 +19,6 @@ namespace Ryujinx.Graphics.Gal.OpenGL
private ConcurrentQueue<Action> ActionsQueue;
- private FrameBuffer FbRenderer;
-
public OpenGLRenderer()
{
Blend = new OGLBlend();
@@ -36,16 +34,6 @@ namespace Ryujinx.Graphics.Gal.OpenGL
ActionsQueue = new ConcurrentQueue<Action>();
}
- public void InitializeFrameBuffer()
- {
- FbRenderer = new FrameBuffer(1280, 720);
- }
-
- public void ResetFrameBuffer()
- {
- FbRenderer.Reset();
- }
-
public void QueueAction(Action ActionMthd)
{
ActionsQueue.Enqueue(ActionMthd);
@@ -63,33 +51,12 @@ namespace Ryujinx.Graphics.Gal.OpenGL
public void Render()
{
- FbRenderer.Render();
+ FrameBuffer.Render();
}
public void SetWindowSize(int Width, int Height)
{
- FbRenderer.WindowWidth = Width;
- FbRenderer.WindowHeight = Height;
- }
-
- public unsafe void SetFrameBuffer(
- byte* Fb,
- int Width,
- int Height,
- float ScaleX,
- float ScaleY,
- float OffsX,
- float OffsY,
- float Rotate)
- {
- Matrix2 Transform;
-
- Transform = Matrix2.CreateScale(ScaleX, ScaleY);
- Transform *= Matrix2.CreateRotation(Rotate);
-
- Vector2 Offs = new Vector2(OffsX, OffsY);
-
- FbRenderer.Set(Fb, Width, Height, Transform, Offs);
+ //TODO
}
public void SetBlendEnable(bool Enable)
@@ -132,19 +99,46 @@ namespace Ryujinx.Graphics.Gal.OpenGL
});
}
- public void SetFb(int FbIndex, int Width, int Height)
+ public void CreateFrameBuffer(long Tag, int Width, int Height)
{
- ActionsQueue.Enqueue(() => FrameBuffer.Set(FbIndex, Width, Height));
+ ActionsQueue.Enqueue(() => FrameBuffer.Create(Tag, Width, Height));
}
- public void BindFrameBuffer(int FbIndex)
+ public void BindFrameBuffer(long Tag)
{
- ActionsQueue.Enqueue(() => FrameBuffer.Bind(FbIndex));
+ ActionsQueue.Enqueue(() => FrameBuffer.Bind(Tag));
}
- public void DrawFrameBuffer(int FbIndex)
+ public void BindFrameBufferTexture(long Tag, int Index, GalTextureSampler Sampler)
{
- ActionsQueue.Enqueue(() => FrameBuffer.Draw(FbIndex));
+ ActionsQueue.Enqueue(() =>
+ {
+ FrameBuffer.BindTexture(Tag, Index);
+
+ OGLTexture.Set(Sampler);
+ });
+ }
+
+ public void SetFrameBuffer(long Tag)
+ {
+ ActionsQueue.Enqueue(() => FrameBuffer.Set(Tag));
+ }
+
+ public void SetFrameBuffer(byte[] Data, int Width, int Height)
+ {
+ ActionsQueue.Enqueue(() => FrameBuffer.Set(Data, Width, Height));
+ }
+
+ public void SetFrameBufferTransform(float SX, float SY, float Rotate, float TX, float TY)
+ {
+ Matrix2 Transform;
+
+ Transform = Matrix2.CreateScale(SX, SY);
+ Transform *= Matrix2.CreateRotation(Rotate);
+
+ Vector2 Offs = new Vector2(TX, TY);
+
+ ActionsQueue.Enqueue(() => FrameBuffer.SetTransform(Transform, Offs));
}
public void ClearBuffers(int RtIndex, GalClearBufferFlags Flags)
@@ -239,14 +233,19 @@ namespace Ryujinx.Graphics.Gal.OpenGL
ActionsQueue.Enqueue(() => Shader.BindProgram());
}
- public void SetTexture(int Index, GalTexture Tex)
+ public void SetTextureAndSampler(int Index, GalTexture Texture, GalTextureSampler Sampler)
{
- ActionsQueue.Enqueue(() => Texture.Set(Index, Tex));
+ ActionsQueue.Enqueue(() =>
+ {
+ this.Texture.Set(Index, Texture);
+
+ OGLTexture.Set(Sampler);
+ });
}
- public void SetSampler(int Index, GalTextureSampler Sampler)
+ public void BindTexture(int Index)
{
- ActionsQueue.Enqueue(() => Texture.Set(Index, Sampler));
+ ActionsQueue.Enqueue(() => Texture.Bind(Index));
}
}
} \ No newline at end of file