Reputation:
Houston, we have a problem. Here's a simplified code version:
main.cpp
#include <SFML/Graphics.hpp>
#include "global.hpp"
#include "init.hpp"
int main(void)
{
createWindow();
loadLevel();
while(window.isOpen())
{
if(!handleEvents()) window.close();
window.clear();
window.draw(bgSprite);
window.display();
}
return 0;
}
global.hpp
sf::Texture bgTexture;
sf::Sprite bgSprite;
init.hpp
void loadGraphics(void)
{
bgTexture.loadFromFile("bg.png");
bgSprite.setTexture(bgTexture);
}
Even though the texture and sprite variables are global, window screen remains black. However, when I put the variables inside the main() function, everything works perfectly. Could someone explain why is this happening?
I thought that you can call global variables whenever and wherever you wish, and they will disappear only when the program itself terminates.
By the way, I also tried putting the variables and loadGraphics() right behind main() (not in a header file), still, no results. I also commented out all additional code, so the problem definitely lies here.
I didn't call the loadGraphics(function). Thank You! I'm sorry for your wasted time. Everything started working correctly. Sad lol - spent over 1 hour fixing this thing...
Upvotes: 0
Views: 653
Reputation: 254461
You never call loadGraphics
. Call that at the start of main
, and your program will probably work.
But you'd almost certainly be better off without globals; and in any case, you don't want to define them in a header since that will break the One Definition Rule if you include that header more than once in your program.
If you really do want them to be global, then declare them (without definining them) in the header:
extern sf::Texture bgTexture;
and define them (as you've done) in just one source file.
Likewise, you shouldn't define a non-inline function in a header for the same reason. Either leave it in the header and make it inline:
inline void loadGraphics() // void parameter is pointless
{
bgTexture.loadFromFile("bg.png");
bgSprite.setTexture(bgTexture);
}
or just declare it in the header
void loadGraphics();
and move your definition into a source file.
You might avoid globals by encapsulating them in a class:
struct Graphics {
Graphics(std::string file) {
texture.loadFromFile(file);
sprite.setTexture(texture);
}
sf::Texture texture;
sf::Sprite sprite;
};
and instantiating this in main
Graphics graphics("bg.png");
//...
window.draw(graphics.sprite);
Upvotes: 4
Reputation: 3209
When you place a variable global to a project, you need to place it in a .cpp file and make a .h which declares it as extern. This allows for all the files to refer to the same global variable.
In your case, you'd change the code as so:
global.hpp
extern sf::Texture bgTexture;
extern sf::Sprite bgSprite;
global.cpp
sf::Texture bgTexture;
sf::Sprite bgSprite;
Also, as in Mike's answer, you never call loadGraphics()
.
Personally, I'd put that in another .cpp file and put a .hpp file with the prototype.
Also, when compiling, you'll have to compile all the cpp files together into a single executable (i.e. link them together)
Upvotes: 2
Reputation: 8066
bgTexture
and bgSprite
are never set. I don't see any call to your loadGraphics
function in the main
.
You should start by calling your loadGraphics
function
Upvotes: 0