mirror of
https://github.com/ishanjitchattaraj/simple-sober-external.git
synced 2026-10-27 12:44:36 +00:00
Initial commit
This commit is contained in:
commit
d59cdbc52c
86 files changed
+3714
No files matched your search
@@ -0,0 +1,633 @@
|
||||
using ImGuiNET;
|
||||
using OpenTK.Graphics.OpenGL4;
|
||||
using OpenTK.Mathematics;
|
||||
using System;
|
||||
using System.Runtime.CompilerServices;
|
||||
using System.Runtime.InteropServices;
|
||||
|
||||
namespace Dear_ImGui_Sample.Backends
|
||||
{
|
||||
public unsafe static class ImguiImplOpenGL3
|
||||
{
|
||||
// See: https://github.com/ImGuiNET/ImGui.NET/issues/527
|
||||
internal struct ImDrawCmd_fixed
|
||||
{
|
||||
public Vector4 ClipRect;
|
||||
public ulong TextureId;
|
||||
public uint VtxOffset;
|
||||
public uint IdxOffset;
|
||||
public uint ElemCount;
|
||||
public nint UserCallback;
|
||||
public unsafe void* UserCallbackData;
|
||||
public int UserCallbackDataSize;
|
||||
public int UserCallbackDataOffset;
|
||||
}
|
||||
internal struct ImDrawCmdPtr_fixed
|
||||
{
|
||||
public unsafe ImDrawCmd_fixed* NativePtr { get; }
|
||||
|
||||
public unsafe nint GetTexID()
|
||||
{
|
||||
return ImGuiNative.ImDrawCmd_GetTexID((ImDrawCmd*)NativePtr);
|
||||
}
|
||||
}
|
||||
|
||||
struct RendererData {
|
||||
public int FontTexture;
|
||||
public int ShaderHandle;
|
||||
public int UniformLocationTex;
|
||||
public int UniformLocationProjMtx;
|
||||
public int AttribLocationVtxPos;
|
||||
public int AttribLocationVtxUV;
|
||||
public int AttribLocationVtxColor;
|
||||
public int VboHandle;
|
||||
public int EboHandle;
|
||||
// FIXME: ??
|
||||
public bool HasPolygonMode;
|
||||
public bool HasClipOrigin;
|
||||
|
||||
public int GlslVersion;
|
||||
public bool KHRDebugAvailable;
|
||||
}
|
||||
|
||||
static RendererData* GetBackendData()
|
||||
{
|
||||
return ImGui.GetCurrentContext() == 0 ? null : (RendererData*)ImGui.GetIO().BackendRendererUserData;
|
||||
}
|
||||
|
||||
public static bool Init(bool useKHRDebugIfAvailable = true)
|
||||
{
|
||||
var io = ImGui.GetIO();
|
||||
|
||||
RendererData* bd = (RendererData*)NativeMemory.AllocZeroed((uint)sizeof(RendererData));
|
||||
|
||||
int major = GL.GetInteger(GetPName.MajorVersion);
|
||||
int minor = GL.GetInteger(GetPName.MinorVersion);
|
||||
bd->HasPolygonMode = true;
|
||||
bd->HasClipOrigin = major > 4 || (major == 4 && minor >= 5);
|
||||
|
||||
bd->GlslVersion = (major, minor) switch
|
||||
{
|
||||
(4, 6) => 460,
|
||||
(4, 5) => 450,
|
||||
(4, 4) => 440,
|
||||
(4, 3) => 430,
|
||||
(4, 2) => 420,
|
||||
(4, 1) => 410,
|
||||
(4, 0) => 400,
|
||||
(3, 3) => 330,
|
||||
(3, 2) => 150,
|
||||
(3, 1) => 140,
|
||||
(3, 0) => 130,
|
||||
(2, 1) => 120,
|
||||
(2, 0) => 110,
|
||||
_ => 110,
|
||||
};
|
||||
|
||||
if (useKHRDebugIfAvailable)
|
||||
bd->KHRDebugAvailable = (major == 4 && minor >= 3) || IsExtensionSupported("KHR_debug");
|
||||
else
|
||||
bd->KHRDebugAvailable = false;
|
||||
|
||||
io.BackendRendererUserData = (IntPtr)bd;
|
||||
io.NativePtr->BackendRendererName = (byte*)Unsafe.AsPointer(ref MemoryMarshal.GetReference("opentk_impl_opengl3"u8));
|
||||
|
||||
io.BackendFlags |= ImGuiBackendFlags.RendererHasVtxOffset;
|
||||
io.BackendFlags |= ImGuiBackendFlags.RendererHasViewports;
|
||||
|
||||
InitMultiViewportSupport();
|
||||
|
||||
return true;
|
||||
|
||||
static bool IsExtensionSupported(string name)
|
||||
{
|
||||
int n = GL.GetInteger(GetPName.NumExtensions);
|
||||
for (int i = 0; i < n; i++)
|
||||
{
|
||||
string extension = GL.GetString(StringNameIndexed.Extensions, i);
|
||||
if (extension == name) return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
public static void Shutdown()
|
||||
{
|
||||
var io = ImGui.GetIO();
|
||||
|
||||
RendererData* bd = (RendererData*)io.NativePtr->BackendRendererUserData;
|
||||
|
||||
ShutdownMultiViewportSupport();
|
||||
|
||||
io.NativePtr->BackendRendererName = null;
|
||||
io.NativePtr->BackendRendererUserData = null;
|
||||
|
||||
io.BackendFlags &= ~(ImGuiBackendFlags.RendererHasVtxOffset);
|
||||
|
||||
NativeMemory.Free(bd);
|
||||
}
|
||||
|
||||
public static void NewFrame()
|
||||
{
|
||||
RendererData* bd = GetBackendData();
|
||||
|
||||
if (bd->ShaderHandle == 0)
|
||||
{
|
||||
CreateDeviceObjects();
|
||||
}
|
||||
if (bd->FontTexture == 0)
|
||||
{
|
||||
CreateFontsTexture();
|
||||
}
|
||||
}
|
||||
|
||||
public static void SetupRenderState(ImDrawDataPtr drawData, int fbWidth, int fbHeight, int vao)
|
||||
{
|
||||
RendererData* bd = GetBackendData();
|
||||
|
||||
GL.Enable(EnableCap.Blend);
|
||||
GL.BlendEquation(BlendEquationMode.FuncAdd);
|
||||
GL.BlendFuncSeparate(BlendingFactorSrc.SrcAlpha, BlendingFactorDest.OneMinusSrcAlpha, BlendingFactorSrc.One, BlendingFactorDest.OneMinusSrcAlpha);
|
||||
GL.Disable(EnableCap.CullFace);
|
||||
GL.Disable(EnableCap.DepthTest);
|
||||
GL.Disable(EnableCap.StencilTest);
|
||||
GL.Enable(EnableCap.ScissorTest);
|
||||
// FIXME: check for 3.1
|
||||
GL.Disable(EnableCap.PrimitiveRestart);
|
||||
|
||||
GL.PolygonMode(TriangleFace.FrontAndBack, PolygonMode.Fill);
|
||||
|
||||
bool clip_origin_lower_left = true;
|
||||
ClipOrigin clip_origin = (ClipOrigin)GL.GetInteger(GetPName.ClipOrigin);
|
||||
if (clip_origin == ClipOrigin.UpperLeft)
|
||||
clip_origin_lower_left = false;
|
||||
|
||||
GL.Viewport(0, 0, fbWidth, fbHeight);
|
||||
float L = drawData.DisplayPos.X;
|
||||
float R = drawData.DisplayPos.X + drawData.DisplaySize.X;
|
||||
float T = drawData.DisplayPos.Y;
|
||||
float B = drawData.DisplayPos.Y + drawData.DisplaySize.Y;
|
||||
if (clip_origin_lower_left == false)
|
||||
(T, B) = (B, T); // Swap top and bottom if origin is upper left.
|
||||
Matrix4 mvp = Matrix4.CreateOrthographicOffCenter(L, R, B, T, -1, 1);
|
||||
GL.UseProgram(bd->ShaderHandle);
|
||||
GL.Uniform1(bd->UniformLocationTex, 0);
|
||||
GL.UniformMatrix4(bd->UniformLocationProjMtx, true, ref mvp);
|
||||
|
||||
GL.BindSampler(0, 0);
|
||||
|
||||
GL.BindVertexArray(vao);
|
||||
GL.BindBuffer(BufferTarget.ArrayBuffer, bd->VboHandle);
|
||||
GL.BindBuffer(BufferTarget.ElementArrayBuffer, bd->EboHandle);
|
||||
GL.EnableVertexAttribArray(bd->AttribLocationVtxPos);
|
||||
GL.EnableVertexAttribArray(bd->AttribLocationVtxUV);
|
||||
GL.EnableVertexAttribArray(bd->AttribLocationVtxColor);
|
||||
GL.VertexAttribPointer(bd->AttribLocationVtxPos, 2, VertexAttribPointerType.Float, false, sizeof(ImDrawVert), 0);
|
||||
GL.VertexAttribPointer(bd->AttribLocationVtxUV, 2, VertexAttribPointerType.Float, false, sizeof(ImDrawVert), 8);
|
||||
GL.VertexAttribPointer(bd->AttribLocationVtxColor, 4, VertexAttribPointerType.UnsignedByte, true, sizeof(ImDrawVert), 16);
|
||||
|
||||
if (bd->KHRDebugAvailable)
|
||||
{
|
||||
GL.ObjectLabel(ObjectLabelIdentifier.VertexArray, vao, -1, "OpenTK_ImGui: VAO");
|
||||
}
|
||||
}
|
||||
|
||||
public static void RenderDrawData(ImDrawDataPtr drawData)
|
||||
{
|
||||
int fbWidth = (int)(drawData.DisplaySize.X * drawData.FramebufferScale.X);
|
||||
int fbHeight = (int)(drawData.DisplaySize.Y * drawData.FramebufferScale.Y);
|
||||
if (fbWidth <= 0 || fbHeight <= 0)
|
||||
return;
|
||||
|
||||
int last_active_texture = GL.GetInteger(GetPName.ActiveTexture);
|
||||
GL.ActiveTexture(TextureUnit.Texture0);
|
||||
int last_program = GL.GetInteger(GetPName.CurrentProgram);
|
||||
int last_texture = GL.GetInteger(GetPName.TextureBinding2D);
|
||||
int last_sampler = GL.GetInteger(GetPName.SamplerBinding);
|
||||
int last_array_buffer = GL.GetInteger(GetPName.ArrayBufferBinding);
|
||||
int last_vao = GL.GetInteger(GetPName.VertexArrayBinding);
|
||||
// OpenGL 3.0 & 3.1 have separate polygon modes for front and back.
|
||||
Span<int> last_polygon_mode = stackalloc int[2];
|
||||
GL.GetInteger(GetPName.PolygonMode, out last_polygon_mode[0]);
|
||||
Span<int> last_viewport = stackalloc int[4];
|
||||
GL.GetInteger(GetPName.Viewport, out last_viewport[0]);
|
||||
Span<int> last_scissor_box = stackalloc int[4];
|
||||
GL.GetInteger(GetPName.ScissorBox, out last_scissor_box[0]);
|
||||
int last_blend_src_rgb = GL.GetInteger(GetPName.BlendSrcRgb);
|
||||
int last_blend_dst_rgb = GL.GetInteger(GetPName.BlendDstRgb);
|
||||
int last_blend_src_alpha = GL.GetInteger(GetPName.BlendSrcAlpha);
|
||||
int last_blend_dst_alpha = GL.GetInteger(GetPName.BlendDstAlpha);
|
||||
int last_blend_equation_rgb = GL.GetInteger(GetPName.BlendEquationRgb);
|
||||
int last_blend_equation_alpha = GL.GetInteger(GetPName.BlendEquationAlpha);
|
||||
bool last_enable_blend = GL.IsEnabled(EnableCap.Blend);
|
||||
bool last_enable_cull_face = GL.IsEnabled(EnableCap.CullFace);
|
||||
bool last_enable_depth_test = GL.IsEnabled(EnableCap.DepthTest);
|
||||
bool last_enable_stencil_test = GL.IsEnabled(EnableCap.StencilTest);
|
||||
bool last_enable_scissor_test = GL.IsEnabled(EnableCap.ScissorTest);
|
||||
// FIXME: Check for >= 3.1
|
||||
bool last_enable_primitive_restart = GL.IsEnabled(EnableCap.PrimitiveRestart);
|
||||
|
||||
int vao = GL.GenVertexArray();
|
||||
SetupRenderState(drawData, fbWidth, fbHeight, vao);
|
||||
|
||||
var clipOff = drawData.DisplayPos;
|
||||
var clipScale = drawData.FramebufferScale;
|
||||
for (int n = 0; n < drawData.CmdListsCount; n++)
|
||||
{
|
||||
ImDrawListPtr drawList = drawData.CmdLists[n];
|
||||
|
||||
nint vtx_buffer_size = drawList.VtxBuffer.Size * (int)sizeof(ImDrawVert);
|
||||
nint idx_buffer_size = drawList.IdxBuffer.Size * (int)sizeof(ushort);
|
||||
GL.BufferData(BufferTarget.ArrayBuffer, vtx_buffer_size, drawList.VtxBuffer.Data, BufferUsageHint.StreamDraw);
|
||||
GL.BufferData(BufferTarget.ElementArrayBuffer, idx_buffer_size, drawList.IdxBuffer.Data, BufferUsageHint.StreamDraw);
|
||||
|
||||
for (int cmd_i = 0; cmd_i < drawList.CmdBuffer.Size; cmd_i++)
|
||||
{
|
||||
// FIXME: This is a hack to make 32-bit builds work. See: https://github.com/ImGuiNET/ImGui.NET/issues/527
|
||||
ImDrawCmdPtr_fixed cmdPtr = new ImPtrVector<ImDrawCmdPtr_fixed>(drawList.NativePtr->CmdBuffer, sizeof(ImDrawCmd_fixed))[cmd_i];
|
||||
ref ImDrawCmd_fixed cmd = ref Unsafe.AsRef<ImDrawCmd_fixed>(cmdPtr.NativePtr);
|
||||
if (cmd.UserCallback != 0)
|
||||
{
|
||||
// FIXME: ...
|
||||
nint ImDrawCallback_ResetRenderState = -8;
|
||||
if (cmd.UserCallback == ImDrawCallback_ResetRenderState)
|
||||
{
|
||||
SetupRenderState(drawData, fbWidth, fbHeight, vao);
|
||||
}
|
||||
else
|
||||
{
|
||||
throw new NotImplementedException("User callbacks are not implemented yet...");
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
Vector2 clip_min = new((cmd.ClipRect.X -clipOff.X) *clipScale.X, (cmd.ClipRect.Y - clipOff.Y) * clipScale.Y);
|
||||
Vector2 clip_max = new((cmd.ClipRect.Z -clipOff.X) *clipScale.X, (cmd.ClipRect.W - clipOff.Y) * clipScale.Y);
|
||||
if (clip_max.X <= clip_min.X || clip_max.Y <= clip_min.Y)
|
||||
continue;
|
||||
|
||||
GL.Scissor((int)clip_min.X, (int)((float)fbHeight - clip_max.Y), (int)(clip_max.X - clip_min.X), (int)(clip_max.Y - clip_min.Y));
|
||||
|
||||
GL.BindTexture(TextureTarget.Texture2D, (int)cmdPtr.GetTexID());
|
||||
|
||||
GL.DrawElementsBaseVertex(PrimitiveType.Triangles, (int)cmd.ElemCount, DrawElementsType.UnsignedShort, (int)(cmd.IdxOffset * sizeof(ushort)), (int)cmd.VtxOffset);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
GL.DeleteVertexArray(vao);
|
||||
|
||||
if (last_program == 0 || GL.IsProgram(last_program)) GL.UseProgram(last_program);
|
||||
GL.BindTexture(TextureTarget.Texture2D, last_texture);
|
||||
GL.BindSampler(0, last_sampler);
|
||||
GL.ActiveTexture((TextureUnit)last_active_texture);
|
||||
GL.BindVertexArray(last_vao);
|
||||
GL.BindBuffer(BufferTarget.ArrayBuffer, last_array_buffer);
|
||||
GL.BlendEquationSeparate((BlendEquationMode)last_blend_equation_rgb, (BlendEquationMode)last_blend_equation_alpha);
|
||||
GL.BlendFuncSeparate((BlendingFactorSrc)last_blend_src_rgb, (BlendingFactorDest)last_blend_dst_rgb, (BlendingFactorSrc)last_blend_src_alpha, (BlendingFactorDest)last_blend_dst_alpha);
|
||||
if (last_enable_blend) GL.Enable(EnableCap.Blend); else GL.Disable(EnableCap.Blend);
|
||||
if (last_enable_cull_face) GL.Enable(EnableCap.CullFace); else GL.Disable(EnableCap.CullFace);
|
||||
if (last_enable_depth_test) GL.Enable(EnableCap.DepthTest); else GL.Disable(EnableCap.DepthTest);
|
||||
if (last_enable_stencil_test) GL.Enable(EnableCap.StencilTest); else GL.Disable(EnableCap.StencilTest);
|
||||
if (last_enable_scissor_test) GL.Enable(EnableCap.ScissorTest); else GL.Disable(EnableCap.ScissorTest);
|
||||
if (last_enable_primitive_restart) GL.Enable(EnableCap.PrimitiveRestart); else GL.Disable(EnableCap.PrimitiveRestart);
|
||||
|
||||
if (true)
|
||||
{
|
||||
// FIXME:
|
||||
// if (bd->HasPolygonMode) {
|
||||
// if (bd->GlVersion <= 310 || bd->GlProfileIsCompat) {
|
||||
// glPolygonMode(GL_FRONT, (GLenum)last_polygon_mode[0]);
|
||||
// glPolygonMode(GL_BACK, (GLenum)last_polygon_mode[1]);
|
||||
// } else {
|
||||
// glPolygonMode(GL_FRONT_AND_BACK, (GLenum)last_polygon_mode[0]);
|
||||
// }
|
||||
// }
|
||||
GL.PolygonMode(TriangleFace.FrontAndBack, (PolygonMode)last_polygon_mode[0]);
|
||||
}
|
||||
|
||||
GL.Viewport(last_viewport[0], last_viewport[1], last_viewport[2], last_viewport[3]);
|
||||
GL.Scissor(last_scissor_box[0], last_scissor_box[1], last_scissor_box[2], last_scissor_box[3]);
|
||||
}
|
||||
|
||||
static void CreateFontsTexture()
|
||||
{
|
||||
var io = ImGui.GetIO();
|
||||
RendererData* bd = GetBackendData();
|
||||
|
||||
ImGuiNative.ImFontAtlas_AddFontDefault(io.Fonts.NativePtr, null);
|
||||
//io.Fonts.AddFontDefault();
|
||||
io.Fonts.GetTexDataAsRGBA32(out byte* pixels, out int width, out int height);
|
||||
|
||||
int last_texture = GL.GetInteger(GetPName.TextureBinding2D);
|
||||
bd->FontTexture = GL.GenTexture();
|
||||
GL.BindTexture(TextureTarget.Texture2D, bd->FontTexture);
|
||||
GL.TexParameter(TextureTarget.Texture2D, TextureParameterName.TextureMinFilter, (int)TextureMinFilter.Linear);
|
||||
GL.TexParameter(TextureTarget.Texture2D, TextureParameterName.TextureMagFilter, (int)TextureMagFilter.Linear);
|
||||
GL.TexParameter(TextureTarget.Texture2D, TextureParameterName.TextureWrapS, (int)TextureWrapMode.ClampToEdge);
|
||||
GL.TexParameter(TextureTarget.Texture2D, TextureParameterName.TextureWrapT, (int)TextureWrapMode.ClampToEdge);
|
||||
GL.PixelStore(PixelStoreParameter.UnpackRowLength, 0);
|
||||
GL.TexImage2D(TextureTarget.Texture2D, 0, PixelInternalFormat.Rgba, width, height, 0, PixelFormat.Rgba, PixelType.UnsignedByte, (IntPtr)pixels);
|
||||
|
||||
io.Fonts.SetTexID(bd->FontTexture);
|
||||
|
||||
GL.BindTexture(TextureTarget.Texture2D, last_texture);
|
||||
|
||||
if (bd->KHRDebugAvailable)
|
||||
{
|
||||
GL.ObjectLabel(ObjectLabelIdentifier.Texture, bd->FontTexture, -1, "OpenTK_ImGui: Font Texture");
|
||||
}
|
||||
}
|
||||
|
||||
static void DestroyFontsTexture()
|
||||
{
|
||||
var io = ImGui.GetIO();
|
||||
RendererData* bd = GetBackendData();
|
||||
|
||||
if (bd->FontTexture != 0)
|
||||
{
|
||||
GL.DeleteTexture(bd->FontTexture);
|
||||
io.Fonts.SetTexID(0);
|
||||
bd->FontTexture = 0;
|
||||
}
|
||||
}
|
||||
|
||||
static bool CheckShader(int handle, string desc)
|
||||
{
|
||||
GL.GetShader(handle, ShaderParameter.CompileStatus, out int status);
|
||||
GL.GetShader(handle, ShaderParameter.InfoLogLength, out int logLength);
|
||||
if (status == 0)
|
||||
{
|
||||
Console.Error.WriteLine($"ERROR: ImguiImplOpenGL3.CheckShader: Failed to compile {desc}!");
|
||||
}
|
||||
if (logLength > 1)
|
||||
{
|
||||
string log = GL.GetShaderInfoLog(handle);
|
||||
Console.Error.WriteLine(log);
|
||||
}
|
||||
return status == 1;
|
||||
}
|
||||
|
||||
static bool CheckProgram(int handle, string desc)
|
||||
{
|
||||
GL.GetProgram(handle, GetProgramParameterName.LinkStatus, out int status);
|
||||
GL.GetProgram(handle, GetProgramParameterName.InfoLogLength, out int logLength);
|
||||
if (status == 0)
|
||||
{
|
||||
Console.Error.WriteLine($"ERROR: ImguiImplOpenGL3.CheckProgram: Failed to link {desc}!");
|
||||
}
|
||||
if (logLength > 1)
|
||||
{
|
||||
string log = GL.GetProgramInfoLog(handle);
|
||||
Console.Error.WriteLine(log);
|
||||
}
|
||||
return status == 1;
|
||||
}
|
||||
|
||||
static void CreateDeviceObjects()
|
||||
{
|
||||
RendererData* bd = GetBackendData();
|
||||
|
||||
int last_texture = GL.GetInteger(GetPName.TextureBinding2D);
|
||||
int last_array_buffer = GL.GetInteger(GetPName.ArrayBufferBinding);
|
||||
int last_pixel_unpack_buffer = GL.GetInteger(GetPName.PixelUnpackBufferBinding);
|
||||
int last_vertex_array = GL.GetInteger(GetPName.VertexArray);
|
||||
|
||||
string vertex_shader_glsl_120 =
|
||||
"""
|
||||
uniform mat4 ProjMtx;
|
||||
attribute vec2 Position;
|
||||
attribute vec2 UV;
|
||||
attribute vec4 Color;
|
||||
varying vec2 Frag_UV;
|
||||
varying vec4 Frag_Color;
|
||||
void main()
|
||||
{
|
||||
Frag_UV = UV;
|
||||
Frag_Color = Color;
|
||||
gl_Position = vec4(Position.xy,0,1) * ProjMtx;
|
||||
}
|
||||
""";
|
||||
|
||||
string vertex_shader_glsl_130 =
|
||||
"""
|
||||
uniform mat4 ProjMtx;
|
||||
in vec2 Position;
|
||||
in vec2 UV;
|
||||
in vec4 Color;
|
||||
out vec2 Frag_UV;
|
||||
out vec4 Frag_Color;
|
||||
void main()
|
||||
{
|
||||
Frag_UV = UV;
|
||||
Frag_Color = Color;
|
||||
gl_Position = vec4(Position.xy,0,1) * ProjMtx;
|
||||
}
|
||||
""";
|
||||
|
||||
string vertex_shader_glsl_300_es =
|
||||
"""
|
||||
precision highp float;
|
||||
layout(location = 0) in vec2 Position;
|
||||
layout(location = 1) in vec2 UV;
|
||||
layout(location = 2) in vec4 Color;
|
||||
uniform mat4 ProjMtx;
|
||||
out vec2 Frag_UV;
|
||||
out vec4 Frag_Color;
|
||||
void main()
|
||||
{
|
||||
Frag_UV = UV;
|
||||
Frag_Color = Color;
|
||||
gl_Position = vec4(Position.xy,0,1) * ProjMtx;
|
||||
}
|
||||
""";
|
||||
|
||||
string vertex_shader_glsl_410_core =
|
||||
"""
|
||||
layout(location = 0) in vec2 Position;
|
||||
layout(location = 1) in vec2 UV;
|
||||
layout(location = 2) in vec4 Color;
|
||||
uniform mat4 ProjMtx;
|
||||
out vec2 Frag_UV;
|
||||
out vec4 Frag_Color;
|
||||
void main()
|
||||
{
|
||||
Frag_UV = UV;
|
||||
Frag_Color = Color;
|
||||
gl_Position = vec4(Position.xy,0,1) * ProjMtx;
|
||||
}
|
||||
""";
|
||||
|
||||
string fragment_shader_glsl_120 =
|
||||
"""
|
||||
#ifdef GL_ES
|
||||
precision mediump float;
|
||||
#endif
|
||||
uniform sampler2D Texture;
|
||||
varying vec2 Frag_UV;
|
||||
varying vec4 Frag_Color;
|
||||
void main()
|
||||
{
|
||||
gl_FragColor = Frag_Color * texture2D(Texture, Frag_UV.st);
|
||||
}
|
||||
""";
|
||||
|
||||
string fragment_shader_glsl_130 =
|
||||
"""
|
||||
uniform sampler2D Texture;
|
||||
in vec2 Frag_UV;
|
||||
in vec4 Frag_Color;
|
||||
out vec4 Out_Color;
|
||||
void main()
|
||||
{
|
||||
Out_Color = Frag_Color * texture(Texture, Frag_UV.st);
|
||||
}
|
||||
""";
|
||||
|
||||
string fragment_shader_glsl_300_es =
|
||||
"""
|
||||
precision mediump float;
|
||||
uniform sampler2D Texture;
|
||||
in vec2 Frag_UV;
|
||||
in vec4 Frag_Color;
|
||||
layout(location = 0) out vec4 Out_Color;
|
||||
void main()
|
||||
{
|
||||
Out_Color = Frag_Color * texture(Texture, Frag_UV.st);
|
||||
}
|
||||
""";
|
||||
|
||||
string fragment_shader_glsl_410_core =
|
||||
"""
|
||||
uniform sampler2D Texture;
|
||||
in vec2 Frag_UV;
|
||||
in vec4 Frag_Color;
|
||||
layout(location = 0) out vec4 Out_Color;
|
||||
void main()
|
||||
{
|
||||
Out_Color = Frag_Color * texture(Texture, Frag_UV.st);
|
||||
}
|
||||
""";
|
||||
|
||||
string vertex_shader;
|
||||
string fragment_shader;
|
||||
if (bd->GlslVersion < 130)
|
||||
{
|
||||
vertex_shader = vertex_shader_glsl_120;
|
||||
fragment_shader = fragment_shader_glsl_120;
|
||||
}
|
||||
else if (bd->GlslVersion >= 410)
|
||||
{
|
||||
vertex_shader = vertex_shader_glsl_410_core;
|
||||
fragment_shader = fragment_shader_glsl_410_core;
|
||||
}
|
||||
else if (bd->GlslVersion == 300)
|
||||
{
|
||||
vertex_shader = vertex_shader_glsl_300_es;
|
||||
fragment_shader = fragment_shader_glsl_300_es;
|
||||
}
|
||||
else
|
||||
{
|
||||
vertex_shader = vertex_shader_glsl_130;
|
||||
fragment_shader = fragment_shader_glsl_130;
|
||||
}
|
||||
|
||||
vertex_shader = vertex_shader.Insert(0, $"#version {bd->GlslVersion}{Environment.NewLine}");
|
||||
fragment_shader = fragment_shader.Insert(0, $"#version {bd->GlslVersion}{Environment.NewLine}");
|
||||
|
||||
int vert = GL.CreateShader(ShaderType.VertexShader);
|
||||
// FIXME: Version string...
|
||||
GL.ShaderSource(vert, vertex_shader);
|
||||
GL.CompileShader(vert);
|
||||
CheckShader(vert, "vertex shader");
|
||||
|
||||
int frag = GL.CreateShader(ShaderType.FragmentShader);
|
||||
// FIXME: Version string...
|
||||
GL.ShaderSource(frag, fragment_shader);
|
||||
GL.CompileShader(frag);
|
||||
CheckShader(frag, "fragment shader");
|
||||
|
||||
bd->ShaderHandle = GL.CreateProgram();
|
||||
GL.AttachShader(bd->ShaderHandle, vert);
|
||||
GL.AttachShader(bd->ShaderHandle, frag);
|
||||
GL.LinkProgram(bd->ShaderHandle);
|
||||
CheckProgram(bd->ShaderHandle, "shader program");
|
||||
|
||||
GL.DetachShader(bd->ShaderHandle, vert);
|
||||
GL.DetachShader(bd->ShaderHandle, frag);
|
||||
GL.DeleteShader(vert);
|
||||
GL.DeleteShader(frag);
|
||||
|
||||
bd->UniformLocationTex = GL.GetUniformLocation(bd->ShaderHandle, "Texture");
|
||||
bd->UniformLocationProjMtx = GL.GetUniformLocation(bd->ShaderHandle, "ProjMtx");
|
||||
bd->AttribLocationVtxPos = GL.GetAttribLocation(bd->ShaderHandle, "Position");
|
||||
bd->AttribLocationVtxUV = GL.GetAttribLocation(bd->ShaderHandle, "UV");
|
||||
bd->AttribLocationVtxColor = GL.GetAttribLocation(bd->ShaderHandle, "Color");
|
||||
|
||||
bd->VboHandle = GL.GenBuffer();
|
||||
bd->EboHandle = GL.GenBuffer();
|
||||
|
||||
CreateFontsTexture();
|
||||
|
||||
GL.BindTexture(TextureTarget.Texture2D, last_texture);
|
||||
GL.BindBuffer(BufferTarget.ArrayBuffer, last_array_buffer);
|
||||
GL.BindBuffer(BufferTarget.PixelUnpackBuffer, last_pixel_unpack_buffer);
|
||||
GL.BindVertexArray(last_vertex_array);
|
||||
|
||||
if (bd->KHRDebugAvailable)
|
||||
{
|
||||
GL.ObjectLabel(ObjectLabelIdentifier.Buffer, bd->VboHandle, -1, "OpenTK_ImGui: VBO");
|
||||
GL.ObjectLabel(ObjectLabelIdentifier.Buffer, bd->EboHandle, -1, "OpenTK_ImGui: EBO");
|
||||
GL.ObjectLabel(ObjectLabelIdentifier.Shader, bd->ShaderHandle, -1, "OpenTK_ImGui: Shader");
|
||||
}
|
||||
}
|
||||
|
||||
static void DestroyDeviceObjects()
|
||||
{
|
||||
RendererData* bd = GetBackendData();
|
||||
|
||||
if (bd->VboHandle != 0)
|
||||
{
|
||||
GL.DeleteBuffer(bd->VboHandle);
|
||||
bd->VboHandle = 0;
|
||||
}
|
||||
|
||||
if (bd->EboHandle != 0)
|
||||
{
|
||||
GL.DeleteBuffer(bd->EboHandle);
|
||||
bd->EboHandle = 0;
|
||||
}
|
||||
|
||||
if (bd->ShaderHandle != 0)
|
||||
{
|
||||
GL.DeleteProgram(bd->ShaderHandle);
|
||||
bd->ShaderHandle = 0;
|
||||
}
|
||||
|
||||
DestroyFontsTexture();
|
||||
}
|
||||
|
||||
static void InitMultiViewportSupport()
|
||||
{
|
||||
var platformIO = ImGui.GetPlatformIO();
|
||||
platformIO.Renderer_RenderWindow = (IntPtr)(delegate* unmanaged[Cdecl]<ImGuiViewportPtr, void>)&Renderer_RenderWindow;
|
||||
}
|
||||
|
||||
static void ShutdownMultiViewportSupport()
|
||||
{
|
||||
ImGui.DestroyPlatformWindows();
|
||||
}
|
||||
|
||||
[UnmanagedCallersOnly(CallConvs = [typeof(CallConvCdecl)])]
|
||||
static void Renderer_RenderWindow(ImGuiViewportPtr viewport)
|
||||
{
|
||||
if (viewport.Flags.HasFlag(ImGuiViewportFlags.NoRendererClear))
|
||||
{
|
||||
GL.ClearColor(Color4.Black);
|
||||
GL.Clear(ClearBufferMask.ColorBufferBit);
|
||||
}
|
||||
RenderDrawData(viewport.DrawData);
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in new issue
Block a user