#include "ltexture.h" #define STB_IMAGE_IMPLEMENTATION #include "stb_image.h" // Constructor LTexture::LTexture(SDL_Renderer *renderer, std::string path) { // Copia punteros this->renderer = renderer; this->path = path; // Inicializa texture = nullptr; width = 0; height = 0; // Carga el fichero en la textura if (path != "") { loadFromFile(path, renderer); } } // Destructor LTexture::~LTexture() { // Libera memoria unload(); } // Carga una imagen desde un fichero bool LTexture::loadFromFile(std::string path, SDL_Renderer *renderer) { int req_format = STBI_rgb_alpha; int width, height, orig_format; unsigned char *data = stbi_load(path.c_str(), &width, &height, &orig_format, req_format); if (data == nullptr) { SDL_Log("Loading image failed: %s", stbi_failure_reason()); exit(1); } int depth, pitch; Uint32 pixel_format; if (req_format == STBI_rgb) { depth = 24; pitch = 3 * width; // 3 bytes por pixel * pixels per linea pixel_format = SDL_PIXELFORMAT_RGB24; } else { // STBI_rgb_alpha (RGBA) depth = 32; pitch = 4 * width; pixel_format = SDL_PIXELFORMAT_RGBA32; } // Limpia unload(); // La textura final SDL_Texture *newTexture = nullptr; // Carga la imagen desde una ruta específica SDL_Surface *loadedSurface = SDL_CreateRGBSurfaceWithFormatFrom((void *)data, width, height, depth, pitch, pixel_format); if (loadedSurface == nullptr) { printf("Unable to load image %s!\n", path.c_str()); } else { // Crea la textura desde los pixels de la surface newTexture = SDL_CreateTextureFromSurface(renderer, loadedSurface); if (newTexture == nullptr) { printf("Unable to create texture from %s! SDL Error: %s\n", path.c_str(), SDL_GetError()); } else { // Obtiene las dimensiones de la imagen this->width = loadedSurface->w; this->height = loadedSurface->h; } // Elimina la textura cargada SDL_FreeSurface(loadedSurface); } // Return success texture = newTexture; return texture != nullptr; } // Crea una textura en blanco bool LTexture::createBlank(SDL_Renderer *renderer, int width, int height, SDL_TextureAccess access) { // Crea una textura sin inicializar texture = SDL_CreateTexture(renderer, SDL_PIXELFORMAT_RGBA8888, access, width, height); if (texture == nullptr) { printf("Unable to create blank texture! SDL Error: %s\n", SDL_GetError()); } else { this->width = width; this->height = height; } return texture != nullptr; } // Libera la memoria de la textura void LTexture::unload() { // Libera la textura si existe if (texture != nullptr) { SDL_DestroyTexture(texture); texture = nullptr; width = 0; height = 0; } } // Establece el color para la modulacion void LTexture::setColor(Uint8 red, Uint8 green, Uint8 blue) { SDL_SetTextureColorMod(texture, red, green, blue); } // Establece el blending void LTexture::setBlendMode(SDL_BlendMode blending) { SDL_SetTextureBlendMode(texture, blending); } // Establece el alpha para la modulación void LTexture::setAlpha(Uint8 alpha) { SDL_SetTextureAlphaMod(texture, alpha); } // Renderiza la textura en un punto específico void LTexture::render(SDL_Renderer *renderer, int x, int y, SDL_Rect *clip, float zoomW, float zoomH, double angle, SDL_Point *center, SDL_RendererFlip flip) { // Establece el destini de renderizado en la pantalla SDL_Rect renderQuad = {x, y, width, height}; // Obtiene las dimesiones del clip de renderizado if (clip != nullptr) { renderQuad.w = clip->w; renderQuad.h = clip->h; } renderQuad.w = renderQuad.w * zoomW; renderQuad.h = renderQuad.h * zoomH; // Renderiza a pantalla SDL_RenderCopyEx(renderer, texture, clip, &renderQuad, angle, center, flip); } // Establece la textura como objetivo de renderizado void LTexture::setAsRenderTarget(SDL_Renderer *renderer) { SDL_SetRenderTarget(renderer, texture); } // Obtiene el ancho de la imagen int LTexture::getWidth() { return width; } // Obtiene el alto de la imagen int LTexture::getHeight() { return height; } // Recarga la textura bool LTexture::reLoad() { return loadFromFile(path, renderer); }