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

Author Topic: Inheriting from sf::Drawable  (Read 2209 times)

0 Members and 1 Guest are viewing this topic.

Muzinzafrika

  • Newbie
  • *
  • Posts: 4
    • View Profile
    • Email
Inheriting from sf::Drawable
« on: June 04, 2018, 12:36:29 am »
Hi,
I created a Button class which will make it easier to make clickable buttons and I wanted it to inherit from sf::Drawable so I could use the nice looking SFML interface and just write window.draw(button). My button is a Vertex Array, and when inside the draw function (which overrides the virtual one in sf::Drawable) i want to draw only the Vertex Array everything is fine. However, when I add a second line, in which I draw a text object on top of my Vertex Array, upon starting the whole window is white and closes after a few seconds. Is it possible to fix this so I can keep inheriting from sf::Drawable? To explain it better:

sf::Text text;
sf::VertexArray arr;
virtual void draw(sf::RenderTarget& target, sf::RenderStates states) const
    {
        target.draw(arr, states);
    }   -> no error
////
virtual void draw(sf::RenderTarget& target, sf::RenderStates states) const
    {
        target.draw(arr, states);
        target.draw(text);
    }   -> error

eXpl0it3r

  • SFML Team
  • Hero Member
  • *****
  • Posts: 11034
    • View Profile
    • development blog
    • Email
Re: Inheriting from sf::Drawable
« Reply #1 on: June 04, 2018, 07:07:01 am »
If it crashes what's the error/callstack?
If it just freezes, do you handle events?
Official FAQ: https://www.sfml-dev.org/faq.php
Official Discord Server: https://discord.gg/nr4X7Fh
——————————————————————
Dev Blog: https://duerrenberger.dev/blog/

Muzinzafrika

  • Newbie
  • *
  • Posts: 4
    • View Profile
    • Email
Re: Inheriting from sf::Drawable
« Reply #2 on: June 04, 2018, 11:17:40 pm »
Unfortunately I am not exactly advanced and don't know what you mean by error/callstack.
And yes, I do handle events. But it doesn't freeze - it opens a white window and crashes after about 2 seconds.

eXpl0it3r

  • SFML Team
  • Hero Member
  • *****
  • Posts: 11034
    • View Profile
    • development blog
    • Email
Re: Inheriting from sf::Drawable
« Reply #3 on: June 04, 2018, 11:35:43 pm »
Can you provide a complete but minimal code example that reproduces the issue? :)
Official FAQ: https://www.sfml-dev.org/faq.php
Official Discord Server: https://discord.gg/nr4X7Fh
——————————————————————
Dev Blog: https://duerrenberger.dev/blog/

Muzinzafrika

  • Newbie
  • *
  • Posts: 4
    • View Profile
    • Email
Re: Inheriting from sf::Drawable
« Reply #4 on: June 05, 2018, 10:35:08 pm »
#include <SFML/Graphics.hpp>
#include <iostream>
#include <string>
using namespace std;
class Button : public sf::Drawable
{
    sf::VertexArray arr;
    sf::Text text;
    sf::IntRect location;
    virtual void draw(sf::RenderTarget& target, sf::RenderStates states) const
    {
        target.draw(arr, states);
        target.draw(text);
    }
public:
    Button(const sf::Color& c1, const sf::Color& c2 ,
           const sf::Color& c3, const sf::Color& c4,
           const sf::IntRect rect, string displayedText)
    {
        arr=sf::VertexArray(sf::Quads, 4);
        arr[0].position={rect.left + rect.width, rect.top};
        arr[1].position={rect.left, rect.top};
        arr[2].position={rect.left, rect.top + rect.height};
        arr[3].position={rect.left + rect.width, rect.top + rect.height};
        arr[0].color=c1;
        arr[1].color=c2;
        arr[2].color=c3;
        arr[3].color=c4;
        location=rect;
        text.setString(displayedText);
        sf::Font font;
        if(!font.loadFromFile("Sanchezregular.otf"))
        {
            cout << "Loading font file failed";
            system("pause");
        }
        text.setFont(font);
        text.setColor(sf::Color::Red);
        text.setCharacterSize(location.height/5);
        text.setOrigin(sf::Vector2f(text.getGlobalBounds().left+text.getGlobalBounds().width/2,
                                    text.getGlobalBounds().top+text.getGlobalBounds().height/2));

    }
    //some more functions
};
int main()
{
    sf::RenderWindow window(sf::VideoMode(1280, 720), "BUG", sf::Style::Close);

    Button button(sf::Color(210, 210, 210), sf::Color(210, 210, 210),
                  sf::Color(110, 110, 110), sf::Color(110, 110, 110),
                  {400, 200, 300, 100}, "BUTTON");



    while (window.isOpen())
    {
        window.clear(sf::Color(98, 139, 135));
        sf::Event event;
        while (window.pollEvent(event))
        {
            switch(event.type)
            {
            case sf::Event::Closed:
                window.close();
                break;
            }
        }
        window.draw(button);
        window.display();
    }
}


It's funny because when I remove the while loop which is controlled by the pollevent function (so don't handle events) everything is drawn fine except the text and then it crashes when before a white screen appeared

Arcade

  • Full Member
  • ***
  • Posts: 230
    • View Profile
Re: Inheriting from sf::Drawable
« Reply #5 on: June 06, 2018, 12:31:15 am »
One problem your code has is that you are creating the sf::Font object locally in your constructor. The font will go out of scope and be destroyed when your constructor returns. The draw() function will then try to draw your text with a non-existent font.

From the SFML documentation:
Quote
The font argument refers to a font that must exist as long as the text uses it. Indeed, the text doesn't store its own copy of the font, but rather keeps a pointer to the one that you passed to this function. If the font is destroyed and the text tries to use it, the behavior is undefined.

Muzinzafrika

  • Newbie
  • *
  • Posts: 4
    • View Profile
    • Email
Re: Inheriting from sf::Drawable
« Reply #6 on: June 06, 2018, 09:51:43 pm »
Thank you so much!!! Everything works fine now! And all this trouble was caused by such a simple mistake... Guess I have a lot to learn :)