Game Development Community

Inverting a texture in gTexManager.cc

by Chris \"Hobbiticus\" Weiland · in Torque Game Engine · 12/05/2002 (9:08 pm) · 6 replies

This has stumped me for the longest time now, and I've tried it various ways. Can someone try doing this and get back to me if they can? If you do, I can release my terrain bump mapping sooner :D

#1
12/06/2002 (3:28 am)
I assume that you need an inverted texture because you want to do a subtractive blend?

You can test for subtractive blending support in the engine and do this in hardware, unless of course I've got the wrong end of the stick? ;)

If not then given ...

GBitmap& mBitmap (Valid 32-bit bitmap)
TextureHandle& mTexture (Associated texture handle)

... and only touching mip level 0 then ...

// Get pixel address (0,0) of bitmap data for mip level 0.
u32* pImageBits = mBitmap.getAddress(0,0,0);

// Fetch total pixel count for bitmap.
u32 PixelCount = mBitmap.getWidth(0) * mBitmap.getHeight(0);

// Invert only the RGB components of the bitmap (leave alpha alone).
for (u32 index = 0; index < PixelCount; ++index)
   pImageBits[index] ^= 0x00ffffff;

// Upload the bitmap to the cards' texture unit.
mTexture.refresh();

Hey, I've just typed this from work so I've not put it through Torque but it looks right to me.

- Melv.
#2
12/06/2002 (8:58 am)
Well, since i'm working in gTexManager.cc, I don't have a texture handle to work with, but i DO have the source bitmap, pDL. I need to invert the texture inside of createGLName() so I can do what I want to with it. (I need to retain the origional and inverted texture)

Here's some code that might help..

In terrData.cc, I want to do this:
mBumpTextureHandle = TextureHandle(mBumpTextureName, BumpTexture);
mInvertedBumpTextureHandle = TextureHandle(mBumpTextureName, InvertedBumpTexture);
So, i use the same name, but a different texture type to get it to invert in gTexManager.cc. That way, in gTexManager.cc, I can do something like:
if (type == InvertedBumpTexture)
{
//for (every mip map level)
//{
//   do some funky math to invert the texture
//   possibly in a copy of the texture
//   call glTexImage2D() to load the texture
//}
}
else
{
//do the same stuff but without inverting
//for all other texture types
}
I hope you can do this, because I can't :(
#3
12/09/2002 (10:26 am)
Does it have to be done at runtime ?
ie Invert the texture in your favorite imaging tool, save it with a name related to its original version, and modify your code so you use both ??
Just an idea, as my low level grasp of 3D gfx is not sufficient at this moment to really tackle your problem...
Have a good one
#4
12/09/2002 (11:27 am)
I'm guessing you've solved this already but... Wouldn't this modified loadTexture function with Melvs code work?

TextureObject *TextureManager::loadTexture(const char* textureName, TextureHandleType type, bool clampToEdge)
{
   // case of assigning texture to NULL
   if(!textureName)
      return NULL;
   
   textureName = StringTable->insert(textureName);
   
   TextureObject *ret = TextureDictionary::find(textureName, type, clampToEdge);

   if(ret)
      return ret;

   GBitmap *bmp = loadBitmapInstance(textureName);
   if(!bmp)
      return NULL;
   
   if( type == InvertedBumpTexture )
   {
	// Get pixel address (0,0) of bitmap data for mip level 0.
	U32* pImageBits = bmp->getAddress(0,0,0);

	// Fetch total pixel count for bitmap.
	U32 PixelCount = bmp->getWidth(0) * mBitmap.getHeight(0);

	// Invert only the RGB components of the bitmap (leave alpha alone).
	for (u32 index = 0; index < PixelCount; ++index)
		pImageBits[index] ^= 0x00ffffff;
   }

   return registerTexture(textureName, bmp, type, clampToEdge);
}
#5
12/09/2002 (12:00 pm)
Nicolas: That's what I'm currently doing, but it would be better to invert the texture in code because then only one texture has to be specified AND the bump map and inverted bump map are guaranteed to match up.

And, I didn't think to put that in loadTexture. I'll try that out right now.
#6
12/11/2002 (1:40 pm)
OMG thanks a lot. It worked! :D

But, I had to make some modifications. Here's the working code:
if( type == InvertedBumpTexture )
   {
	// Get pixel address (0,0) of bitmap data for mip level 0.
	U8* pImageBits = bmp->getAddress(0,0,0);

	// Fetch total pixel count for bitmap.
	U32 PixelCount = bmp->getWidth(0) * bmp->getHeight(0) * bmp->bytesPerPixel;

	// Invert only the RGB components of the bitmap (leave alpha alone).
	for (U32 index = 0; index < PixelCount; ++index)
		pImageBits[index] ^= 0x00ffffff;
   }