Sign in to follow this  
traiger

png's as textures

Recommended Posts

Does anyone here use png's as textures as I am having problems. I can load the image via SDL and even apply it as a texture provided that the alpha channel is not used. So does any anyone use png's as textures where transparency is used? Thanks Paul

Share this post


Link to post
Share on other sites
What exactly is the problem, does the texture turn into some funky hippie pattern, does the whole program crash and burn, or is it just not transparent.

Normaly it shouldn't be a problem, even with png files, you probobly just have to tell openGL that it is a transparent texture, you allso need to make shure you have to correct blending.

Share this post


Link to post
Share on other sites
I'm using them with SDL + SDL_Image + OpenGL, and currently have no problems with them :-) even with those that are partially transparent.

Here's function that I use to load textures:


bool SC :: TextureMgr :: LoadTexture(const TexturesItor & _itor, const char * _directory, const char * _textureName)
{
string filename(_directory);
filename += _textureName;
TextureGroupItor textureItor = _itor->second->find(_textureName);

if (textureItor != _itor->second->end())
{
++(textureItor->second.refCount);

#ifdef __SC_LOG_TEXTURE_REUSE__
log2("Reusing", filename);
#endif
return true;
}

#ifdef __SC_LOG_TEXTURE_NEW__
log2("New", filename)
#endif

if (!fileExists(filename.c_str())) return false;

// -------------------------------------------------

SDL_Surface * tmp = IMG_Load(filename.c_str());

if (tmp == 0) return false;

// first check whether it is needed to expand texture size to powers of 2

usint w = tmp->w;
usint h = tmp->h;

usint physicalW = tmp->w;
usint physicalH = tmp->h;

SDL_Surface * image = tmp; // create alias

bool IsWidth = IsPowerOfTwo(w);
bool IsHeight = IsPowerOfTwo(h);

// -------------------------------------------------

if ((!IsWidth) || (!IsHeight) || (tmp->format->BitsPerPixel != 32))
{

#ifdef __SC_LOG_TEXTURE_STARTUP__
if ((!IsWidth) || (!IsHeight)) debug("This texture needs to be resized during startup.")
if (tmp->format->BitsPerPixel != 32) debug("This texture needs to have altered color depth.")
debug("In release versions, please remember to fix it so startups will be much shorter.")
#endif

if (!IsWidth) w = PowerOfTwo(w);
if (!IsHeight) h = PowerOfTwo(h);

// -------------------------------------------------

Uint32 rmask, gmask, bmask, amask;

/*
SDL interprets each pixel as a 32-bit number, so our masks must depend on the endianness
(byte order) of the machine
*/


#if SDL_BYTEORDER == SDL_BIG_ENDIAN
rmask = 0xff000000;
gmask = 0x00ff0000;
bmask = 0x0000ff00;
amask = 0x000000ff;
#else
rmask = 0x000000ff;
gmask = 0x0000ff00;
bmask = 0x00ff0000;
amask = 0xff000000;
#endif

// -------------------------------------------------

// now image is no longer alias to tmp, rather that new surface
image = SDL_CreateRGBSurface(SDL_SWSURFACE /*| SDL_SRCALPHA*/, w, h, 32, rmask, gmask, bmask, amask);

if ( image == 0 )
{
logError2("TextureMgr", "Couldn't allocate memory for expanding texture to power of 2")
SDL_FreeSurface(tmp);
SC_ASSERT(!"Couldn't allocate memory for expanding texture to power of 2")
return false;
}

SDL_Rect area;
area.x = 0;
area.y = 0;
area.w = tmp->w;
area.h = tmp->h;

// it was fucking stupid bug with 32 bpp textures that needed to be resized
if ( tmp->format->BitsPerPixel == 32)
SDL_SetAlpha(tmp, 0, 0);

// copy the tmp into the new GL texture image
SDL_BlitSurface(tmp, &area, image, &area);
SDL_FreeSurface(tmp);
tmp = 0;
}

// -------------------------------------------------

TextureHandle textureHwnd;

glGenTextures(1, &textureHwnd.id);
glBindTexture(GL_TEXTURE_2D, textureHwnd.id);

glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);

glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);

glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, w, h, 0, GL_RGBA, GL_UNSIGNED_BYTE, image->pixels);

textureHwnd.width = w;
textureHwnd.height = h;
textureHwnd.physicalWidth = physicalW;
textureHwnd.physicalHeight = physicalH;
textureHwnd.refCount = 1;

if (tmp) SDL_FreeSurface(tmp);
else SDL_FreeSurface(image);

// now add it to map
(_itor->second)->insert(TextureGroupPair(_textureName, textureHwnd));

return true;
}




Also, check your rendering code - ie. are you enabling transparency (glEnable(GL_BLEND))?


HTH

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this