diff --git a/.vscode/settings.json b/.vscode/settings.json index ce3c2d5..2882144 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -11,22 +11,19 @@ "**/.[^v]*": true, // hide any files that start with a '.' but keep the .vscode folder ".vs": true, // Visual Studio settings "getFNA.sh": true, + "imgui.ini": true, "MonoGameContent.targets": true, - "project_name/obj": true, - "project_name/bin": true, + "**/obj": true, + "**/bin": true, ".gitignore": true, ".gitmodules": true, "README.md": true, "fnalibs": true, - "project_name/CompiledContent/bin": true, - "project_name/CompiledContent/obj": true, "project_name/CompiledContent/.mgstats": true, - "project_name/*.csproj*": true, - "*.sln": true, + "**/*.csproj*": true, + "**/*.sln": true, "FNA/[^src]*": true, // hide everything but the src folder - "Nez.FNA/[^Nez]*": true, // hide everything but the Nez folder - "Nez.FNA/Nez.FNA*": true, // we miss the Nez.FNA* stuff with the above line so hide that too - "Nez.FNA/Nez/{[^DN]*}": true, // hide everything except what begins with D or N - "Nez.FNA/Nez/Nez.*.*": true, + "Nez/{[^DN]*}": true, // hide everything except what begins with D or N + "Nez/Nez.*.*": true, // hide the files in the root of the repo } } diff --git a/.vscode/tasks.json b/.vscode/tasks.json index 3d8b600..e27f8d5 100644 --- a/.vscode/tasks.json +++ b/.vscode/tasks.json @@ -98,6 +98,9 @@ "type": "shell", "group": "build", "command": "msbuild /t:BuildContent", + "options": { + "cwd": "${workspaceFolder}/project_name" + }, "problemMatcher": "$msCompile" }, diff --git a/getFNA.sh b/getFNA.sh index b6f04d5..64a2e36 100755 --- a/getFNA.sh +++ b/getFNA.sh @@ -82,6 +82,7 @@ function getLibs() tar xjC $MY_DIR/fnalibs -f $MY_DIR/fnalibs.tar.bz2 if [ $? -eq 0 ]; then echo "Finished decompressing!" + echo "" rm $MY_DIR/fnalibs.tar.bz2 else >&2 echo "ERROR: Unable to decompress successfully." @@ -142,7 +143,7 @@ if [[ $newProjectName = 'exit' || -z "$newProjectName" ]]; then fi # any files that need to have project_name replaced with the new project name should be here -files=(project_name.sln .gitignore project_name/project_name.sln project_name/project_name.csproj project_name/Game1.cs project_name/Program.cs .vscode/tasks.json .vscode/settings.json .vscode/launch.json .vscode/buildEffects.sh .vscode/processT4Templates.sh) +files=(project_name.sln .gitignore project_name/project_name.csproj project_name/Game1.cs project_name/Program.cs .vscode/tasks.json .vscode/settings.json .vscode/launch.json .vscode/buildEffects.sh .vscode/processT4Templates.sh) for file in "${files[@]}"; do sed -i '' "s/project_name/$newProjectName/g" $file done @@ -154,16 +155,16 @@ mv project_name/project_name.csproj.user "project_name/$newProjectName.csproj.us mv project_name "$newProjectName" git init -git submodule add https://github.com/prime31/Nez.FNA.git -cd Nez.FNA +git submodule add https://github.com/prime31/Nez.git +cd Nez git submodule init git submodule update command -v pbcopy > /dev/null 2>&1 if [ ! $? -eq 0 ]; then - printf "\n\nManually run the following command:\n\nnuget restore Nez.FNA/Nez/Nez.sln && msbuild Nez.FNA/Nez/Nez.sln && msbuild /t:restore $newProjectName\n\n" + printf "\n\nManually run the following command:\n\nnuget restore Nez/Nez.sln && msbuild Nez/Nez.sln && msbuild /t:restore $newProjectName\n\n" else - echo "nuget restore Nez.FNA/Nez/Nez.sln && msbuild Nez.FNA/Nez/Nez.sln && msbuild /t:restore $newProjectName" | pbcopy + echo "nuget restore Nez/Nez.sln && msbuild Nez/Nez.sln && msbuild /t:restore $newProjectName" | pbcopy echo "" echo "A build command was copied to your clipboard. Paste and run it now." echo "" diff --git a/project_name.sln b/project_name.sln index 66b23b2..daf790d 100644 --- a/project_name.sln +++ b/project_name.sln @@ -5,20 +5,21 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "project_name", "project_nam EndProject Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "FNA", "FNA\FNA.csproj", "{35253CE1-C864-4CD3-8249-4D1319748E8F}" EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Nez.FNA", "Nez.FNA\Nez.FNA\Nez.FNA.csproj", "{11A5855C-B12C-4F8D-B935-56F3D0B671C3}" +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Nez.FNA", "Nez\Nez.Portable\Nez.FNA.csproj", "{11A5855C-B12C-4F8D-B935-56F3D0B671C3}" EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Nez.FNA.ImGui", "Nez\Nez.ImGui\Nez.FNA.ImGui.csproj", "{16DA6D66-4DFD-46D4-A367-C02B48B80CAA}" +EndProject + Global GlobalSection(ProjectConfigurationPlatforms) = postSolution - {8C576ECC-147D-4B4A-8EC1-56533D26A178}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {8C576ECC-147D-4B4A-8EC1-56533D26A178}.Debug|Any CPU.Build.0 = Debug|Any CPU + {3CB9E917-FEF7-453F-A88D-6B85B552B058}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {3CB9E917-FEF7-453F-A88D-6B85B552B058}.Debug|Any CPU.Build.0 = Debug|Any CPU {35253CE1-C864-4CD3-8249-4D1319748E8F}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {35253CE1-C864-4CD3-8249-4D1319748E8F}.Debug|Any CPU.Build.0 = Debug|Any CPU {11A5855C-B12C-4F8D-B935-56F3D0B671C3}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {11A5855C-B12C-4F8D-B935-56F3D0B671C3}.Debug|Any CPU.Build.0 = Debug|Any CPU - {AD548A1D-01B2-410E-B3ED-ADAC05C3C4A3}.Debug|Any CPU.ActiveCfg = Release|Any CPU - {AD548A1D-01B2-410E-B3ED-ADAC05C3C4A3}.Debug|Any CPU.Build.0 = Release|Any CPU - {3CB9E917-FEF7-453F-A88D-6B85B552B058}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {3CB9E917-FEF7-453F-A88D-6B85B552B058}.Debug|Any CPU.Build.0 = Debug|Any CPU + {16DA6D66-4DFD-46D4-A367-C02B48B80CAA}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {16DA6D66-4DFD-46D4-A367-C02B48B80CAA}.Debug|Any CPU.Build.0 = Debug|Any CPU EndGlobalSection GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Any CPU = Debug|Any CPU diff --git a/project_name/Game1.cs b/project_name/Game1.cs index e474f16..9f9faa5 100644 --- a/project_name/Game1.cs +++ b/project_name/Game1.cs @@ -1,4 +1,5 @@ using Nez; +using Nez.ImGuiTools; namespace project_name { diff --git a/project_name/ImGui/ImGuiManager.cs b/project_name/ImGui/ImGuiManager.cs deleted file mode 100644 index d7a4b8f..0000000 --- a/project_name/ImGui/ImGuiManager.cs +++ /dev/null @@ -1,221 +0,0 @@ -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 drawCommands = new List(); - 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(); - } - - /// - /// this is where we issue any and all ImGui commands to be drawn - /// - 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 - - /// - /// registers an Action that will be called and any ImGui drawing can be done in it - /// - /// - public void registerDrawCommand( Action drawCommand ) - { - drawCommands.Add( drawCommand ); - } - - /// - /// removes the Action from the draw commands - /// - /// - public void unregisterDrawCommand( Action drawCommand ) - { - drawCommands.Remove( drawCommand ); - } - - /// - /// adds the font to the atlas and regenerates it - /// - /// - /// - /// - 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(); - if( service == null ) - { - service = new ImGuiManager(); - Core.registerGlobalManager( service ); - } - - service.setEnabled( !service.enabled ); - } - - } -} \ No newline at end of file diff --git a/project_name/ImGui/ImGuiRenderer.cs b/project_name/ImGui/ImGuiRenderer.cs deleted file mode 100644 index 0905145..0000000 --- a/project_name/ImGui/ImGuiRenderer.cs +++ /dev/null @@ -1,389 +0,0 @@ -using Microsoft.Xna.Framework; -using Microsoft.Xna.Framework.Graphics; -using Microsoft.Xna.Framework.Input; -using Nez; -using System; -using System.Collections.Generic; -using System.Runtime.InteropServices; - -namespace ImGuiNET -{ - /// - /// ImGui renderer for use with XNA-likes (FNA & MonoGame) - /// - public class ImGuiRenderer - { - public ImFontPtr defaultFontPtr { get; private set; } - - // Graphics - BasicEffect _effect; - RasterizerState _rasterizerState; - - readonly VertexDeclaration _vertexDeclaration; - readonly int _vertexDeclarationSize; - - byte[] _vertexData; - VertexBuffer _vertexBuffer; - int _vertexBufferSize; - - byte[] _indexData; - IndexBuffer _indexBuffer; - int _indexBufferSize; - - // Textures - Dictionary _loadedTextures = new Dictionary(); - - int _textureId; - IntPtr? _fontTextureId; - - // Input - int _scrollWheelValue; - - List _keys = new List(); - - public ImGuiRenderer( Game game ) - { - unsafe { _vertexDeclarationSize = sizeof( ImDrawVert ); } - _vertexDeclaration = new VertexDeclaration( - _vertexDeclarationSize, - // Position - new VertexElement( 0, VertexElementFormat.Vector2, VertexElementUsage.Position, 0 ), - // UV - new VertexElement( 8, VertexElementFormat.Vector2, VertexElementUsage.TextureCoordinate, 0 ), - // Color - new VertexElement( 16, VertexElementFormat.Color, VertexElementUsage.Color, 0 ) - ); - - ImGui.SetCurrentContext( ImGui.CreateContext() ); - - _rasterizerState = new RasterizerState() - { - CullMode = CullMode.None, - DepthBias = 0, - FillMode = FillMode.Solid, - MultiSampleAntiAlias = false, - ScissorTestEnable = true, - SlopeScaleDepthBias = 0 - }; - - setupInput(); - } - - #region ImGuiRenderer - - /// - /// Creates a texture and loads the font data from ImGui. Should be called when the is initialized but before any rendering is done - /// - public unsafe void rebuildFontAtlas() - { - // 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 - var pixels = new byte[width * height * bytesPerPixel]; - Marshal.Copy( new IntPtr( pixelData ), pixels, 0, pixels.Length ); - - // Create and register the texture as an XNA texture - var tex2d = new Texture2D( Core.graphicsDevice, width, height, false, SurfaceFormat.Color ); - tex2d.SetData( pixels ); - - // Should a texture already have been built previously, unbind it first so it can be deallocated - if( _fontTextureId.HasValue ) - unbindTexture( _fontTextureId.Value ); - - // Bind the new texture to an ImGui-friendly id - _fontTextureId = bindTexture( tex2d ); - - // Let ImGui know where to find the texture - io.Fonts.SetTexID( _fontTextureId.Value ); - io.Fonts.ClearTexData(); // Clears CPU side texture data - } - - /// - /// Creates a pointer to a texture, which can be passed through ImGui calls such as . That pointer is then used by ImGui to let us know what texture to draw - /// - public IntPtr bindTexture( Texture2D texture ) - { - var id = new IntPtr( _textureId++ ); - _loadedTextures.Add( id, texture ); - return id; - } - - /// - /// Removes a previously created texture pointer, releasing its reference and allowing it to be deallocated - /// - public void unbindTexture( IntPtr textureId ) - { - _loadedTextures.Remove( textureId ); - } - - /// - /// Sets up ImGui for a new frame, should be called at frame start - /// - public void beforeLayout( float deltaTime ) - { - ImGui.GetIO().DeltaTime = deltaTime; - updateInput(); - ImGui.NewFrame(); - } - - /// - /// Asks ImGui for the generated geometry data and sends it to the graphics pipeline, should be called after the UI is drawn using ImGui.** calls - /// - public void afterLayout() - { - ImGui.Render(); - unsafe { renderDrawData( ImGui.GetDrawData() ); } - } - - #endregion ImGuiRenderer - - #region Setup & Update - - /// - /// Maps ImGui keys to XNA keys. We use this later on to tell ImGui what keys were pressed - /// - void setupInput() - { - var io = ImGui.GetIO(); - - _keys.Add( io.KeyMap[(int)ImGuiKey.Tab] = (int)Keys.Tab ); - _keys.Add( io.KeyMap[(int)ImGuiKey.LeftArrow] = (int)Keys.Left ); - _keys.Add( io.KeyMap[(int)ImGuiKey.RightArrow] = (int)Keys.Right ); - _keys.Add( io.KeyMap[(int)ImGuiKey.UpArrow] = (int)Keys.Up ); - _keys.Add( io.KeyMap[(int)ImGuiKey.DownArrow] = (int)Keys.Down ); - _keys.Add( io.KeyMap[(int)ImGuiKey.PageUp] = (int)Keys.PageUp ); - _keys.Add( io.KeyMap[(int)ImGuiKey.PageDown] = (int)Keys.PageDown ); - _keys.Add( io.KeyMap[(int)ImGuiKey.Home] = (int)Keys.Home ); - _keys.Add( io.KeyMap[(int)ImGuiKey.End] = (int)Keys.End ); - _keys.Add( io.KeyMap[(int)ImGuiKey.Delete] = (int)Keys.Delete ); - _keys.Add( io.KeyMap[(int)ImGuiKey.Backspace] = (int)Keys.Back ); - _keys.Add( io.KeyMap[(int)ImGuiKey.Enter] = (int)Keys.Enter ); - _keys.Add( io.KeyMap[(int)ImGuiKey.Escape] = (int)Keys.Escape ); - _keys.Add( io.KeyMap[(int)ImGuiKey.A] = (int)Keys.A ); - _keys.Add( io.KeyMap[(int)ImGuiKey.C] = (int)Keys.C ); - _keys.Add( io.KeyMap[(int)ImGuiKey.V] = (int)Keys.V ); - _keys.Add( io.KeyMap[(int)ImGuiKey.X] = (int)Keys.X ); - _keys.Add( io.KeyMap[(int)ImGuiKey.Y] = (int)Keys.Y ); - _keys.Add( io.KeyMap[(int)ImGuiKey.Z] = (int)Keys.Z ); - - - // MonoGame-specific ////////////////////// - // _game.Window.TextInput += (s, a) => - // { - // if (a.Character == '\t') return; - - // io.AddInputCharacter(a.Character); - // }; - /////////////////////////////////////////// - - // FNA-specific /////////////////////////// - TextInputEXT.TextInput += c => - { - if( c == '\t' ) return; - - ImGui.GetIO().AddInputCharacter( c ); - }; - /////////////////////////////////////////// - } - - /// - /// Updates the to the current matrices and texture - /// - Effect updateEffect( Texture2D texture ) - { - _effect = _effect ?? new BasicEffect( Core.graphicsDevice ); - - var io = ImGui.GetIO(); - - // MonoGame-specific ////////////////////// - //var offset = .5f; - /////////////////////////////////////////// - - // FNA-specific /////////////////////////// - var offset = 0f; - /////////////////////////////////////////// - - _effect.World = Matrix.Identity; - _effect.View = Matrix.Identity; - _effect.Projection = Matrix.CreateOrthographicOffCenter( offset, io.DisplaySize.X + offset, io.DisplaySize.Y + offset, offset, -1f, 1f ); - _effect.TextureEnabled = true; - _effect.Texture = texture; - _effect.VertexColorEnabled = true; - - return _effect; - } - - /// - /// Sends XNA input state to ImGui - /// - void updateInput() - { - var io = ImGui.GetIO(); - - var mouse = Mouse.GetState(); - var keyboard = Keyboard.GetState(); - - for( int i = 0; i < _keys.Count; i++ ) - { - io.KeysDown[_keys[i]] = keyboard.IsKeyDown( (Keys)_keys[i] ); - } - - io.KeyShift = keyboard.IsKeyDown( Keys.LeftShift ) || keyboard.IsKeyDown( Keys.RightShift ); - io.KeyCtrl = keyboard.IsKeyDown( Keys.LeftControl ) || keyboard.IsKeyDown( Keys.RightControl ); - io.KeyAlt = keyboard.IsKeyDown( Keys.LeftAlt ) || keyboard.IsKeyDown( Keys.RightAlt ); - io.KeySuper = keyboard.IsKeyDown( Keys.LeftWindows ) || keyboard.IsKeyDown( Keys.RightWindows ); - - io.DisplaySize = new System.Numerics.Vector2( Core.graphicsDevice.PresentationParameters.BackBufferWidth, Core.graphicsDevice.PresentationParameters.BackBufferHeight ); - io.DisplayFramebufferScale = new System.Numerics.Vector2( 1f, 1f ); - - io.MousePos = new System.Numerics.Vector2( mouse.X, mouse.Y ); - - io.MouseDown[0] = mouse.LeftButton == ButtonState.Pressed; - io.MouseDown[1] = mouse.RightButton == ButtonState.Pressed; - io.MouseDown[2] = mouse.MiddleButton == ButtonState.Pressed; - - var scrollDelta = mouse.ScrollWheelValue - _scrollWheelValue; - io.MouseWheel = scrollDelta > 0 ? 1 : scrollDelta < 0 ? -1 : 0; - _scrollWheelValue = mouse.ScrollWheelValue; - } - - #endregion Setup & Update - - #region Internals - - /// - /// Gets the geometry as set up by ImGui and sends it to the graphics device - /// - void renderDrawData( ImDrawDataPtr drawData ) - { - // Setup render state: alpha-blending enabled, no face culling, no depth testing, scissor enabled, vertex/texcoord/color pointers - var lastViewport = Core.graphicsDevice.Viewport; - var lastScissorBox = Core.graphicsDevice.ScissorRectangle; - - Core.graphicsDevice.BlendFactor = Color.White; - Core.graphicsDevice.BlendState = BlendState.NonPremultiplied; - Core.graphicsDevice.RasterizerState = _rasterizerState; - Core.graphicsDevice.DepthStencilState = DepthStencilState.DepthRead; - - // Handle cases of screen coordinates != from framebuffer coordinates (e.g. retina displays) - drawData.ScaleClipRects( ImGui.GetIO().DisplayFramebufferScale ); - - // Setup projection - Core.graphicsDevice.Viewport = new Viewport( 0, 0, Core.graphicsDevice.PresentationParameters.BackBufferWidth, Core.graphicsDevice.PresentationParameters.BackBufferHeight ); - - updateBuffers( drawData ); - renderCommandLists( drawData ); - - // Restore modified state - Core.graphicsDevice.Viewport = lastViewport; - Core.graphicsDevice.ScissorRectangle = lastScissorBox; - } - - unsafe void updateBuffers( ImDrawDataPtr drawData ) - { - if( drawData.TotalVtxCount == 0 ) - { - return; - } - - // Expand buffers if we need more room - if( drawData.TotalVtxCount > _vertexBufferSize ) - { - _vertexBuffer?.Dispose(); - - _vertexBufferSize = (int)( drawData.TotalVtxCount * 1.5f ); - _vertexBuffer = new VertexBuffer( Core.graphicsDevice, _vertexDeclaration, _vertexBufferSize, BufferUsage.None ); - _vertexData = new byte[_vertexBufferSize * _vertexDeclarationSize]; - } - - if( drawData.TotalIdxCount > _indexBufferSize ) - { - _indexBuffer?.Dispose(); - - _indexBufferSize = (int)( drawData.TotalIdxCount * 1.5f ); - _indexBuffer = new IndexBuffer( Core.graphicsDevice, IndexElementSize.SixteenBits, _indexBufferSize, BufferUsage.None ); - _indexData = new byte[_indexBufferSize * sizeof( ushort )]; - } - - // Copy ImGui's vertices and indices to a set of managed byte arrays - int vtxOffset = 0; - int idxOffset = 0; - - for( var n = 0; n < drawData.CmdListsCount; n++ ) - { - var cmdList = drawData.CmdListsRange[n]; - - fixed ( void* vtxDstPtr = &_vertexData[vtxOffset * _vertexDeclarationSize] ) - fixed ( void* idxDstPtr = &_indexData[idxOffset * sizeof( ushort )] ) - { - Buffer.MemoryCopy( (void*)cmdList.VtxBuffer.Data, vtxDstPtr, _vertexData.Length, cmdList.VtxBuffer.Size * _vertexDeclarationSize ); - Buffer.MemoryCopy( (void*)cmdList.IdxBuffer.Data, idxDstPtr, _indexData.Length, cmdList.IdxBuffer.Size * sizeof( ushort ) ); - } - - vtxOffset += cmdList.VtxBuffer.Size; - idxOffset += cmdList.IdxBuffer.Size; - } - - // Copy the managed byte arrays to the gpu vertex- and index buffers - _vertexBuffer.SetData( _vertexData, 0, drawData.TotalVtxCount * _vertexDeclarationSize ); - _indexBuffer.SetData( _indexData, 0, drawData.TotalIdxCount * sizeof( ushort ) ); - } - - unsafe void renderCommandLists( ImDrawDataPtr drawData ) - { - Core.graphicsDevice.SetVertexBuffer( _vertexBuffer ); - Core.graphicsDevice.Indices = _indexBuffer; - - int vtxOffset = 0; - int idxOffset = 0; - - for( int n = 0; n < drawData.CmdListsCount; n++ ) - { - var cmdList = drawData.CmdListsRange[n]; - for( int cmdi = 0; cmdi < cmdList.CmdBuffer.Size; cmdi++ ) - { - var drawCmd = cmdList.CmdBuffer[cmdi]; - if( !_loadedTextures.ContainsKey( drawCmd.TextureId ) ) - { - throw new InvalidOperationException( $"Could not find a texture with id '{drawCmd.TextureId}', please check your bindings" ); - } - - Core.graphicsDevice.ScissorRectangle = new Rectangle( - (int)drawCmd.ClipRect.X, - (int)drawCmd.ClipRect.Y, - (int)( drawCmd.ClipRect.Z - drawCmd.ClipRect.X ), - (int)( drawCmd.ClipRect.W - drawCmd.ClipRect.Y ) - ); - - var effect = updateEffect( _loadedTextures[drawCmd.TextureId] ); - foreach( var pass in effect.CurrentTechnique.Passes ) - { - pass.Apply(); - -#pragma warning disable CS0618 // // FNA does not expose an alternative method. - Core.graphicsDevice.DrawIndexedPrimitives( - primitiveType: PrimitiveType.TriangleList, - baseVertex: vtxOffset, - minVertexIndex: 0, - numVertices: cmdList.VtxBuffer.Size, - startIndex: idxOffset, - primitiveCount: (int)drawCmd.ElemCount / 3 - ); -#pragma warning restore CS0618 - } - - idxOffset += (int)drawCmd.ElemCount; - } - - vtxOffset += cmdList.VtxBuffer.Size; - } - } - - #endregion Internals - } -} \ No newline at end of file diff --git a/project_name/project_name.csproj b/project_name/project_name.csproj index e257a0f..c73e4ef 100644 --- a/project_name/project_name.csproj +++ b/project_name/project_name.csproj @@ -13,7 +13,8 @@ - + + @@ -71,32 +72,4 @@ PreserveNewest - - - - $(NuGetPackageRoot)\imgui.net\**\runtimes\ - - - - - %(Filename)%(Extension) - PreserveNewest - - - %(Filename)%(Extension) - PreserveNewest - - - libcimgui.dylib - PreserveNewest - - - %(Filename)%(Extension) - PreserveNewest - - - - - -