SFML community forums

Help => General => Topic started by: Kestis on January 15, 2018, 10:07:37 pm

Title: Declaring sf::Font and sf::Color in a header
Post by: Kestis on January 15, 2018, 10:07:37 pm
I needed a way to easily use same font and colors throughout my UI. Every UI component like button or textbox has its own class with render function. At first I made the fonts and colors as parameters of the render function but it seemed stupid to include them in every single one function call. Therefore I made a header which declares them:
#pragma once
#include <SFML\Graphics.hpp>

extern sf::Color baseColor;
extern sf::Color darkAccent;
extern sf::Color lightAccent;
extern sf::Color colorAccent;

extern sf::Font baseUiFont;
The header is included in every .cpp file that needs the variables.

Then I define them in the beginning of my main() like so:
sf::Color baseColor(50, 50, 50);
sf::Color darkAccent(30, 30, 30);
sf::Color lighAccent(70, 70, 70);
sf::Color colorAccent(255, 140, 0);

sf::Font baseUiFont;
baseUiFont.loadFromFile("Resources/OpenSans-Regular.ttf");
The problem is that this does not work. I get two errors:
Error   LNK2001 unresolved external symbol "class sf::Color baseColor" (?baseColor@@3VColor@sf@@A)
Error   LNK1120 1 unresolved externals
I tested similar declaration and definition of a simple int variable and it did work. Therefore I think that the problem is in the way SFML works. Is there a solution to this? All I need is a simple way to pass these variables to every object that needs them.
Title: Re: Declaring sf::Font and sf::Color in a header
Post by: FRex on January 15, 2018, 11:20:21 pm
To define a global like that it has to be in a single cpp file outside of any function, it's not SFML specific. It's also bad and possibly breaking to use some SFML classes globally because they internally touch GL (Color doesn't but Font does) and that can break things up or cause errors during global clean up when program exits.
Title: Re: Declaring sf::Font and sf::Color in a header
Post by: eXpl0it3r on January 15, 2018, 11:27:42 pm
You can't have global initialized SFML resources.
Title: Re: Declaring sf::Font and sf::Color in a header
Post by: Phanoo on January 16, 2018, 11:14:15 am
you can wrap them in a struct:

In some 'globals.h' file
typedef struct ui{
struct color{
sf::Color base;
sf::Color darkAccent;
sf::Color lightAccent;
sf::Color accent;
}color;
sf::Font font;
};

extern struct ui;
 

In a cpp file:
struct ui;

void initialize(){
// init the ui...
}
 

Then initialize it somewhere in your application (in the main if it's a very small app that doesn't need better organization).

Globals aren't a bad if they are used for global things... just group them into structs or classes to avoid too much 'extern' keywords
Title: Re: Declaring sf::Font and sf::Color in a header
Post by: dmitry_t on February 16, 2018, 07:46:47 am
Quote
Then I define them in the beginning of my main() like so:
Since the variables are defined inside a function, they are not global. So they are not visible outside of the main() function.
Put the definitions at the .cpp file level to make them accessible through 'external' declarations.
Title: Re: Declaring sf::Font and sf::Color in a header
Post by: Hapax on February 17, 2018, 03:44:58 pm
Globals aren't a bad if they are used for global things... just group them into structs or classes to avoid too much 'extern' keywords
You can't have global initialized SFML resources.