diff --git a/src/CodeGenerator/TypeInfo.cs b/src/CodeGenerator/TypeInfo.cs index 52e68f7..de90495 100644 --- a/src/CodeGenerator/TypeInfo.cs +++ b/src/CodeGenerator/TypeInfo.cs @@ -138,7 +138,9 @@ namespace CodeGenerator public static readonly HashSet SkippedFunctions = new HashSet() { "igInputText", - "igInputTextMultiline" + "igInputTextMultiline", + "igCalcTextSize", + "igInputTextWithHint" }; } } \ No newline at end of file diff --git a/src/ImGui.NET.SampleProgram/ImGuiController.cs b/src/ImGui.NET.SampleProgram/ImGuiController.cs index 3c600ad..4cbe615 100644 --- a/src/ImGui.NET.SampleProgram/ImGuiController.cs +++ b/src/ImGui.NET.SampleProgram/ImGuiController.cs @@ -99,8 +99,8 @@ namespace ImGuiNET byte[] vertexShaderBytes = LoadEmbeddedShaderCode(gd.ResourceFactory, "imgui-vertex", ShaderStages.Vertex); byte[] fragmentShaderBytes = LoadEmbeddedShaderCode(gd.ResourceFactory, "imgui-frag", ShaderStages.Fragment); - _vertexShader = factory.CreateShader(new ShaderDescription(ShaderStages.Vertex, vertexShaderBytes, "VS")); - _fragmentShader = factory.CreateShader(new ShaderDescription(ShaderStages.Fragment, fragmentShaderBytes, "FS")); + _vertexShader = factory.CreateShader(new ShaderDescription(ShaderStages.Vertex, vertexShaderBytes, gd.BackendType == GraphicsBackend.Metal ? "VS" : "main")); + _fragmentShader = factory.CreateShader(new ShaderDescription(ShaderStages.Fragment, fragmentShaderBytes, gd.BackendType == GraphicsBackend.Metal ? "FS" : "main")); VertexLayoutDescription[] vertexLayouts = new VertexLayoutDescription[] { @@ -123,7 +123,8 @@ namespace ImGuiNET PrimitiveTopology.TriangleList, new ShaderSetDescription(vertexLayouts, new[] { _vertexShader, _fragmentShader }), new ResourceLayout[] { _layout, _textureLayout }, - outputDescription); + outputDescription, + ResourceBindingModel.Default); _pipeline = factory.CreateGraphicsPipeline(ref pd); _mainResourceSet = factory.CreateResourceSet(new ResourceSetDescription(_layout, diff --git a/src/ImGui.NET.SampleProgram/Program.cs b/src/ImGui.NET.SampleProgram/Program.cs index 9d69b8a..0781b9f 100644 --- a/src/ImGui.NET.SampleProgram/Program.cs +++ b/src/ImGui.NET.SampleProgram/Program.cs @@ -38,7 +38,7 @@ namespace ImGuiNET // Create window, GraphicsDevice, and all resources necessary for the demo. VeldridStartup.CreateWindowAndGraphicsDevice( new WindowCreateInfo(50, 50, 1280, 720, WindowState.Normal, "ImGui.NET Sample Program"), - new GraphicsDeviceOptions(true, null, true), + new GraphicsDeviceOptions(true, null, true, ResourceBindingModel.Improved, true, true), out _window, out _gd); _window.Resized += () => diff --git a/src/ImGui.NET.SampleProgram/Shaders/SPIR-V/imgui-frag.glsl b/src/ImGui.NET.SampleProgram/Shaders/SPIR-V/imgui-frag.glsl index 2d1c1d7..f94fa48 100644 --- a/src/ImGui.NET.SampleProgram/Shaders/SPIR-V/imgui-frag.glsl +++ b/src/ImGui.NET.SampleProgram/Shaders/SPIR-V/imgui-frag.glsl @@ -13,4 +13,4 @@ layout (location = 0) out vec4 outputColor; void main() { outputColor = color * texture(sampler2D(FontTexture, FontSampler), texCoord); -} +} \ No newline at end of file diff --git a/src/ImGui.NET.SampleProgram/Shaders/SPIR-V/imgui-frag.spv b/src/ImGui.NET.SampleProgram/Shaders/SPIR-V/imgui-frag.spv index c8d71cc..5d3d96f 100644 Binary files a/src/ImGui.NET.SampleProgram/Shaders/SPIR-V/imgui-frag.spv and b/src/ImGui.NET.SampleProgram/Shaders/SPIR-V/imgui-frag.spv differ diff --git a/src/ImGui.NET.SampleProgram/Shaders/SPIR-V/imgui-vertex.glsl b/src/ImGui.NET.SampleProgram/Shaders/SPIR-V/imgui-vertex.glsl index 6fdab3f..6249a36 100644 --- a/src/ImGui.NET.SampleProgram/Shaders/SPIR-V/imgui-vertex.glsl +++ b/src/ImGui.NET.SampleProgram/Shaders/SPIR-V/imgui-vertex.glsl @@ -3,27 +3,26 @@ #extension GL_ARB_separate_shader_objects : enable #extension GL_ARB_shading_language_420pack : enable -layout (location = 0) in vec2 vsin_position; -layout (location = 1) in vec2 vsin_texCoord; -layout (location = 2) in vec4 vsin_color; +layout (location = 0) in vec2 in_position; +layout (location = 1) in vec2 in_texCoord; +layout (location = 2) in vec4 in_color; -layout (binding = 0) uniform Projection +layout (binding = 0) uniform ProjectionMatrixBuffer { - mat4 projection; + mat4 projection_matrix; }; -layout (location = 0) out vec4 vsout_color; -layout (location = 1) out vec2 vsout_texCoord; +layout (location = 0) out vec4 color; +layout (location = 1) out vec2 texCoord; -out gl_PerVertex +out gl_PerVertex { vec4 gl_Position; }; void main() { - gl_Position = projection * vec4(vsin_position, 0, 1); - vsout_color = vsin_color; - vsout_texCoord = vsin_texCoord; - gl_Position.y = -gl_Position.y; + gl_Position = projection_matrix * vec4(in_position, 0, 1); + color = in_color; + texCoord = in_texCoord; } diff --git a/src/ImGui.NET.SampleProgram/Shaders/SPIR-V/imgui-vertex.spv b/src/ImGui.NET.SampleProgram/Shaders/SPIR-V/imgui-vertex.spv index 795cd0e..b40ec8c 100644 Binary files a/src/ImGui.NET.SampleProgram/Shaders/SPIR-V/imgui-vertex.spv and b/src/ImGui.NET.SampleProgram/Shaders/SPIR-V/imgui-vertex.spv differ diff --git a/src/ImGui.NET/Generated/ImGui.gen.cs b/src/ImGui.NET/Generated/ImGui.gen.cs index 5cc7a0a..d355fcf 100644 --- a/src/ImGui.NET/Generated/ImGui.gen.cs +++ b/src/ImGui.NET/Generated/ImGui.gen.cs @@ -1262,37 +1262,6 @@ namespace ImGuiNET float ret = ImGuiNative.igCalcItemWidth(); return ret; } - public static Vector2 CalcTextSize(string text) - { - Vector2 __retval; - byte* native_text; - int text_byteCount = 0; - if (text != null) - { - text_byteCount = Encoding.UTF8.GetByteCount(text); - if (text_byteCount > Util.StackAllocationSizeLimit) - { - native_text = Util.Allocate(text_byteCount + 1); - } - else - { - byte* native_text_stackBytes = stackalloc byte[text_byteCount + 1]; - native_text = native_text_stackBytes; - } - int native_text_offset = Util.GetUtf8(text, native_text, text_byteCount); - native_text[native_text_offset] = 0; - } - else { native_text = null; } - byte* native_text_end = null; - byte hide_text_after_double_hash = 0; - float wrap_width = -1.0f; - ImGuiNative.igCalcTextSize(&__retval, native_text, native_text_end, hide_text_after_double_hash, wrap_width); - if (text_byteCount > Util.StackAllocationSizeLimit) - { - Util.Free(native_text); - } - return __retval; - } public static void CaptureKeyboardFromApp() { byte want_capture_keyboard_value = 1; @@ -8305,297 +8274,6 @@ namespace ImGuiNET } return ret != 0; } - public static bool InputTextWithHint(string label, string hint, string buf, uint buf_size) - { - byte* native_label; - int label_byteCount = 0; - if (label != null) - { - label_byteCount = Encoding.UTF8.GetByteCount(label); - if (label_byteCount > Util.StackAllocationSizeLimit) - { - native_label = Util.Allocate(label_byteCount + 1); - } - else - { - byte* native_label_stackBytes = stackalloc byte[label_byteCount + 1]; - native_label = native_label_stackBytes; - } - int native_label_offset = Util.GetUtf8(label, native_label, label_byteCount); - native_label[native_label_offset] = 0; - } - else { native_label = null; } - byte* native_hint; - int hint_byteCount = 0; - if (hint != null) - { - hint_byteCount = Encoding.UTF8.GetByteCount(hint); - if (hint_byteCount > Util.StackAllocationSizeLimit) - { - native_hint = Util.Allocate(hint_byteCount + 1); - } - else - { - byte* native_hint_stackBytes = stackalloc byte[hint_byteCount + 1]; - native_hint = native_hint_stackBytes; - } - int native_hint_offset = Util.GetUtf8(hint, native_hint, hint_byteCount); - native_hint[native_hint_offset] = 0; - } - else { native_hint = null; } - byte* native_buf; - int buf_byteCount = 0; - if (buf != null) - { - buf_byteCount = Encoding.UTF8.GetByteCount(buf); - if (buf_byteCount > Util.StackAllocationSizeLimit) - { - native_buf = Util.Allocate(buf_byteCount + 1); - } - else - { - byte* native_buf_stackBytes = stackalloc byte[buf_byteCount + 1]; - native_buf = native_buf_stackBytes; - } - int native_buf_offset = Util.GetUtf8(buf, native_buf, buf_byteCount); - native_buf[native_buf_offset] = 0; - } - else { native_buf = null; } - ImGuiInputTextFlags flags = (ImGuiInputTextFlags)0; - ImGuiInputTextCallback callback = null; - void* user_data = null; - byte ret = ImGuiNative.igInputTextWithHint(native_label, native_hint, native_buf, buf_size, flags, callback, user_data); - if (label_byteCount > Util.StackAllocationSizeLimit) - { - Util.Free(native_label); - } - if (hint_byteCount > Util.StackAllocationSizeLimit) - { - Util.Free(native_hint); - } - if (buf_byteCount > Util.StackAllocationSizeLimit) - { - Util.Free(native_buf); - } - return ret != 0; - } - public static bool InputTextWithHint(string label, string hint, string buf, uint buf_size, ImGuiInputTextFlags flags) - { - byte* native_label; - int label_byteCount = 0; - if (label != null) - { - label_byteCount = Encoding.UTF8.GetByteCount(label); - if (label_byteCount > Util.StackAllocationSizeLimit) - { - native_label = Util.Allocate(label_byteCount + 1); - } - else - { - byte* native_label_stackBytes = stackalloc byte[label_byteCount + 1]; - native_label = native_label_stackBytes; - } - int native_label_offset = Util.GetUtf8(label, native_label, label_byteCount); - native_label[native_label_offset] = 0; - } - else { native_label = null; } - byte* native_hint; - int hint_byteCount = 0; - if (hint != null) - { - hint_byteCount = Encoding.UTF8.GetByteCount(hint); - if (hint_byteCount > Util.StackAllocationSizeLimit) - { - native_hint = Util.Allocate(hint_byteCount + 1); - } - else - { - byte* native_hint_stackBytes = stackalloc byte[hint_byteCount + 1]; - native_hint = native_hint_stackBytes; - } - int native_hint_offset = Util.GetUtf8(hint, native_hint, hint_byteCount); - native_hint[native_hint_offset] = 0; - } - else { native_hint = null; } - byte* native_buf; - int buf_byteCount = 0; - if (buf != null) - { - buf_byteCount = Encoding.UTF8.GetByteCount(buf); - if (buf_byteCount > Util.StackAllocationSizeLimit) - { - native_buf = Util.Allocate(buf_byteCount + 1); - } - else - { - byte* native_buf_stackBytes = stackalloc byte[buf_byteCount + 1]; - native_buf = native_buf_stackBytes; - } - int native_buf_offset = Util.GetUtf8(buf, native_buf, buf_byteCount); - native_buf[native_buf_offset] = 0; - } - else { native_buf = null; } - ImGuiInputTextCallback callback = null; - void* user_data = null; - byte ret = ImGuiNative.igInputTextWithHint(native_label, native_hint, native_buf, buf_size, flags, callback, user_data); - if (label_byteCount > Util.StackAllocationSizeLimit) - { - Util.Free(native_label); - } - if (hint_byteCount > Util.StackAllocationSizeLimit) - { - Util.Free(native_hint); - } - if (buf_byteCount > Util.StackAllocationSizeLimit) - { - Util.Free(native_buf); - } - return ret != 0; - } - public static bool InputTextWithHint(string label, string hint, string buf, uint buf_size, ImGuiInputTextFlags flags, ImGuiInputTextCallback callback) - { - byte* native_label; - int label_byteCount = 0; - if (label != null) - { - label_byteCount = Encoding.UTF8.GetByteCount(label); - if (label_byteCount > Util.StackAllocationSizeLimit) - { - native_label = Util.Allocate(label_byteCount + 1); - } - else - { - byte* native_label_stackBytes = stackalloc byte[label_byteCount + 1]; - native_label = native_label_stackBytes; - } - int native_label_offset = Util.GetUtf8(label, native_label, label_byteCount); - native_label[native_label_offset] = 0; - } - else { native_label = null; } - byte* native_hint; - int hint_byteCount = 0; - if (hint != null) - { - hint_byteCount = Encoding.UTF8.GetByteCount(hint); - if (hint_byteCount > Util.StackAllocationSizeLimit) - { - native_hint = Util.Allocate(hint_byteCount + 1); - } - else - { - byte* native_hint_stackBytes = stackalloc byte[hint_byteCount + 1]; - native_hint = native_hint_stackBytes; - } - int native_hint_offset = Util.GetUtf8(hint, native_hint, hint_byteCount); - native_hint[native_hint_offset] = 0; - } - else { native_hint = null; } - byte* native_buf; - int buf_byteCount = 0; - if (buf != null) - { - buf_byteCount = Encoding.UTF8.GetByteCount(buf); - if (buf_byteCount > Util.StackAllocationSizeLimit) - { - native_buf = Util.Allocate(buf_byteCount + 1); - } - else - { - byte* native_buf_stackBytes = stackalloc byte[buf_byteCount + 1]; - native_buf = native_buf_stackBytes; - } - int native_buf_offset = Util.GetUtf8(buf, native_buf, buf_byteCount); - native_buf[native_buf_offset] = 0; - } - else { native_buf = null; } - void* user_data = null; - byte ret = ImGuiNative.igInputTextWithHint(native_label, native_hint, native_buf, buf_size, flags, callback, user_data); - if (label_byteCount > Util.StackAllocationSizeLimit) - { - Util.Free(native_label); - } - if (hint_byteCount > Util.StackAllocationSizeLimit) - { - Util.Free(native_hint); - } - if (buf_byteCount > Util.StackAllocationSizeLimit) - { - Util.Free(native_buf); - } - return ret != 0; - } - public static bool InputTextWithHint(string label, string hint, string buf, uint buf_size, ImGuiInputTextFlags flags, ImGuiInputTextCallback callback, IntPtr user_data) - { - byte* native_label; - int label_byteCount = 0; - if (label != null) - { - label_byteCount = Encoding.UTF8.GetByteCount(label); - if (label_byteCount > Util.StackAllocationSizeLimit) - { - native_label = Util.Allocate(label_byteCount + 1); - } - else - { - byte* native_label_stackBytes = stackalloc byte[label_byteCount + 1]; - native_label = native_label_stackBytes; - } - int native_label_offset = Util.GetUtf8(label, native_label, label_byteCount); - native_label[native_label_offset] = 0; - } - else { native_label = null; } - byte* native_hint; - int hint_byteCount = 0; - if (hint != null) - { - hint_byteCount = Encoding.UTF8.GetByteCount(hint); - if (hint_byteCount > Util.StackAllocationSizeLimit) - { - native_hint = Util.Allocate(hint_byteCount + 1); - } - else - { - byte* native_hint_stackBytes = stackalloc byte[hint_byteCount + 1]; - native_hint = native_hint_stackBytes; - } - int native_hint_offset = Util.GetUtf8(hint, native_hint, hint_byteCount); - native_hint[native_hint_offset] = 0; - } - else { native_hint = null; } - byte* native_buf; - int buf_byteCount = 0; - if (buf != null) - { - buf_byteCount = Encoding.UTF8.GetByteCount(buf); - if (buf_byteCount > Util.StackAllocationSizeLimit) - { - native_buf = Util.Allocate(buf_byteCount + 1); - } - else - { - byte* native_buf_stackBytes = stackalloc byte[buf_byteCount + 1]; - native_buf = native_buf_stackBytes; - } - int native_buf_offset = Util.GetUtf8(buf, native_buf, buf_byteCount); - native_buf[native_buf_offset] = 0; - } - else { native_buf = null; } - void* native_user_data = (void*)user_data.ToPointer(); - byte ret = ImGuiNative.igInputTextWithHint(native_label, native_hint, native_buf, buf_size, flags, callback, native_user_data); - if (label_byteCount > Util.StackAllocationSizeLimit) - { - Util.Free(native_label); - } - if (hint_byteCount > Util.StackAllocationSizeLimit) - { - Util.Free(native_hint); - } - if (buf_byteCount > Util.StackAllocationSizeLimit) - { - Util.Free(native_buf); - } - return ret != 0; - } public static bool InvisibleButton(string str_id, Vector2 size) { byte* native_str_id; diff --git a/src/ImGui.NET/ImGui.Manual.cs b/src/ImGui.NET/ImGui.Manual.cs index 8fac3de..cec21cf 100644 --- a/src/ImGui.NET/ImGui.Manual.cs +++ b/src/ImGui.NET/ImGui.Manual.cs @@ -355,6 +355,79 @@ namespace ImGuiNET return result != 0; } + public static Vector2 CalcTextSize(string text) + => CalcTextSizeImpl(text); + + public static Vector2 CalcTextSize(string text, int start) + => CalcTextSizeImpl(text, start); + + public static Vector2 CalcTextSize(string text, float wrapWidth) + => CalcTextSizeImpl(text, wrapWidth: wrapWidth); + + public static Vector2 CalcTextSize(string text, bool hideTextAfterDoubleHash) + => CalcTextSizeImpl(text, hideTextAfterDoubleHash: hideTextAfterDoubleHash); + + public static Vector2 CalcTextSize(string text, int start, int length) + => CalcTextSizeImpl(text, start, length); + + public static Vector2 CalcTextSize(string text, int start, bool hideTextAfterDoubleHash) + => CalcTextSizeImpl(text, start, hideTextAfterDoubleHash: hideTextAfterDoubleHash); + + public static Vector2 CalcTextSize(string text, int start, float wrapWidth) + => CalcTextSizeImpl(text, start, wrapWidth: wrapWidth); + + public static Vector2 CalcTextSize(string text, bool hideTextAfterDoubleHash, float wrapWidth) + => CalcTextSizeImpl(text, hideTextAfterDoubleHash: hideTextAfterDoubleHash, wrapWidth: wrapWidth); + + public static Vector2 CalcTextSize(string text, int start, int length, bool hideTextAfterDoubleHash) + => CalcTextSizeImpl(text, start, length, hideTextAfterDoubleHash); + + public static Vector2 CalcTextSize(string text, int start, int length, float wrapWidth) + => CalcTextSizeImpl(text, start, length, wrapWidth: wrapWidth); + + public static Vector2 CalcTextSize(string text, int start, int length, bool hideTextAfterDoubleHash, float wrapWidth) + => CalcTextSizeImpl(text, start, length, hideTextAfterDoubleHash, wrapWidth); + + private static Vector2 CalcTextSizeImpl( + string text, + int start = 0, + int? length = null, + bool hideTextAfterDoubleHash = false, + float wrapWidth = -1.0f) + { + Vector2 ret; + byte* nativeTextStart = null; + byte* nativeTextEnd = null; + int textByteCount = 0; + if (text != null) + { + + int textToCopyLen = length.HasValue ? length.Value : text.Length; + textByteCount = Util.CalcSizeInUtf8(text, start, textToCopyLen); + if (textByteCount > Util.StackAllocationSizeLimit) + { + nativeTextStart = Util.Allocate(textByteCount + 1); + } + else + { + byte* nativeTextStackBytes = stackalloc byte[textByteCount + 1]; + nativeTextStart = nativeTextStackBytes; + } + + int nativeTextOffset = Util.GetUtf8(text, start, textToCopyLen, nativeTextStart, textByteCount); + nativeTextStart[nativeTextOffset] = 0; + nativeTextEnd = nativeTextStart + nativeTextOffset; + } + + ImGuiNative.igCalcTextSize(&ret, nativeTextStart, nativeTextEnd, *((byte*)(&hideTextAfterDoubleHash)), wrapWidth); + if (textByteCount > Util.StackAllocationSizeLimit) + { + Util.Free(nativeTextStart); + } + + return ret; + } + public static bool InputText( string label, IntPtr buf, diff --git a/src/ImGui.NET/Util.cs b/src/ImGui.NET/Util.cs index 34280a0..52785b6 100644 --- a/src/ImGui.NET/Util.cs +++ b/src/ImGui.NET/Util.cs @@ -32,7 +32,22 @@ namespace ImGuiNET } internal static byte* Allocate(int byteCount) => (byte*)Marshal.AllocHGlobal(byteCount); + internal static void Free(byte* ptr) => Marshal.FreeHGlobal((IntPtr)ptr); + + internal static int CalcSizeInUtf8(string s, int start, int length) + { + if (start < 0 || length < 0 || start + length > s.Length) + { + throw new ArgumentOutOfRangeException(); + } + + fixed (char* utf16Ptr = s) + { + return Encoding.UTF8.GetByteCount(utf16Ptr + start, length); + } + } + internal static int GetUtf8(string s, byte* utf8Bytes, int utf8ByteCount) { fixed (char* utf16Ptr = s) @@ -40,5 +55,18 @@ namespace ImGuiNET return Encoding.UTF8.GetBytes(utf16Ptr, s.Length, utf8Bytes, utf8ByteCount); } } + + internal static int GetUtf8(string s, int start, int length, byte* utf8Bytes, int utf8ByteCount) + { + if (start < 0 || length < 0 || start + length > s.Length) + { + throw new ArgumentOutOfRangeException(); + } + + fixed (char* utf16Ptr = s) + { + return Encoding.UTF8.GetBytes(utf16Ptr + start, length, utf8Bytes, utf8ByteCount); + } + } } }