#include "texture.h" #define STB_IMAGE_IMPLEMENTATION #include "stb_image.h" #include #include "systempalette.h" #include "destsurface.h" // Constructor Texture::Texture(SDL_Renderer *renderer, std::string path, bool verbose) { // Copia punteros this->renderer = renderer; this->path = path; // Inicializa this->pixels = nullptr; this->width = 0; this->height = 0; this->color = 0xffffffff; // Carga el fichero en la textura if (path != "") { loadFromFile(path, verbose); } } // Destructor Texture::~Texture() { // Libera memoria unload(); } // Carga una imagen desde un fichero bool Texture::loadFromFile(std::string path, bool verbose) { const std::string filename = path.substr(path.find_last_of("\\/") + 1); 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); } else { if (verbose) { std::cout << "Image loaded: " << filename.c_str() << std::endl; } } // Limpia unload(); this->width = width; this->height = height; const int size = width*height; this->pixels = new uint8_t[size]; for (int i = 0; i < size; ++i) this->pixels[i] = SystemPalette::getEntry(data[i]); // Return success stbi_image_free(data); return this->pixels != nullptr; } // Crea una textura en blanco bool Texture::createBlank(SDL_Renderer *renderer, int width, int height, SDL_TextureAccess access) { // Crea una textura sin inicializar this->pixels = new uint8_t[width*height]; this->width = width; this->height = height; return this->pixels != nullptr; } // Libera la memoria de la textura void Texture::unload() { // Libera la textura si existe if (pixels != nullptr) { delete[] pixels; pixels = nullptr; width = 0; height = 0; } } // Establece el color para la modulacion void Texture::setColor(Uint8 red, Uint8 green, Uint8 blue) { this->color = (red << 24) + (green << 16) + (blue << 8) + 255; } // Establece el blending void Texture::setBlendMode(SDL_BlendMode blending) { //SDL_SetTextureBlendMode(texture, blending); } // Establece el alpha para la modulación void Texture::setAlpha(Uint8 alpha) { //SDL_SetTextureAlphaMod(texture, alpha); } // Renderiza la textura en un punto específico void Texture::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 destino 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); uint8_t *destSurface = DestSurface::getPixels(); int canvasWidth = DestSurface::getWidth(); int y_inc = 1, y_ini = 0, y_fin = renderQuad.h-1; if (flip && SDL_FLIP_VERTICAL==SDL_FLIP_VERTICAL) { auto tmp=y_ini; y_ini=y_fin; y_fin=tmp; y_inc=-1; } int x_inc = 1, x_ini = 0, x_fin = renderQuad.w-1; if (flip && SDL_FLIP_HORIZONTAL==SDL_FLIP_HORIZONTAL) { auto tmp=x_ini; x_ini=x_fin; x_fin=tmp; x_inc=-1; } for (int yy=y_ini; yy <= y_fin; yy += y_inc) { for (int xx=x_ini; xx <= x_fin; xx += x_inc) { destSurface[ x+xx + y+yy * canvasWidth ] = pixels[ clip->x+xx + clip->y+yy * width ]; } } } // Establece la textura como objetivo de renderizado void Texture::setAsRenderTarget(SDL_Renderer *renderer) { //SDL_SetRenderTarget(renderer, texture); } // Obtiene el ancho de la imagen int Texture::getWidth() { return width; } // Obtiene el alto de la imagen int Texture::getHeight() { return height; } // Recarga la textura bool Texture::reLoad() { return loadFromFile(path, renderer); } // Obtiene la textura SDL_Texture *Texture::getSDLTexture() { return nullptr; //texture; }