mirror of
https://github.com/prime31/FNA-VSCode-Template.git
synced 2025-10-31 21:50:44 +07:00
Visual Studio support
add renderer to project
This commit is contained in:
parent
ed4a035574
commit
5b29f8e3cc
19
getFNA.sh
19
getFNA.sh
@ -68,7 +68,9 @@ function downloadImGui()
|
|||||||
{
|
{
|
||||||
checkGit
|
checkGit
|
||||||
echo "Downloading ImGui..."
|
echo "Downloading ImGui..."
|
||||||
git -C $MY_DIR clone https://github.com/mellinoe/ImGui.NET.git --recursive
|
echo "Temporarily using ImGui.NET branch until ImGui.NET master is updated"
|
||||||
|
#git -C $MY_DIR clone https://github.com/mellinoe/ImGui.NET.git --recursive
|
||||||
|
git -C $MY_DIR clone -b fix-MonoGame-FNA https://github.com/prime31/ImGui.NET.git --recursive
|
||||||
if [ $? -eq 0 ]; then
|
if [ $? -eq 0 ]; then
|
||||||
echo "Finished downloading!\n"
|
echo "Finished downloading!\n"
|
||||||
else
|
else
|
||||||
@ -168,12 +170,7 @@ if [ ! -d "$MY_DIR/project_name" ]; then
|
|||||||
exit 1
|
exit 1
|
||||||
fi
|
fi
|
||||||
|
|
||||||
# copy over ImGui files before renaming the project
|
|
||||||
echo "Copying ImGui renderer to project..."
|
|
||||||
cp "$MY_DIR/ImGui.NET/src/ImGui.NET.SampleProgram.XNA/DrawVertDeclaration.cs" "$MY_DIR/project_name/ImGui"
|
|
||||||
cp "$MY_DIR/ImGui.NET/src/ImGui.NET.SampleProgram.XNA/ImGuiRenderer.cs" "$MY_DIR/project_name/ImGui"
|
|
||||||
sed -i '' "s/cimgui/cimgui.dylib/g" ImGui.NET/src/ImGui.NET/Generated/ImGuiNative.gen.cs
|
|
||||||
|
|
||||||
read -p "Enter the project name to use for your folder and csproj file or 'exit' to quit: " newProjectName
|
read -p "Enter the project name to use for your folder and csproj file or 'exit' to quit: " newProjectName
|
||||||
if [[ $newProjectName = 'exit' || -z "$newProjectName" ]]; then
|
if [[ $newProjectName = 'exit' || -z "$newProjectName" ]]; then
|
||||||
exit 1
|
exit 1
|
||||||
@ -202,4 +199,10 @@ cd Nez.FNA
|
|||||||
git submodule init
|
git submodule init
|
||||||
git submodule update
|
git submodule update
|
||||||
|
|
||||||
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"
|
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"
|
||||||
|
else
|
||||||
|
echo "nuget restore Nez.FNA/Nez/Nez.sln && msbuild Nez.FNA/Nez/Nez.sln && msbuild /t:restore $newProjectName" | pbcopy
|
||||||
|
echo "command copied to your clipboard\n"
|
||||||
|
fi
|
||||||
|
|||||||
@ -39,6 +39,8 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "FNA", "FNA\FNA.csproj", "{3
|
|||||||
EndProject
|
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.FNA\Nez.FNA\Nez.FNA.csproj", "{11A5855C-B12C-4F8D-B935-56F3D0B671C3}"
|
||||||
EndProject
|
EndProject
|
||||||
|
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "ImGui.NET", "ImGui.NET\src\ImGui.NET\ImGui.NET.csproj", "{AD548A1D-01B2-410E-B3ED-ADAC05C3C4A3}"
|
||||||
|
EndProject
|
||||||
Global
|
Global
|
||||||
GlobalSection(ProjectConfigurationPlatforms) = postSolution
|
GlobalSection(ProjectConfigurationPlatforms) = postSolution
|
||||||
{8C576ECC-147D-4B4A-8EC1-56533D26A178}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
{8C576ECC-147D-4B4A-8EC1-56533D26A178}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||||
@ -47,6 +49,8 @@ Global
|
|||||||
{35253CE1-C864-4CD3-8249-4D1319748E8F}.Debug|Any CPU.Build.0 = 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.ActiveCfg = Debug|Any CPU
|
||||||
{11A5855C-B12C-4F8D-B935-56F3D0B671C3}.Debug|Any CPU.Build.0 = 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
|
||||||
EndGlobalSection
|
EndGlobalSection
|
||||||
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
||||||
Debug|Any CPU = Debug|Any CPU
|
Debug|Any CPU = Debug|Any CPU
|
||||||
|
|||||||
28
project_name/ImGui/DrawVertDeclaration.cs
Normal file
28
project_name/ImGui/DrawVertDeclaration.cs
Normal file
@ -0,0 +1,28 @@
|
|||||||
|
using Microsoft.Xna.Framework.Graphics;
|
||||||
|
|
||||||
|
namespace ImGuiNET.SampleProgram.XNA
|
||||||
|
{
|
||||||
|
public static class DrawVertDeclaration
|
||||||
|
{
|
||||||
|
public static readonly VertexDeclaration Declaration;
|
||||||
|
public static readonly int Size;
|
||||||
|
|
||||||
|
static DrawVertDeclaration()
|
||||||
|
{
|
||||||
|
unsafe { Size = sizeof(ImDrawVert); }
|
||||||
|
|
||||||
|
Declaration = new VertexDeclaration(
|
||||||
|
Size,
|
||||||
|
|
||||||
|
// 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)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
387
project_name/ImGui/ImGuiRenderer.cs
Normal file
387
project_name/ImGui/ImGuiRenderer.cs
Normal file
@ -0,0 +1,387 @@
|
|||||||
|
using Microsoft.Xna.Framework;
|
||||||
|
using Microsoft.Xna.Framework.Graphics;
|
||||||
|
using Microsoft.Xna.Framework.Input;
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Runtime.InteropServices;
|
||||||
|
|
||||||
|
namespace ImGuiNET.SampleProgram.XNA
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// ImGui renderer for use with XNA-likes (FNA & MonoGame)
|
||||||
|
/// </summary>
|
||||||
|
public class ImGuiRenderer
|
||||||
|
{
|
||||||
|
private Game _game;
|
||||||
|
|
||||||
|
// Graphics
|
||||||
|
private GraphicsDevice _graphicsDevice;
|
||||||
|
|
||||||
|
private BasicEffect _effect;
|
||||||
|
private RasterizerState _rasterizerState;
|
||||||
|
|
||||||
|
private byte[] _vertexData;
|
||||||
|
private VertexBuffer _vertexBuffer;
|
||||||
|
private int _vertexBufferSize;
|
||||||
|
|
||||||
|
private byte[] _indexData;
|
||||||
|
private IndexBuffer _indexBuffer;
|
||||||
|
private int _indexBufferSize;
|
||||||
|
|
||||||
|
// Textures
|
||||||
|
private Dictionary<IntPtr, Texture2D> _loadedTextures;
|
||||||
|
|
||||||
|
private int _textureId;
|
||||||
|
private IntPtr? _fontTextureId;
|
||||||
|
|
||||||
|
// Input
|
||||||
|
private int _scrollWheelValue;
|
||||||
|
|
||||||
|
private List<int> _keys = new List<int>();
|
||||||
|
|
||||||
|
public ImGuiRenderer(Game game)
|
||||||
|
{
|
||||||
|
var context = ImGui.CreateContext();
|
||||||
|
ImGui.SetCurrentContext(context);
|
||||||
|
|
||||||
|
_game = game ?? throw new ArgumentNullException(nameof(game));
|
||||||
|
_graphicsDevice = game.GraphicsDevice;
|
||||||
|
|
||||||
|
_loadedTextures = new Dictionary<IntPtr, Texture2D>();
|
||||||
|
|
||||||
|
_rasterizerState = new RasterizerState()
|
||||||
|
{
|
||||||
|
CullMode = CullMode.None,
|
||||||
|
DepthBias = 0,
|
||||||
|
FillMode = FillMode.Solid,
|
||||||
|
MultiSampleAntiAlias = false,
|
||||||
|
ScissorTestEnable = true,
|
||||||
|
SlopeScaleDepthBias = 0
|
||||||
|
};
|
||||||
|
|
||||||
|
SetupInput();
|
||||||
|
}
|
||||||
|
|
||||||
|
#region ImGuiRenderer
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Creates a texture and loads the font data from ImGui. Should be called when the <see cref="GraphicsDevice" /> is initialized but before any rendering is done
|
||||||
|
/// </summary>
|
||||||
|
public virtual unsafe void RebuildFontAtlas()
|
||||||
|
{
|
||||||
|
// Get font texture from ImGui
|
||||||
|
var io = ImGui.GetIO();
|
||||||
|
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];
|
||||||
|
unsafe { Marshal.Copy(new IntPtr(pixelData), pixels, 0, pixels.Length); }
|
||||||
|
|
||||||
|
// Create and register the texture as an XNA texture
|
||||||
|
var tex2d = new Texture2D(_graphicsDevice, width, height, false, SurfaceFormat.Color);
|
||||||
|
tex2d.SetData(pixels);
|
||||||
|
|
||||||
|
// Should a texture already have been build 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
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Creates a pointer to a texture, which can be passed through ImGui calls such as <see cref="ImGui.Image" />. That pointer is then used by ImGui to let us know what texture to draw
|
||||||
|
/// </summary>
|
||||||
|
public virtual IntPtr BindTexture(Texture2D texture)
|
||||||
|
{
|
||||||
|
var id = new IntPtr(_textureId++);
|
||||||
|
|
||||||
|
_loadedTextures.Add(id, texture);
|
||||||
|
|
||||||
|
return id;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Removes a previously created texture pointer, releasing its reference and allowing it to be deallocated
|
||||||
|
/// </summary>
|
||||||
|
public virtual void UnbindTexture(IntPtr textureId)
|
||||||
|
{
|
||||||
|
_loadedTextures.Remove(textureId);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Sets up ImGui for a new frame, should be called at frame start
|
||||||
|
/// </summary>
|
||||||
|
public virtual void BeforeLayout(float deltaTime)
|
||||||
|
{
|
||||||
|
ImGui.GetIO().DeltaTime = deltaTime;
|
||||||
|
UpdateInput();
|
||||||
|
ImGui.NewFrame();
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 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
|
||||||
|
/// </summary>
|
||||||
|
public virtual void AfterLayout()
|
||||||
|
{
|
||||||
|
ImGui.Render();
|
||||||
|
|
||||||
|
unsafe { RenderDrawData(ImGui.GetDrawData()); }
|
||||||
|
}
|
||||||
|
|
||||||
|
#endregion ImGuiRenderer
|
||||||
|
|
||||||
|
#region Setup & Update
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Maps ImGui keys to XNA keys. We use this later on to tell ImGui what keys were pressed
|
||||||
|
/// </summary>
|
||||||
|
protected virtual 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);
|
||||||
|
};
|
||||||
|
///////////////////////////////////////////
|
||||||
|
|
||||||
|
ImGui.GetIO().Fonts.AddFontDefault();
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Updates the <see cref="Effect" /> to the current matrices and texture
|
||||||
|
/// </summary>
|
||||||
|
protected virtual Effect UpdateEffect(Texture2D texture)
|
||||||
|
{
|
||||||
|
_effect = _effect ?? new BasicEffect(_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;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Sends XNA input state to ImGui
|
||||||
|
/// </summary>
|
||||||
|
protected virtual 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(_graphicsDevice.PresentationParameters.BackBufferWidth, _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
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets the geometry as set up by ImGui and sends it to the graphics device
|
||||||
|
/// </summary>
|
||||||
|
private void RenderDrawData(ImDrawDataPtr drawData)
|
||||||
|
{
|
||||||
|
// Setup render state: alpha-blending enabled, no face culling, no depth testing, scissor enabled, vertex/texcoord/color pointers
|
||||||
|
var lastViewport = _graphicsDevice.Viewport;
|
||||||
|
var lastScissorBox = _graphicsDevice.ScissorRectangle;
|
||||||
|
|
||||||
|
_graphicsDevice.BlendFactor = Color.White;
|
||||||
|
_graphicsDevice.BlendState = BlendState.NonPremultiplied;
|
||||||
|
_graphicsDevice.RasterizerState = _rasterizerState;
|
||||||
|
_graphicsDevice.DepthStencilState = DepthStencilState.DepthRead;
|
||||||
|
|
||||||
|
// Handle cases of screen coordinates != from framebuffer coordinates (e.g. retina displays)
|
||||||
|
drawData.ScaleClipRects(ImGui.GetIO().DisplayFramebufferScale);
|
||||||
|
|
||||||
|
// Setup projection
|
||||||
|
_graphicsDevice.Viewport = new Viewport(0, 0, _graphicsDevice.PresentationParameters.BackBufferWidth, _graphicsDevice.PresentationParameters.BackBufferHeight);
|
||||||
|
|
||||||
|
UpdateBuffers(drawData);
|
||||||
|
|
||||||
|
RenderCommandLists(drawData);
|
||||||
|
|
||||||
|
// Restore modified state
|
||||||
|
_graphicsDevice.Viewport = lastViewport;
|
||||||
|
_graphicsDevice.ScissorRectangle = lastScissorBox;
|
||||||
|
}
|
||||||
|
|
||||||
|
private 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(_graphicsDevice, DrawVertDeclaration.Declaration, _vertexBufferSize, BufferUsage.None);
|
||||||
|
_vertexData = new byte[_vertexBufferSize * DrawVertDeclaration.Size];
|
||||||
|
}
|
||||||
|
|
||||||
|
if (drawData.TotalIdxCount > _indexBufferSize)
|
||||||
|
{
|
||||||
|
_indexBuffer?.Dispose();
|
||||||
|
|
||||||
|
_indexBufferSize = (int)(drawData.TotalIdxCount * 1.5f);
|
||||||
|
_indexBuffer = new IndexBuffer(_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 (int n = 0; n < drawData.CmdListsCount; n++)
|
||||||
|
{
|
||||||
|
ImDrawListPtr cmdList = drawData.CmdListsRange[n];
|
||||||
|
|
||||||
|
fixed (void* vtxDstPtr = &_vertexData[vtxOffset * DrawVertDeclaration.Size])
|
||||||
|
fixed (void* idxDstPtr = &_indexData[idxOffset * sizeof(ushort)])
|
||||||
|
{
|
||||||
|
Buffer.MemoryCopy((void*)cmdList.VtxBuffer.Data, vtxDstPtr, _vertexData.Length, cmdList.VtxBuffer.Size * DrawVertDeclaration.Size);
|
||||||
|
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 * DrawVertDeclaration.Size);
|
||||||
|
_indexBuffer.SetData(_indexData, 0, drawData.TotalIdxCount * sizeof(ushort));
|
||||||
|
}
|
||||||
|
|
||||||
|
private unsafe void RenderCommandLists(ImDrawDataPtr drawData)
|
||||||
|
{
|
||||||
|
_graphicsDevice.SetVertexBuffer(_vertexBuffer);
|
||||||
|
_graphicsDevice.Indices = _indexBuffer;
|
||||||
|
|
||||||
|
int vtxOffset = 0;
|
||||||
|
int idxOffset = 0;
|
||||||
|
|
||||||
|
for (int n = 0; n < drawData.CmdListsCount; n++)
|
||||||
|
{
|
||||||
|
ImDrawListPtr cmdList = drawData.CmdListsRange[n];
|
||||||
|
|
||||||
|
for (int cmdi = 0; cmdi < cmdList.CmdBuffer.Size; cmdi++)
|
||||||
|
{
|
||||||
|
ImDrawCmdPtr 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");
|
||||||
|
}
|
||||||
|
|
||||||
|
_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.
|
||||||
|
_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
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -72,19 +72,19 @@
|
|||||||
<!-- Copy ImGui native code to output -->
|
<!-- Copy ImGui native code to output -->
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<Content Include="..\ImGui.NET\deps\cimgui\win-x86\*.*" Condition="'$(OS)' == 'Windows_NT' AND '$(Platform)' != 'x64'">
|
<Content Include="..\ImGui.NET\deps\cimgui\win-x86\*.*" Condition="'$(OS)' == 'Windows_NT' AND '$(Platform)' != 'x64'">
|
||||||
<Link>osx\%(RecursiveDir)%(Filename)%(Extension)</Link>
|
<Link>%(RecursiveDir)%(Filename)%(Extension)</Link>
|
||||||
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
||||||
</Content>
|
</Content>
|
||||||
<Content Include="..\ImGui.NET\deps\cimgui\win-x64\*.*" Condition="'$(OS)' == 'Windows_NT' AND '$(Platform)' != 'x86'">
|
<Content Include="..\ImGui.NET\deps\cimgui\win-x64\*.*" Condition="'$(OS)' == 'Windows_NT' AND '$(Platform)' != 'x86'">
|
||||||
<Link>osx\%(RecursiveDir)%(Filename)%(Extension)</Link>
|
<Link>%(RecursiveDir)%(Filename)%(Extension)</Link>
|
||||||
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
||||||
</Content>
|
</Content>
|
||||||
<Content Include="..\ImGui.NET\deps\cimgui\osx-x64\*.*" Condition="'$(OS)' != 'Windows_NT' AND $(IsOSX) == 'true'">
|
<Content Include="..\ImGui.NET\deps\cimgui\osx-x64\*.*" Condition="'$(OS)' != 'Windows_NT' AND $(IsOSX) == 'true'">
|
||||||
<Link>osx\%(RecursiveDir)%(Filename)%(Extension)</Link>
|
<Link>%(RecursiveDir)%(Filename)%(Extension)</Link>
|
||||||
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
||||||
</Content>
|
</Content>
|
||||||
<Content Include="..\ImGui.NET\deps\cimgui\linux-x64\*.*" Condition="'$(OS)' != 'Windows_NT' AND $(IsLinux) == 'true'">
|
<Content Include="..\ImGui.NET\deps\cimgui\linux-x64\*.*" Condition="'$(OS)' != 'Windows_NT' AND $(IsLinux) == 'true'">
|
||||||
<Link>osx\%(RecursiveDir)%(Filename)%(Extension)</Link>
|
<Link>%(RecursiveDir)%(Filename)%(Extension)</Link>
|
||||||
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
||||||
</Content>
|
</Content>
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user