summaryrefslogtreecommitdiff
path: root/src/resources
diff options
context:
space:
mode:
authorBjørn Lindeijer <bjorn@lindeijer.nl>2005-06-21 18:41:45 +0000
committerBjørn Lindeijer <bjorn@lindeijer.nl>2005-06-21 18:41:45 +0000
commitc2a830c71ef0e271e48ef57a80ee5b00a977a4de (patch)
tree9c8f13688ddbf159a34640ad4cf4fdda3eb20ecf /src/resources
parentc392a1aa234b304b634c4ace6375ad96397a30b9 (diff)
downloadmana-c2a830c71ef0e271e48ef57a80ee5b00a977a4de.tar.gz
mana-c2a830c71ef0e271e48ef57a80ee5b00a977a4de.tar.bz2
mana-c2a830c71ef0e271e48ef57a80ee5b00a977a4de.tar.xz
mana-c2a830c71ef0e271e48ef57a80ee5b00a977a4de.zip
Image loader now automatically determines whether to use masked drawing or
an alpha layer.
Diffstat (limited to 'src/resources')
-rw-r--r--src/resources/image.cpp157
-rw-r--r--src/resources/image.h9
-rw-r--r--src/resources/mapreader.cpp2
-rw-r--r--src/resources/resourcemanager.cpp12
-rw-r--r--src/resources/resourcemanager.h6
5 files changed, 114 insertions, 72 deletions
diff --git a/src/resources/image.cpp b/src/resources/image.cpp
index 2669059e..c34ba42f 100644
--- a/src/resources/image.cpp
+++ b/src/resources/image.cpp
@@ -50,7 +50,7 @@ Image::~Image()
unload();
}
-Image* Image::load(void* buffer, unsigned int bufferSize, int flags)
+Image* Image::load(void* buffer, unsigned int bufferSize)
{
// Load the raw file data from the buffer in an RWops structure
SDL_RWops *rw = SDL_RWFromMem(buffer, bufferSize);
@@ -58,29 +58,12 @@ Image* Image::load(void* buffer, unsigned int bufferSize, int flags)
// Use SDL_Image to load the raw image data and have it free the data
SDL_Surface* tmpImage = IMG_Load_RW(rw, 1);
-#ifndef USE_OPENGL
-
- SDL_Surface *image;
- if (flags & IMG_ALPHA) {
- image = SDL_DisplayFormatAlpha(tmpImage);
- }
- else {
- SDL_SetColorKey(tmpImage, SDL_SRCCOLORKEY | SDL_RLEACCEL,
- SDL_MapRGB(tmpImage->format, 255, 0, 255));
- image = SDL_DisplayFormat(tmpImage);
- }
- SDL_FreeSurface(tmpImage);
-
- // Check if the file was opened and return the appropriate value.
- if (!image) {
- logger->log("Error: Image convert failed.");
+ if (tmpImage == NULL) {
+ logger->log("Error, image load failed");
return NULL;
}
- return new Image(image);
-
-#else
-
+ // Determine 32-bit masks based on byte order
Uint32 rmask, gmask, bmask, amask;
#if SDL_BYTEORDER == SDL_BIG_ENDIAN
rmask = 0xff000000;
@@ -94,21 +77,92 @@ Image* Image::load(void* buffer, unsigned int bufferSize, int flags)
amask = 0xff000000;
#endif
+ // Convert the image to a 32 bit software surface for processing
SDL_Surface *formatImage = SDL_CreateRGBSurface(SDL_SWSURFACE, 0, 0, 32,
rmask, gmask, bmask, amask);
if (formatImage == NULL) {
- logger->log("Error", "Image load failed: not enough memory");
+ logger->log("Error, image load failed: not enough memory");
+ SDL_FreeSurface(tmpImage);
+ return NULL;
}
SDL_Surface *image = SDL_ConvertSurface(
tmpImage, formatImage->format, SDL_SWSURFACE);
+
SDL_FreeSurface(formatImage);
- SDL_FreeSurface(tmpImage);
- unsigned int *rawData = (unsigned int *)image->pixels;
- int width = image->w;
- int height = image->h;
+ if (image == NULL) {
+ logger->log("Error, image load failed: not enough memory");
+ return NULL;
+ }
+
+ bool hasPink = false;
+ bool hasAlpha = false;
+ int i;
+ Uint32 pink = SDL_MapRGB(image->format, 255, 0, 255);
+
+ // Figure out whether the image has pink pixels
+ for (i = 0; i < image->w * image->h; ++i)
+ {
+ if (((Uint32*)image->pixels)[i] == pink)
+ {
+ hasPink = true;
+ break;
+ }
+ }
+
+ // Figure out whether the image uses its alpha layer
+ for (i = 0; i < image->w * image->h; ++i)
+ {
+ Uint8 r, g, b, a;
+ SDL_GetRGBA(
+ ((Uint32*)image->pixels)[i],
+ image->format,
+ &r, &g, &b, &a);
+
+ if (a != 255)
+ {
+ hasAlpha = true;
+ break;
+ }
+ }
+
+ SDL_FreeSurface(image);
+
+ if (hasPink && !hasAlpha) {
+ SDL_SetColorKey(tmpImage, SDL_SRCCOLORKEY | SDL_RLEACCEL,
+ SDL_MapRGB(tmpImage->format, 255, 0, 255));
+ } else if (hasAlpha) {
+ SDL_SetAlpha(tmpImage, SDL_SRCALPHA | SDL_RLEACCEL, SDL_ALPHA_OPAQUE);
+ }
+
+#ifndef USE_OPENGL
+
+ // Set color key and alpha blending optins, and convert the surface to the
+ // current display format
+ SDL_Surface *prevImage = tmpImage;
+ if (hasAlpha) {
+ image = SDL_DisplayFormatAlpha(tmpImage);
+ }
+ else {
+ image = SDL_DisplayFormat(tmpImage);
+ }
+ SDL_FreeSurface(prevImage);
+
+ if (image == NULL) {
+ logger->log("Error: Image convert failed.");
+ return NULL;
+ }
+
+ logger->log("Alpha: %d, Magic pink: %d", hasAlpha, hasPink);
+
+ return new Image(image);
+
+#else
+
+ int width = tmpImage->w;
+ int height = tmpImage->h;
int realWidth = 1, realHeight = 1;
while (realWidth < width && realWidth < 1024) {
@@ -119,47 +173,44 @@ Image* Image::load(void* buffer, unsigned int bufferSize, int flags)
realHeight *= 2;
}
- unsigned int *realData = new unsigned int[realWidth * realHeight];
- int x, y;
+ SDL_SetAlpha(tmpImage, 0, SDL_ALPHA_OPAQUE);
+ SDL_Surface *oldImage = tmpImage;
+ tmpImage = SDL_CreateRGBSurface(SDL_SWSURFACE, realWidth, realHeight, 32,
+ rmask, gmask, bmask, amask);
- for (y = 0; y < realHeight; y++)
- {
- for (x = 0; x < realWidth; x++)
- {
- if (x < width && y < height)
- {
- if (rawData[x + y * width] == 0xffff00ff)
- {
- realData[x + y * realWidth] = 0x00000000;
- }
- else
- {
- realData[x + y * realWidth] = rawData[x + y * width];
- }
- }
- else
- {
- realData[x + y * realWidth] = 0;
- }
- }
+ if (tmpImage == NULL) {
+ logger->log("Error, image convert failed: out of memory");
+ return NULL;
}
+ SDL_BlitSurface(oldImage, NULL, tmpImage, NULL);
+ SDL_FreeSurface(oldImage);
+
GLuint texture;
glGenTextures(1, &texture);
- logger->log("Binding texture %d (%dx%d)", texture, realWidth, realHeight);
+ logger->log("Binding texture %d (%dx%d)",
+ texture, tmpImage->w, tmpImage->h);
glBindTexture(GL_TEXTURE_2D, texture);
+
+ if (SDL_MUSTLOCK(tmpImage)) {
+ SDL_LockSurface(tmpImage);
+ }
+
glTexImage2D(
GL_TEXTURE_2D, 0, 4,
- realWidth, realHeight,
+ tmpImage->w, tmpImage->h,
0, GL_RGBA, GL_UNSIGNED_BYTE,
- realData);
+ tmpImage->pixels);
glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
- delete[] realData;
- SDL_FreeSurface(image);
+ if (SDL_MUSTLOCK(tmpImage)) {
+ SDL_UnlockSurface(tmpImage);
+ }
+
+ SDL_FreeSurface(tmpImage);
GLenum error = glGetError();
if (error)
diff --git a/src/resources/image.h b/src/resources/image.h
index ebc2c971..14aa4550 100644
--- a/src/resources/image.h
+++ b/src/resources/image.h
@@ -31,10 +31,6 @@
#endif
#include <string>
-// This flag causes image alpha channel to be preserved, otherwise masking is
-// used.
-#define IMG_ALPHA 1
-
// Forward declarations
class SubImage;
@@ -56,14 +52,11 @@ class Image : public Resource
*
* @param buffer The memory buffer containing the image data.
* @param bufferSize The size of the memory buffer in bytes.
- * @param flags These flags allow controlling the way the image is
- * loaded. Currently only IMG_ALPHA is supported, which
- * causes alpha layer to be preserved.
*
* @return <code>NULL</code> if the an error occurred, a valid pointer
* otherwise.
*/
- static Image *load(void* buffer, unsigned int bufferSize, int flags);
+ static Image *load(void* buffer, unsigned int bufferSize);
/**
* Frees the resources created by SDL.
diff --git a/src/resources/mapreader.cpp b/src/resources/mapreader.cpp
index b62e6029..abd269d0 100644
--- a/src/resources/mapreader.cpp
+++ b/src/resources/mapreader.cpp
@@ -265,7 +265,7 @@ Tileset* MapReader::readTileset(
sourceStr.erase(0, 3); // Remove "../"
ResourceManager *resman = ResourceManager::getInstance();
- Image* tilebmp = resman->getImage(sourceStr, IMG_ALPHA);
+ Image* tilebmp = resman->getImage(sourceStr);
if (tilebmp)
{
diff --git a/src/resources/resourcemanager.cpp b/src/resources/resourcemanager.cpp
index 0abc10eb..1e2f4f31 100644
--- a/src/resources/resourcemanager.cpp
+++ b/src/resources/resourcemanager.cpp
@@ -73,7 +73,7 @@ ResourceManager::~ResourceManager()
}
Resource* ResourceManager::get(const E_RESOURCE_TYPE &type,
- const std::string &idPath, int flags)
+ const std::string &idPath)
{
// Check if the id exists, and return the value if it does.
std::map<std::string, ResourceEntry>::iterator resIter =
@@ -122,7 +122,7 @@ Resource* ResourceManager::get(const E_RESOURCE_TYPE &type,
if (buffer != NULL)
{
// Let the image class load it
- resource = Image::load(buffer, fileSize, flags);
+ resource = Image::load(buffer, fileSize);
// Cleanup
free(buffer);
@@ -177,19 +177,19 @@ Resource* ResourceManager::get(const E_RESOURCE_TYPE &type,
return resource;
}
-Image *ResourceManager::getImage(const std::string &idPath, int flags)
+Image *ResourceManager::getImage(const std::string &idPath)
{
- return (Image*)get(IMAGE, idPath, flags);
+ return (Image*)get(IMAGE, idPath);
}
Music *ResourceManager::getMusic(const std::string &idPath)
{
- return (Music*)get(MUSIC, idPath, 0);
+ return (Music*)get(MUSIC, idPath);
}
SoundEffect *ResourceManager::getSoundEffect(const std::string &idPath)
{
- return (SoundEffect*)get(SOUND_EFFECT, idPath, 0);
+ return (SoundEffect*)get(SOUND_EFFECT, idPath);
}
ResourceManager* ResourceManager::getInstance()
diff --git a/src/resources/resourcemanager.h b/src/resources/resourcemanager.h
index 3c72eb43..2204d455 100644
--- a/src/resources/resourcemanager.h
+++ b/src/resources/resourcemanager.h
@@ -78,20 +78,18 @@ class ResourceManager
*
* @param type The type of resource to load.
* @param idPath The resource identifier path.
- * @param flags Flags to control the loading of certain resources.
* @return A valid resource or <code>NULL</code> if the resource could
* not be loaded.
*/
Resource *get(
const E_RESOURCE_TYPE &type,
- const std::string &idPath,
- int flags = 0);
+ const std::string &idPath);
/**
* Convenience wrapper around ResourceManager::create for loading
* images.
*/
- Image *getImage(const std::string &idPath, int flags = 0);
+ Image *getImage(const std::string &idPath);
/**
* Convenience wrapper around ResourceManager::create for loading