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

Author Topic: [Problem]: Disappearing Text upon Resize in a Debug Window  (Read 5635 times)

0 Members and 4 Guests are viewing this topic.

7krs

  • Newbie
  • *
  • Posts: 39
    • View Profile
    • Email
[Problem]: Disappearing Text upon Resize in a Debug Window
« on: August 19, 2012, 12:42:32 pm »
Hello again, I'm having some trouble with a resource class that contains a debug window with a fully functional scrolling system. It also adjusts itself to new screen (RenderWindow) sizes. Here's my problem and how to reproduce it:

[TO REPRODUCE] : Compile/Build/Run in either Debug or Release mode. Resize the window, again, and again... and sometimes, the text will completely disappear from the debug window. The scroll-bar will still be there tho. LaurentGomila-SFML-2b3d9bd (SFML-2.0 rc) used. Code Blocks 10.05 used. Win7 x86 used.

Normal:


Resized, this happens:


Here's the complete code:

//camelCase all the way!

#include <SFML/Graphics.hpp> //Obvious header
#include <string> //std::string
#include <iostream> //std::cin && std::cout
//#include <vector> //std::vector<type>
#include <cstdio> //std::getchar() (Just to pause an element, it's better than using std::cin >> to pause because you don't need to declare a variable)
#include <deque> //std::deque<type> (Stores sf::Text), I guess I should replace it with pointers to sf::Text)
#include <fstream> //std::ofstream
#include <sstream> //std::stringstream << number << string .str().c_str, used for log + number + .txt

/// A CLASS FOR COMPLETE RESOURCE CONTROL PER WINDOW:
/// resources.hpp
class resources
{
    ///Debugger information and methods:
    sf::RectangleShape debugBar; //The little scroll bar on the right side. Size_x = debugWindow.getSize().x/20?, size_y defined by amount of text. Can be modded to be click-drag-able
    std::deque<sf::Text> debugInfo; //push the front, pop the back.
    sf::RenderTexture debugWindow; //The actual window; size_x = window.getSize().x, size_y = window.getSize().y/3
    void debugUpdate(bool scrolled); //Called after ever << input, as well as scrollDebug
    void debugLog(); //Called if the size of debugInfo becomes too large, takes a chunk and puts it in a log file. File is cleaned on startup. File named after the instance-number of this class e.g.: "log2.txt"
    sf::Font debugFont;
    int debugCharacterSize, scroll;
    int debugThisInstance; //Based off the static debugInstance
    float debugTextsPerWindow, debugTextH, debugWindowY;
    static int debugInstance; //Used for the naming of logs
    bool debugVisible;
    ///Debugger information end.
    int windowSizeX, windowSizeY, windowBitsPerPixel;
    std::string windowTitle;
    sf::View view;
public:
    resources(); //Ctor initialized from the same folder the binaries are in. Currently replacement for dirty, quick initialization
    resources(std::string& rootFolder); //Ctor loads settings from a specific folder, that's how I'd like to handle different windows and their respective settings
    ~resources();
    void resize(); //Also modifies the debugging field
    ///To do with debugging:
    void operator << (std::string debugMessage); //Merely adds a message to the deque
    void operator << (const char * debugMessage);
    void debugScroll(bool upOrDown); //The boolean specifies up or down
    inline void debugDraw(); //Function assumes you have already cleared the window, and that you will display it afterwards. Should always be the last draw();
    void debugToggle();
    ///End of debugging specifications
    sf::Event event;
    sf::RenderWindow window;
};

/// resources.cpp
int resources::debugInstance = 0;

//Private member functions:
void resources::debugUpdate(bool scrolled = false)
{
    if (debugInfo.size() >= 100) //If the size is this large, it'll take a chunk of 20 items and store it, then continue
        debugLog();
    if (!scrolled)
        scroll = 0;
    debugWindow.clear(sf::Color(127,127,127,127));
    for (int i = scroll; i < debugInfo.size(); i++)
    {
        debugInfo[i].setPosition(0.f, (debugWindow.getSize().y - (debugInfo[(i)].getGlobalBounds().height+5)) - debugInfo[i].getGlobalBounds().height*(i-scroll));
        debugWindow.draw(debugInfo[(i)]);
    }
    debugBar.setSize(sf::Vector2f(debugBar.getSize().x, debugWindowY * (debugTextsPerWindow/debugInfo.size())));                                          ///sets a level of percentage, fully represents one screen
    debugBar.setPosition(sf::Vector2f(windowSizeX - debugBar.getGlobalBounds().width, (debugWindow.getSize().y - debugBar.getGlobalBounds().height) - (scroll/debugTextsPerWindow)*(debugBar.getGlobalBounds().height) )); ///Okay, so I can change position based on amount of texts and current scroll position.
    debugWindow.draw(debugBar);
    debugWindow.display();
}

