| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313 |
- using OpenTK;
- using OpenTK.Graphics.OpenGL;
- using System;
- using System.Collections.Generic;
- namespace Ryujinx.Graphics.Gal.OpenGL
- {
- public class OpenGLRenderer : IGalRenderer
- {
- private struct VertexBuffer
- {
- public int VaoHandle;
- public int VboHandle;
- public int PrimCount;
- }
- private struct Texture
- {
- public int Handle;
- }
- private List<VertexBuffer> VertexBuffers;
- private Texture[] Textures;
- private Queue<Action> ActionsQueue;
- private FrameBuffer FbRenderer;
- public OpenGLRenderer()
- {
- VertexBuffers = new List<VertexBuffer>();
- Textures = new Texture[8];
- ActionsQueue = new Queue<Action>();
- }
- public void InitializeFrameBuffer()
- {
- FbRenderer = new FrameBuffer(1280, 720);
- }
- public void QueueAction(Action ActionMthd)
- {
- ActionsQueue.Enqueue(ActionMthd);
- }
- public void RunActions()
- {
- int Count = ActionsQueue.Count;
- while (Count-- > 0)
- {
- ActionsQueue.Dequeue()();
- }
- }
- public void Render()
- {
- FbRenderer.Render();
- for (int Index = 0; Index < VertexBuffers.Count; Index++)
- {
- VertexBuffer Vb = VertexBuffers[Index];
- if (Vb.VaoHandle != 0 &&
- Vb.PrimCount != 0)
- {
- GL.BindVertexArray(Vb.VaoHandle);
- GL.DrawArrays(PrimitiveType.TriangleStrip, 0, Vb.PrimCount);
- }
- }
- }
- 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 Rotate)
- {
- Matrix2 Transform;
- Transform = Matrix2.CreateScale(ScaleX, ScaleY);
- Transform *= Matrix2.CreateRotation(Rotate);
- FbRenderer.Set(Fb, Width, Height, Transform);
- }
- public void SendVertexBuffer(int Index, byte[] Buffer, int Stride, GalVertexAttrib[] Attribs)
- {
- if (Index < 0)
- {
- throw new ArgumentOutOfRangeException(nameof(Index));
- }
- if (Buffer.Length == 0 || Stride == 0)
- {
- return;
- }
- EnsureVbInitialized(Index);
- VertexBuffer Vb = VertexBuffers[Index];
- Vb.PrimCount = Buffer.Length / Stride;
- VertexBuffers[Index] = Vb;
- IntPtr Length = new IntPtr(Buffer.Length);
- GL.BindBuffer(BufferTarget.ArrayBuffer, Vb.VboHandle);
- GL.BufferData(BufferTarget.ArrayBuffer, Length, Buffer, BufferUsageHint.StreamDraw);
- GL.BindBuffer(BufferTarget.ArrayBuffer, 0);
- GL.BindVertexArray(Vb.VaoHandle);
- for (int Attr = 0; Attr < 16; Attr++)
- {
- GL.DisableVertexAttribArray(Attr);
- }
- foreach (GalVertexAttrib Attrib in Attribs)
- {
- if (Attrib.Index >= 3) break;
- GL.EnableVertexAttribArray(Attrib.Index);
- GL.BindBuffer(BufferTarget.ArrayBuffer, Vb.VboHandle);
- int Size = 0;
- switch (Attrib.Size)
- {
- case GalVertexAttribSize._8:
- case GalVertexAttribSize._16:
- case GalVertexAttribSize._32:
- Size = 1;
- break;
- case GalVertexAttribSize._8_8:
- case GalVertexAttribSize._16_16:
- case GalVertexAttribSize._32_32:
- Size = 2;
- break;
- case GalVertexAttribSize._8_8_8:
- case GalVertexAttribSize._11_11_10:
- case GalVertexAttribSize._16_16_16:
- case GalVertexAttribSize._32_32_32:
- Size = 3;
- break;
- case GalVertexAttribSize._8_8_8_8:
- case GalVertexAttribSize._10_10_10_2:
- case GalVertexAttribSize._16_16_16_16:
- case GalVertexAttribSize._32_32_32_32:
- Size = 4;
- break;
- }
- bool Signed =
- Attrib.Type == GalVertexAttribType.Snorm ||
- Attrib.Type == GalVertexAttribType.Sint ||
- Attrib.Type == GalVertexAttribType.Sscaled;
- bool Normalize =
- Attrib.Type == GalVertexAttribType.Snorm ||
- Attrib.Type == GalVertexAttribType.Unorm;
- VertexAttribPointerType Type = 0;
- switch (Attrib.Type)
- {
- case GalVertexAttribType.Snorm:
- case GalVertexAttribType.Unorm:
- case GalVertexAttribType.Sint:
- case GalVertexAttribType.Uint:
- case GalVertexAttribType.Uscaled:
- case GalVertexAttribType.Sscaled:
- {
- switch (Attrib.Size)
- {
- case GalVertexAttribSize._8:
- case GalVertexAttribSize._8_8:
- case GalVertexAttribSize._8_8_8:
- case GalVertexAttribSize._8_8_8_8:
- {
- Type = Signed
- ? VertexAttribPointerType.Byte
- : VertexAttribPointerType.UnsignedByte;
- break;
- }
- case GalVertexAttribSize._16:
- case GalVertexAttribSize._16_16:
- case GalVertexAttribSize._16_16_16:
- case GalVertexAttribSize._16_16_16_16:
- {
- Type = Signed
- ? VertexAttribPointerType.Short
- : VertexAttribPointerType.UnsignedShort;
- break;
- }
- case GalVertexAttribSize._10_10_10_2:
- case GalVertexAttribSize._11_11_10:
- case GalVertexAttribSize._32:
- case GalVertexAttribSize._32_32:
- case GalVertexAttribSize._32_32_32:
- case GalVertexAttribSize._32_32_32_32:
- {
- Type = Signed
- ? VertexAttribPointerType.Int
- : VertexAttribPointerType.UnsignedInt;
- break;
- }
- }
- break;
- }
- case GalVertexAttribType.Float:
- {
- Type = VertexAttribPointerType.Float;
- break;
- }
- }
- GL.VertexAttribPointer(
- Attrib.Index,
- Size,
- Type,
- Normalize,
- Stride,
- Attrib.Offset);
- }
- GL.BindVertexArray(0);
- }
- public void SendR8G8B8A8Texture(int Index, byte[] Buffer, int Width, int Height)
- {
- EnsureTexInitialized(Index);
- GL.BindTexture(TextureTarget.Texture2D, Textures[Index].Handle);
- GL.TexParameter(TextureTarget.Texture2D, TextureParameterName.TextureWrapS, (int)TextureWrapMode.Repeat);
- GL.TexParameter(TextureTarget.Texture2D, TextureParameterName.TextureWrapT, (int)TextureWrapMode.Repeat);
- 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,
- Width,
- Height,
- 0,
- PixelFormat.Rgba,
- PixelType.UnsignedByte,
- Buffer);
- }
- public void BindTexture(int Index)
- {
- GL.ActiveTexture(TextureUnit.Texture0 + Index);
- GL.BindTexture(TextureTarget.Texture2D, Textures[Index].Handle);
- }
- private void EnsureVbInitialized(int VbIndex)
- {
- while (VbIndex >= VertexBuffers.Count)
- {
- VertexBuffers.Add(new VertexBuffer());
- }
- VertexBuffer Vb = VertexBuffers[VbIndex];
- if (Vb.VaoHandle == 0)
- {
- Vb.VaoHandle = GL.GenVertexArray();
- }
- if (Vb.VboHandle == 0)
- {
- Vb.VboHandle = GL.GenBuffer();
- }
- VertexBuffers[VbIndex] = Vb;
- }
- private void EnsureTexInitialized(int TexIndex)
- {
- Texture Tex = Textures[TexIndex];
- if (Tex.Handle == 0)
- {
- Tex.Handle = GL.GenTexture();
- }
- Textures[TexIndex] = Tex;
- }
- }
- }
|