VertexArray.cs 3.8 KB

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