Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Feature/VL.ImGui.Stride #667

Merged
merged 25 commits into from
Mar 7, 2024
Merged
Show file tree
Hide file tree
Changes from 7 commits
Commits
Show all changes
25 commits
Select commit Hold shift + click to select a range
f63a489
Add VL.Core.Commands to Solution, was missing
kopffarben Feb 9, 2024
e35671d
VL.Imgui.Stride
kopffarben Feb 9, 2024
5e35f47
Helppatch shows MEMORYLEAK in BuildImFontAtlas() in VL.Imgui.Skia and…
kopffarben Feb 9, 2024
20a6db4
atlas.AddFontFromFileTTF caused the Memoryleak
kopffarben Feb 9, 2024
52b433a
Merge remote-tracking branch 'remotes/origin/main' into feature/VL.Im…
kopffarben Feb 13, 2024
f4b05f1
Move out some Functions from ToSkiaLayer to VL,ImGui.Renderhelper tha…
kopffarben Feb 13, 2024
28e4a1b
some CleanUp
kopffarben Feb 13, 2024
e8a1a00
remove ColorSpace Transformation from shaders/ImGuiShader_DrawFX.sdsl
kopffarben Feb 14, 2024
0b4bf91
ColorConversion in Shader
kopffarben Feb 21, 2024
0a4a2d3
WIP
kopffarben Feb 22, 2024
06aa334
WIP
kopffarben Feb 22, 2024
3871f97
WIP
kopffarben Feb 22, 2024
8e67d8f
get rid off unsafe ... use GCHandle instead
kopffarben Feb 23, 2024
966ab06
REWORK ToSkiaLayer.cs and SkiaWidget.cs and SkiaContext.cs
kopffarben Feb 23, 2024
94dd520
SkiaWidget is now working
kopffarben Feb 23, 2024
9425eba
Merge remote-tracking branch 'remotes/origin/main' into feature/VL.Im…
kopffarben Feb 23, 2024
c1ed36b
WIP InputHandeling
kopffarben Feb 23, 2024
400a08a
Throw Error when ImGuiRenderer is used inside ImGuiRenderer
kopffarben Feb 24, 2024
8205359
Skia Input Handling
kopffarben Feb 28, 2024
4082f68
CleanUP and working Skia Notification ... skiaRenderer don't push Tra…
kopffarben Mar 5, 2024
b491503
more CleanUP
kopffarben Mar 5, 2024
af909f9
Merge remote-tracking branch 'remotes/origin/main' into feature/VL.Im…
kopffarben Mar 5, 2024
2ee41af
WIP and CleanUP
kopffarben Mar 5, 2024
e700d86
WIP SceneWidget
kopffarben Mar 5, 2024
a44e84c
WIP SceneWidget
kopffarben Mar 5, 2024
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
293 changes: 3 additions & 290 deletions VL.ImGui.Skia/src/ToSkiaLayer.cs

Large diffs are not rendered by default.

3 changes: 3 additions & 0 deletions VL.ImGui.Stride/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
# VL.ImGui.Stride

Implementation to work with [VL.Stride](../VL.Stride).
321 changes: 321 additions & 0 deletions VL.ImGui.Stride/VL.ImGui.Stride.vl

Large diffs are not rendered by default.

220 changes: 220 additions & 0 deletions VL.ImGui.Stride/help/Basics/HowTo ImGui in Stride.vl

Large diffs are not rendered by default.

26 changes: 26 additions & 0 deletions VL.ImGui.Stride/shaders/ImGuiShader_DrawFX.sdsl
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
shader ImGuiShader_DrawFX : ColorUtilityTemp, ShaderBase
{

matrix proj;
stage Texture2D tex;

SamplerState TexSampler {
Filter = ANISOTROPIC;
AddressU = Wrap;
AddressV = Wrap;
MaxAnisotropy = 16;
};

stream float2 pos : POSITION;
stream float2 uv : TEXCOORD0;
stream float4 col : COLOR;

override stage void VSMain() {
streams.ShadingPosition = mul(proj, float4(streams.pos, 0.0, 1.0f)) + float4(-1.0f, 1.0f, 0.0f, 0.0f);
}

override stage void PSMain() {
streams.ColorTarget = SRgbToLinearPrecise(streams.col) * tex.Sample(TexSampler, streams.uv);
kopffarben marked this conversation as resolved.
Show resolved Hide resolved
}

};
25 changes: 25 additions & 0 deletions VL.ImGui.Stride/shaders/ImGuiShader_DrawFX.sdsl.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
// <auto-generated>
// Do not edit this file yourself!
//
// This code was generated by Stride Shader Mixin Code Generator.
// To generate it yourself, please install Stride.VisualStudio.Package .vsix
// and re-save the associated .sdfx.
// </auto-generated>

