Welcome, Guest. Please login or register. Did you miss your activation email?

Author Topic: Text render issue  (Read 9693 times)

0 Members and 1 Guest are viewing this topic.

Gleade

  • Jr. Member
  • **
  • Posts: 55
    • View Profile
Text render issue
« on: October 11, 2018, 02:45:28 am »
Hi,

Version: .NET 2.4

I'm trying to simply draw text and I'm wondering if anyone else is experiencing this issue. The issue is that the text isn't displaying correctly, it's missing characters and has strange gaps in between characters.
What is interesting is I'm getting similar but different results per-run of my application. I have not attempted to replicate the problem, but I will if no one else has or is experiencing this issue.

Trying to draw "Loading: 100%"
Run 1 (Notice the huge gap):

Run 2 (Notice the missing "1"):


Trying to draw "Hello, World" (Not sure what's going on here):

Antonio9227

  • Newbie
  • *
  • Posts: 25
    • View Profile
Re: Text render issue
« Reply #1 on: October 11, 2018, 03:53:16 pm »
Can you post a snippet of your code please? I haven't experienced anything like this when working with text objects and it seems interesting.

Gleade

  • Jr. Member
  • **
  • Posts: 55
    • View Profile
Re: Text render issue
« Reply #2 on: October 11, 2018, 11:24:05 pm »
Hello,

Thank you for your interest. Ive created an engine and it wraps alot of sfml's functionality. I'm at work at the moment, but I'll happily try and recreate what I'm doing in my engine in a complete minimal example afterwards.

Gleade

  • Jr. Member
  • **
  • Posts: 55
    • View Profile
Re: Text render issue
« Reply #3 on: October 12, 2018, 12:13:14 pm »
I think I found the problem, I'm loading the font from a resource (as byte data). The problem does not occur if I load the font from a local file. Also note: It only appears to occur if the text is changing.

Code below that reproduces my bug:

Code: [Select]
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using SFML;
using SFML.Graphics;

namespace MInimalExample
{
    class Program
    {
            static void Main(string[] args)
            {
                Console.WriteLine("Press ESC key to close window");
                var window = new SimpleWindow();
                window.Run();

                Console.WriteLine("All done");
            }

    }

    class SimpleWindow
    {
        public void Run()
        {
            Font font = new Font(Properties.Resources.FLAPHEAD);

            Text text = new Text("Hello, World", font);

            var mode = new SFML.Window.VideoMode(800, 600);
            var window = new SFML.Graphics.RenderWindow(mode, "SFML works!");
            window.Closed += Window_Closed;


            // Start the game loop
            while (window.IsOpen)
            {
                window.Clear();
                // Process events
                window.DispatchEvents();

                text.DisplayedString = $"Hi {DateTime.Now}";

                window.Draw(text);

                // Finally, display the rendered frame on screen
                window.Display();
            }
        }

        private void Window_Closed(object sender, EventArgs e)
        {
            var window = (SFML.Window.Window)sender;
                window.Close();
        }

    }
}


Laurent

  • Administrator
  • Hero Member
  • *****
  • Posts: 32504
    • View Profile
    • SFML's website
    • Email
Re: Text render issue
« Reply #4 on: October 12, 2018, 12:52:23 pm »
This problem may occur if the byte[] data is destroyed while the font is still being used by one or more Text instances.

The Font class itself doesn't ensure that the given byte array remains in memory (ie. it doesn't keep a reference to it), so is it possible that your Properties.Resources.FLAPHEAD array gets destroyed somehow?
Laurent Gomila - SFML developer

Gleade

  • Jr. Member
  • **
  • Posts: 55
    • View Profile
Re: Text render issue
« Reply #5 on: October 12, 2018, 02:45:15 pm »
Interestingly enough, if I just load from local file into a byte array, I get the same result. You can clearly see the scope in this example.

Code: [Select]
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using SFML;
using SFML.Graphics;

namespace MInimalExample
{
    class Program
    {
            static void Main(string[] args)
            {
                Console.WriteLine("Press ESC key to close window");
                var window = new SimpleWindow();
                window.Run();

                Console.WriteLine("All done");
            }

    }