void resources::debugLog() //Operation takes 4.2~0.x ms on a bad school-computer, 5200RPM HDD, 320GB
{
    std::stringstream filename;
    filename << "log" << debugThisInstance << ".txt";
    std::ofstream log(filename.str().c_str(), std::ios::app);
    if (log.is_open())
    {
        for (int i = debugInfo.size()-1; i > (debugInfo.size()-80) && i > 0; i--)
        {
            log << (std::string)debugInfo[i].getString() << '\n';
            debugInfo.pop_back();
        }
    }
    else
        std::cout << std::string("Error saving debug info to log file!\n");
        //If we were to do (*this) << "...", and the file could not be made/opened, we'd end up with a massive, recursive spam!
        //Eventually, the call stack would overflow, the program would terminate.
}

//Public member functions:
resources::resources()
{
    debugInstance++;
    debugThisInstance = debugInstance;
    debugCharacterSize = 10;
    scroll = 0;
    windowSizeX = 400;
    windowSizeY = 300;
    windowBitsPerPixel = 32;
    windowTitle = "Debugger Test!";
    ///DEBUGGER INFORMATION:
    debugFont.loadFromFile("visitor1.ttf"); //Quickly load a font file.
    debugWindow.create(windowSizeX, windowSizeY/3);
    debugWindow.clear(sf::Color(127,127,127,127));
    debugWindow.display();
    debugVisible = true;
    debugBar.setSize(sf::Vector2f(windowSizeX/50, 0));
    debugBar.setFillColor(sf::Color(180,180,180,127));
    debugWindowY = (float) debugWindow.getSize().y;
    *this << " Debugger initialization";
    debugTextH = (float) debugInfo[0].getGlobalBounds().height;
    debugTextsPerWindow = debugWindowY / debugTextH;
    debugUpdate();
    ///END DEBUGGER INFORMATION
    window.create(sf::VideoMode(windowSizeX,windowSizeY,windowBitsPerPixel),windowTitle.c_str(), sf::Style::Default);
}

resources::resources(std::string& rootFolder)
{
}

resources::~resources()
{
}

void resources::resize()
{
    windowSizeX = window.getSize().x;
    windowSizeY = window.getSize().y;
    view = sf::View(sf::FloatRect(0,0,windowSizeX, windowSizeY));
    window.setView(view);
    ///We need to re-initialize some parameters of the debug-texture:
    debugWindow.create(windowSizeX,windowSizeY/3);
    debugBar.setSize(sf::Vector2f(windowSizeX/50, 0));
    debugWindowY = (float) debugWindow.getSize().y;
    debugTextH = (float) debugInfo[0].getGlobalBounds().height;
    debugTextsPerWindow = debugWindowY / debugTextH;
    debugUpdate();
    std::stringstream windowSizes; windowSizes << " Window resized: " << windowSizeX << "x" << windowSizeY;
    *this << windowSizes.str();
}

//Operator << for the debug window
void resources::operator << (std::string debugMessage)
{
    debugInfo.push_front(sf::Text(debugMessage, debugFont, debugCharacterSize));
    debugUpdate();
}

void resources::operator << (const char * debugMessage)
{
    *this << std::string(debugMessage);
}

void resources::debugScroll(bool upOrDown = true)
{
    if (upOrDown && scroll < debugInfo.size()-debugTextsPerWindow && debugInfo.size() > debugTextsPerWindow)
        scroll++;
    else if (scroll > 0 && !upOrDown)
        scroll--;
    debugUpdate(true);
}

inline void resources::debugDraw()
{
    if (debugVisible)
        window.draw(sf::Sprite(debugWindow.getTexture()));
}

void resources::debugToggle()
{
    if (debugVisible)
        *this << " Closing debug window";
    else
        *this << " Opening debug window";
    debugVisible = !debugVisible;
}

/// RESOURCE CLASS.