using System;
using Stride.Core;
using Stride.Rendering;
using Stride.Graphics;
using Stride.Shaders;
using Stride.Core.Mathematics;
using Buffer = Stride.Graphics.Buffer;

namespace Stride.Rendering
{
public static partial class ImGuiShader_DrawFXKeys
{
public static readonly ValueParameterKey<Matrix> proj = ParameterKeys.NewValue<Matrix>();
public static readonly ObjectParameterKey<Texture> tex = ParameterKeys.NewObject<Texture>();
public static readonly ObjectParameterKey<SamplerState> TexSampler = ParameterKeys.NewObject<SamplerState>();
}
}
66 changes: 66 additions & 0 deletions VL.ImGui.Stride/src/ImGuiRenderer.DeviceObjects.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
using Stride.Graphics;
using Stride.Core.Mathematics;
using Buffer = Stride.Graphics.Buffer;

namespace VL.ImGui
{
partial class ImGuiRenderer
{
void CreateDeviceObjects()
{
// set up a commandlist
commandList = context.CommandList;



var layout = new VertexDeclaration(
VertexElement.Position<Vector2>(),
VertexElement.TextureCoordinate<Vector2>(),
VertexElement.Color(PixelFormat.R8G8B8A8_UNorm)
);

imVertLayout = layout;

// pipeline desc
var pipeline = new PipelineStateDescription()
{
BlendState = BlendStates.NonPremultiplied,

RasterizerState = new RasterizerStateDescription()
{
CullMode = CullMode.None,
DepthBias = 0,
FillMode = FillMode.Solid,
MultisampleAntiAliasLine = false,
ScissorTestEnable = true,
SlopeScaleDepthBias = 0,
},

PrimitiveType = PrimitiveType.TriangleList,
InputElements = imVertLayout.CreateInputElements(),
DepthStencilState = DepthStencilStates.Default,

EffectBytecode = imShader.EffectInstance.Effect.Bytecode,
RootSignature = imShader.EffectInstance.RootSignature,

Output = new RenderOutputDescription(PixelFormat.R8G8B8A8_UNorm)
};


// finally set up the pipeline
var pipelineState = PipelineState.New(device, ref pipeline);
imPipeline = pipelineState;


// Setup Buffers
var is32Bits = false;
var indexBuffer = Buffer.Index.New(device, INITIAL_INDEX_BUFFER_SIZE * sizeof(ushort), GraphicsResourceUsage.Dynamic);
var indexBufferBinding = new IndexBufferBinding(indexBuffer, is32Bits, 0);
indexBinding = indexBufferBinding;

var vertexBuffer = Buffer.Vertex.New(device, INITIAL_VERTEX_BUFFER_SIZE * imVertLayout.CalculateSize(), GraphicsResourceUsage.Dynamic);
var vertexBufferBinding = new VertexBufferBinding(vertexBuffer, layout, 0);
vertexBinding = vertexBufferBinding;
}
}
}
32 changes: 32 additions & 0 deletions VL.ImGui.Stride/src/ImGuiRenderer.FontTexture.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
using ImGuiNET;
using Stride.Graphics;

namespace VL.ImGui
{
partial class ImGuiRenderer
{
void BuildImFontAtlas(ImFontAtlasPtr atlas, float scaling)
{
atlas.BuildImFontAtlas(scaling, _context, fonts);

unsafe
{
atlas.GetTexDataAsRGBA32(out byte* pixelData, out int width, out int height, out int bytesPerPixel);
if (width == 0 || height == 0)
{
// Something went wrong, load default font
atlas.Clear();
_context.Fonts.Clear();
atlas.AddFontDefault();
atlas.GetTexDataAsRGBA32(out pixelData, out width, out height, out bytesPerPixel);
}

var newFontTexture = Texture.New2D(device, width, height, PixelFormat.R8G8B8A8_UNorm_SRgb, TextureFlags.ShaderResource);
kopffarben marked this conversation as resolved.
Show resolved Hide resolved
newFontTexture.SetData(commandList, new DataPointer(pixelData, (width * height) * bytesPerPixel));
fontTexture?.Dispose();
fontTexture = newFontTexture;
atlas.ClearTexData();
}
}
}
}
29 changes: 29 additions & 0 deletions VL.ImGui.Stride/src/ImGuiRenderer.InputHandling.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
using Stride.Input;
using Stride.Rendering;
using System.Reactive.Disposables;
using VL.Stride;

