55using Hexa . NET . ImPlot ;
66using Staple . Internal ;
77using System ;
8+ using System . Collections . Generic ;
89using System . Linq ;
910using System . Numerics ;
1011using System . Runtime . CompilerServices ;
@@ -23,8 +24,8 @@ internal class ImGuiProxy
2324 public Shader imageProgram ;
2425 public VertexLayout layout ;
2526 public bgfx . UniformHandle textureUniform ;
26- public Texture fontTexture ;
2727 public bgfx . TextureHandle activeTexture ;
28+ public readonly List < ( Texture , byte [ ] , int ) > textures = [ ] ;
2829
2930 public ImFontPtr editorFont ;
3031
@@ -84,28 +85,35 @@ public bool Initialize()
8485 ImNodes . SetImGuiContext ( ImGuiContext ) ;
8586
8687 ImNodesContext = ImNodes . CreateContext ( ) ;
88+
8789 ImNodes . SetCurrentContext ( ImNodesContext ) ;
8890 ImNodes . StyleColorsDark ( ImNodes . GetStyle ( ) ) ;
8991
9092 ImPlotContext = ImPlot . CreateContext ( ) ;
93+
9194 ImPlot . SetCurrentContext ( ImPlotContext ) ;
9295 ImPlot . StyleColorsDark ( ImPlot . GetStyle ( ) ) ;
9396
9497 var io = ImGui . GetIO ( ) ;
98+ var platformIO = ImGui . GetPlatformIO ( ) ;
9599
96100 unsafe
97101 {
98102 var setPtr = Marshal . GetFunctionPointerForDelegate ( SetClipboardText ) ;
99103 var getPtr = Marshal . GetFunctionPointerForDelegate ( GetClipboardText ) ;
100104
101- io . SetClipboardTextFn = ( void * ) setPtr ;
102- io . GetClipboardTextFn = ( void * ) getPtr ;
103- io . ClipboardUserData = ( void * ) nint . Zero ;
105+ platformIO . RendererTextureMaxWidth = platformIO . RendererTextureMaxHeight = ( int ) bgfx . get_caps ( ) ->limits . maxTextureSize ;
106+ platformIO . PlatformSetClipboardTextFn = ( void * ) setPtr ;
107+ platformIO . PlatformGetClipboardTextFn = ( void * ) getPtr ;
108+ platformIO . PlatformClipboardUserData = ( void * ) nint . Zero ;
109+
110+ io . Fonts . AddFontDefault ( ) ;
104111 }
105112
106- io . BackendFlags |= ImGuiBackendFlags . RendererHasVtxOffset ;
113+ io . BackendFlags |= ImGuiBackendFlags . RendererHasVtxOffset |
114+ ImGuiBackendFlags . RendererHasTextures ;
107115
108- io . Fonts . AddFontDefault ( ) ;
116+ io . ConfigWindowsMoveFromTitleBarOnly = true ;
109117
110118 var editor = Convert . FromBase64String ( FontData . IntelOneMonoMedium ) ;
111119 var header = Convert . FromBase64String ( FontData . IntelOneMonoBold ) ;
@@ -150,37 +158,6 @@ public bool Initialize()
150158
151159 textureUniform = bgfx . create_uniform ( "s_tex" , bgfx . UniformType . Sampler , 1 ) ;
152160
153- unsafe
154- {
155- byte * data = null ;
156- int fontWidth = 0 ;
157- int fontHeight = 0 ;
158-
159- io . Fonts . GetTexDataAsRGBA32 ( & data , ref fontWidth , ref fontHeight ) ;
160-
161- byte [ ] fontData = new byte [ fontWidth * fontHeight * 4 ] ;
162-
163- for ( int i = 0 ; i < fontData . Length ; i ++ )
164- {
165- fontData [ i ] = data [ i ] ;
166- }
167-
168- fontTexture = Texture . CreatePixels ( "FONT" , fontData , ( ushort ) fontWidth , ( ushort ) fontHeight , new TextureMetadata ( )
169- {
170- useMipmaps = false ,
171- } ,
172- TextureFormat . BGRA8 ) ;
173-
174- ResourceManager . instance . LockAsset ( "FONT" ) ;
175- }
176-
177- if ( fontTexture == null )
178- {
179- Log . Error ( "Failed to load font" ) ;
180-
181- return false ;
182- }
183-
184161 return true ;
185162 }
186163
@@ -200,15 +177,21 @@ public void Destroy()
200177
201178 program ? . Destroy ( ) ;
202179 imageProgram ? . Destroy ( ) ;
203- fontTexture ? . Destroy ( ) ;
180+
181+ foreach ( var texture in textures )
182+ {
183+ texture . Item1 . Destroy ( ) ;
184+ }
185+
186+ textures . Clear ( ) ;
204187
205188 if ( pinnedClipboardHandle . IsAllocated )
206189 {
207190 pinnedClipboardHandle . Free ( ) ;
208191 }
209192 }
210193
211- public ImGuiKey GetKey ( KeyCode key )
194+ public static ImGuiKey GetKey ( KeyCode key )
212195 {
213196 return key switch
214197 {
@@ -364,7 +347,9 @@ public void BeginFrame()
364347
365348 ImGui . NewFrame ( ) ;
366349
367- ImGui . PushFont ( editorFont ) ;
350+ ImGuizmo . BeginFrame ( ) ;
351+
352+ ImGui . PushFont ( editorFont , 20 ) ;
368353
369354 frameBegun = true ;
370355 }
@@ -405,6 +390,137 @@ private void Render(ImDrawDataPtr drawData)
405390 return ;
406391 }
407392
393+ if ( drawData . Textures . Size != 0 )
394+ {
395+ var t = new Span < ImTextureDataPtr > ( drawData . Textures . Data , drawData . Textures . Size ) ;
396+
397+ foreach ( var texture in t )
398+ {
399+ switch ( texture . Status )
400+ {
401+ case ImTextureStatus . WantCreate :
402+
403+ {
404+ var bytesPerPixel = texture . BytesPerPixel ;
405+
406+ var pixels = new byte [ texture . Width * texture . Height * bytesPerPixel ] ;
407+
408+ fixed ( void * ptr = pixels )
409+ {
410+ Buffer . MemoryCopy ( texture . Pixels , ptr , pixels . Length , pixels . Length ) ;
411+ }
412+
413+ var outTexture = Texture . CreatePixels ( $ "ImGui { texture . UniqueID } ", pixels ,
414+ ( ushort ) texture . Width , ( ushort ) texture . Height ,
415+ new TextureMetadata ( )
416+ {
417+ useMipmaps = false ,
418+ } , texture . Format switch
419+ {
420+ ImTextureFormat . Rgba32 => TextureFormat . RGBA8 ,
421+ ImTextureFormat . Alpha8 => TextureFormat . A8 ,
422+ _ => TextureFormat . RGBA8 ,
423+ } ) ;
424+
425+ if ( outTexture != null )
426+ {
427+ ResourceManager . instance . LockAsset ( $ "ImGui { texture . UniqueID } ") ;
428+
429+ textures . Add ( ( outTexture , pixels , bytesPerPixel ) ) ;
430+
431+ texture . SetTexID ( new ImTextureID ( ( ulong ) outTexture . handle . idx ) ) ;
432+ }
433+ else
434+ {
435+ texture . SetTexID ( ImTextureID . Null ) ;
436+ }
437+
438+ texture . SetStatus ( ImTextureStatus . Ok ) ;
439+ }
440+
441+ break ;
442+
443+ case ImTextureStatus . WantUpdates :
444+
445+ {
446+ var index = textures . FindIndex ( x => x . Item1 . handle . idx == texture . TexID . Handle ) ;
447+
448+ if ( index >= 0 )
449+ {
450+ var ( target , pixels , bytesPerPixel ) = textures [ index ] ;
451+
452+ var updates = texture . Updates ;
453+
454+ fixed( byte * ptr = pixels )
455+ {
456+ for ( var i = 0 ; i < updates . Size ; i ++ )
457+ {
458+ var update = updates . Data [ i ] ;
459+
460+ for ( var y = 0 ; y < update . H ; y ++ )
461+ {
462+ Buffer . MemoryCopy ( texture . GetPixelsAt ( update . X , update . Y + y ) ,
463+ ptr + update . X * bytesPerPixel + ( ( update . Y + y ) * texture . Width * bytesPerPixel ) ,
464+ update . W * bytesPerPixel , update . W * bytesPerPixel ) ;
465+ }
466+ }
467+ }
468+
469+ target . Destroy ( ) ;
470+
471+ target = Texture . CreatePixels ( $ "ImGui { texture . UniqueID } ", pixels ,
472+ ( ushort ) texture . Width , ( ushort ) texture . Height ,
473+ new TextureMetadata ( )
474+ {
475+ useMipmaps = false ,
476+ } , texture . Format switch
477+ {
478+ ImTextureFormat . Rgba32 => TextureFormat . RGBA8 ,
479+ ImTextureFormat . Alpha8 => TextureFormat . A8 ,
480+ _ => TextureFormat . RGBA8 ,
481+ } ) ;
482+
483+ if ( target != null )
484+ {
485+ textures [ index ] = ( target , pixels , bytesPerPixel ) ;
486+
487+ texture . SetTexID ( new ImTextureID ( ( ulong ) target . handle . idx ) ) ;
488+ }
489+ else
490+ {
491+ texture . SetTexID ( ImTextureID . Null ) ;
492+ }
493+
494+ texture . SetStatus ( ImTextureStatus . Ok ) ;
495+ }
496+ }
497+
498+ break ;
499+
500+ case ImTextureStatus . WantDestroy :
501+
502+ if ( texture . UnusedFrames > 0 )
503+ {
504+ for ( var i = 0 ; i < textures . Count ; i ++ )
505+ {
506+ if ( textures [ i ] . Item1 . handle . idx == texture . TexID . Handle )
507+ {
508+ textures [ i ] . Item1 . Destroy ( ) ;
509+
510+ textures . RemoveAt ( i ) ;
511+
512+ break ;
513+ }
514+ }
515+
516+ texture . SetStatus ( ImTextureStatus . Destroyed ) ;
517+ }
518+
519+ break ;
520+ }
521+ }
522+ }
523+
408524 bgfx . set_view_name ( viewID , "ImGui" , int . MaxValue ) ;
409525 bgfx . set_view_mode ( viewID , bgfx . ViewMode . Sequential ) ;
410526
@@ -424,8 +540,8 @@ private void Render(ImDrawDataPtr drawData)
424540
425541 var cmdList = drawData . CmdLists . Data [ i ] ;
426542
427- var numVertices = cmdList -> VtxBuffer . Size ;
428- var numIndices = cmdList -> IdxBuffer . Size ;
543+ var numVertices = cmdList . VtxBuffer . Size ;
544+ var numIndices = cmdList . IdxBuffer . Size ;
429545
430546 if ( RenderSystem . CheckAvailableTransientBuffers ( ( uint ) numVertices , layout . layout , ( uint ) numIndices ) == false )
431547 {
@@ -441,15 +557,15 @@ private void Render(ImDrawDataPtr drawData)
441557
442558 var size = numVertices * sizeof ( ImDrawVert ) ;
443559
444- Buffer . MemoryCopy ( ( void * ) cmdList -> VtxBuffer . Data , tvb . data , size , size ) ;
560+ Buffer . MemoryCopy ( ( void * ) cmdList . VtxBuffer . Data , tvb . data , size , size ) ;
445561
446562 size = numIndices * sizeof ( ushort ) ;
447563
448- Buffer . MemoryCopy ( ( void * ) cmdList -> IdxBuffer . Data , tib . data , size , size ) ;
564+ Buffer . MemoryCopy ( ( void * ) cmdList . IdxBuffer . Data , tib . data , size , size ) ;
449565
450- for ( var j = 0 ; j < cmdList -> CmdBuffer . Size ; j ++ )
566+ for ( var j = 0 ; j < cmdList . CmdBuffer . Size ; j ++ )
451567 {
452- var drawCmd = cmdList -> CmdBuffer . Data [ j ] ;
568+ var drawCmd = cmdList . CmdBuffer . Data [ j ] ;
453569
454570 if ( drawCmd . ElemCount == 0 || drawCmd . UserCallback != null )
455571 {
@@ -461,17 +577,17 @@ private void Render(ImDrawDataPtr drawData)
461577
462578 bgfx . ProgramHandle program = this . program . instances . First ( ) . Value . program ;
463579
464- if ( drawCmd . TextureId != IntPtr . Zero )
580+ if ( drawCmd . GetTexID ( ) . IsNull == false )
465581 {
466582 program = imageProgram . instances . First ( ) . Value . program ;
467583
468- var index = ( ushort ) drawCmd . TextureId . Handle ;
584+ var index = ( ushort ) drawCmd . GetTexID ( ) . Handle ;
469585
470586 activeTexture . idx = index ;
471587 }
472588 else
473589 {
474- activeTexture . idx = fontTexture . handle . idx ;
590+ activeTexture . idx = ushort . MaxValue ;
475591 }
476592
477593 var clipRect = new Vector4 ( ( drawCmd . ClipRect . X - clipPos . X ) * clipScale . X ,
@@ -504,23 +620,26 @@ private void Render(ImDrawDataPtr drawData)
504620 }
505621
506622 [ MethodImpl ( MethodImplOptions . AggressiveInlining ) ]
507- public static IntPtr GetImGuiTexture ( Texture texture )
623+ public static ImTextureRef GetImGuiTexture ( Texture texture )
508624 {
509- if ( texture == null ||
510- texture . handle . Valid == false ||
511- texture . Disposed ||
512- texture . metadata . readBack )
625+ unsafe
513626 {
514- return IntPtr . Zero ;
515- }
627+ if ( texture == null ||
628+ texture . handle . Valid == false ||
629+ texture . Disposed ||
630+ texture . metadata . readBack )
631+ {
632+ return new ImTextureRef ( texId : ImTextureID . Null ) ;
633+ }
516634
517- return new IntPtr ( texture . handle . idx ) ;
635+ return new ImTextureRef ( texId : new ImTextureID ( ( ulong ) texture . handle . idx ) ) ;
636+ }
518637 }
519638
520639 [ MethodImpl ( MethodImplOptions . AggressiveInlining ) ]
521640 public static uint ImGuiRGBA ( byte r , byte g , byte b , byte a = 255 )
522641 {
523- return r | ( ( uint ) g << 8 ) | ( ( uint ) b << 16 ) | ( ( uint ) a << 24 ) ;
642+ return ImGui . ColorConvertFloat4ToU32 ( new Vector4 ( r / 255.0f , g / 255.0f , b / 255.0f , a / 255.0f ) ) ;
524643 }
525644
526645 [ MethodImpl ( MethodImplOptions . AggressiveInlining ) ]
0 commit comments