switch to new ImGuiManager

This commit is contained in:
Mike 2019-02-17 01:13:43 -08:00
parent ba222d1dc9
commit ef9814253c
5 changed files with 235 additions and 110 deletions

5
.vscode/tasks.json vendored
View File

@ -97,10 +97,7 @@
"label": "Build Content",
"type": "shell",
"group": "build",
"command": "mono /Applications/Pipeline.app/Contents/MonoBundle/MGCB.exe /@:Content.mgcb",
"options": {
"cwd": "${workspaceFolder}/project_name/CompiledContent"
},
"command": "msbuild /t:BuildContent",
"problemMatcher": "$msCompile"
},

View File

@ -18,9 +18,6 @@ namespace project_name
// setup a Scene so we have something to show
var newScene = new Scene();
newScene.addRenderer(new DefaultRenderer());
// optionally render Nez in an ImGui window
newScene.finalRenderDelegate = new ImGuiFinalRenderDelegate();
var logo = newScene.content.Load<Microsoft.Xna.Framework.Graphics.Texture2D>("nez-logo-black");
newScene.createEntity("logo")
@ -28,6 +25,11 @@ namespace project_name
.addComponent(new Nez.Sprites.Sprite(logo));
scene = newScene;
// optionally render Nez in an ImGui window
var imGuiManager = new ImGuiManager();
Core.registerGlobalManager( imGuiManager );
imGuiManager.setEnabled( true );
}
}
}

View File

@ -1,95 +0,0 @@
using System;
using System.Reflection;
using ImGuiNET;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Graphics;
namespace Nez
{
public class ImGuiFinalRenderDelegate : IFinalRenderDelegate
{
public Scene scene { get; set; }
ImGuiRenderer _imGuiRenderer;
RenderTarget2D _lastRenderTarget;
IntPtr _renderTargetId;
public ImGuiFinalRenderDelegate()
{
_imGuiRenderer = new ImGuiRenderer( Core.instance );
_imGuiRenderer.rebuildFontAtlas();
ImGui.GetIO().ConfigWindowsMoveFromTitleBarOnly = true;
}
[Console.Command( "toggle-imgui", "Toggles the Dear ImGui renderer" )]
static void toggleImGui()
{
if( Core.scene.finalRenderDelegate == null )
Core.scene.finalRenderDelegate = new ImGuiFinalRenderDelegate();
else
Core.scene.finalRenderDelegate = null;
}
void layoutGui()
{
ImGui.ShowDemoWindow();
var maxSize = new System.Numerics.Vector2( _lastRenderTarget.Width, _lastRenderTarget.Height );
var minSize = maxSize / 4;
maxSize *= 4;
unsafe
{
ImGui.SetNextWindowSizeConstraints( minSize, maxSize, data =>
{
var size = ( *data ).CurrentSize;
var ratio = size.X / _lastRenderTarget.Width;
( *data ).DesiredSize.Y = ratio * _lastRenderTarget.Height;
} );
}
ImGui.SetNextWindowPos( new System.Numerics.Vector2( 0, 0 ), ImGuiCond.FirstUseEver );
ImGui.PushStyleVar( ImGuiStyleVar.WindowPadding, new System.Numerics.Vector2( 0, 0 ) );
ImGui.Begin( "Game Window" );
ImGui.Image( _renderTargetId, ImGui.GetContentRegionAvail() );
ImGui.End();
ImGui.PopStyleVar();
}
#region IFinalRenderDelegate
public void handleFinalRender( RenderTarget2D finalRenderTarget, Color letterboxColor, RenderTarget2D source, Rectangle finalRenderDestinationRect, SamplerState samplerState )
{
if( _lastRenderTarget != source )
{
// unbind the old texture if we had one
if( _lastRenderTarget != null )
_imGuiRenderer.unbindTexture( _renderTargetId );
// bind the new texture
_lastRenderTarget = source;
_renderTargetId = _imGuiRenderer.bindTexture( source );
}
Core.graphicsDevice.setRenderTarget( finalRenderTarget );
Core.graphicsDevice.Clear( letterboxColor );
_imGuiRenderer.beforeLayout( Time.deltaTime );
layoutGui();
_imGuiRenderer.afterLayout();
}
public void onAddedToScene()
{ }
public void onSceneBackBufferSizeChanged( int newWidth, int newHeight )
{ }
public void unload()
{ }
#endregion
}
}