namespace VL.ImGui
{
partial class ImGuiRenderer
{
IDisposable SubscribeToInputSource(IInputSource inputSource, RenderDrawContext context)
{
if (inputSource is null)
return Disposable.Empty;

var inputManager = context.RenderContext.Services.GetService<InputManager>();
if (inputManager is null)
return Disposable.Empty;

return inputManager.GetNotifications(inputSource, sender: this)
.Subscribe(notification =>
{
using (_context.MakeCurrent())
{
_io.HandleNotification(notification);
}
});
}
}
}
99 changes: 99 additions & 0 deletions VL.ImGui.Stride/src/ImGuiRenderer.RenderDrawData.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,99 @@
using ImGuiNET;

using Stride.Graphics;
using Stride.Core.Mathematics;
using Buffer = Stride.Graphics.Buffer;
using Stride.Rendering;
using System.Runtime.CompilerServices;

namespace VL.ImGui
{
partial class ImGuiRenderer
{
void CheckBuffers(ImDrawDataPtr drawData)
{
uint totalVBOSize = (uint)(drawData.TotalVtxCount * Unsafe.SizeOf<ImDrawVert>());
if (totalVBOSize > vertexBinding.Buffer.SizeInBytes)
{
var vertexBuffer = Buffer.Vertex.New(device, (int)(totalVBOSize * 1.5f));
vertexBinding = new VertexBufferBinding(vertexBuffer, imVertLayout, 0);
}

uint totalIBOSize = (uint)(drawData.TotalIdxCount * sizeof(ushort));
if (totalIBOSize > indexBinding?.Buffer.SizeInBytes)
{
var is32Bits = false;
var indexBuffer = Buffer.Index.New(device, (int)(totalIBOSize * 1.5f));
indexBinding = new IndexBufferBinding(indexBuffer, is32Bits, 0);
}
}

void UpdateBuffers(ImDrawDataPtr drawData)
{
// copy de dators
int vtxOffsetBytes = 0;
int idxOffsetBytes = 0;

for (int n = 0; n < drawData.CmdListsCount; n++)
{
ImDrawListPtr cmdList = drawData.CmdLists[n];
vertexBinding.Buffer.SetData(commandList, new DataPointer(cmdList.VtxBuffer.Data, cmdList.VtxBuffer.Size * Unsafe.SizeOf<ImDrawVert>()), vtxOffsetBytes);
indexBinding.Buffer.SetData(commandList, new DataPointer(cmdList.IdxBuffer.Data, cmdList.IdxBuffer.Size * sizeof(ushort)), idxOffsetBytes);
vtxOffsetBytes += cmdList.VtxBuffer.Size * Unsafe.SizeOf<ImDrawVert>();
idxOffsetBytes += cmdList.IdxBuffer.Size * sizeof(ushort);
}
}

void RenderDrawLists(ImDrawDataPtr drawData)
{
CheckBuffers(drawData); // potentially resize buffers first if needed
UpdateBuffers(drawData); // updeet em now

// set pipeline stuff
var is32Bits = false;
commandList.SetPipelineState(imPipeline);
commandList.SetVertexBuffer(0, vertexBinding.Buffer, 0, Unsafe.SizeOf<ImDrawVert>());
commandList.SetIndexBuffer(indexBinding.Buffer, 0, is32Bits);
imShader.Parameters.Set(ImGuiShader_DrawFXKeys.tex, fontTexture);

int vtxOffset = 0;
int idxOffset = 0;
for (int n = 0; n < drawData.CmdListsCount; n++)
{
ImDrawListPtr cmdList = drawData.CmdLists[n];

for (int i = 0; i < cmdList.CmdBuffer.Size; i++)
{
ImDrawCmdPtr cmd = cmdList.CmdBuffer[i];

if (cmd.TextureId != IntPtr.Zero)
{
// TODO CHECK THIS ... i think there are allways only one ??
// imShader.Parameters.Set(ImGuiShaderKeys.tex, fontTexture);
}
else
{
commandList.SetScissorRectangle(
new Rectangle(
(int)cmd.ClipRect.X,
(int)cmd.ClipRect.Y,
(int)(cmd.ClipRect.Z - cmd.ClipRect.X),
(int)(cmd.ClipRect.W - cmd.ClipRect.Y)
)
);

imShader.Parameters.Set(ImGuiShader_DrawFXKeys.tex, fontTexture);
imShader.Parameters.Set(ImGuiShader_DrawFXKeys.proj, ref projMatrix);
imShader.EffectInstance.Apply(context);

commandList.DrawIndexed((int)cmd.ElemCount, idxOffset, vtxOffset);
}

idxOffset += (int)cmd.ElemCount;
}

vtxOffset += cmdList.VtxBuffer.Size;
}
}
}
}
Loading