#define STB_IMAGE_IMPLEMENTATION #include "texture.h" #include // Para SDL_GetError #include // Para SDL_Log #include // Para SDL_PixelFormat #include // Para SDL_CreateSurfaceFrom, SDL_DestroySurface #include // Para NULL #include // Para exit #include // Para basic_ostream, char_traits, operator<< #include // Para operator<<, string #include "stb_image.h" // Para stbi_failure_reason, stbi_image_free Texture::Texture(SDL_Renderer *renderer) : renderer_(renderer), texture_(nullptr), width_(0), height_(0) {} Texture::Texture(SDL_Renderer *renderer, const std::string &file_path) : renderer_(renderer), texture_(nullptr), width_(0), height_(0) { loadFromFile(file_path); } Texture::~Texture() { free(); } // Carga la imagen desde una ruta especificada bool Texture::loadFromFile(const std::string &file_path) { const std::string filename = file_path.substr(file_path.find_last_of("\\/") + 1); int req_format = STBI_rgb_alpha; int width, height, orig_format; unsigned char *data = stbi_load(file_path.c_str(), &width, &height, &orig_format, req_format); if (data == nullptr) { SDL_Log("Error al cargar la imagen: %s", stbi_failure_reason()); exit(1); } else { std::cout << "Imagen cargada: " << filename.c_str() << std::endl; } int pitch; SDL_PixelFormat pixel_format; if (req_format == STBI_rgb) { pitch = 3 * width; // 3 bytes por pixel * pixels por línea pixel_format = SDL_PIXELFORMAT_RGB24; } else { // STBI_rgb_alpha (RGBA) pitch = 4 * width; pixel_format = SDL_PIXELFORMAT_RGBA32; } // Libera la memoria previa free(); // La textura final SDL_Texture *new_texture = nullptr; // Crea la superficie de la imagen desde los datos cargados SDL_Surface *loaded_surface = SDL_CreateSurfaceFrom(width, height, pixel_format, (void *)data, pitch); if (loaded_surface == nullptr) { std::cout << "No se pudo cargar la imagen " << file_path << std::endl; } else { // Crea la textura desde los píxeles de la superficie new_texture = SDL_CreateTextureFromSurface(renderer_, loaded_surface); if (new_texture == nullptr) { std::cout << "No se pudo crear la textura desde " << file_path << "! Error de SDL: " << SDL_GetError() << std::endl; } else { // Obtiene las dimensiones de la imagen width_ = loaded_surface->w; height_ = loaded_surface->h; // Configurar filtro nearest neighbor para píxel perfect SDL_SetTextureScaleMode(new_texture, SDL_SCALEMODE_NEAREST); } // Destruye la superficie cargada SDL_DestroySurface(loaded_surface); } // Devuelve el resultado del proceso stbi_image_free(data); texture_ = new_texture; return texture_ != nullptr; } // Libera la textura si existe void Texture::free() { if (texture_ != nullptr) { SDL_DestroyTexture(texture_); texture_ = nullptr; width_ = 0; height_ = 0; } } // Renderiza la textura en pantalla void Texture::render(SDL_FRect *src, SDL_FRect *dst) { SDL_RenderTexture(renderer_, texture_, src, dst); } // Obtiene el ancho de la imagen int Texture::getWidth() { return width_; } // Obtiene la altura de la imagen int Texture::getHeight() { return height_; } // Modula el color de la textura void Texture::setColor(int r, int g, int b) { SDL_SetTextureColorMod(texture_, r, g, b); }