View File

@ -0,0 +1,221 @@
using Nez;
using ImGuiNET;
using Microsoft.Xna.Framework;
using System;
using Microsoft.Xna.Framework.Graphics;
using System.Collections.Generic;
namespace Nez
{
public class ImGuiManager : GlobalManager, IFinalRenderDelegate, IDisposable
{
public Scene scene { get; set; }
public List<Action> drawCommands = new List<Action>();
public ImGuiRenderer renderer { get; private set; }
RenderTarget2D _lastRenderTarget;
IntPtr _renderTargetId;
bool _isGameWindowFocused;
public ImGuiManager( string pathToFontFile, float fontSizePixels )
{
renderer = new ImGuiRenderer( Core.instance );
if( pathToFontFile != null )
ImGui.GetIO().Fonts.AddFontFromFileTTF( pathToFontFile, fontSizePixels );
renderer.rebuildFontAtlas();
Core.emitter.addObserver( CoreEvents.SceneChanged, onSceneChanged );
}
public ImGuiManager() : this( null, -1 )
{}
void onSceneChanged()
{
// when the Scene changes we need to rewire ourselves up as the IFinalRenderDelegate in the new Scene
// if we were previously enabled
drawCommands.Clear();
if( enabled )
onEnabled();
}
/// <summary>
/// this is where we issue any and all ImGui commands to be drawn
/// </summary>
void layoutGui()
{
for( var i = drawCommands.Count - 1; i >= 0; i-- )
drawCommands[i]();
ImGui.ShowDemoWindow();
if( _lastRenderTarget == null )
return;
var maxSize = new System.Numerics.Vector2( _lastRenderTarget.Width, _lastRenderTarget.Height );
var minSize = maxSize / 4;
maxSize *= 4;
unsafe
{
ImGui.SetNextWindowSizeConstraints( minSize, maxSize, data =>
{
var size = ( *data ).CurrentSize;
var ratio = size.X / _lastRenderTarget.Width;
( *data ).DesiredSize.Y = ratio * _lastRenderTarget.Height;
} );
}
ImGui.SetNextWindowPos( new System.Numerics.Vector2( 0, 0 ), ImGuiCond.FirstUseEver );
ImGui.PushStyleVar( ImGuiStyleVar.WindowPadding, new System.Numerics.Vector2( 0, 0 ) );
ImGui.Begin( "Game Window" );
_isGameWindowFocused = ImGui.IsWindowFocused();
//Nugget.InputDisplay.cursorScreenPos = new Vector2( ImGui.GetCursorScreenPos().X, ImGui.GetCursorScreenPos().Y );
//Nugget.InputDisplay.scaleX = ImGui.GetContentRegionAvail().X / _lastRenderTarget.Width;
//Nugget.InputDisplay.scaleY = ImGui.GetContentRegionAvail().Y / _lastRenderTarget.Height;
//Debug.log( $"window pos: {ImGui.GetWindowPos()}" );
//Debug.log( $"avail size: {ImGui.GetContentRegionAvail()}" );
//Debug.log( $"rt {_lastRenderTarget.Width} x {_lastRenderTarget.Height}" );
//Debug.log( $"scaleX: {ImGui.GetContentRegionAvail().X / _lastRenderTarget.Width}" );
//Debug.log( $"scaleY: {ImGui.GetContentRegionAvail().Y / _lastRenderTarget.Height}" );
//Debug.log( ImGui.GetWindowSize() - ImGui.GetContentRegionAvail() );
//Debug.log( $"titleHeight: {titleHeight}" );
//Debug.log( $"screenPos: {ImGui.GetCursorScreenPos()}" );
ImGui.Image( _renderTargetId, ImGui.GetContentRegionAvail() );
ImGui.End();
ImGui.PopStyleVar();
}
#region Public API
/// <summary>
/// registers an Action that will be called and any ImGui drawing can be done in it
/// </summary>
/// <param name="drawCommand"></param>
public void registerDrawCommand( Action drawCommand )
{
drawCommands.Add( drawCommand );
}
/// <summary>
/// removes the Action from the draw commands
/// </summary>
/// <param name="drawCommand"></param>
public void unregisterDrawCommand( Action drawCommand )
{
drawCommands.Remove( drawCommand );
}
/// <summary>
/// adds the font to the atlas and regenerates it
/// </summary>
/// <param name="pathToFontFile"></param>
/// <param name="fontSizePixels"></param>
/// <returns></returns>
public ImFontPtr addFontAndRegenerateAtlas( string pathToFontFile, float fontSizePixels )
{
var fontPtr = ImGui.GetIO().Fonts.AddFontFromFileTTF( pathToFontFile, fontSizePixels );
renderer.rebuildFontAtlas();
return fontPtr;
}
#endregion
#region GlobalManager Lifecycle
public override void onEnabled()
{
Core.scene.finalRenderDelegate = this;
}
public override void onDisabled()
{
Core.scene.finalRenderDelegate = null;
}
public override void update()
{
renderer.beforeLayout( Time.deltaTime );
layoutGui();
}
#endregion
#region IFinalRenderDelegate
public void handleFinalRender( RenderTarget2D finalRenderTarget, Color letterboxColor, RenderTarget2D source, Rectangle finalRenderDestinationRect, SamplerState samplerState )
{
if( _lastRenderTarget != source )
{
// unbind the old texture if we had one
if( _lastRenderTarget != null )
renderer.unbindTexture( _renderTargetId );
// bind the new texture
_lastRenderTarget = source;
_renderTargetId = renderer.bindTexture( source );
}
Core.graphicsDevice.setRenderTarget( finalRenderTarget );
Core.graphicsDevice.Clear( letterboxColor );
renderer.afterLayout();
}
public void onAddedToScene()
{ }
public void onSceneBackBufferSizeChanged( int newWidth, int newHeight )
{ }
public void unload()
{ }
#endregion
#region IDisposable Support
bool _isDisposed = false; // To detect redundant calls
protected virtual void Dispose( bool disposing )
{
if( !_isDisposed )
{
if( disposing )
{
Core.emitter.removeObserver( CoreEvents.SceneChanged, onSceneChanged );
}
_isDisposed = true;
}
}
void IDisposable.Dispose()
{
Dispose( true );
}
#endregion
[Console.Command( "toggle-imgui", "Toggles the Dear ImGui renderer" )]
static void toggleImGui()
{
// install the service if it isnt already there
var service = Core.getGlobalManager<ImGuiManager>();
if( service == null )
{
service = new ImGuiManager();
Core.registerGlobalManager( service );
}
service.setEnabled( !service.enabled );
}
}
}

