VertexArray.cs 3.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135
  1. using OpenTK.Graphics.OpenGL;
  2. using Ryujinx.Graphics.GAL.InputAssembler;
  3. using Ryujinx.Graphics.OpenGL.Formats;
  4. using System;
  5. namespace Ryujinx.Graphics.OpenGL
  6. {
  7. class VertexArray : IDisposable
  8. {
  9. public int Handle { get; }
  10. private bool _needsAttribsUpdate;
  11. private VertexBufferDescriptor[] _vertexBuffers;
  12. private VertexAttribDescriptor[] _vertexAttribs;
  13. public VertexArray()
  14. {
  15. Handle = GL.GenVertexArray();
  16. }
  17. public void Bind()
  18. {
  19. GL.BindVertexArray(Handle);
  20. }
  21. public void SetVertexBuffers(VertexBufferDescriptor[] vertexBuffers)
  22. {
  23. int bindingIndex = 0;
  24. foreach (VertexBufferDescriptor vb in vertexBuffers)
  25. {
  26. if (vb.Buffer.Buffer != null)
  27. {
  28. int bufferHandle = ((Buffer)vb.Buffer.Buffer).Handle;
  29. GL.BindVertexBuffer(bindingIndex, bufferHandle, (IntPtr)vb.Buffer.Offset, vb.Stride);
  30. GL.VertexBindingDivisor(bindingIndex, vb.Divisor);
  31. }
  32. else
  33. {
  34. GL.BindVertexBuffer(bindingIndex, 0, IntPtr.Zero, 0);
  35. }
  36. bindingIndex++;
  37. }
  38. _vertexBuffers = vertexBuffers;
  39. _needsAttribsUpdate = true;
  40. }
  41. public void SetVertexAttributes(VertexAttribDescriptor[] vertexAttribs)
  42. {
  43. int attribIndex = 0;
  44. foreach (VertexAttribDescriptor attrib in vertexAttribs)
  45. {
  46. FormatInfo fmtInfo = FormatTable.GetFormatInfo(attrib.Format);
  47. GL.EnableVertexAttribArray(attribIndex);
  48. int offset = attrib.Offset;
  49. int size = fmtInfo.Components;
  50. bool isFloat = fmtInfo.PixelType == PixelType.Float ||
  51. fmtInfo.PixelType == PixelType.HalfFloat;
  52. if (isFloat || fmtInfo.Normalized || fmtInfo.Scaled)
  53. {
  54. VertexAttribType type = (VertexAttribType)fmtInfo.PixelType;
  55. GL.VertexAttribFormat(attribIndex, size, type, fmtInfo.Normalized, offset);
  56. }
  57. else
  58. {
  59. VertexAttribIntegerType type = (VertexAttribIntegerType)fmtInfo.PixelType;
  60. GL.VertexAttribIFormat(attribIndex, size, type, offset);
  61. }
  62. GL.VertexAttribBinding(attribIndex, attrib.BufferIndex);
  63. attribIndex++;
  64. }
  65. for (; attribIndex < 16; attribIndex++)
  66. {
  67. GL.DisableVertexAttribArray(attribIndex);
  68. }
  69. _vertexAttribs = vertexAttribs;
  70. }
  71. public void SetIndexBuffer(Buffer indexBuffer)
  72. {
  73. GL.BindBuffer(BufferTarget.ElementArrayBuffer, indexBuffer?.Handle ?? 0);
  74. }
  75. public void Validate()
  76. {
  77. for (int attribIndex = 0; attribIndex < _vertexAttribs.Length; attribIndex++)
  78. {
  79. VertexAttribDescriptor attrib = _vertexAttribs[attribIndex];
  80. if ((uint)attrib.BufferIndex >= _vertexBuffers.Length)
  81. {
  82. GL.DisableVertexAttribArray(attribIndex);
  83. continue;
  84. }
  85. if (_vertexBuffers[attrib.BufferIndex].Buffer.Buffer == null)
  86. {
  87. GL.DisableVertexAttribArray(attribIndex);
  88. continue;
  89. }
  90. if (_needsAttribsUpdate)
  91. {
  92. GL.EnableVertexAttribArray(attribIndex);
  93. }
  94. }
  95. _needsAttribsUpdate = false;
  96. }
  97. public void Dispose()
  98. {
  99. GL.DeleteVertexArray(Handle);
  100. }
  101. }
  102. }