Removed Subrepository
This commit is contained in:
173
C#/OpenGLTutorial/Rendering/Objects/Components/TextComponent.cs
Normal file
173
C#/OpenGLTutorial/Rendering/Objects/Components/TextComponent.cs
Normal file
@@ -0,0 +1,173 @@
|
||||
#pragma warning disable CA1416
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Drawing;
|
||||
using System.Drawing.Drawing2D;
|
||||
using System.Drawing.Imaging;
|
||||
using System.Drawing.Text;
|
||||
using System.IO;
|
||||
using System.Numerics;
|
||||
using System.Text;
|
||||
using System.Text.Json;
|
||||
using OpenGLTutorial.Rendering.Display;
|
||||
using static OpenGL.GL;
|
||||
|
||||
namespace OpenGLTutorial.Rendering.Objects.Components {
|
||||
|
||||
[Serializable]
|
||||
public class TextSettings {
|
||||
public int GlyphsPerLine { get; set; } = 16;
|
||||
public int GlyphLineCount { get; set; } = 16;
|
||||
public int GlyphWidth { get; set; } = 30;
|
||||
public int GlyphHeight { get; set; } = 48;
|
||||
|
||||
public float CharXSpacing { get; set; } = 0.0f;
|
||||
|
||||
// Used to offset rendering glyphs to bitmap
|
||||
public int AtlasOffsetX { get; set; } = -3;
|
||||
public int AtlasOffsetY { get; set; } = -1;
|
||||
public int FontSize { get; set; } = 35;
|
||||
public bool BitmapFont { get; set; } = false;
|
||||
public float TexCoordOffset { get; set; } = 0.005f;
|
||||
|
||||
public void Save(string file) {
|
||||
string json = JsonSerializer.Serialize(this, new JsonSerializerOptions {WriteIndented = true});
|
||||
File.WriteAllText(file, json, Encoding.UTF8);
|
||||
}
|
||||
|
||||
public static TextSettings Load(string file) {
|
||||
string text = File.ReadAllText(file, Encoding.UTF8);
|
||||
return JsonSerializer.Deserialize<TextSettings>(text);
|
||||
}
|
||||
}
|
||||
|
||||
public class TextComponent : IComponent {
|
||||
|
||||
public static TextSettings CompileFont(string fontNameOrUrl, string output, TextSettings settings = null) {
|
||||
if (settings is null)
|
||||
settings = new TextSettings();
|
||||
|
||||
int bitmapWidth = settings.GlyphsPerLine * settings.GlyphWidth;
|
||||
int bitmapHeight = settings.GlyphLineCount * settings.GlyphHeight;
|
||||
|
||||
using Bitmap texture = new Bitmap(bitmapWidth, bitmapHeight, PixelFormat.Format32bppArgb);
|
||||
Font font;
|
||||
if (File.Exists(fontNameOrUrl))
|
||||
{
|
||||
var collection = new PrivateFontCollection();
|
||||
collection.AddFontFile(fontNameOrUrl);
|
||||
var fontFamily = new FontFamily(Path.GetFileNameWithoutExtension(fontNameOrUrl), collection);
|
||||
font = new Font(fontFamily, settings.FontSize);
|
||||
}
|
||||
else {
|
||||
font = new Font(new FontFamily(fontNameOrUrl), settings.FontSize);
|
||||
}
|
||||
|
||||
using (var g = Graphics.FromImage(texture)) {
|
||||
if (settings.BitmapFont) {
|
||||
g.SmoothingMode = SmoothingMode.None;
|
||||
g.TextRenderingHint = TextRenderingHint.SingleBitPerPixel;
|
||||
}
|
||||
else {
|
||||
g.SmoothingMode = SmoothingMode.HighQuality;
|
||||
g.TextRenderingHint = TextRenderingHint.AntiAliasGridFit;
|
||||
}
|
||||
|
||||
for (int p = 0; p < settings.GlyphLineCount; p++) {
|
||||
for (int n = 0; n < settings.GlyphsPerLine; n++) {
|
||||
char c = (char)(n + p * settings.GlyphsPerLine);
|
||||
g.DrawString(c.ToString(), font, Brushes.White,
|
||||
n * settings.GlyphWidth + settings.AtlasOffsetX,
|
||||
p * settings.GlyphHeight + settings.AtlasOffsetY);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
texture.Save(output);
|
||||
|
||||
return settings;
|
||||
}
|
||||
|
||||
public string Text { get; set; }
|
||||
public Vector2 Size { get; private set; }
|
||||
|
||||
public Color TextColor { get; set; } = Color.White;
|
||||
private Shape Shape { get; set; }
|
||||
private Texture Texture { get; set; }
|
||||
private TextSettings Settings { get; set; }
|
||||
private string CurrentText { get; set; }
|
||||
|
||||
public TextComponent(string fontImage, string text, TextSettings settings = null, int renderingMode = GL_STATIC_DRAW) {
|
||||
Texture = new Texture(fontImage);
|
||||
Shape = new Shape(Shapes.Rectangle, renderingMode);
|
||||
Settings = settings is not null ? settings : new TextSettings();
|
||||
}
|
||||
|
||||
public void Load(GameObject thisObject) {
|
||||
Texture.Load();
|
||||
Shape.Load();
|
||||
}
|
||||
|
||||
public void Update(GameObject thisObject) {
|
||||
if (CurrentText == Text) return;
|
||||
CurrentText = Text;
|
||||
List<float> vertices = new List<float>();
|
||||
float x = 0;
|
||||
float y = 0;
|
||||
float uW = Settings.GlyphWidth / (float)Texture.Width;
|
||||
float vH = Settings.GlyphHeight / (float)Texture.Height;
|
||||
float w = Settings.GlyphWidth / (float)Settings.GlyphHeight;
|
||||
const float h = 1.0f;
|
||||
|
||||
for (int n = 0; n < Text.Length; n++) {
|
||||
char idx = Text[n];
|
||||
|
||||
if (idx == '\n') {
|
||||
y += 1;
|
||||
x = 0;
|
||||
continue;
|
||||
}
|
||||
if (idx == '\t') {
|
||||
x += (w + Settings.CharXSpacing) * 4;
|
||||
continue;
|
||||
}
|
||||
|
||||
float u = (idx % Settings.GlyphsPerLine) * uW + Settings.TexCoordOffset;
|
||||
float v = (idx / Settings.GlyphsPerLine) * vH + Settings.TexCoordOffset;
|
||||
|
||||
vertices.AddRange(new[] {
|
||||
x, y + h, TextColor.R, TextColor.G, TextColor.B, TextColor.A, u, v + vH,
|
||||
x + w, y + h, TextColor.R, TextColor.G, TextColor.B, TextColor.A, u + uW, v + vH,
|
||||
x, y, TextColor.R, TextColor.G, TextColor.B, TextColor.A, u, v,
|
||||
|
||||
x + w, y, TextColor.R, TextColor.G, TextColor.B, TextColor.A, u + uW, v,
|
||||
x + w, y + h, TextColor.R, TextColor.G, TextColor.B, TextColor.A, u + uW, v + vH,
|
||||
x, y, TextColor.R, TextColor.G, TextColor.B, TextColor.A, u, v
|
||||
});
|
||||
|
||||
x += w + Settings.CharXSpacing;
|
||||
}
|
||||
|
||||
Shape.SetVertices(vertices.ToArray());
|
||||
Size = new Vector2(x, y);
|
||||
}
|
||||
|
||||
public void Destroy(GameObject thisObject) {
|
||||
Shape.Delete();
|
||||
Texture.Delete();
|
||||
}
|
||||
|
||||
public void Render(GameObject thisObject) {
|
||||
glEnable(GL_BLEND);
|
||||
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
|
||||
Texture.Use();
|
||||
|
||||
glBindVertexArray(Shape.Vao);
|
||||
glDrawArrays(GL_TRIANGLES, 0, Shape.GetVertexCount());
|
||||
glBindVertexArray(0);
|
||||
|
||||
glBindTexture(GL_TEXTURE_2D, 0);
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user