int main()
{
    resources rsc;
    try
    {
        //A simple loop:
        while (true)
        {
            if (rsc.window.waitEvent(rsc.event))
            {
                switch (rsc.event.type)
                {
                    case sf::Event::Resized:
                        rsc.resize();
                        break;
                    case sf::Event::KeyPressed:
                        switch (rsc.event.key.code)
                        {
                            case sf::Keyboard::Escape:
                                return 0;
                            case sf::Keyboard::Insert:
                                rsc.debugToggle();
                                break;
                            case sf::Keyboard::O:
                                rsc.debugScroll();
                                break;
                            case sf::Keyboard::E:
                                rsc.debugScroll(false);
                                break;
                            case sf::Keyboard::Up:
                                rsc << " Up pressed";
                                break;
                            case sf::Keyboard::Down:
                                rsc << " Down pressed";
                                break;
                            case sf::Keyboard::Left:
                                rsc << " Left pressed";
                                break;
                            case sf::Keyboard::Right:
                                rsc << " Right pressed";
                                break;
                            default: rsc << " unknown button pressed"; break;
                        }
                        break;
                    case sf::Event::Closed:
                        return 0;
                    default: break;
                }
            }
            rsc.window.clear(sf::Color::Black);
            rsc.debugDraw();
            rsc.window.display();
        }
    }
    catch (const char * error)
    {
        std::cout << "Error: " << error << std::endl << "Press enter to exit.";
        std::getchar();
    }
    std::getchar();
    return 0;
}
 

http://fontgal.com/font/10468-visitor
is the font used.

