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

Author Topic: [SOLVED] unable to draw sf::Text - with BAD_ACCESS exception being raised  (Read 2922 times)

0 Members and 1 Guest are viewing this topic.

TheSpaceEvader

  • Newbie
  • *
  • Posts: 6
    • View Profile
    • Email
In an effort to refactor, I recently moved the majority of the code in my main method into it's own Game class. However, upon doing so I appear to have broken a number of my window.draw() statements, without having them give any particular error, but rather, raising a EXC_BAD_ACCESS (code: EXC_I386_GPFLT) exception when I step through them in debug. Further research (https://bit.ly/2tXDEV3) indicates that this could mean that I'm using a "non-canonical pointer", but I'm relatively new to C++ development so I would not know where to even begin with this?

main.cpp:
#include "Game.h"


Game *game = nullptr;

int main()
{
    game = new Game;

    game->setUp();
    game->update();

    return 0;
}

Game.h:
#include <SFML/Graphics.hpp>

class Game {
public:
    void setUp();
    void update();

private:
    sf::RenderWindow window;
    sf::Vector2u screenDimensions;
    sf::Sound music;
    sf::Text title, score;
    int textAlpha = 256, playerScore = 0;
    std::vector<Ring> rings;
    sf::View backgroundView, playerView;
    bool quitGame = false;

    void textSetUp(sf::Text &text, std::string string, sf::Font font, unsigned int characterSize, sf::Color fillColour, sf::Text::Style style, sf::Vector2f position);
    void textSetUp(sf::Text &text, std::string string, sf::Font font, unsigned int characterSize, sf::Color fillColour, sf::Text::Style style, sf::Vector2f position, sf::Color outlineColour, float outlineThickness);
};

Game.cpp:
#include "Game.h"

void Game::setUp() {
    screenDimensions.x = 1920;
    screenDimensions.y = 1280;

    // Window:
    window.create(sf::VideoMode(screenDimensions.x, screenDimensions.y), "Sk-iver", sf::Style::Titlebar | sf::Style::Close | sf::Style::Resize);
    window.setPosition(sf::Vector2i(200, 150));
    window.setKeyRepeatEnabled(false); // TODO investigate
    window.setVerticalSyncEnabled(true);
    window.setFramerateLimit(60);

    // Music:
    sf::SoundBuffer musicBuffer;
    if(!musicBuffer.loadFromFile("Resources/Sounds/nice_music.ogg"))
        std::cout << "ERROR: could not load audio file from file path" << std::endl;

    music.setBuffer(musicBuffer);
    music.setLoop(true);
    music.setVolume(20);
    music.play();

    // Title & Score Font assignment:
    sf::Font font;
    if(!font.loadFromFile("Font/Arial_Unicode.ttf"))
        std::cout << "ERROR: Could not load font file." << std::endl;

    // Title & Score Colour assignment:
    sf::Color scoreColour = titleColour = sf::Color::White;
    scoreColour.a = 150;

    // Title:
    std::string titleString = "Sk-iver";
    sf::Vector2f titlePosition((screenDimensions.x - title.getGlobalBounds().width) / 2,
                               (screenDimensions.y - title.getGlobalBounds().height) / 2);
    textSetUp(title, titleString, font, 500, titleColour, sf::Text::Bold, titlePosition);

    // Score:
    sf::Vector2f scorePosition(screenDimensions.x - score.getGlobalBounds().width, 0);
    textSetUp(score, std::to_string(playerScore), font, 80, scoreColour, sf::Text::Italic, scorePosition, sf::Color::Black, 5);

    // Background View:
    backgroundView.reset(sf::FloatRect(0, 0, screenDimensions.x, screenDimensions.y));
    backgroundView.setViewport(sf::FloatRect(0, 0, 1.0f, 1.0f));

    // Player View:
    playerView.reset(sf::FloatRect(0, 0, screenDimensions.x, screenDimensions.y));
    playerView.setViewport(sf::FloatRect(0, 0, 1.0f, 1.0f));
}

