-
Bonjour,
J'ai une petit soucis au niveau du chargement d'une texture, lorsque je fais :
loadFromFile("leChemin.png");
Dans tout mon projet tout va bien, mais lorsque ce que j’essaie de charger une texture de 1280x3136 on me renvoi cette erreur dans la console :
(http://s7.postimage.org/jcagg1csb/erreur_sfml.png)
A priori je sais lire, je me dit que il n'est pas possible de charger une texture d'une taille aussi grande, mais premièrement ce soucis arrive uniquement sur le PC de mon travail (carte graphique intégré Intel, je suppose que le problème viens de la... alors que sur mon PC de domicile, aucun problème (nVidia)) et deuxièmement en aucun cas, je n’essaie de charger une texture de 2048x4092 comme le message l'indique.
Voila, je vous remercie d'avance pour votre aide.
Cordialement.
-
Cette limite est propre à chaque carte graphique en effet, et tu vois 4096 car SFML est obligé d'arrondir à la puissance de 2 supérieure (toujours à cause de la carte graphique).
-
Donc en gros, je doit découper ma texture en plusieurs petits morceaux pour que mon jeu puisse être utilisé sur toutes les machines ? :-\
Comment savoir quel tailles est prise en charge par toutes les CG ?
Merci de ta réponse,
Cordialement.
-
Tu n'es pas obligé de prédécouper tes images, tu peux les charger dans des sf::Image (là tu n'as aucune restriction de taille) puis découper en autant de sf::Texture qu'il faut, selon la valeur renvoyée par sf::Texture::getMaximumSize().
Note que tu peux utiliser la bibliothèque Thor, qui possède des classes BigSprite et BigTexture qui font ce boulot automatiquement pour toi.
-
Merci beaucoup Laurent, et sinon, le sf::Texture::getMaximumSize() sera toujours un multiple de 32 ?
-
sf::Texture::getMaximumSize() sera toujours un multiple de 32 ?
Ce sera toujours une puissance de 2, donc oui.
-
J'ai tenté de faire le découpage précédemment recommandé.
Hors je n'arrive pas affiché la texture découpé... Hors j'ai bien vérifié avec un saveToFile() pour voir que je découpe correctement. Je ne vois pas ou est ma stupide erreur ???
J'ai fais un projet au code minimal,
Voici le code :
#include <SFML/Graphics.hpp>
#include <iostream>
std::vector<sf::Texture*>* decoupageTilesetEnTexture(sf::Image *img);
int main()
{
sf::Image img;
if (img.loadFromFile("tileset.jpg"))
{
std::vector<sf::Texture*> *listeTexture = decoupageTilesetEnTexture(&img);
std::cout << "nbDeTexture = " << listeTexture->size() << std::endl;
sf::RenderWindow window(sf::VideoMode(500, 500), "SFML works!");
while (window.isOpen())
{
sf::Event event;
while (window.pollEvent(event))
{
if (event.type == sf::Event::Closed)
window.close();
}
window.clear();
sf::Sprite* sprite = new sf::Sprite(*(listeTexture->at(0)));
window.draw(*sprite);
window.display();
delete sprite;
}
}
return 0;
}
std::vector<sf::Texture*>* decoupageTilesetEnTexture(sf::Image *img)
{
unsigned int nb_tour_x = img->getSize().x/sf::Texture::getMaximumSize();
unsigned int nb_tour_y = img->getSize().y/sf::Texture::getMaximumSize();
unsigned int maximum_size_x;
unsigned int maximum_size_y;
if (sf::Texture::getMaximumSize() > img->getSize().x)
{
maximum_size_x = img->getSize().x;
}
else
{
maximum_size_x = sf::Texture::getMaximumSize();
}
if (sf::Texture::getMaximumSize() > img->getSize().y)
{
maximum_size_y = img->getSize().y;
}
else
{
maximum_size_y = sf::Texture::getMaximumSize();
}
std::vector<sf::Texture*> *listeTexture = new std::vector<sf::Texture*>();
//std::string var;
for (unsigned int x = 0; x<=nb_tour_x; x++)
{
for (unsigned int y = 0; y<=nb_tour_y; y++)
{
sf::Image newImg;
unsigned int offset_x = maximum_size_x*x;
unsigned int offset_y = maximum_size_y*y;
unsigned int size_x = maximum_size_x;
unsigned int size_y = maximum_size_y;
if ((offset_x+maximum_size_x) > img->getSize().x)
{
size_x = img->getSize().x-offset_x;
}
if ((offset_y+maximum_size_y) > img->getSize().y)
{
size_y = img->getSize().y-offset_y;
}
newImg.create(size_x, size_y, sf::Color::Blue);
//newImg.copy(*img, 0, 0, sf::IntRect(offset_x, offset_y, offset_x+size_x, offset_y+size_y));
//var+= "+";
//newImg.saveToFile(var+"test.png");
sf::Texture *texture = new sf::Texture();
texture->loadFromImage(newImg, sf::IntRect(0,0,size_x, size_y));
listeTexture->push_back(texture);
}
}
return listeTexture;
}
Merci a ceux qui prendrons la peine de regardé mon code,
Cordialement.
-
newImg.create(size_x, size_y, sf::Color::Blue);
texture->loadFromImage(newImg, sf::IntRect(0,0,size_x, size_y));
Là tu crées une nouvelle image vide, et tu charges la texture depuis celle-ci. Normal que la texture soit tout aussi vide.
Je ne comprends pas pourquoi tu veux créer une image intermédiaire, il n'y a qu'à ajuster correctement le second paramètre de loadFromImage (le rectangle à charger).
-
Merci Laurent, effectivement c’était stupide ;D
Cependant, j'ai toujours le même problème, le sprite ne s'affiche pas.
Voici le code corrigé :
#include <SFML/Graphics.hpp>
#include <iostream>
std::vector<sf::Texture*>* decoupageTilesetEnTexture(sf::Image *img);
int main()
{
sf::Image img;
if (img.loadFromFile("tileset.jpg"))
{
std::vector<sf::Texture*> *listeTexture = decoupageTilesetEnTexture(&img);
std::cout << "nbDeTexture = " << listeTexture->size() << std::endl;
sf::RenderWindow window(sf::VideoMode(500, 500), "SFML works!");
while (window.isOpen())
{
sf::Event event;
while (window.pollEvent(event))
{
if (event.type == sf::Event::Closed)
window.close();
}
window.clear();
sf::Sprite* sprite = new sf::Sprite(*(listeTexture->at(0)));
window.draw(*sprite);
window.display();
delete sprite;
}
}
return 0;
}
std::vector<sf::Texture*>* decoupageTilesetEnTexture(sf::Image *img)
{
unsigned int nb_tour_x = img->getSize().x/sf::Texture::getMaximumSize();
unsigned int nb_tour_y = img->getSize().y/sf::Texture::getMaximumSize();
unsigned int maximum_size_x;
unsigned int maximum_size_y;
if (sf::Texture::getMaximumSize() > img->getSize().x)
{
maximum_size_x = img->getSize().x;
}
else
{
maximum_size_x = sf::Texture::getMaximumSize();
}
if (sf::Texture::getMaximumSize() > img->getSize().y)
{
maximum_size_y = img->getSize().y;
}
else
{
maximum_size_y = sf::Texture::getMaximumSize();
}
std::vector<sf::Texture*> *listeTexture = new std::vector<sf::Texture*>();
for (unsigned int x = 0; x<=nb_tour_x; x++)
{
for (unsigned int y = 0; y<=nb_tour_y; y++)
{
unsigned int offset_x = maximum_size_x*x;
unsigned int offset_y = maximum_size_y*y;
unsigned int size_x = maximum_size_x;
unsigned int size_y = maximum_size_y;
if ((offset_x+maximum_size_x) > img->getSize().x)
{
size_x = img->getSize().x-offset_x;
}
if ((offset_y+maximum_size_y) > img->getSize().y)
{
size_y = img->getSize().y-offset_y;
}
sf::Texture *texture = new sf::Texture();
texture->loadFromImage(*img, sf::IntRect(offset_x, offset_y, size_x, size_y));
listeTexture->push_back(texture);
}
}
return listeTexture;
}
A noter que le size() me retourne un nombre cohérent.
Merci en tout cas,
Cordialement.
-
Si ton image fait moins que sf::Texture::getMaximumSize(), tu feras 0 tour, donc tu n'auras aucune texture en sortie. Est-ce que tu es dans ce cas de figure ?
Et sinon avec le debugger et une exécution pas à pas (ou au pire du "std::cout debugging"), tu n'arrives pas à voir ce que fait ton code ? C'est quand même plus simple que d'essayer de deviner d'où vient le problème en scrutant le code.
-
Non, je ne rentre pas dans le cas.
Par contre je n'arrive vraiment pas a debug, en faite j'ai une texture toute blanche de la bonne taille a la place de ce qui est sensé être affiché.
Et le draw() affiche bien la texture blanche sans bronché... je ne comprend pas.
Cordialement.
-
Je viens de solutionné mon problème...
Le problème viens du fait que je déclarais le sf::RenderWindow après avoir chargé le fichier Image, rien a voir avec mon code en faite. Il y a une part d'ironie dans l'histoire ;D
Merci pour ton aide Laurent, cordialement.
-
Ah... Ca c'est pas normal.
Tu utilises quelle version de SFML 2 ? La RC ou bien des sources plus récentes ?
Tu es sous quel OS ?
-
La RC, oui. Je suis sous Windows7 ;D (j'ai compilée les sources pour la nouvelle version de mingw fournit avec le nouveau c::b)
-
Tes drivers graphiques sont-ils à jour ?
-
Sa n'as pas de rapport avec les drivers par ce que j'ai testé sur 3 PC différents (AMD Radeon HD 7800 series, une N560GTX, et un chipset intégré intel), je pense que sa viens de la version SFML que j'avais utilisé comme pour compilé, je me souviens pas exactement laquelle j'avais prise, vue que je navigue régulièrement entre ces 3 PC justement) :P
-
Après plusieurs test, c'est au niveau de la méthode loadFromImage() que sa se passe.
Si met :
texture->loadFromImage(*img, sf::IntRect(0, 0, 200, 200));
sf::RenderWindow window(sf::VideoMode(500, 500), "SFML works!");
Sa fonctionne a merveille.
Sinon :
sf::RenderWindow window(sf::VideoMode(500, 500), "SFML works!");
texture->loadFromImage(*img, sf::IntRect(0, 0, 200, 200));
Sa ne fonctionne plus (je voit bien la taille de l'image mais la texture est toute blanche).
Et non pas au chargement de l'image comme je l’avais dit précédemment.
Voila pour la petite histoire, en tout cas c'est résolu, merci beaucoup.