EvergineTeam / Feedback

Feedback, feature requests, and bug reports for Evergine.
https://evergine.com
14 stars 1 forks source link

How to display special characters in evergine #182

Open 666wwx opened 6 months ago

666wwx commented 6 months ago

Such as Chinese, in Text3D. Chinese characters cannot be displayed,Display as “ ” Hope to receive a response, thank you very much!

LaplaceStudio commented 4 months ago

如果你的最终项目是Windows应用(UWP应用或WinForms应用),可以通过使用Win2D来实现在Evergine的场景中显示中文文本的目的。Win2D中的CanvasGeometry提供了一个Tessellate方法,可以生成几何体的细分三角形。使用这些三角形,可以在Evergine中创建网格组件,最终显示中文甚至其它任何可见文本。以下是一个示例:](url)

文本网格类: ` public class TextMesh : PrimitiveBaseMesh {

public string Text { get; set; }
public bool TwoSides { get; set; }
public float FontSize { get; set; }
public TextMesh(string text, float fontSize = 14, bool twoSides = true) {
    Text = text ?? string.Empty;
    TwoSides = twoSides;
    FontSize = fontSize;
}

protected override void Build(PrimitiveModelBuilder builder) {
   // 创建文本几何体
    var cd = CanvasDevice.GetSharedDevice();
    var format = new Microsoft.Graphics.Canvas.Text.CanvasTextFormat() { FontSize = FontSize };
    var txtLayout = new Microsoft.Graphics.Canvas.Text.CanvasTextLayout(cd, Text, format, 1000, 1000);
    var geo = CanvasGeometry.CreateText(txtLayout);
    geo = geo.Transform(System.Numerics.Matrix3x2.CreateScale(-1)); 

    var triangles = geo.Tessellate();//获取细分三角形

    builder.SetCapacity(triangles.Length * 3, triangles.Length * 3); //顶点数量与顶点索引数量一致,均为三角形数量*3
    //将三角形顶点与索引添加到PrimitiveModelBuilder中
    foreach (var triangle in triangles) {
        var vertex1 = new Vector3(triangle.Vertex1.X, triangle.Vertex1.Y, 0);
        var vertex2 = new Vector3(triangle.Vertex2.X, triangle.Vertex2.Y, 0);
        var vertex3 = new Vector3(triangle.Vertex3.X, triangle.Vertex3.Y, 0);
        var normal = Vector3.Cross(vertex1 - vertex2, vertex1 - vertex3);//计算顶点法线(即三角面法线)
        builder.AddIndex(builder.VerticesCount + 0);
        builder.AddIndex(builder.VerticesCount + 1);
        builder.AddIndex(builder.VerticesCount + 2);
        builder.AddVertex(vertex1, -normal);
        builder.AddVertex(vertex2, -normal);
        builder.AddVertex(vertex3, -normal);
        // 添加另一侧
        if (TwoSides) {
            builder.AddIndex(builder.VerticesCount + 0);
            builder.AddIndex(builder.VerticesCount + 1);
            builder.AddIndex(builder.VerticesCount + 2);
            builder.AddVertex(vertex1, normal);
            builder.AddVertex(vertex3, normal);
            builder.AddVertex(vertex2, normal);
        }
    }
}

protected override int GetPrimitiveHashCode() {
    return Text.GetHashCode();
}

} `

使用示例: var textEntity = new Entity() .AddComponent(new Transform3D()) .AddComponent(new MaterialComponent() { Material = standardMat.Material }) .AddComponent(new TextMesh("你好世界!")) .AddComponent(new MeshRenderer()); this.Managers.EntityManager.Add(textEntity);

效果:

46fa3127939b41bf0b544cb4ed6ccd4

文本的字体,大小,对齐方式等,都可以在CanvasTextFormat类型的参数中设置。文本的颜色可以在文本所属的Enity的材质组件中设置。

注意:Win2d.uwp面向Windows 10应用,与.Net Standard不兼容(因为使用了Windows Runtime API),因此你只能在UWP项目中引用这个包。但通常上面的TextMesh的使用者是一个Evergine Scene,Evergine Studio自动生成的MyScene位于共享代码库中(目标框架为.Net Standard),无法使用Win2D.uwp。解决方式是不使用Evergine Studio自动生成的MyScene作为应用场景,而是在UWP应用项目(或者Windows通用类库项目)中手动创建一个新的场景(包括场景中的相机,环境,阳光等),在UWP项目中引用Win2d.uwp,然后使用上面的代码构建TextMesh。

另:上面的示例仍然可以优化(内存占用和性能),比如使用下面的方法:

666wwx commented 4 months ago

我很好奇你是国内哪家公司的?ω?