Je charge des images avec stb_image, puis je transmets sur SDL avec des fonctions comme SDL_CreateRGBSurfaceWithFormatFrom et SDL_CreateTextureFromSurface, mais cette dernière fonction plante et ferme le programme, mais seulement au deuxième passage, parce-que je charge des images en boucle.
Voici le code :
int textureChannels = 0;
int width, height;
stbi_uc* pixels = stbi_load((static_cast<const std::string>(directory) + static_cast<const std::string>(object.filename)).c_str(), &width, &height, &textureChannels, textureChannels);
if (!pixels)
{
const std::string error = "Error by loading an image : ";
const std::string description = stbi_failure_reason();
stbi_image_free(pixels);
SDL_SetError((error + description).data());
return -1;
}
SDL_Surface* surface = NULL;
surface = SDL_CreateRGBSurfaceWithFormatFrom(reinterpret_cast<void*>(pixels), width, height,
textureChannels * 8, textureChannels * width, (textureChannels == STBI_rgb) ? SDL_PIXELFORMAT_RGB24 : SDL_PIXELFORMAT_RGBA32);
stbi_image_free(pixels);
if (surface == NULL)
{
const std::string error = "Error by creating a surface with a specific format : ";
const std::string description = SDL_GetError();
SDL_FreeSurface(surface);
SDL_SetError((error + description).data());
return -1;
}
if (transparentColor != NULL)
{
SDL_SetColorKey(surface, SDL_TRUE, SDL_MapRGB(surface->format, transparentColor->r, transparentColor->g, transparentColor->b));
}
SDL_SetSurfaceRLE(surface, SDL_TRUE);
object.texture = NULL;
object.texture = SDL_CreateTextureFromSurface(renderer, surface);
SDL_FreeSurface(surface);
if (object.texture == NULL)
{
const std::string error = "Error by creating a texture from surface : ";
const std::string description = SDL_GetError();
SDL_DestroyTexture(object.texture);
SDL_SetError((error + description).data());
return -1;
}
Oui j'utilise quelques trucs c++...
La surface passée en argument a l'air valide.
Merci davance pour vos réponses.
Thomas
- Edité par ThomasMoerschell 20 novembre 2017 à 17:19:44
Ligne 33 et 34... Il faudrait peut-être attribuer la valeur de SDL_CreateTextureFromSurface(renderer, surface) à object.texture si tu veux que ce dernier ne soit pas NULL.
Sinon, ton code est écrit en C++, si tu veux correctement utiliser une bibliothèque C comme SDL en C++, il faut l'encapsuler pour que les ressources soient gérées automatiquement (RAII, …).
- Edité par Mad scientist 20 novembre 2017 à 12:17:56
Faisons les choses dans l'ordre s'il te plaît parce que je suis un peu perdu...
En 1, est-ce que ta surface ressemble à quelque chose ?
Ensuite pourquoi perdre du temps à travailler sur une surface si au final tu veux une texture ? Pourquoi ne pas directement créer une texture ?
Et est-il vraiment nécessaire de charger tes images en boucle ? C'est généralement considéré comme un défaut de conception... Surtout que je ne vois pas de libération avant l'allocation de la texture...
Ta fonction stbi_load fait quoi exactement ? Je trouve bizarre qu'elle prenne en argument et un pointeur sur int et la valeur du même int. Pourquoi pas, mais ça m'interpelle.
Dites moi si il y a quelquechose de faux dans le code
Ensuite, mon programme charge ces images à partir de directives qui lui sont données à partir d'un fichier externe, et là, je ne vois pas trop comment me passer de la boucle.
Puis stbi_load prend en paramètre un int dans lequel est stocké le nombre de canaux désiré ou 0. et enregistre le nombre de canaux optimaux dans le pointeur qui lui est donné.
Cela ressemble à un défaut de pitch, mais c'est trop répétitif pour que ce soit uniquement ça. Sais tu nous montrer quelle résultat tu devrais obtenir ? Quelle type d'image ? png, jpg... ?
Comment as-tu défini la valeur de format (arg 2 de SDL_CreateTexture) ? Si ta texture change assez souvent, il serait préférable de la passer en SDL_TEXTUREACCESS_STREAMING, mais je te laisse voir ça... Aussi, il peut être prudent de passer ta texture au blend :
Quand j'ai décodé les animations GIF et que je bloquais sur ce genre de problème, je prenais une toute petite image (5*5 par exemple) puis je faisais un dump des pixels (chaque valeur rgba) dans un fichier pour voir si le résultat était cohérent à chaque étape. L'avantage d'une petite image est que ça reste interprétable.
Je ne connais pas trop cette lib STB_image, mais elle ne semble pas gérer les images avec une profondeur supérieure à 32bits (8bits/couleur) :
// DOCUMENTATION
//
// Limitations:
// - no 16-bit-per-channel PNG
// - no 12-bit-per-channel JPEG
// - no JPEGs with arithmetic coding
// - no 1-bit BMP
// - GIF always returns *comp=4
Du coup, tu devrais choisir une image avec un format que tu vas pouvoir maîtriser (fais toi même un petit png32 ou plus simple, un bmp24) et fige ton code pour ce format en particulier dans un premier temps (textureChannels = 4 pour SBI_Load(), SDL_PIXELFORMAT_RGBA8888 pour la texture en figeant les dimensions à la création (valeurs données pour le png32)).
Au pire, utilise une image 4*4 avec une colonne de chaque couleur pure, ce sera plus facile à interpréter dans un fichier texte.
Quand tu poses ta texture sur le renderer, fais le en NULL, NULL pour étendre la texture sur l'affichage et y voir quelque chose...
Au delà de ça, au moins pour le côté SDL2 que je maîtrise plus, ton code semble correct... Attention si tu passes en SDL_TEXTUREACCESS_STREAMING, il faut lock/unlock la texture pour l'accès aux pixels...
Mais à force de modifier et de remodifier le code, j'ai dû corriger une erreur presque invisible sans le savoir. Du coup, si je passe par une SDL_Surface, les images s'affichent correctement. J'ai encore quelques problèmes de trigo et de conteneurs c++, mais c'est une autre histoire.
N'empêche que si quelqu'un a une idée pour ne pas devoir passer par une SDL_Surface, je suis preneur. Je vous dis si je trouve du nouveau.
Merci à tous.
SDL_CreateTextureFromSurface plante
× Après avoir cliqué sur "Répondre" vous serez invité à vous connecter pour que votre message soit publié.
× Attention, ce sujet est très ancien. Le déterrer n'est pas forcément approprié. Nous te conseillons de créer un nouveau sujet pour poser ta question.
Bonhomme !! | Jeu de plateforme : Prototype.
On écrit "j'ai tort", pas "tord" qui est le verbe "tordre" à la 3ème personne de l'indicatif présent
Bonhomme !! | Jeu de plateforme : Prototype.
Bonhomme !! | Jeu de plateforme : Prototype.