// text set up for title Text
void Game::textSetUp(sf::Text &text, std::string string, sf::Font font, unsigned int characterSize, sf::Color fillColour, sf::Text::Style style, sf::Vector2f position) {
    text.setString(string);
    text.setFont(font);
    text.setCharacterSize(characterSize);
    text.setFillColor(fillColour);
    text.setStyle(style);
    text.setPosition(position);
}

// text set up for score Text
void Game::textSetUp(sf::Text &text, std::string string, sf::Font font, unsigned int characterSize, sf::Color fillColour, sf::Text::Style style, sf::Vector2f position, sf::Color outlineColour, float outlineThickness) {
    text.setString(string);
    text.setFont(font);
    text.setCharacterSize(characterSize);
    text.setFillColor(fillColour);
    text.setStyle(style);
    text.setPosition(position);
    text.setOutlineColor(outlineColour);
    text.setOutlineThickness(outlineThickness);
}

void Game::update() {
    // todo find a more elegant solution for this
    Diver player = Diver(window.getSize());
    Background background = Background(window.getSize());

    while(!quitGame) // beginning of game loop
    {
        // Get player inputs:
        quitGame = HandleEvents(music, window);
       
        window.setView(backgroundView);

        // Background (update & draw):
        background.update();
        background.draw(window);

        // Rings (generate, update & draw):
        if (clock.getElapsedTime().asSeconds() > 9)
        {
            Ring ring = Ring(window.getSize());
            rings.emplace_back(ring);
            clock.restart();
        }

        // todo make two vectors, one for all rings where getStage()<= 1, and those that == 2
        for (auto &ring : rings)
        {
            if(ring.getStage() <= 1)
            {
                int tempScore = ring.update(player);

                // Score update
                if(tempScore)  // i.e. if tempScore != 0
                {
                    playerScore += tempScore;

                    score.setString(std::to_string(playerScore));
                    score.setPosition(screenDimensions.x - score.getGlobalBounds().width, 0);
                }

                ring.draw(window);
            }
        }

        // The Player (update & draw):
        window.setView(playerView);

        player.getInputs();
        frameCounter = player.update(clock, frameCounter, frameSpeed);
        player.draw(window);

        // slowly fades out title - todo: needs to be in it's own title object
        if (textAlpha > 5) // means that title is no longer drawn once no longer visible
        {
            if (clock.getElapsedTime().asSeconds() > 5)
            {
                titleColour.a = static_cast<sf::Uint8>(textAlpha--);
                title.setFillColor(titleColour);
            }

            window.draw(title);
        }
        else
        {
            window.draw(score);
        }

        window.display();
        window.clear();
    }
}
 

Note: music is also not working, which I have also not altered and believe may be related, but cannot prove this atm. Otherwise, most other sprites/shapes called in their own draw functions are drawing as normal.

Any help with this would be greatly GREATLY appreciated!
« Last Edit: July 02, 2018, 07:18:04 pm by TheSpaceEvader »

Arcade

  • Full Member
  • ***
  • Posts: 230
    • View Profile
Re: unable to draw sf::Text - with BAD_ACCESS exception being raised
« Reply #1 on: July 02, 2018, 05:24:09 pm »
From the SFML documentation of sf::Text::setFont()
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.

You are creating a sf::Font object locally in your Game::setUp() function. The font will go out of scope and be destroyed when that function ends. You will then get undefined behavior when you try to draw your text in Game::update().

Similarly, textures need to exist for as long as sprites use them and SoundBuffers need to exist for as long as sounds use them.

TheSpaceEvader

  • Newbie
  • *
  • Posts: 6
    • View Profile
    • Email
Re: unable to draw sf::Text - with BAD_ACCESS exception being raised
« Reply #2 on: July 02, 2018, 07:15:58 pm »
Yes, that was it! Thank you so so much, i've been banging my head against this for days now!  ;D