38bool Image::mUseOpenGL =
false;
39bool Image::mPowerOfTwoTextures =
true;
40int Image::mTextureType = 0;
41int Image::mTextureSize = 0;
59 Log::info(
"Image::Image(SDL_Texture*, ...): Couldn't load invalid Surface!");
64Image::Image(GLuint glimage,
int width,
int height,
int texWidth,
int texHeight):
76 Log::info(
"Image::Image(GLuint, ...): Couldn't load invalid Surface!");
92 glDeleteTextures(1, &mGLImage);
100 SDL_Surface *tmpImage = IMG_Load_RW(rw, 1);
104 Log::info(
"Error, image load failed: %s", IMG_GetError());
110 SDL_FreeSurface(tmpImage);
116 SDL_Surface *surf = IMG_Load_RW(rw, 1);
120 Log::info(
"Error, image load failed: %s", IMG_GetError());
124 if (surf->format->format != SDL_PIXELFORMAT_RGBA32)
126 Log::warn(
"Image format is %s, not SDL_PIXELFORMAT_RGBA32. Converting...",
127 SDL_GetPixelFormatName(surf->format->format));
129 SDL_Surface *convertedSurf = SDL_ConvertSurfaceFormat(surf, SDL_PIXELFORMAT_RGBA32, 0);
130 SDL_FreeSurface(surf);
133 Log::info(
"Error, image convert failed: %s", SDL_GetError());
136 surf = convertedSurf;
139 auto *pixels =
static_cast<SDL_Color *
>(surf->pixels);
140 for (SDL_Color *p_end = pixels + surf->w * surf->h; pixels != p_end; ++pixels)
145 int v[3] = { pixels->r, pixels->g, pixels->b };
154 SDL_FreeSurface(surf);
162 return _GLload(tmpImage);
181 mAlpha = std::clamp(alpha, 0.0f, 1.0f);
189 SDL_Texture *texture = SDL_CreateTextureFromSurface(
mRenderer, image);
190 return new Image(texture, image->w, image->h);
199Image *Image::_GLload(SDL_Surface *image)
204 int width = image->w;
205 int height = image->h;
206 int realWidth = powerOfTwo(width);
207 int realHeight = powerOfTwo(height);
209 if (realWidth < width || realHeight < height)
211 Log::warn(
"Image too large, cropping to %dx%d texture!",
212 realWidth, realHeight);
216 Uint32 rmask, gmask, bmask, amask;
217#if SDL_BYTEORDER == SDL_BIG_ENDIAN
229 bool needsConversion = !(realWidth == width &&
230 realHeight == height &&
231 image->format->BytesPerPixel == 4 &&
232 image->format->Rmask == rmask &&
233 image->format->Gmask == gmask &&
234 image->format->Bmask == bmask &&
235 image->format->Amask == amask);
239 SDL_Surface *oldImage = image;
240 image = SDL_CreateRGBSurface(SDL_SWSURFACE, realWidth, realHeight,
241 32, rmask, gmask, bmask, amask);
245 Log::info(
"Error, image convert failed: out of memory");
250 SDL_SetSurfaceBlendMode(oldImage, SDL_BLENDMODE_NONE);
251 SDL_BlitSurface(oldImage,
nullptr, image,
nullptr);
255 glGenTextures(1, &texture);
256 OpenGLGraphics::bindTexture(mTextureType, texture);
258 if (SDL_MUSTLOCK(image))
259 SDL_LockSurface(image);
261 glTexImage2D(mTextureType, 0, GL_RGBA8,
263 0, GL_RGBA, GL_UNSIGNED_BYTE,
266 glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
267 glTexParameteri(mTextureType, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
268 glTexParameteri(mTextureType, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
270 if (SDL_MUSTLOCK(image))
271 SDL_UnlockSurface(image);
274 SDL_FreeSurface(image);
276 if (GLenum error = glGetError())
278 const char *errmsg =
"Unknown error";
281 case GL_INVALID_ENUM:
282 errmsg =
"GL_INVALID_ENUM";
284 case GL_INVALID_VALUE:
285 errmsg =
"GL_INVALID_VALUE";
287 case GL_INVALID_OPERATION:
288 errmsg =
"GL_INVALID_OPERATION";
290 case GL_STACK_OVERFLOW:
291 errmsg =
"GL_STACK_OVERFLOW";
293 case GL_STACK_UNDERFLOW:
294 errmsg =
"GL_STACK_UNDERFLOW";
296 case GL_OUT_OF_MEMORY:
297 errmsg =
"GL_OUT_OF_MEMORY";
300 Log::error(
"Image GL import failed: %s", errmsg);
304 return new Image(texture, width, height, realWidth, realHeight);
307void Image::setLoadAsOpenGL(
bool useOpenGL)
312int Image::powerOfTwo(
int input)
315 if (mPowerOfTwoTextures)
318 while (value < input && value < mTextureSize)
327 return value >= mTextureSize ? mTextureSize : value;
340 mTexWidth, mTexHeight);
354 int x,
int y,
int width,
int height):
355 Image(texture, width, height),
367 int x,
int y,
int width,
int height,
368 int texWidth,
int texHeight):
369 Image(image, width, height, texWidth, texHeight),
Class for dispatching pixel-recoloring amongst several palettes.
void update(int color[3]) const
Modifies a pixel color.
Defines a class for loading and storing images.
static Image * _SDLload(SDL_Surface *tmpImage)
SDL_Surface to SDL_Texture Image loader.
static Resource * load(SDL_RWops *rw)
Loads an image from an SDL_RWops structure.
static bool useOpenGL()
Tells if the system is using OpenGL or SDL.
Image * getSubImage(int x, int y, int width, int height)
Creates a new image with the desired clipping rectangle.
static bool mDisableTransparency
Stores whether the transparency is disabled.
Image(SDL_Texture *texture, int width, int height)
SDL Constructor.
void setAlpha(float alpha)
Sets the alpha value of this image.
static void setRenderer(SDL_Renderer *renderer)
static SDL_Renderer * mRenderer
A generic reference counted resource object.
A clipped version of a larger image.
SubImage(Image *parent, SDL_Texture *texture, int x, int y, int width, int height)
void warn(const char *log_text,...) LOG_PRINTF_ATTR
void info(const char *log_text,...) LOG_PRINTF_ATTR
void error(const char *log_text,...) LOG_PRINTF_ATTR