Program.OpenGL.cs 5.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127
  1. using System;
  2. using System.Numerics;
  3. using System.Text;
  4. using System.Linq;
  5. using ImGuiNET;
  6. using OpenTK.Graphics.OpenGL;
  7. using OpenTK.Windowing.GraphicsLibraryFramework;
  8. namespace Pow3r
  9. {
  10. internal sealed unsafe partial class Program
  11. {
  12. private int _glFontTexture;
  13. private void InitOpenGL()
  14. {
  15. if (GL.GetString(StringName.Extensions).Split(' ').Contains("GL_ARB_debug_output"))
  16. GL.Arb.DebugMessageCallback(GLDebugCallbackDelegate, 0x0105);
  17. GL.Enable(EnableCap.ScissorTest);
  18. GL.Enable(EnableCap.Blend);
  19. GL.BlendEquation(BlendEquationMode.FuncAdd);
  20. GL.BlendFuncSeparate(
  21. BlendingFactorSrc.SrcAlpha,
  22. BlendingFactorDest.OneMinusSrcAlpha,
  23. BlendingFactorSrc.One,
  24. BlendingFactorDest.OneMinusSrcAlpha);
  25. var io = ImGui.GetIO();
  26. io.Fonts.GetTexDataAsRGBA32(out byte* pixels, out var width, out var height, out _);
  27. _glFontTexture = GL.GenTexture();
  28. GL.BindTexture(TextureTarget.Texture2D, _glFontTexture);
  29. GL.TexImage2D(TextureTarget.Texture2D, 0, PixelInternalFormat.Rgba, width, height, 0, PixelFormat.Bgra, PixelType.UnsignedByte, (nint) pixels);
  30. GL.TexParameter(TextureTarget.Texture2D, TextureParameterName.TextureMagFilter, (int) TextureMagFilter.Nearest);
  31. GL.TexParameter(TextureTarget.Texture2D, TextureParameterName.TextureMinFilter, (int) TextureMinFilter.Nearest);
  32. GL.TexParameter(TextureTarget.Texture2D, TextureParameterName.TextureWrapS, (int) TextureWrapMode.ClampToEdge);
  33. GL.TexParameter(TextureTarget.Texture2D, TextureParameterName.TextureWrapT, (int) TextureWrapMode.ClampToEdge);
  34. /*
  35. GL.TextureParameter(_fontTexture, TextureParameterName.TextureSwizzleR, 1);
  36. GL.TextureParameter(_fontTexture, TextureParameterName.TextureSwizzleG, 1);
  37. GL.TextureParameter(_fontTexture, TextureParameterName.TextureSwizzleB, 1);
  38. GL.TextureParameter(_fontTexture, TextureParameterName.TextureSwizzleA, (int) All.Red);*/
  39. io.Fonts.SetTexID(_glFontTexture);
  40. io.Fonts.ClearTexData();
  41. }
  42. private void RenderOpenGL()
  43. {
  44. GLFW.GetFramebufferSize(_window.WindowPtr, out var fbW, out var fbH);
  45. GL.Viewport(0, 0, fbW, fbH);
  46. GL.Disable(EnableCap.ScissorTest);
  47. GL.ClearColor(0, 0, 0, 1);
  48. GL.Clear(ClearBufferMask.ColorBufferBit);
  49. GL.Enable(EnableCap.ScissorTest);
  50. GL.Enable(EnableCap.Texture2D);
  51. var drawData = ImGui.GetDrawData();
  52. var l = drawData.DisplayPos.X;
  53. var r = drawData.DisplayPos.X + drawData.DisplaySize.X;
  54. var t = drawData.DisplayPos.Y;
  55. var b = drawData.DisplayPos.Y + drawData.DisplaySize.Y;
  56. var matrix = Matrix4x4.CreateOrthographicOffCenter(l, r, b, t, -1, 1);
  57. GL.MatrixMode(MatrixMode.Projection);
  58. GL.LoadMatrix((float*) &matrix);
  59. var clipOff = drawData.DisplayPos;
  60. var clipScale = drawData.FramebufferScale;
  61. GL.EnableClientState(ArrayCap.VertexArray);
  62. GL.EnableClientState(ArrayCap.TextureCoordArray);
  63. GL.EnableClientState(ArrayCap.ColorArray);
  64. for (var n = 0; n < drawData.CmdListsCount; n++)
  65. {
  66. var drawList = drawData.CmdListsRange[n];
  67. for (var cmdI = 0; cmdI < drawList.CmdBuffer.Size; cmdI++)
  68. {
  69. var cmd = drawList.CmdBuffer[cmdI];
  70. GL.BindTexture(TextureTarget.Texture2D, (uint) cmd.TextureId);
  71. Vector4 clipRect = default;
  72. clipRect.X = (cmd.ClipRect.X - clipOff.X) * clipScale.X;
  73. clipRect.Y = (cmd.ClipRect.Y - clipOff.Y) * clipScale.Y;
  74. clipRect.Z = (cmd.ClipRect.Z - clipOff.X) * clipScale.X;
  75. clipRect.W = (cmd.ClipRect.W - clipOff.Y) * clipScale.Y;
  76. GL.Scissor((int) clipRect.X, (int) (fbH - clipRect.W), (int) (clipRect.Z - clipRect.X),
  77. (int) (clipRect.W - clipRect.Y));
  78. IntPtr adjustedVB = drawList.VtxBuffer.Data + (nint) (sizeof(ImDrawVert) * cmd.VtxOffset);
  79. GL.VertexPointer(2, VertexPointerType.Float, sizeof(ImDrawVert), adjustedVB);
  80. GL.TexCoordPointer(2, TexCoordPointerType.Float, sizeof(ImDrawVert), adjustedVB + 8);
  81. GL.ColorPointer(4, ColorPointerType.UnsignedByte, sizeof(ImDrawVert), adjustedVB + 16);
  82. GL.DrawElements(PrimitiveType.Triangles, (int) cmd.ElemCount,
  83. DrawElementsType.UnsignedShort,
  84. drawList.IdxBuffer.Data + (nint) (cmd.IdxOffset * 2));
  85. }
  86. }
  87. _window.SwapBuffers();
  88. }
  89. private static readonly DebugProcArb GLDebugCallbackDelegate = GLDebugCallback;
  90. private static void GLDebugCallback(DebugSource source, DebugType type, int id, DebugSeverity severity,
  91. int length, IntPtr message, IntPtr userParam)
  92. {
  93. var msg = Encoding.UTF8.GetString((byte*) message, length);
  94. if (severity == DebugSeverity.DebugSeverityNotification)
  95. return;
  96. Console.WriteLine($"[{type}][{severity}] {source}: {msg}");
  97. }
  98. }
  99. }