Hey folks!
It's just like the subject says; I've recently switched to 2.0 from 1.6 and I'm having an issue with loaded textures or images being the correct dimensions but a blank rectangle of white.
My code:
// TextureManager.h
#include "EngineComponents/TextureManager.h"
#include "DependantBase.h"
#include "MyException.h"
#include "StreamUtilities.h"
#include <SFML/Graphics/Texture.hpp>
#include <SFML/Graphics/Image.hpp>
std::ofstream TextureManager::log("logs/TextureManager.txt");
template<> TextureManager * TextureDependant::provider = NULL;
TextureManager::TextureManager(const std::string cfgPath) : textures(true)
{
log << "Texture/Image manager initializing, config path: " << cfgPath << std::endl;
std::ifstream file(cfgPath.c_str(), std::ios::binary);
if(!file)
{
log << "Error: could not load file: " << cfgPath << std::endl;
throw EngineException::fileNotFound;
}
std::string folderPath, extension;
StreamUtilities::Fetch<std::string>("folderPath", file, folderPath);
StreamUtilities::Fetch<std::string>("fileExtension", file, extension);
log << "Folder path: " << folderPath << "\nFile extension: " << extension << std::endl;
unsigned count = StreamUtilities::Count("image", file);
if(!count)
{
log << "Warning: No image tags found in file. Intended? (Probably not.)" << std::endl;
return;
}
std::string fileName;
for(unsigned i = 0; i < count; i++)
{
StreamUtilities::Fetch<std::string>("image", file, fileName);
StreamUtilities::Ignore("image", file);
sf::Texture * t = new sf::Texture;
if(!t->loadFromFile(folderPath + fileName + extension))
{
log << "Warning: unable to load file: " << folderPath << fileName << extension << std::endl;
delete t;
continue;
}
textures.Add(fileName, t);
}
log << "\nImage manager successfully initialized! Number of images loaded: " << textures.Size() << '\n' << std::endl;
}
TextureManager::~TextureManager()
{
log << "Image manager shutting down." << std::endl;
textures.Clean();
log << "Image manager freed memory; finished shutting down." << std::endl;
}
const sf::Texture * const TextureManager::Find(const std::string Name)
{
return static_cast<const sf::Texture*>(textures.Find(Name));
}
// Main.cpp
#include "Application.h"
#include "EngineComponents/TextureManager.h"
#include "DependantBase.h"
#include <fstream>
#include <SFML/Graphics.hpp>
int main()
{
Application app("config/Application.txt");
sf::Sprite s;
s.setTexture(*app.textures->Find(std::string("A")));
sf::RenderWindow window(sf::VideoMode(300, 200), "SFML works!");
while (window.isOpen())
{
sf::Event event;
while (window.pollEvent(event))
{
if (event.type == sf::Event::Closed)
window.close();
}
window.clear();
window.draw(s);
window.display();
}
return 0;
}
There are some parts there that don't make sense out of context; the Application class has a TextureManager* called textures. The TextureManager class has a PtrMap type I wrote that wraps the C++ list class; it's called textures and takes a bool on construction that determines whether the pointers should be deleted when the Manager goes out of scope.
I know that the textures' loadFromFile calls are returning true, so I don't know what's going on.
Hey folks!
It's just like the subject says; I've recently switched to 2.0 from 1.6 and I'm having an issue with loaded textures or images being the correct dimensions but a blank rectangle of white.
I know that the textures' loadFromFile calls are returning true, so I don't know what's going on.
A white rectangle normally means that the texture the sprite is pointing at doesn't exist.
It's hard to tell where the problem is since the provided code contains a lot of unrelated stuff and other important things are left out.
What many programmers make wrong is not keeping track of the used texture resource. I can reakky recommend to use smart pointers and RAII so you won't have to deal with the deletion of your allocated memory. Although it seems like it gets handled correctly.
At this line:
return static_cast<const sf::Texture*>(textures.Find(Name));
You're making a cast, do you just 'add' the cons
You should post more cod on the TextureManager, it seems like something is going wrong in there...
A white rectangle normally means that the texture the sprite is pointing at doesn't exist.
It's hard to tell where the problem is since the provided code contains a lot of unrelated stuff and other important things are left out.
What many programmers make wrong is not keeping track of the used texture resource. I can reakky recommend to use smart pointers and RAII so you won't have to deal with the deletion of your allocated memory. Although it seems like it gets handled correctly.
At this line:
return static_cast<const sf::Texture*>(textures.Find(Name));
You're making a cast, do you just 'add' the cons
You should post more cod on the TextureManager, it seems like something is going wrong in there...
That actually is all of the code for the TextureManager. Unless you want the header, in which case:
// TextureManager.h
#ifndef TextureManager_H_i
#define TextureManager_H_i
#include "PtrMap.h"
#include <fstream>
#include <string>
template<typename T> class DependantBase;
namespace sf
{
class Texture;
}
class TextureManager
{
private:
static std::ofstream log;
typedef PtrMap<sf::Texture> TextureMap;
TextureMap textures;
public:
TextureManager(const std::string cfgPath);
~TextureManager();
const sf::Texture * const Find(const std::string Name);
};
typedef DependantBase<TextureManager> TextureDependant;
#endif
Still lots of random stuff in there. Memory leaks aren't an issue though, take my word for it. PtrMap takes care of it in it's destructor; it deletes any pointers in the std::map that it wraps.
As for the white color, the sprite's size is being adjusted correctly; if the texture is 16x16, then the sprite is 16x16. It's just white, which is pretty irritating since it seems to be doing the other things correctly. It's just not reading the pixel data(apparently; I don't pretend to know how things work behind the scenes).
And yes, I just add the const :D
That wouldn't be the problem would it!?
I got it figured out. All it was:
/* From this: */
//...
Application app("config/Application.txt");
sf::RenderWindow window(sf::VideoMode(300, 200), "SFML works!");
/* To this: */
sf::RenderWindow window(sf::VideoMode(300, 200), "SFML works!");
Application app("config/Application.txt");
Nobody said OpenGL is initialized by creating a window ??? That's kind of irritating, but at least it wasn't anything wrong in my code.
SFML 1.6 has great tutorials, but 2.0's don't cover the whole API yet. This might be something to stick in there ;)