add some debug features using keys in gl avalonia:
- [U] - use default material for rendering - [I] - toggle text shader (show raw texture) - [O] - change text thickness ([O] - increase, [Shift] + [O] - decrease)
This commit is contained in:
Родитель
1a62b273cf
Коммит
2c4715b3a7
|
@ -98,7 +98,7 @@ public static class ElementsExamples {
|
|||
|
||||
Label l = new("amogus", canvas.canvas);
|
||||
canvas.AddElement(l);
|
||||
l.color = new("#FF8855");
|
||||
l.color = new("#eb4034");
|
||||
l.GenerateMesh();
|
||||
|
||||
// l.beforeRender += () => {
|
||||
|
|
|
@ -17,5 +17,5 @@ public abstract class ChartFactory {
|
|||
|
||||
public abstract Texture CreateTexture(string path);
|
||||
public abstract Texture CreateTexture(float2 size);
|
||||
public abstract FontTextures CreateFontTextureAtlas(FreeTypeFaceFacade face);
|
||||
public abstract FontTextures CreateFontTextureAtlas(FreeTypeFaceFacade face, uint resolution = 32);
|
||||
}
|
|
@ -19,11 +19,11 @@ public class Font {
|
|||
this.textures = textures;
|
||||
}
|
||||
|
||||
public static Font LoadFromPath(string path, ChartsCanvas canvas) {
|
||||
public static Font LoadFromPath(string path, ChartsCanvas canvas, uint resolution = 32) {
|
||||
using FileStream fs = new(path, FileMode.Open);
|
||||
FT.FT_New_Face(FreeType.ftLib.Native, path, 0, out IntPtr face).CheckError();
|
||||
FreeTypeFaceFacade faceF = new(FreeType.ftLib, face);
|
||||
|
||||
return new("todo", false, false, false, canvas.factory.CreateFontTextureAtlas(faceF));
|
||||
return new("todo", false, false, false, canvas.factory.CreateFontTextureAtlas(faceF, resolution));
|
||||
}
|
||||
}
|
|
@ -9,15 +9,14 @@ public abstract class FontTextureAtlas {
|
|||
public List<FontCharData> characters = new();
|
||||
protected RectPack packer;
|
||||
|
||||
protected FontTextureAtlas(int size = 1024) => packer = new(size, 0);
|
||||
protected FontTextureAtlas(int size = 1024) => packer = new(size, 1);
|
||||
|
||||
public unsafe (int i, int x, int y) Pack(int width, int height, string character) {
|
||||
float2 size = texture.size;
|
||||
float2 pos = packer.Pack(new(width, height));
|
||||
if (pos == new float2(-1, -1)) return (-1, 0, 0);
|
||||
|
||||
AddChar((int) pos.x, (int) pos.y, width, height, character);
|
||||
|
||||
AddChar((int)pos.x, (int)pos.y, width, height, character);
|
||||
return (characters.Count - 1, (int) pos.x, (int) pos.y);
|
||||
}
|
||||
|
||||
|
|
|
@ -0,0 +1,6 @@
|
|||
namespace SomeChartsUi.ui.text;
|
||||
|
||||
//TODO: impl
|
||||
public class TextMesh {
|
||||
|
||||
}
|
|
@ -17,5 +17,5 @@ public class GlChartFactory : ChartFactory {
|
|||
public override Shader CreateShader(string name, string vertex, string fragment) => new GlShader(name, vertex, fragment);
|
||||
public override Texture CreateTexture(string path) => new GlTexture(path);
|
||||
public override Texture CreateTexture(float2 size) => throw new NotImplementedException();
|
||||
public override unsafe FontTextures CreateFontTextureAtlas(FreeTypeFaceFacade face) => new GlFontTextures(face);
|
||||
public override unsafe FontTextures CreateFontTextureAtlas(FreeTypeFaceFacade face, uint resolution) => new GlFontTextures(face, resolution);
|
||||
}
|
|
@ -22,7 +22,8 @@ public class GlChartsBackend : ChartsBackendBase {
|
|||
|
||||
//TODO: oof
|
||||
public override unsafe void DrawText(string text, color col, FontData font, RenderableTransform transform) {
|
||||
testFont ??= Font.LoadFromPath("data/Comfortaa-VariableFont_wght.ttf", renderer.owner);
|
||||
uint resolution = 32;
|
||||
testFont ??= Font.LoadFromPath("data/Comfortaa-VariableFont_wght.ttf", renderer.owner, resolution);
|
||||
// (FontCharData ch, int atlas) glyph = "AMOGUSamogus".ToCharArray().Select(c => testFont.textures.GetGlyph(c.ToString())).Last();
|
||||
Random rnd = new();
|
||||
//char c = (char) rnd.Next(60, 200);
|
||||
|
@ -53,30 +54,39 @@ public class GlChartsBackend : ChartsBackendBase {
|
|||
|
||||
for (int i = 0; i < 1; i++) {
|
||||
float xPos = 0;
|
||||
float zPos = i * 0.1f;
|
||||
foreach (char c in "Lorem ipsum dolor sit amet, consectetur adipiscing elit. Sed tincidunt mollis pretium. Phasellus euismod tortor consequat, lobortis erat quis, accumsan ligula. Vestibulum at dolor congue ante ultricies lacinia. Vestibulum nec tellus nec mauris porttitor rhoncus. Nulla pellentesque placerat pulvinar. Nullam ut rutrum ante. Nulla nunc tellus, accumsan et facilisis ut, placerat vel neque. Proin feugiat eleifend justo nec posuere. Vestibulum convallis ipsum ut rutrum faucibus. Fusce faucibus suscipit nibh, ac pellentesque lorem pellentesque et. Donec at arcu a purus ultrices sagittis. Proin at congue diam.") {
|
||||
|
||||
string str =
|
||||
"Lorem ipsum dolor sit amet, consectetur adipiscing elit. Sed tincidunt mollis pretium. Phasellus euismod tortor consequat, lobortis erat quis, accumsan ligula. Vestibulum at dolor congue ante ultricies lacinia. Vestibulum nec tellus nec mauris porttitor rhoncus. Nulla pellentesque placerat pulvinar. Nullam ut rutrum ante. Nulla nunc tellus, accumsan et facilisis ut, placerat vel neque. Proin feugiat eleifend justo nec posuere. Vestibulum convallis ipsum ut rutrum faucibus. Fusce faucibus suscipit nibh, ac pellentesque lorem pellentesque et. Donec at arcu a purus ultrices sagittis. Proin at congue diam.";
|
||||
|
||||
for (int index = 0; index < str.Length; index++) {
|
||||
char c = str[index];
|
||||
|
||||
float s = 16f / resolution;
|
||||
|
||||
(FontCharData ch, int atlas) glyph = testFont.textures.GetGlyph(c.ToString());
|
||||
|
||||
float s = 16 / 32f;
|
||||
float zPos = index * 0.001f;
|
||||
float yPos = -glyph.ch.baseline*s;
|
||||
|
||||
Vertex[] vertices = new Vertex[4] {
|
||||
new(new(xPos, 0, zPos), new(0, 0), new(glyph.ch.position.x / 1024, glyph.ch.position.y / 1024 + glyph.ch.size.y / 1024), col),
|
||||
new(new(xPos, s*glyph.ch.size.y, zPos), new(0, 1), new(glyph.ch.position.x / 1024, glyph.ch.position.y / 1024), col),
|
||||
new(new(xPos+s*glyph.ch.size.x, s*glyph.ch.size.y, zPos), new(1, 1), new(glyph.ch.position.x / 1024 + glyph.ch.size.x / 1024, glyph.ch.position.y / 1024), col),
|
||||
new(new(xPos+s*glyph.ch.size.x, 0, zPos), new(1, 0), new(glyph.ch.position.x / 1024 + glyph.ch.size.x / 1024, glyph.ch.position.y / 1024 + glyph.ch.size.y / 1024), col),
|
||||
new(new(xPos, 0 + yPos, zPos), new(0, 0), new(glyph.ch.position.x / 1024, glyph.ch.position.y / 1024 + glyph.ch.size.y / 1024), col),
|
||||
new(new(xPos, s * glyph.ch.size.y + yPos, zPos), new(0, 1), new(glyph.ch.position.x / 1024, glyph.ch.position.y / 1024), col),
|
||||
new(new(xPos + s * glyph.ch.size.x, s * glyph.ch.size.y + yPos, zPos), new(1, 1), new(glyph.ch.position.x / 1024 + glyph.ch.size.x / 1024, glyph.ch.position.y / 1024), col),
|
||||
new(new(xPos + s * glyph.ch.size.x, 0 + yPos, zPos), new(1, 0), new(glyph.ch.position.x / 1024 + glyph.ch.size.x / 1024, glyph.ch.position.y / 1024 + glyph.ch.size.y / 1024), col),
|
||||
};
|
||||
|
||||
|
||||
using Mesh m = owner.factory.CreateMesh();
|
||||
m.SetIndexes(indices);
|
||||
m.SetVertices(vertices);
|
||||
|
||||
|
||||
if (testFont.textures.atlases.Count > 0) {
|
||||
((GlTexture)testFont.textures.atlases[0].texture).Bind();
|
||||
Material mat = new(GlShaders.basicText);
|
||||
Material mat = new(AvaloniaGlChartsCanvas.debugTextMat ? GlShaders.basicTextured : GlShaders.basicText);
|
||||
mat.SetProperty("texture0", ((GlTexture)testFont.textures.atlases[0].texture));
|
||||
mat.SetProperty("u_gamma", AvaloniaGlChartsCanvas.textThickness);
|
||||
DrawMesh(m, mat, transform);
|
||||
}
|
||||
|
||||
xPos += 16;
|
||||
xPos += glyph.ch.advance*s;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -1,3 +1,4 @@
|
|||
using System;
|
||||
using Avalonia.Input;
|
||||
using SomeChartsUi.ui;
|
||||
using SomeChartsUi.ui.canvas;
|
||||
|
@ -20,6 +21,16 @@ public class AvaloniaGlCanvasUiController : CanvasUiControllerBase {
|
|||
base.OnKey(key, mods);
|
||||
|
||||
if (key == keycode.y) AvaloniaGlChartsCanvas.polygonMode = (PolygonMode)(((int)AvaloniaGlChartsCanvas.polygonMode + 1) % 3);
|
||||
if (key == keycode.u) AvaloniaGlChartsCanvas.useDefaultMat = !AvaloniaGlChartsCanvas.useDefaultMat;
|
||||
if (key == keycode.I) AvaloniaGlChartsCanvas.debugTextMat = !AvaloniaGlChartsCanvas.debugTextMat;
|
||||
if (key == keycode.p) GlChartsBackend.perspectiveMode = !GlChartsBackend.perspectiveMode;
|
||||
if (key == keycode.o) {
|
||||
float th = AvaloniaGlChartsCanvas.textThickness;
|
||||
th += (mods & keymods.shift) != 0 ? -.01f : .01f;
|
||||
if (th > 1) th -= 1;
|
||||
if (th < 0) th += 1;
|
||||
Console.WriteLine(th);
|
||||
AvaloniaGlChartsCanvas.textThickness = th;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -23,7 +23,9 @@ public enum PolygonMode {
|
|||
}
|
||||
|
||||
public class AvaloniaGlChartsCanvas : OpenGlControlBase {
|
||||
|
||||
public static bool useDefaultMat = false;
|
||||
public static bool debugTextMat = false;
|
||||
public static float textThickness = 0.52f;
|
||||
public static PolygonMode polygonMode = PolygonMode.fill;
|
||||
public readonly ChartsCanvas canvas = CreateCanvas();
|
||||
|
||||
|
|
|
@ -1,3 +1,4 @@
|
|||
using System;
|
||||
using Avalonia.OpenGL;
|
||||
using FreeTypeSharp.Native;
|
||||
using MathStuff.vectors;
|
||||
|
@ -9,7 +10,6 @@ namespace SomeChartsUiAvalonia.utils;
|
|||
|
||||
public class GlFontTextureAtlas : FontTextureAtlas {
|
||||
private GlFontTextures _owner;
|
||||
public const uint resolution = 32;
|
||||
|
||||
public GlFontTextureAtlas(GlFontTextures owner, int size = 1024) : base(size) {
|
||||
_owner = owner;
|
||||
|
@ -20,22 +20,15 @@ public class GlFontTextureAtlas : FontTextureAtlas {
|
|||
GlTexture tex = new(width, height, GlConsts.GL_RED, GlConsts.GL_UNSIGNED_BYTE);
|
||||
|
||||
tex.Bind();
|
||||
GlInfo.glExt!.GenerateMipmap(GlConsts.GL_TEXTURE_2D);
|
||||
//GlInfo.glExt!.GenerateMipmap(GlConsts.GL_TEXTURE_2D);
|
||||
|
||||
return tex;
|
||||
}
|
||||
protected override unsafe void AddChar(int x, int y, int w, int h, string ch) {
|
||||
//CodePoint point = new(ch[0]);
|
||||
//Glyph glyph = _owner.face.GetGlyph(point, 32);
|
||||
FT.FT_Set_Pixel_Sizes(_owner.face.Face, 0, resolution);
|
||||
uint res0 = 0;
|
||||
uint res = resolution;
|
||||
//FT.FT_Set_Char_Size(_owner.face.Face, (IntPtr)(&res0), (IntPtr)(&res), 0, resolution);
|
||||
FT.FT_Load_Char(_owner.face.Face, ch[0], FT.FT_LOAD_RENDER).CheckError();
|
||||
uint height = _owner.face.FaceRec->glyph->bitmap.rows;
|
||||
|
||||
float advance = *(float*) &_owner.face.FaceRec->glyph->advance.x;
|
||||
float baseline = *(float*) &_owner.face.FaceRec->glyph->advance.y;
|
||||
float advance = *(int*)&_owner.face.FaceRec->glyph->linearHoriAdvance / 65536f;
|
||||
|
||||
float baseline = _owner.face.FaceRec->glyph->bitmap.rows - _owner.face.FaceRec->glyph->bitmap_top;
|
||||
Console.WriteLine(baseline);
|
||||
float2 size = new(w, h);
|
||||
FontCharData data = new(advance, baseline, new(x, y), size, ch);
|
||||
characters.Add(data);
|
||||
|
@ -46,6 +39,6 @@ public class GlFontTextureAtlas : FontTextureAtlas {
|
|||
GlInfo.glExt!.PixelStorei(GlConsts.GL_UNPACK_ALIGNMENT, 1);
|
||||
GlInfo.glExt!.TexSubImage2D(GlConsts.GL_TEXTURE_2D, level, x, y, width, height, GlConsts.GL_RED, GlConsts.GL_UNSIGNED_BYTE, img);
|
||||
//GlInfo.glExt!.TexSubImage2D(GlConsts.GL_TEXTURE_2D, 1, x>>1, y>>1, width>>1, height>>1, GlConsts.GL_RED, GlConsts.GL_UNSIGNED_BYTE, img);
|
||||
GlInfo.glExt.GenerateMipmap(GlConsts.GL_TEXTURE_2D);
|
||||
//GlInfo.glExt.GenerateMipmap(GlConsts.GL_TEXTURE_2D);
|
||||
}
|
||||
}
|
|
@ -7,23 +7,25 @@ namespace SomeChartsUiAvalonia.utils;
|
|||
|
||||
public class GlFontTextures : FontTextures {
|
||||
public FreeTypeFaceFacade face;
|
||||
|
||||
public uint resolution;
|
||||
|
||||
public unsafe GlFontTextures(FreeTypeFaceFacade face) => this.face = face;
|
||||
public GlFontTextures(FreeTypeFaceFacade face, uint resolution) {
|
||||
this.face = face;
|
||||
this.resolution = resolution;
|
||||
}
|
||||
|
||||
|
||||
|
||||
protected override unsafe (FontCharData ch, int atlas) Add(string character) {
|
||||
//CodePoint point = new(character[0]);
|
||||
FT.FT_Set_Pixel_Sizes(face.Face, 0, GlFontTextureAtlas.resolution);
|
||||
FT.FT_Set_Pixel_Sizes(face.Face, 0, resolution);
|
||||
FT.FT_Load_Char(face.Face, character[0], FT.FT_LOAD_RENDER).CheckError();
|
||||
|
||||
uint charIndex = face.GetCharIndex(character[0]);
|
||||
if (charIndex == 0) return (default, -1);
|
||||
|
||||
|
||||
FT.FT_Render_Glyph((IntPtr)face.GlyphSlot, FT_Render_Mode.FT_RENDER_MODE_SDF).CheckError();
|
||||
uint width = face.FaceRec->glyph->bitmap.width;
|
||||
uint height = face.FaceRec->glyph->bitmap.rows;
|
||||
FT.FT_Render_Glyph((IntPtr)face.GlyphSlot, FT_Render_Mode.FT_RENDER_MODE_SDF).CheckError();
|
||||
|
||||
|
||||
for (int i = 0; i < atlases.Count; i++) {
|
||||
int index = Add_(atlases[i]);
|
||||
|
|
|
@ -67,7 +67,7 @@ public class GlTexture : Texture, IDisposable {
|
|||
}
|
||||
|
||||
public static void SetFilter(TextureFilter v) {
|
||||
SetParameter(GlConsts.GL_TEXTURE_MIN_FILTER, (v == TextureFilter.nearest ? GlConsts.GL_NEAREST : GlConsts.GL_LINEAR_MIPMAP_LINEAR));
|
||||
SetParameter(GlConsts.GL_TEXTURE_MIN_FILTER, (v == TextureFilter.nearest ? GlConsts.GL_NEAREST : GlConsts.GL_LINEAR));
|
||||
SetParameter(GlConsts.GL_TEXTURE_MAG_FILTER, (int)v);
|
||||
}
|
||||
|
||||
|
|
|
@ -96,7 +96,7 @@ public class GlMesh : Mesh {
|
|||
|
||||
BindBuffers();
|
||||
if (updateRequired | isDynamic) UpdateBuffers();
|
||||
GlShader shader = material == null ? GlShaders.basic : (GlShader) material.shader;
|
||||
GlShader shader = material == null || AvaloniaGlChartsCanvas.useDefaultMat ? GlShaders.basic : (GlShader) material.shader;
|
||||
if (shader.shaderProgram == 0) shader.TryCompile();
|
||||
if (shader.shaderProgram == 0) return;
|
||||
|
||||
|
|
Загрузка…
Ссылка в новой задаче