Press 'O' to scroll up (Only works if there's more text than the window)
Press 'E' to scroll down.
Press any arrow key to lodge a respective message.
Insert toggles the debug window.
Press any other key to lodge a standard message.

I've spent several hours tracing it, I searched the web, this forum, no hits. So I am forced to ask it here. My apologies if the question is already answered and I didn't find it.
« Last Edit: August 19, 2012, 01:11:57 pm by 7krs »

eXpl0it3r

  • SFML Team
  • Hero Member
  • *****
  • Posts: 11032
    • View Profile
    • development blog
    • Email
Re: [Problem]: Disappearing Text upon Resize in a Debug Window
« Reply #1 on: August 19, 2012, 01:09:42 pm »
Unfortunatly I couldn't reproduce the problem. I've resized the window about 30 times and everything worked fine, except that I didn't see the 'scrollbar' you were talking about. How should this look like?

As for the code, since I can't reproduce it, it's impossible to debug and find the location on where things go south thus one would need to skim through the code and for that 241 lines are quite time consuming.
If you want help you should provide a minimal example, e.g. throw everything out that isn't really needed and always check if the problem still exists. If there's a point at which the code does produce the problem, then you might take a closer look at that piece and try to understand what goes wrong, with that you might be able to figure it out on your own. But if you don't understand it, then you can post that minimal and complete example that reproduces the problem here and we might look through the minimal code. ;)
Official FAQ: https://www.sfml-dev.org/faq.php
Official Discord Server: https://discord.gg/nr4X7Fh
——————————————————————
Dev Blog: https://duerrenberger.dev/blog/

7krs

  • Newbie
  • *
  • Posts: 39
    • View Profile
    • Email
Re: [Problem]: Disappearing Text upon Resize in a Debug Window
« Reply #2 on: August 19, 2012, 01:15:42 pm »
Thanks for your reply, exploit3r, but to me this is the minimal example (Since all of it is needed).
Have you added about 100 debug-lines? At that point it starts logging chunks of 20 lines at a time. Could you provide a picture where you couldn't see the bar? See the pictures I just posted, it is located on the right of the debug RenderTexture (The slightly darker grey bar).

Edit: Slightly LIGHTER grey bar.  :P
« Last Edit: August 19, 2012, 01:52:38 pm by 7krs »

eXpl0it3r

  • SFML Team
  • Hero Member
  • *****
  • Posts: 11032
    • View Profile
    • development blog
    • Email
Re: [Problem]: Disappearing Text upon Resize in a Debug Window
« Reply #3 on: August 19, 2012, 02:52:44 pm »
I noticed that the scrollbar is visible in the beginning and if I scroll up to the first entry I can also see it, but other than that it stays hidden (see attachment).
Yes I've added over 100 lines and everything was shown correctly.

Although you still could've reduced the code by throwing out the scrollbar and all the unnessecary stuff in the class (like operator <<) and just worked with texts, I've taken a look at the code.
You should allmost never need to use while(true), it's as bad of a design as using goto statements it's also much more likely to create endless loops...
Next thing I wonder is why you create two windows in your resource class?
I'm not sure if you have noticed this or if you understand what it does, you're using window.waitEvent() instead of pollEvent() thus nothing will happen on your window unless you trigger an event (MouseMove over the window, key pressed, window resized, etc). Is this intentional? I mean you then could only display something when an event is triggered on that window.

[attachment deleted by admin]
Official FAQ: https://www.sfml-dev.org/faq.php
Official Discord Server: https://discord.gg/nr4X7Fh
——————————————————————
Dev Blog: https://duerrenberger.dev/blog/

7krs

  • Newbie
  • *
  • Posts: 39
    • View Profile
    • Email
Re: [Problem]: Disappearing Text upon Resize in a Debug Window
« Reply #4 on: August 19, 2012, 03:07:34 pm »
You are not showing the entire window that contains the RenderWindow, so I can not see what you see.

You should allmost never need to use while(true), it's as bad of a design as using goto statements it's also much more likely to create endless loops...

I merely return 0; if something happens (like window is closed, or escape is pressed), do note that this is an example and I will not have this in my final product. It is simply used to test out this class.

Next thing I wonder is why you create two windows in your resource class?

I fail to spot this, I can only see one instance of sf::RenderWindow. Are you referring to sf::RenderTexture?

I'm not sure if you have noticed this or if you understand what it does, you're using window.waitEvent() instead of pollEvent() thus nothing will happen on your window unless you trigger an event (MouseMove over the window, key pressed, window resized, etc). Is this intentional? I mean you then could only display something when an event is triggered on that window.

Yes, the if (waitEvent()) is intentional for my menus, while (waitEvent()) would not work, as waitEvent() never returns false except for minimizing and maximizing. Why is this intentional? Because nothing really happens, music may play, but sfml creates its own thread regarding that, so I don't need to waste clock cycles on something redundant.

eXpl0it3r

  • SFML Team
  • Hero Member
  • *****
  • Posts: 11032
    • View Profile
    • development blog
    • Email
Re: [Problem]: Disappearing Text upon Resize in a Debug Window
« Reply #5 on: August 19, 2012, 03:33:48 pm »
You are not showing the entire window that contains the RenderWindow, so I can not see what you see.
Well there's nothing more to see, but I can gladly provide a full screenshot of the window. ;D

Do note that this is an example and I will not have this in my final product. It is simply used to test out this class.
Then it's okay to do so. ;)

I fail to spot this, I can only see one instance of sf::RenderWindow. Are you referring to sf::RenderTexture?
Haha, yeah my bad I was confused because they quite look a like from the class names and since you both call them 'window' it's also quite confusing. ;)

Yes, the if (waitEvent()) is intentional for my menus, while (waitEvent()) would not work, as waitEvent() never returns false except for minimizing and maximizing. Why is this intentional? Because nothing really happens, music may play, but sfml creates its own thread regarding that, so I don't need to waste clock cycles on something redundant.
I see. But keep in mind that it really will only show new texts when an input happens, thus you if you print out something that isn't directly connected to an event you might get a delay until a new event occurs.

Ah I now just saw the pictures (didn't show before) in your first post and I see that your scrollbar is located on the right, whereas I see the scrollbar in the beginning on the left (see picture).

[attachment deleted by admin]
Official FAQ: https://www.sfml-dev.org/faq.php
Official Discord Server: https://discord.gg/nr4X7Fh
——————————————————————
Dev Blog: https://duerrenberger.dev/blog/

7krs

  • Newbie
  • *
  • Posts: 39
    • View Profile
    • Email
Re: [Problem]: Disappearing Text upon Resize in a Debug Window
« Reply #6 on: August 19, 2012, 03:47:37 pm »
I see. But keep in mind that it really will only show new texts when an input happens, thus you if you print out something that isn't directly connected to an event you might get a delay until a new event occurs.

Aaahh, I know what you mean.

   
window.clear();
debugDraw();
window.display();
 

added to debugUpdate(bool); thanks, useful if a message is lodged without any event to trigger it.
However, the problem of disappearing texts still persists.

Ah I now just saw the pictures (didn't show before) in your first post and I see that your scrollbar is located on the right, whereas I see the scrollbar in the beginning on the left (see picture).

Maybe there is something wrong with your debugUpdate(bool) function. I shall re-paste it here:
Edit: I edited the first post to include the pictures. So it's not your fault for not spotting them.

void resources::debugUpdate(bool debugScrolled = false)
{
    if (debugInfo.size() >= 100) //If the size is this large, it'll take a chunk of 20 items and store it, then continue
        debugLog();
    if (!debugScrolled)
        debugScroll = 0;
    debugWindow.clear(sf::Color(127,127,127,127));
    for (int i = debugScroll; i < debugInfo.size(); i++)
    {
        debugInfo[i].setPosition(0.f, (debugWindow.getSize().y - (debugInfo[(i)].getGlobalBounds().height+5)) - debugInfo[i].getGlobalBounds().height*(i-debugScroll));
        debugWindow.draw(debugInfo[(i)]);
    }
    debugBar.setSize(sf::Vector2f(debugBar.getSize().x, debugWindowY * (debugTextsPerWindow/debugInfo.size())));                                          ///sets a level of percentage, fully represents one screen
    debugBar.setPosition(sf::Vector2f(windowSizeX - debugBar.getGlobalBounds().width, (debugWindow.getSize().y - debugBar.getGlobalBounds().height) - (debugScroll/debugTextsPerWindow)*(debugBar.getGlobalBounds().height) )); ///Okay, so I can change position based on amount of texts and current debugScroll position.
    debugWindow.draw(debugBar);
    debugWindow.display();
    window.clear();
    debugDraw();
    window.display();
}
 

If you care to help me finding out why the debugBar doesn't show correctly with you I'd be grateful. (I'd like this to work on different computers).
« Last Edit: August 19, 2012, 03:54:38 pm by 7krs »

7krs

  • Newbie
  • *
  • Posts: 39
    • View Profile
    • Email
Re: [Problem]: Disappearing Text upon Resize in a Debug Window
« Reply #7 on: August 23, 2012, 12:06:07 am »
I'm back with the absolute minimum, but complete example that reproduces the issue.

#include <SFML/Graphics.hpp>

int main()
{
    sf::RenderWindow window;
    window.create(sf::VideoMode(400,300,32), "Test", sf::Style::Default);
    sf::Event event;
    sf::RenderTexture rt;
    sf::Sprite sp;
    sf::Font font;
    font.loadFromFile("visitor1.ttf");
    rt.create(window.getSize().x, window.getSize().y/3.f);
    rt.clear(sf::Color(127,127,127,127));
    sp.setTexture(rt.getTexture(), true);
    sf::Text text;
    text.setString(" Initialization Complete");
    text.setFont(font);
    rt.draw(text);
    rt.display();
    sf::View view;
    while (window.isOpen())
    {
        while (window.pollEvent(event))
        {
            switch (event.type)
            {
                case sf::Event::KeyPressed:
                    window.setSize(sf::Vector2u(std::rand()%1166+200, std::rand()%618+150));
                    view.setSize(window.getSize().x, window.getSize().y);
                    view.setCenter(window.getSize().x/2.f, window.getSize().y/2.f);
                    window.setView(view);
                    rt.create(window.getSize().x, window.getSize().y/3.f);
                    rt.clear(sf::Color(127,127,127,127));
                    rt.draw(text);
                    rt.display();
                    sp.setTexture(rt.getTexture(), true);
                    break;
                case sf::Event::Closed:
                    window.close();
                    return 0;
                default: break;
            }
        }
        window.clear();
        window.draw(sp);
        window.display();
    }
    return 0;
}
 

Doesn't matter if you use waitEvent, or set a framerateLimit(), if or while for the event loop. It will always, out of complete randomness, after having resized quickly or slowly (the input per second), regardless of specific window size, regardless of manually resizing with the mouse (you gotta have an event, I deleted the mouse event because it's not necessary) or with an in-game event, the text will sometimes simply not appear in the RenderTexture.

Try adding an sf::CircleShape, and draw it into the RenderTexture at resize, the circle will be present even if the text disappears.

I have updated SFML-2.0 to the latest release candidate: "LaurentGomila-SFML-757a785" 22.08.2012 UCT+1 @ 10PM.

eXpl0it3r

  • SFML Team
  • Hero Member
  • *****
  • Posts: 11032
    • View Profile
    • development blog
    • Email
Re: [Problem]: Disappearing Text upon Resize in a Debug Window
« Reply #8 on: August 23, 2012, 02:17:07 am »
Well I still don't have such a problem; I can resize the window as much as I want but the text never disappears... :-\

What graphics card are you using? Is your driver up to date?
Official FAQ: https://www.sfml-dev.org/faq.php
Official Discord Server: https://discord.gg/nr4X7Fh
——————————————————————
Dev Blog: https://duerrenberger.dev/blog/

7krs

  • Newbie
  • *
  • Posts: 39
    • View Profile
    • Email
Re: [Problem]: Disappearing Text upon Resize in a Debug Window
« Reply #9 on: August 23, 2012, 07:43:33 am »
"ATI Radeon HD 3200 Graphics"

Under windows 7 device manager.

"Windows has determined the driver software for your device is up to date."