Code/Rendering/ImDrawList.cs
using Sandbox.Rendering;
using System;
namespace Duccsoft.ImGui.Rendering;
public class ImDrawList
{
public ImDrawList( string name )
{
CommandList = new CommandList( $"ImGui DrawList {name}" )
{
Flags = CommandList.Flag.Hud
};
}
public CommandList CommandList { get; private set; }
#region Rect
public void AddRect( Vector2 upperLeft, Vector2 lowerRight, Color32 color, float rounding = 0f, ImDrawFlags flags = ImDrawFlags.None, float thickness = 1.0f )
{
DrawRect( upperLeft, lowerRight, Color.Transparent, color, rounding, flags, thickness );
}
public void AddRectFilled( Vector2 upperLeft, Vector2 lowerRight, Color32 color, float rounding = 0f, ImDrawFlags flags = ImDrawFlags.None )
=> DrawRect( upperLeft, lowerRight, color, Color.Transparent, rounding, flags, borderThickness: 0f );
private void DrawRect( Vector2 upperLeft, Vector2 lowerRight, Color fillColor, Color borderColor, float rounding, ImDrawFlags flags, float borderThickness )
{
// Transform
CommandList.Set( "BoxPosition", upperLeft );
CommandList.Set( "BoxSize", lowerRight - upperLeft );
// Background
CommandList.SetCombo( "D_BACKGROUND_IMAGE", 0 );
if ( borderThickness >= 1f )
{
// Border
CommandList.Set( "HasBorder", 1 );
// TODO: Use ImDrawFlags to determine which borders are rounded.
CommandList.Set( "BorderSize", borderThickness );
CommandList.Set( "BorderRadius", rounding );
CommandList.Set( "BorderColorL", borderColor );
CommandList.Set( "BorderColorT", borderColor );
CommandList.Set( "BorderColorR", borderColor );
CommandList.Set( "BorderColorB", borderColor );
CommandList.SetCombo( "D_BORDER_IMAGE", 0 );
}
CommandList.DrawQuad( new Rect( upperLeft, lowerRight - upperLeft ), Material.UI.Box, fillColor );
}
#endregion
#region Triangle
//public void AddTriangleFilled( Vector2 p1, Vector2 p2, Vector3 p3, Color32 color )
//{
// throw new NotImplementedException();
//}
#endregion
#region Text
private static TextRendering.Scope TextScope( string text, Color color )
=> new( text, color, ImGui.GetTextLineHeight(), "Consolas" );
public void AddText( Vector2 pos, Color32 color, string text, TextFlag flags = TextFlag.LeftTop )
=> DrawText( new Rect( pos, 1f ), TextScope( text, color ), flags );
private void DrawText( Rect rect, TextRendering.Scope scope, TextFlag flags )
{
var textTexture = TextRendering.GetOrCreateTexture( in scope, clip: default, flags );
if ( !textTexture.IsValid() )
return;
CommandList.Set( "TextureIndex", textTexture.Index );
var size = textTexture.Size;
rect = rect.Align( size, flags );
CommandList.DrawQuad( rect, Material.FromShader( "shaders/ui_text.shader" ), Color.White );
}
#endregion
#region Image
public void AddImage( Texture texture, Vector2 upperLeft, Vector2 lowerRight, Vector2 uv0, Vector2 uv1, Color32 tintColor )
=> DrawImage( texture, upperLeft, lowerRight, uv0, uv1, tintColor );
public void AddImage( Texture texture, Vector2 upperLeft, Vector2 lowerRight )
=> AddImage( texture, upperLeft, lowerRight, uv0: new Vector2( 0, 0 ), uv1: new Vector2( 1, 1 ), tintColor: Color.White );
private void DrawImage( Texture texture, Vector2 upperLeft, Vector2 lowerRight, Vector2 uv0, Vector2 uv1, Color32 tintColor )
{
if ( !texture.IsValid() )
return;
// Transform
CommandList.Set( "BoxPosition", upperLeft );
CommandList.Set( "BoxSize", lowerRight - upperLeft );
// Background
CommandList.SetCombo( "D_BACKGROUND_IMAGE", 1 );
CommandList.Set( "BgRepeat", -1 );
CommandList.Set( "TextureIndex", texture.Index );
var texToRectScale = 1f / (texture.Size / (lowerRight - upperLeft));
var offset = uv0 * texture.Size * texToRectScale;
var size = uv1 * texture.Size * texToRectScale - offset;
var bgPos = new Vector4( offset.x, offset.y, size.x, size.y );
CommandList.Set( "BgPos", bgPos );
// Border
CommandList.Set( "HasBorder", 0 );
CommandList.DrawQuad( new Rect( upperLeft, lowerRight - upperLeft ), Material.FromShader( "shaders/imgui_rect.shader"), tintColor );
}
#endregion Image
}