stash rework draw text

This commit is contained in:
DCFApixels 2025-02-26 23:39:50 +08:00
parent beba6472fc
commit 60938c4d95
7 changed files with 190 additions and 225 deletions

View File

@ -24,19 +24,25 @@ namespace DCFApixels
{
private static PauseStateX _pauseState = PauseStateX.Unpaused;
private static bool _isCameraContext = false;
private static ulong _lastEditorTicks = 1000;
private static double _lastUnityTime;
private static float _deltaTime = 0;
private static ulong _editorTicks = 0;
private static ulong _lastEditorToRenderTicks = 1000;
private static ulong _renderTicks = 100;
//private static ulong _lastEditorToRenderGizmosTicks = 1000;
//private static ulong _renderGizmosTicks = 100;
private static ulong _timeTicks = 0;
public static ulong RenderTicks
{
get { return _renderTicks; }
}
//public static ulong RenderGizmosTicks
//{
// get { return _renderGizmosTicks; }
//}
public static ulong TimeTicks
{
get { return _timeTicks; }
@ -291,14 +297,16 @@ namespace DCFApixels
private static void PostRender_General(ICommandBufferExecutor cbExecutor, Camera camera)
{
if (_lastEditorTicks != _editorTicks)
if (_lastEditorToRenderTicks != _editorTicks)
{
_renderTicks++;
_lastEditorTicks = _editorTicks;
_lastEditorToRenderTicks = _editorTicks;
}
if (DebugXUtility.IsGizmosRender())
{
CallDrawGizmos(camera);
RenderContextController.StaicContextController.Prepare();
RenderContextController.StaicContextController.Render(cbExecutor);
}
@ -308,6 +316,7 @@ namespace DCFApixels
RenderContextController contextController = RenderContextController.GetController(new RenderContext(camera));
contextController.Prepare();
contextController.Render(cbExecutor);
}
#if UNITY_EDITOR
@ -317,13 +326,28 @@ namespace DCFApixels
{
if (obj != Camera.main) { return; }
Camera camera = Camera.current;
//if (_lastEditorToRenderGizmosTicks != _editorTicks)
//{
// _renderGizmosTicks++;
// _lastEditorToRenderGizmosTicks = _editorTicks;
//}
//Camera camera = Camera.current;
//CallDrawGizmos(camera);
}
#endif
private static void CallDrawGizmos(Camera camera)
{
Color guiColor = GUI.color;
Color guiContextColor = GUI.contentColor;
Color guiBackgroundColor = GUI.backgroundColor;
Color gizmosColor = Gizmos.color;
Color handlesColor = Handles.color;
GL.MultMatrix(Handles.matrix);
//TODO ðàñêîìåíòèòü
RenderContextController.StaicContextController.Render_UnityGizmos();
if (camera == null) { return; }
@ -331,10 +355,11 @@ namespace DCFApixels
RenderContextController.GetController(new RenderContext(camera)).Render_UnityGizmos();
GUI.color = guiColor;
GUI.contentColor = guiContextColor;
GUI.backgroundColor = guiBackgroundColor;
Gizmos.color = gizmosColor;
Handles.color = handlesColor;
}
#endif
#endregion
@ -532,7 +557,6 @@ namespace DCFApixels
// //}
//}
[IN(LINE)]
public void Prepare()
{
@ -559,7 +583,6 @@ namespace DCFApixels
_buffers[i].Render(cbExecutor);
}
RunEnd();
}
}
@ -576,6 +599,8 @@ namespace DCFApixels
{
_buffers[i].Render_UnityGizmos();
}
RunEnd();
}
}
@ -697,6 +722,7 @@ namespace DCFApixels
}
return removeCount;
}
public sealed override int RunEnd()
{
int removeCount = 0;
@ -774,6 +800,7 @@ namespace DCFApixels
public override void Render_UnityGizmos()
{
if (_rendererUnityGizmos == null) { return; }
Debug.Log(_gizmos._count);
if (_gizmos.Count <= 0) { return; }
#if DEV_MODE
using (_renderMarker.Auto())

View File

@ -5,73 +5,33 @@ using UnityEditor;
using UnityEngine;
using UnityEngine.Rendering;
namespace DCFApixels {
namespace DCFApixels
{
using IN = System.Runtime.CompilerServices.MethodImplAttribute;
public static partial class DebugX {
public readonly partial struct DrawHandler {
public static partial class DebugX
{
public readonly partial struct DrawHandler
{
#region Text
[IN(LINE)] public DrawHandler TextWorldScale(Vector3 position, object text) => Gizmo(new TextGizmo(position, text, DebugXTextSettings.Default, true));
[IN(LINE)] public DrawHandler TextWorldScale(Vector3 position, object text, DebugXTextSettings settings) => Gizmo(new TextGizmo(position, text, settings, true));
[IN(LINE)] public DrawHandler Text(Vector3 position, object text) => Gizmo(new TextGizmo(position, text, DebugXTextSettings.Default, false));
[IN(LINE)] public DrawHandler Text(Vector3 position, object text, DebugXTextSettings settings) => Gizmo(new TextGizmo(position, text, settings, false));
/// <summary>
/// Draw text at the world position.
/// Can pass any object where ToString() will be called.
/// </summary>
/// <param name="position">World position.</param>
/// <param name="text">String or any other object.</param>
[IN(LINE)] public DrawHandler Text(Vector3 position, object text) => Gizmo(new TextGizmo(new TextBuilder(position, text)));
/// <summary>
/// Draw text at the world position.
/// Can pass any object where ToString() will be called.
/// </summary>
/// <param name="position">World position.</param>
/// <param name="text">String or any other object.</param>
/// <param name="fontSize">Text font size.</param>
[IN(LINE)] public DrawHandler Text(Vector3 position, object text, int fontSize) => Gizmo(new TextGizmo(new TextBuilder(position, text, fontSize)));
/// <summary>
/// Draw text at the world position.
/// Can pass any object where ToString() will be called.
/// </summary>
/// <param name="position">World position.</param>
/// <param name="text">String or any other object.</param>
/// <param name="fontSize">Text font size.</param>
/// <param name="textAnchor">Text alignment.</param>
[IN(LINE)] public DrawHandler Text(Vector3 position, object text, int fontSize, TextAnchor textAnchor) => Gizmo(new TextGizmo(new TextBuilder(position, text, fontSize, textAnchor)));
/// <summary>
/// Use text builder to pass more details about how text-gizmo should be drawn.
/// </summary>
/// <param name="textBuilder">Settings with a builder pattern.</param>
[IN(LINE)] public DrawHandler Text(TextBuilder textBuilder) => Gizmo(new TextGizmo(textBuilder));
private readonly struct TextGizmo : IGizmo<TextGizmo> {
private const int BACKGROUND_TEXTURE_WIDTH = 2;
private const int BACKGROUND_TEXTURE_HEIGHT = 2;
private const int BACKGROUND_TEXTURE_PIXELS_COUNT = BACKGROUND_TEXTURE_WIDTH * BACKGROUND_TEXTURE_HEIGHT;
// TODO: Normally Texture2D should be destroyed when not needed anymore. Though it will live through entire app lifetime. What about editor?
private static Texture2D _backgroundTexture;
private static Color32[] _backgroundTexturePixels;
public readonly TextBuilder TextBuilderInstance;
private readonly struct TextGizmo : IGizmo<TextGizmo>
{
public readonly Vector3 Position;
public readonly string Text;
public readonly DebugXTextSettings Settings;
public readonly bool IsWorldSpaceScale;
[IN(LINE)]
public TextGizmo(TextBuilder textBuilder) {
TextBuilderInstance = textBuilder;
CheckTextureInstance();
}
/// <summary>
/// Texture should be set once after the app domain is cleared.
/// </summary>
private void CheckTextureInstance() {
if (_backgroundTexture != null) {
return;
}
_backgroundTexture = new Texture2D(BACKGROUND_TEXTURE_WIDTH, BACKGROUND_TEXTURE_HEIGHT);
_backgroundTexturePixels = new Color32[BACKGROUND_TEXTURE_PIXELS_COUNT];
_backgroundTexture.SetPixels32(_backgroundTexturePixels);
_backgroundTexture.Apply();
public TextGizmo(Vector3 position, object text, DebugXTextSettings settings, bool isWorldSpaceScale)
{
Position = position;
Text = text.ToString();
Settings = settings;
IsWorldSpaceScale = isWorldSpaceScale;
}
public IGizmoRenderer<TextGizmo> RegisterNewRenderer() { return new Renderer(); }
@ -79,7 +39,11 @@ namespace DCFApixels {
#region Renderer
private class Renderer : IGizmoRenderer_UnityGizmos<TextGizmo>
{
private static Color32[] _backgroundTexturePixels;
private static Texture2D _backgroundTexture;
private static GUIStyle _labelStyle;
private static GUIStyle _labelStyleWithBackground;
private static GUIContent _labelDummy;
public int ExecuteOrder => default(UnlitMat).GetExecuteOrder();
public bool IsStaticRender => false;
@ -88,176 +52,105 @@ namespace DCFApixels {
public void Render_UnityGizmos(Camera camera, GizmosList<TextGizmo> list)
{
#if UNITY_EDITOR
Color defaultColor = GUI.color;
if (_labelStyle == null || _labelDummy == null)
{
_labelStyle = new GUIStyle(GUI.skin.label) {
richText = false
};
_labelDummy = new GUIContent();
}
if (list.Count == 0) {
return;
}
var zoom = GetCameraZoom();
InitStatic();
var zoom = GetCameraZoom(camera);
Handles.BeginGUI();
foreach (ref readonly var item in list)
{
GUI.color = item.Color * GlobalColor;
_labelDummy.text = item.Value.TextBuilderInstance.Text.ToString();
GUI.contentColor = item.Color * GlobalColor;
GUI.backgroundColor = item.Value.Settings.BackgroundColor * GlobalColor;
_labelStyle.fontSize = item.Value.TextBuilderInstance.UseWorldScale
? Mathf.FloorToInt(item.Value.TextBuilderInstance.FontSize / zoom)
: item.Value.TextBuilderInstance.FontSize;
_labelDummy.text = item.Value.Text;
GUIStyle style = item.Value.Settings.IsHasBackground ? _labelStyleWithBackground : _labelStyle;
_labelStyle.alignment = item.Value.TextBuilderInstance.TextAnchor;
style.fontSize = item.Value.IsWorldSpaceScale
? Mathf.FloorToInt(item.Value.Settings.FontSize / zoom)
: item.Value.Settings.FontSize;
_labelStyle.normal = new GUIStyleState {
style.alignment = item.Value.Settings.TextAnchor;
_labelStyle.normal = new GUIStyleState
{
textColor = item.Color * GlobalColor,
};
if (item.Value.TextBuilderInstance.UseBackground) {
for (int i = 0; i < BACKGROUND_TEXTURE_PIXELS_COUNT; i++) {
_backgroundTexturePixels[i] = item.Value.TextBuilderInstance.BackgroundColor;
}
_backgroundTexture.SetPixels32(_backgroundTexturePixels);
_backgroundTexture.Apply();
_labelStyle.normal.background = _backgroundTexture;
}
if (!(HandleUtility.WorldToGUIPointWithDepth(item.Value.TextBuilderInstance.Position).z < 0f))
if (!(HandleUtility.WorldToGUIPointWithDepth(item.Value.Position).z < 0f))
{
GUI.Label(HandleUtility.WorldPointToSizedRect(item.Value.TextBuilderInstance.Position, _labelDummy, _labelStyle), _labelDummy, _labelStyle);
GUI.Label(HandleUtility.WorldPointToSizedRect(item.Value.Position, _labelDummy, _labelStyle), _labelDummy, style);
}
}
Handles.EndGUI();
GUI.color = defaultColor;
float GetCameraZoom() {
const float DEFAULT_ZOOM = 1f;
if (camera != null) {
return camera.orthographicSize;
}
var currentDrawingSceneView = SceneView.currentDrawingSceneView;
if (currentDrawingSceneView == null) {
return DEFAULT_ZOOM;
}
var localCamera = currentDrawingSceneView.camera;
if (localCamera != null) {
return localCamera.orthographicSize;
}
return DEFAULT_ZOOM;
}
#endif
}
private void InitStatic()
{
const int BACKGROUND_TEXTURE_WIDTH = 2;
const int BACKGROUND_TEXTURE_HEIGHT = 2;
const int BACKGROUND_TEXTURE_PIXELS_COUNT = BACKGROUND_TEXTURE_WIDTH * BACKGROUND_TEXTURE_HEIGHT;
if (_labelStyle == null || _labelDummy == null || _labelStyleWithBackground == null)
{
_labelStyle = new GUIStyle(GUI.skin.label)
{
richText = false,
padding = new RectOffset(0, 0, 0, 0),
margin = new RectOffset(0, 0, 0, 0)
};
_labelDummy = new GUIContent();
var backgroundTexturePixels = new Color32[BACKGROUND_TEXTURE_PIXELS_COUNT];
for (int i = 0; i < backgroundTexturePixels.Length; i++)
{
backgroundTexturePixels[i] = new Color32(255, 255, 255, 255);
}
_backgroundTexturePixels = backgroundTexturePixels;
var backgroundTexture = new Texture2D(BACKGROUND_TEXTURE_WIDTH, BACKGROUND_TEXTURE_HEIGHT);
backgroundTexture.SetPixels32(backgroundTexturePixels);
backgroundTexture.Apply();
_backgroundTexture = backgroundTexture;
_labelStyleWithBackground = new GUIStyle(_labelStyle);
_labelStyleWithBackground.normal.background = backgroundTexture;
_labelStyleWithBackground.active.background = backgroundTexture;
_labelStyleWithBackground.focused.background = backgroundTexture;
_labelStyleWithBackground.hover.background = backgroundTexture;
}
}
private static float GetCameraZoom(Camera camera)
{
const float DEFAULT_ZOOM = 1f;
if (camera != null)
{
return camera.orthographicSize;
}
return DEFAULT_ZOOM;
//var currentDrawingSceneView = SceneView.currentDrawingSceneView;
//
//if (currentDrawingSceneView == null)
//{
// return DEFAULT_ZOOM;
//}
//
//var localCamera = currentDrawingSceneView.camera;
//
//if (localCamera != null)
//{
// return localCamera.orthographicSize;
//}
//
//return DEFAULT_ZOOM;
}
}
#endregion
}
#endregion
#region TextBuilder
/// <summary>
/// Set text gizmos instance settings using a builder pattern.
/// </summary>
public struct TextBuilder {
private const TextAnchor DEFAULT_TEXT_ANCHOR = TextAnchor.MiddleLeft;
private const int DEFAULT_FONT_SIZE = 16;
/// <summary>
/// Text world position.
/// </summary>
public Vector3 Position { get; set; }
/// <summary>
/// Text. Uses ToString() of the passed object.
/// </summary>
public object Text { get; set; }
/// <summary>
/// Font size. Default is <see cref="DEFAULT_FONT_SIZE" />.
/// </summary>
public int FontSize { get; set; }
/// <summary>
/// Text alignment. Default is <see cref="DEFAULT_TEXT_ANCHOR" />.
/// </summary>
public TextAnchor TextAnchor { get; set; }
/// <summary>
/// Background texture color.
/// </summary>
public Color BackgroundColor { get; set; }
/// <summary>
/// Flag to use background texture and background color when rendering text gizmo instance.
/// </summary>
public bool UseBackground { get; set; }
/// <summary>
/// If set true - camera zooming will affect text scale to keep same size in the world.
/// </summary>
public bool UseWorldScale { get; set; }
public TextBuilder(Vector3 position, object text, int fontSize = DEFAULT_FONT_SIZE, TextAnchor textAnchor = DEFAULT_TEXT_ANCHOR) : this() {
Position = position;
Text = text;
FontSize = fontSize;
TextAnchor = textAnchor;
}
public TextBuilder SetPosition(Vector3 position) {
Position = position;
return this;
}
public TextBuilder SetText(object text) {
Text = text;
return this;
}
public TextBuilder SetFontSize(int fontSize) {
FontSize = fontSize;
return this;
}
public TextBuilder SetTextAnchor(TextAnchor textAnchor) {
TextAnchor = textAnchor;
return this;
}
public TextBuilder SetBackground(Color backgroundColor) {
UseBackground = true;
BackgroundColor = backgroundColor;
return this;
}
public TextBuilder RemoveBackground() {
UseBackground = false;
return this;
}
public TextBuilder SetWorldScaling() {
UseWorldScale = true;
return this;
}
public TextBuilder RemoveWorldScaling() {
UseWorldScale = false;
return this;
}
}
#endregion
#endregion
}
}
}

View File

@ -0,0 +1,2 @@
fileFormatVersion: 2
guid: c465dc7f5c78c9549a063ecfc5e8326d

View File

@ -0,0 +1,41 @@
using UnityEngine;
namespace DCFApixels
{
public struct DebugXTextSettings
{
public const TextAnchor DEFAULT_TEXT_ANCHOR = TextAnchor.MiddleLeft;
public const int DEFAULT_FONT_SIZE = 16;
public static readonly DebugXTextSettings Default = new DebugXTextSettings(DEFAULT_FONT_SIZE, DEFAULT_TEXT_ANCHOR, default);
public int FontSize;
public TextAnchor TextAnchor;
public Color BackgroundColor;
public bool IsHasBackground
{
get { return BackgroundColor.a > 0; }
}
public DebugXTextSettings(int fontSize, TextAnchor textAnchor, Color backgroundColor)
{
FontSize = fontSize;
TextAnchor = textAnchor;
BackgroundColor = backgroundColor;
}
public DebugXTextSettings SetSize(int fontSize)
{
FontSize = fontSize;
return this;
}
public DebugXTextSettings SetAnchor(TextAnchor textAnchor)
{
TextAnchor = textAnchor;
return this;
}
public DebugXTextSettings SetBackground(Color backgroundColor)
{
BackgroundColor = backgroundColor;
return this;
}
}
}

View File

@ -0,0 +1,2 @@
fileFormatVersion: 2
guid: 5a9b0ba5a6770294b9777fca87f3b7a4

View File

@ -4135,7 +4135,7 @@ GameObject:
m_Component:
- component: {fileID: 1482731616}
m_Layer: 0
m_Name: Hello World
m_Name: Hello World Hello World Hello World
m_TagString: Untagged
m_Icon: {fileID: 0}
m_NavMeshLayer: 0

View File

@ -8,6 +8,7 @@ namespace DCFApixels.DebugXCore.Samples
public Gradient Gradient;
public float GradientMultiplier = 5;
public Transform[] Points;
private static readonly Color _background = new Color(0, 0, 0, 0.5f);
#if UNITY_EDITOR
private void OnDrawGizmos()
@ -20,7 +21,6 @@ namespace DCFApixels.DebugXCore.Samples
Draw();
}
#endif
private void Draw()
{
int i = -1;
@ -29,7 +29,7 @@ namespace DCFApixels.DebugXCore.Samples
i++; DebugX.Draw(GetColor(Points[i])).Cross(Points[i].position, Points[i].localScale.x);
i++; DebugX.Draw(GetColor(Points[i])).BillboardCircle(Points[i].position, Points[i].localScale.x * RADIUS_M);
i++; DebugX.Draw(GetColor(Points[i])).WireMesh<SphereMesh>(Points[i].position, Points[i].rotation, Points[i].localScale * RADIUS_M);
i++; DebugX.Draw(GetColor(Points[i])).Text(Points[i].position, Points[i].name);
i++; DebugX.Draw(GetColor(Points[i])).Text(Points[i].position, Points[i].name, DebugXTextSettings.Default.SetBackground(Color.black));
i++; DebugX.Draw(GetColor(Points[i])).Dot(Points[i].position);
i++; DebugX.Draw(GetColor(Points[i])).WireDot(Points[i].position);