View File

@ -9,10 +9,12 @@ using System.Runtime.InteropServices;
namespace ImGuiNET
{
/// <summary>
/// ImGui renderer for use with XNA-likes (FNA and MonoGame)
/// ImGui renderer for use with XNA-likes (FNA & MonoGame)
/// </summary>
public class ImGuiRenderer
{
public ImFontPtr defaultFontPtr { get; private set; }
// Graphics
BasicEffect _effect;
RasterizerState _rasterizerState;
@ -29,7 +31,7 @@ namespace ImGuiNET
int _indexBufferSize;
// Textures
Dictionary<IntPtr, Texture2D> _loadedTextures;
Dictionary<IntPtr, Texture2D> _loadedTextures = new Dictionary<IntPtr, Texture2D>();
int _textureId;
IntPtr? _fontTextureId;
@ -52,10 +54,7 @@ namespace ImGuiNET
new VertexElement( 16, VertexElementFormat.Color, VertexElementUsage.Color, 0 )
);
var context = ImGui.CreateContext();
ImGui.SetCurrentContext( context );
_loadedTextures = new Dictionary<IntPtr, Texture2D>();
ImGui.SetCurrentContext( ImGui.CreateContext() );
_rasterizerState = new RasterizerState()
{
@ -79,6 +78,9 @@ namespace ImGuiNET
{
// Get font texture from ImGui
var io = ImGui.GetIO();
defaultFontPtr = ImGui.GetIO().Fonts.AddFontDefault();
io.Fonts.GetTexDataAsRGBA32( out byte* pixelData, out int width, out int height, out int bytesPerPixel );
// Copy the data to a managed array
@ -187,8 +189,6 @@ namespace ImGuiNET
ImGui.GetIO().AddInputCharacter( c );
};
///////////////////////////////////////////
ImGui.GetIO().Fonts.AddFontDefault();
}
/// <summary>