├── .github └── FUNDING.yml ├── LICENSE ├── README.md ├── TextBuffer.cs ├── font.png └── screenshots ├── a.png ├── b.png └── c.png /.github/FUNDING.yml: -------------------------------------------------------------------------------- 1 | # These are supported funding model platforms 2 | 3 | github: [ sbarisic ] 4 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | This is free and unencumbered software released into the public domain. 2 | 3 | Anyone is free to copy, modify, publish, use, compile, sell, or 4 | distribute this software, either in source code form or as a compiled 5 | binary, for any purpose, commercial or non-commercial, and by any 6 | means. 7 | 8 | In jurisdictions that recognize copyright laws, the author or authors 9 | of this software dedicate any and all copyright interest in the 10 | software to the public domain. We make this dedication for the benefit 11 | of the public at large and to the detriment of our heirs and 12 | successors. We intend this dedication to be an overt act of 13 | relinquishment in perpetuity of all present and future rights to this 14 | software under copyright law. 15 | 16 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 17 | EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 18 | MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. 19 | IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR 20 | OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, 21 | ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR 22 | OTHER DEALINGS IN THE SOFTWARE. 23 | 24 | For more information, please refer to 25 | 26 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # SFMLTextBuffer 2 | TextBuffers for SFML 3 | 4 | # Screenshots 5 | ![alt text](https://raw.githubusercontent.com/cartman300/SFMLTextBuffer/master/screenshots/a.png "Hello World!") 6 | 7 | ![alt text](https://raw.githubusercontent.com/cartman300/SFMLTextBuffer/master/screenshots/b.png "Colors") 8 | 9 | ![alt text](https://raw.githubusercontent.com/cartman300/SFMLTextBuffer/master/screenshots/c.png "More colors") 10 | 11 | # Example usage 12 | ```c# 13 | TextBuffer TBuffer = new TextBuffer(80, 25, new Texture("font.png")); 14 | TBuffer.Print(10, 10, "Hello World!"); 15 | // TBuffer.Sprite.* - Change position, color, whatever. 16 | 17 | RenderTarget.Draw(TBuffer); 18 | ``` 19 | 20 | # C++ version by harddal 21 | https://github.com/harddal/TextBuffer 22 | 23 | # License 24 | Do whatever you want etc. etc. 25 | -------------------------------------------------------------------------------- /TextBuffer.cs: -------------------------------------------------------------------------------- 1 | using SFML.Graphics; 2 | using SFML.System; 3 | 4 | namespace Graphics { 5 | struct TextBufferEntry { 6 | public char Char; 7 | public Color Fore, Back; 8 | 9 | public TextBufferEntry(char Char, Color Fore, Color Back) { 10 | this.Char = Char; 11 | this.Fore = Fore; 12 | this.Back = Back; 13 | } 14 | 15 | public TextBufferEntry(char Char) 16 | : this(Char, new Color(192, 192, 192), Color.Black) { 17 | } 18 | 19 | public TextBufferEntry(Color Fore, Color Back) 20 | : this((char)0, Fore, Back) { 21 | } 22 | 23 | public TextBufferEntry(Color Colors) 24 | : this(Colors, Colors) { 25 | } 26 | 27 | public static implicit operator char(TextBufferEntry E) { 28 | return E.Char; 29 | } 30 | 31 | public static implicit operator TextBufferEntry(char C) { 32 | return new TextBufferEntry(C); 33 | } 34 | 35 | public static implicit operator TextBufferEntry(byte B) { 36 | return (char)B; 37 | } 38 | } 39 | 40 | class TextBuffer : Drawable { 41 | const string TextBufferVert = @" 42 | #version 110 43 | 44 | void main() { 45 | gl_Position = gl_ModelViewProjectionMatrix * gl_Vertex; 46 | gl_TexCoord[0] = gl_TextureMatrix[0] * gl_MultiTexCoord0; 47 | gl_FrontColor = gl_Color; 48 | } 49 | "; 50 | 51 | const string TextBufferFrag = @" 52 | #version 120 53 | 54 | uniform sampler2D font; 55 | uniform sampler2D foredata; 56 | uniform sampler2D backdata; 57 | uniform vec2 buffersize; 58 | uniform vec4 fontsizes; 59 | 60 | void main() { 61 | vec4 fore = texture2D(foredata, gl_TexCoord[0].xy); 62 | vec4 back = texture2D(backdata, gl_TexCoord[0].xy); 63 | float chr = 255.0f * fore.a; 64 | 65 | vec2 fontpos = vec2(floor(mod(chr, fontsizes.z)) * fontsizes.x, floor(chr / fontsizes.w) * fontsizes.y); 66 | vec2 offset = vec2(mod(gl_TexCoord[0].x * (buffersize.x * fontsizes.x), fontsizes.x), 67 | mod(gl_TexCoord[0].y * (buffersize.y * fontsizes.y), fontsizes.y)); 68 | 69 | vec4 fontclr = texture2D(font, (fontpos + offset) / vec2(fontsizes.x * fontsizes.z, fontsizes.y * fontsizes.w)); 70 | gl_FragColor = mix(back, vec4(fore.rgb, 1.0f), fontclr.r); 71 | } 72 | "; 73 | static Shader TextBufferShader = null; 74 | 75 | public int BufferWidth { 76 | get { 77 | return W; 78 | } 79 | } 80 | 81 | public int BufferHeight { 82 | get { 83 | return H; 84 | } 85 | } 86 | 87 | public int CharWidth { 88 | get { 89 | return CharW; 90 | } 91 | } 92 | 93 | public int CharHeight { 94 | get { 95 | return CharH; 96 | } 97 | } 98 | 99 | public Sprite Sprite { 100 | get; 101 | private set; 102 | } 103 | 104 | int W, H, CharW, CharH; 105 | bool Dirty; 106 | RenderTexture RT; 107 | Vertex[] ScreenQuad; 108 | RenderStates TextStates; 109 | Texture ForeData, BackData, ASCIIFont; 110 | byte[] ForeDataRaw, BackDataRaw; 111 | 112 | public TextBuffer(uint W, uint H, Texture Fnt, int CharW = 8, int CharH = 12) { 113 | this.W = (int)W; 114 | this.H = (int)H; 115 | this.CharW = CharW; 116 | this.CharH = CharH; 117 | Dirty = true; 118 | 119 | SetFontTexture(Fnt); 120 | 121 | ForeDataRaw = new byte[W * H * 4]; 122 | ForeData = new Texture(new Image(W, H, ForeDataRaw)); 123 | ForeData.Smooth = false; 124 | BackDataRaw = new byte[W * H * 4]; 125 | BackData = new Texture(new Image(W, H, BackDataRaw)); 126 | BackData.Smooth = false; 127 | 128 | RT = new RenderTexture(W * (uint)CharW, H * (uint)CharH); 129 | RT.Texture.Smooth = true; 130 | Sprite = new Sprite(RT.Texture); 131 | if (TextBufferShader == null) 132 | TextBufferShader = Shader.FromString(TextBufferVert, TextBufferFrag); 133 | TextStates = new RenderStates(TextBufferShader); 134 | 135 | ScreenQuad = new Vertex[] { 136 | new Vertex(new Vector2f(0, 0), Color.White, new Vector2f(0, 0)), 137 | new Vertex(new Vector2f(RT.Size.X, 0), Color.White, new Vector2f(1, 0)), 138 | new Vertex(new Vector2f(RT.Size.X, RT.Size.Y), Color.White, new Vector2f(1, 1)), 139 | new Vertex(new Vector2f(0, RT.Size.Y), Color.White, new Vector2f(0, 1)), 140 | }; 141 | 142 | Clear(); 143 | } 144 | 145 | public void SetFontTexture(Texture Fnt) { 146 | ASCIIFont = Fnt; 147 | Dirty = true; 148 | } 149 | 150 | public void Set(int X, int Y, char C, Color Fg, Color Bg) { 151 | Set(Y * W + X, C, Fg, Bg); 152 | } 153 | 154 | public void Set(int X, int Y, Color Fg, Color Bg) { 155 | Set(Y * W + X, Fg, Bg); 156 | } 157 | 158 | public void Set(int Idx, Color Fg, Color Bg) { 159 | Idx *= 4; 160 | ForeDataRaw[Idx] = Fg.R; 161 | ForeDataRaw[Idx + 1] = Fg.G; 162 | ForeDataRaw[Idx + 2] = Fg.B; 163 | BackDataRaw[Idx] = Bg.R; 164 | BackDataRaw[Idx + 1] = Bg.G; 165 | BackDataRaw[Idx + 2] = Bg.B; 166 | BackDataRaw[Idx + 3] = Bg.A; 167 | Dirty = true; 168 | } 169 | 170 | public void Set(int Idx, char C, Color Fg, Color Bg) { 171 | Set(Idx, Fg, Bg); 172 | ForeDataRaw[Idx * 4 + 3] = (byte)C; 173 | Dirty = true; 174 | } 175 | 176 | public TextBufferEntry Get(int X, int Y) { 177 | return Get(Y * W + X); 178 | } 179 | 180 | public TextBufferEntry Get(int Idx) { 181 | Idx *= 4; 182 | return new TextBufferEntry((char)ForeDataRaw[Idx + 3], 183 | new Color(ForeDataRaw[Idx], ForeDataRaw[Idx + 1], ForeDataRaw[Idx + 2]), 184 | new Color(BackDataRaw[Idx], BackDataRaw[Idx + 1], BackDataRaw[Idx + 2], BackDataRaw[Idx + 3])); 185 | } 186 | 187 | public TextBufferEntry this[int Idx] { 188 | get { 189 | return Get(Idx); 190 | } 191 | set { 192 | Set(Idx, value.Char, value.Fore, value.Back); 193 | } 194 | } 195 | 196 | public TextBufferEntry this[int X, int Y] { 197 | get { 198 | return Get(X, Y); 199 | } 200 | set { 201 | Set(X, Y, value.Char, value.Fore, value.Back); 202 | } 203 | } 204 | 205 | public void Clear(char C = (char)0) { 206 | Clear(C, Color.White, Color.Black); 207 | } 208 | 209 | public void Clear(char C, Color Fg, Color Bg) { 210 | for (int i = 0; i < W * H; i++) 211 | Set(i, C, Fg, Bg); 212 | } 213 | 214 | public void Print(int X, int Y, string Str) { 215 | Print(Y * W + X, Str); 216 | } 217 | 218 | public void Print(int X, int Y, string Str, Color Fg, Color Bg) { 219 | Print(Y * W + X, Str, Fg, Bg); 220 | } 221 | 222 | public void Print(int I, string Str) { 223 | Print(I, Str, new Color(192, 192, 192), Color.Black); 224 | } 225 | 226 | public void Print(int I, string Str, Color Fg, Color Bg) { 227 | for (int i = 0; i < Str.Length; i++) 228 | Set(I + i, Str[i], Fg, Bg); 229 | } 230 | 231 | void Update() { 232 | if (!Dirty) 233 | return; 234 | Dirty = false; 235 | ForeData.Update(ForeDataRaw); 236 | BackData.Update(BackDataRaw); 237 | 238 | TextStates.Shader.SetParameter("font", ASCIIFont); 239 | TextStates.Shader.SetParameter("foredata", ForeData); 240 | TextStates.Shader.SetParameter("backdata", BackData); 241 | TextStates.Shader.SetParameter("buffersize", W, H); 242 | TextStates.Shader.SetParameter("fontsizes", CharW, CharH, ASCIIFont.Size.X / CharW, ASCIIFont.Size.Y / CharH); 243 | 244 | RT.Clear(Color.Transparent); 245 | RT.Draw(ScreenQuad, PrimitiveType.Quads, TextStates); 246 | RT.Display(); 247 | } 248 | 249 | public void Draw(RenderTarget R, RenderStates S) { 250 | Update(); 251 | Sprite.Draw(R, S); 252 | } 253 | } 254 | } 255 | -------------------------------------------------------------------------------- /font.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sbarisic/SFMLTextBuffer/3991d598600c1f2b25c40b14281aa78ac2f7fac0/font.png -------------------------------------------------------------------------------- /screenshots/a.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sbarisic/SFMLTextBuffer/3991d598600c1f2b25c40b14281aa78ac2f7fac0/screenshots/a.png -------------------------------------------------------------------------------- /screenshots/b.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sbarisic/SFMLTextBuffer/3991d598600c1f2b25c40b14281aa78ac2f7fac0/screenshots/b.png -------------------------------------------------------------------------------- /screenshots/c.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sbarisic/SFMLTextBuffer/3991d598600c1f2b25c40b14281aa78ac2f7fac0/screenshots/c.png --------------------------------------------------------------------------------