diff options
author | Bertram <bertram@cegetel.net> | 2009-08-13 19:53:56 +0200 |
---|---|---|
committer | Bertram <bertram@cegetel.net> | 2009-08-13 19:53:56 +0200 |
commit | 3f21f53869044e5928ed2407a48ac28835da1cb1 (patch) | |
tree | e648cd56f32dca39ee231841c4377b6e6e02de22 | |
parent | dd3df0c3d2adb3601abfedea2142c015cf3442c5 (diff) | |
download | mana-3f21f53869044e5928ed2407a48ac28835da1cb1.tar.gz mana-3f21f53869044e5928ed2407a48ac28835da1cb1.tar.bz2 mana-3f21f53869044e5928ed2407a48ac28835da1cb1.tar.xz mana-3f21f53869044e5928ed2407a48ac28835da1cb1.zip |
Cleaned up the image code a bit...
-rw-r--r-- | src/resources/image.cpp | 284 | ||||
-rw-r--r-- | src/resources/image.h | 90 |
2 files changed, 204 insertions, 170 deletions
diff --git a/src/resources/image.cpp b/src/resources/image.cpp index 9af3059a..b51e1e1e 100644 --- a/src/resources/image.cpp +++ b/src/resources/image.cpp @@ -133,141 +133,11 @@ Image *Image::load(SDL_Surface *tmpImage) #ifdef USE_OPENGL if (mUseOpenGL) { - // Flush current error flag. - glGetError(); - - int width = tmpImage->w; - int height = tmpImage->h; - int realWidth = powerOfTwo(width); - int realHeight = powerOfTwo(height); - - if (realWidth < width || realHeight < height) - { - logger->log("Warning: image too large, cropping to %dx%d texture!", - tmpImage->w, tmpImage->h); - } - - // Make sure the alpha channel is not used, but copied to destination - SDL_SetAlpha(tmpImage, 0, SDL_ALPHA_OPAQUE); - - // Determine 32-bit masks based on byte order - Uint32 rmask, gmask, bmask, amask; -#if SDL_BYTEORDER == SDL_BIG_ENDIAN - rmask = 0xff000000; - gmask = 0x00ff0000; - bmask = 0x0000ff00; - amask = 0x000000ff; -#else - rmask = 0x000000ff; - gmask = 0x0000ff00; - bmask = 0x00ff0000; - amask = 0xff000000; -#endif - - SDL_Surface *oldImage = tmpImage; - tmpImage = SDL_CreateRGBSurface(SDL_SWSURFACE, realWidth, realHeight, - 32, rmask, gmask, bmask, amask); - - if (!tmpImage) - { - logger->log("Error, image convert failed: out of memory"); - return NULL; - } - - SDL_BlitSurface(oldImage, NULL, tmpImage, NULL); - - GLuint texture; - glGenTextures(1, &texture); - glBindTexture(mTextureType, texture); - - if (SDL_MUSTLOCK(tmpImage)) - SDL_LockSurface(tmpImage); - - glTexImage2D( - mTextureType, 0, 4, - tmpImage->w, tmpImage->h, - 0, GL_RGBA, GL_UNSIGNED_BYTE, - tmpImage->pixels); - - glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE); - glTexParameteri(mTextureType, GL_TEXTURE_MIN_FILTER, GL_NEAREST); - glTexParameteri(mTextureType, GL_TEXTURE_MAG_FILTER, GL_NEAREST); - - if (SDL_MUSTLOCK(tmpImage)) { - SDL_UnlockSurface(tmpImage); - } - - SDL_FreeSurface(tmpImage); - - GLenum error = glGetError(); - if (error) - { - std::string errmsg = "Unknown error"; - switch (error) - { - case GL_INVALID_ENUM: - errmsg = "GL_INVALID_ENUM"; - break; - case GL_INVALID_VALUE: - errmsg = "GL_INVALID_VALUE"; - break; - case GL_INVALID_OPERATION: - errmsg = "GL_INVALID_OPERATION"; - break; - case GL_STACK_OVERFLOW: - errmsg = "GL_STACK_OVERFLOW"; - break; - case GL_STACK_UNDERFLOW: - errmsg = "GL_STACK_UNDERFLOW"; - break; - case GL_OUT_OF_MEMORY: - errmsg = "GL_OUT_OF_MEMORY"; - break; - } - logger->log("Error: Image GL import failed: %s", errmsg.c_str()); - return NULL; - } - - return new Image(texture, width, height, realWidth, realHeight); + return _GLload(tmpImage); } #endif - bool hasAlpha = false; - - if (tmpImage->format->BitsPerPixel == 32) - { - // Figure out whether the image uses its alpha layer - for (int i = 0; i < tmpImage->w * tmpImage->h; ++i) - { - Uint8 r, g, b, a; - SDL_GetRGBA( - ((Uint32*) tmpImage->pixels)[i], - tmpImage->format, - &r, &g, &b, &a); - - if (a != 255) - { - hasAlpha = true; - break; - } - } - } - - SDL_Surface *image; - - // Convert the surface to the current display format - if (hasAlpha) - image = SDL_DisplayFormatAlpha(tmpImage); - else - image = SDL_DisplayFormat(tmpImage); - - if (!image) - { - logger->log("Error: Image convert failed."); - return NULL; - } - - return new Image(image); + return _SDLload(tmpImage); } void Image::unload() @@ -313,7 +183,7 @@ void Image::setAlpha(float a) } } -Image* Image::merge(Image *image, int x, int y) +Image* Image::SDLmerge(Image *image, int x, int y) { SDL_Surface* surface = new SDL_Surface(*(image->mImage)); @@ -388,11 +258,6 @@ Image* Image::merge(Image *image, int x, int y) return newImage; } -float Image::getAlpha() const -{ - return mAlpha; -} - Image* Image::SDLgetScaledImage(int width, int height) { // No scaling on incorrect new values. @@ -421,7 +286,150 @@ Image* Image::SDLgetScaledImage(int width, int height) return scaledImage; } +Image *Image::_SDLload(SDL_Surface *tmpImage) +{ + if (!tmpImage) + return NULL; + + bool hasAlpha = false; + + if (tmpImage->format->BitsPerPixel == 32) + { + // Figure out whether the image uses its alpha layer + for (int i = 0; i < tmpImage->w * tmpImage->h; ++i) + { + Uint8 r, g, b, a; + SDL_GetRGBA( + ((Uint32*) tmpImage->pixels)[i], + tmpImage->format, + &r, &g, &b, &a); + + if (a != 255) + { + hasAlpha = true; + break; + } + } + } + + SDL_Surface *image; + + // Convert the surface to the current display format + if (hasAlpha) + image = SDL_DisplayFormatAlpha(tmpImage); + else + image = SDL_DisplayFormat(tmpImage); + + if (!image) + { + logger->log("Error: Image convert failed."); + return NULL; + } + + return new Image(image); +} + #ifdef USE_OPENGL +Image *Image::_GLload(SDL_Surface *tmpImage) +{ + // Flush current error flag. + glGetError(); + + int width = tmpImage->w; + int height = tmpImage->h; + int realWidth = powerOfTwo(width); + int realHeight = powerOfTwo(height); + + if (realWidth < width || realHeight < height) + { + logger->log("Warning: image too large, cropping to %dx%d texture!", + tmpImage->w, tmpImage->h); + } + + // Make sure the alpha channel is not used, but copied to destination + SDL_SetAlpha(tmpImage, 0, SDL_ALPHA_OPAQUE); + + // Determine 32-bit masks based on byte order + Uint32 rmask, gmask, bmask, amask; +#if SDL_BYTEORDER == SDL_BIG_ENDIAN + rmask = 0xff000000; + gmask = 0x00ff0000; + bmask = 0x0000ff00; + amask = 0x000000ff; +#else + rmask = 0x000000ff; + gmask = 0x0000ff00; + bmask = 0x00ff0000; + amask = 0xff000000; +#endif + + SDL_Surface *oldImage = tmpImage; + tmpImage = SDL_CreateRGBSurface(SDL_SWSURFACE, realWidth, realHeight, + 32, rmask, gmask, bmask, amask); + + if (!tmpImage) + { + logger->log("Error, image convert failed: out of memory"); + return NULL; + } + + SDL_BlitSurface(oldImage, NULL, tmpImage, NULL); + + GLuint texture; + glGenTextures(1, &texture); + glBindTexture(mTextureType, texture); + + if (SDL_MUSTLOCK(tmpImage)) + SDL_LockSurface(tmpImage); + + glTexImage2D( + mTextureType, 0, 4, + tmpImage->w, tmpImage->h, + 0, GL_RGBA, GL_UNSIGNED_BYTE, + tmpImage->pixels); + + glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE); + glTexParameteri(mTextureType, GL_TEXTURE_MIN_FILTER, GL_NEAREST); + glTexParameteri(mTextureType, GL_TEXTURE_MAG_FILTER, GL_NEAREST); + + if (SDL_MUSTLOCK(tmpImage)) { + SDL_UnlockSurface(tmpImage); + } + + SDL_FreeSurface(tmpImage); + + GLenum error = glGetError(); + if (error) + { + std::string errmsg = "Unknown error"; + switch (error) + { + case GL_INVALID_ENUM: + errmsg = "GL_INVALID_ENUM"; + break; + case GL_INVALID_VALUE: + errmsg = "GL_INVALID_VALUE"; + break; + case GL_INVALID_OPERATION: + errmsg = "GL_INVALID_OPERATION"; + break; + case GL_STACK_OVERFLOW: + errmsg = "GL_STACK_OVERFLOW"; + break; + case GL_STACK_UNDERFLOW: + errmsg = "GL_STACK_UNDERFLOW"; + break; + case GL_OUT_OF_MEMORY: + errmsg = "GL_OUT_OF_MEMORY"; + break; + } + logger->log("Error: Image GL import failed: %s", errmsg.c_str()); + return NULL; + } + + return new Image(texture, width, height, realWidth, realHeight); +} + void Image::setLoadAsOpenGL(bool useOpenGL) { Image::mUseOpenGL = useOpenGL; diff --git a/src/resources/image.h b/src/resources/image.h index f497f608..824881a3 100644 --- a/src/resources/image.h +++ b/src/resources/image.h @@ -88,16 +88,6 @@ class Image : public Resource static Image *load(SDL_Surface *); /** - * Gets an scaled instance of an image. - * - * @param width The desired width of the scaled image. - * @param height The desired height of the scaled image. - * - * @return A new Image* object. - */ - Image* SDLgetScaledImage(int width, int height); - - /** * Frees the resources created by SDL. */ virtual void unload(); @@ -121,6 +111,17 @@ class Image : public Resource bool isAnOpenGLOne() const; /** + * Sets the alpha value of this image. + */ + virtual void setAlpha(float alpha); + + /** + * Returns the alpha value of this image. + */ + float getAlpha() const + { return mAlpha; } + + /** * Creates a new image with the desired clipping rectangle. * * @return <code>NULL</code> if creation failed and a valid @@ -128,17 +129,32 @@ class Image : public Resource */ virtual Image *getSubImage(int x, int y, int width, int height); + + // SDL only public functions + /** - * Sets the alpha value of this image. + * Gets an scaled instance of an image. + * + * @param width The desired width of the scaled image. + * @param height The desired height of the scaled image. + * + * @return A new Image* object. */ - virtual void setAlpha(float alpha); + Image* SDLgetScaledImage(int width, int height); /** - * Returns the alpha value of this image. + * Merges two image SDL_Surfaces together. This is for SDL use only, as + * reducing the number of surfaces that SDL has to render can cut down + * on the number of blit operations necessary, which in turn can help + * improve overall framerates. Don't use unless you are using it to + * reduce the number of overall layers that need to be drawn through SDL. */ - float getAlpha() const; + Image *SDLmerge(Image *image, int x, int y); #ifdef USE_OPENGL + + // OpenGL only public functions + /** * Sets the target image format. Use <code>false</code> for SDL and * <code>true</code> for OpenGL. @@ -150,20 +166,36 @@ class Image : public Resource static int getTextureType() { return mTextureType; } #endif - /** - * Merges two image SDL_Surfaces together. This is for SDL use only, as - * reducing the number of surfaces that SDL has to render can cut down - * on the number of blit operations necessary, which in turn can help - * improve overall framerates. Don't use unless you are using it to - * reduce the number of overall layers that need to be drawn through SDL. - */ - Image *merge(Image *image, int x, int y); - protected: + + // ----------------------- + // Generic protected members + // ----------------------- + + SDL_Rect mBounds; + bool mLoaded; + float mAlpha; + + // ----------------------- + // SDL protected members + // ----------------------- + + /** SDL Constructor */ + Image(SDL_Surface *image); + + static Image *_SDLload(SDL_Surface *tmpImage); + + + SDL_Surface *mImage; + + + // ----------------------- + // OpenGL protected members + // ----------------------- +#ifdef USE_OPENGL /** - * Constructor. + * OpenGL Constructor. */ -#ifdef USE_OPENGL Image(GLuint glimage, int width, int height, int texWidth, int texHeight); @@ -171,13 +203,9 @@ class Image : public Resource * Returns the first power of two equal or bigger than the input. */ static int powerOfTwo(int input); -#endif - Image(SDL_Surface *image); - SDL_Rect mBounds; - bool mLoaded; + static Image *_GLload(SDL_Surface *tmpImage); -#ifdef USE_OPENGL GLuint mGLImage; int mTexWidth, mTexHeight; @@ -185,8 +213,6 @@ class Image : public Resource static int mTextureType; static int mTextureSize; #endif - SDL_Surface *mImage; - float mAlpha; }; /** |