    class SimpleWindow
    {
        public void Run()
        {
            byte[] bytes = System.IO.File.ReadAllBytes("FLAPHEAD.TTF");
            Font font = new Font(bytes);

            Text text = new Text("Hello, World", font);

            var mode = new SFML.Window.VideoMode(800, 600);
            var window = new SFML.Graphics.RenderWindow(mode, "SFML works!");
            window.Closed += Window_Closed;


            // Start the game loop
            while (window.IsOpen)
            {
                window.Clear();
                // Process events
                window.DispatchEvents();

                text.DisplayedString = $"Hi {DateTime.Now}";

                window.Draw(text);

                // Finally, display the rendered frame on screen
                window.Display();
            }
        }

        private void Window_Closed(object sender, EventArgs e)
        {
            var window = (SFML.Window.Window)sender;
                window.Close();
        }

    }
}


FRex

  • Hero Member
  • *****
  • Posts: 1848
  • Back to C++ gamedev with SFML in May 2023
    • View Profile
    • Email
Re: Text render issue
« Reply #6 on: October 12, 2018, 03:43:02 pm »
https://github.com/SFML/SFML.Net/blob/master/src/Graphics/Font.cs
public Font(byte[] bytes) : base(IntPtr.Zero)
{
    GCHandle pin = GCHandle.Alloc(bytes, GCHandleType.Pinned);
    try
    {
        CPointer = sfFont_createFromMemory(pin.AddrOfPinnedObject(), Convert.ToUInt64(bytes.Length));
    }
    finally
    {
        pin.Free();
    }
    if (CPointer == IntPtr.Zero)
    {
        throw new LoadingFailedException("font");
    }
}

Doesn't that code pin the byte array (to allow taking it's address), open and then (no matter what since it's in a finally block) unpin it, leaving it free to be moved by the GC when it compacts the heap?
Back to C++ gamedev with SFML in May 2023

Laurent

  • Administrator
  • Hero Member
  • *****
  • Posts: 32504
    • View Profile
    • SFML's website
    • Email
Re: Text render issue
« Reply #7 on: October 12, 2018, 03:51:11 pm »
Quote
Doesn't that code pin the byte array (to allow taking it's address), open and then (no matter what since it's in a finally block) unpin it, leaving it free to be moved by the GC when it compacts the heap?
I guess this is a possible explanation. Unfortunately I don't have a deep understanding of what happens here with memory.
Laurent Gomila - SFML developer

FRex

  • Hero Member
  • *****
  • Posts: 1848
  • Back to C++ gamedev with SFML in May 2023
    • View Profile
    • Email
Re: Text render issue
« Reply #8 on: October 12, 2018, 03:57:20 pm »
This is what the description of that option sounds like: https://docs.microsoft.com/en-us/dotnet/api/system.runtime.interopservices.gchandletype?view=netframework-4.7.2

It also makes sense for why that constructor makes a 'bad' Font object no matter where the bytes[] comes from and why pinning is a thing.

Can be easily checked too I guess? Pin the bytes[] and print its address from time to time then free it (the GC pin handle) instantly, then bugs should start once new glyps and info is read after a GC move?
« Last Edit: October 12, 2018, 04:24:23 pm by FRex »
Back to C++ gamedev with SFML in May 2023

Gleade

  • Jr. Member
  • **
  • Posts: 55
    • View Profile
Re: Text render issue
« Reply #9 on: October 13, 2018, 01:21:12 am »
Thanks for that FRex, that looks to be the case. For a work-around, I can confirm that you can use streams instead (FileStream / MemoryStream).

« Last Edit: October 13, 2018, 01:26:13 am by Gleade »

FRex

  • Hero Member
  • *****
  • Posts: 1848
  • Back to C++ gamedev with SFML in May 2023
    • View Profile
    • Email
Re: Text render issue
« Reply #10 on: October 19, 2018, 11:20:04 pm »
Should I open an issue about this, Laurent?
Back to C++ gamedev with SFML in May 2023

eXpl0it3r

  • SFML Team
  • Hero Member
  • *****
  • Posts: 11002
    • View Profile
    • development blog
    • Email
Re: Text render issue
« Reply #11 on: October 20, 2018, 01:40:03 am »
Sure :)
Official FAQ: https://www.sfml-dev.org/faq.php
Official Discord Server: https://discord.gg/nr4X7Fh
——————————————————————
Dev Blog: https://duerrenberger.dev/blog/

FRex

  • Hero Member
  • *****
  • Posts: 1848
  • Back to C++ gamedev with SFML in May 2023
    • View Profile
    • Email
Re: Text render issue
« Reply #12 on: October 20, 2018, 01:54:35 am »
Back to C++ gamedev with SFML in May 2023