I am working on a project, that uses some legacy graphics, that are in an 8bit indexed bitmaps. These are the ones with a 1 byte pixel, pointing to an array of 256 colors.
So far, this is how I have been doing things.... (note, I'm using C#, with OpenTK, although a solution in C++ can be easily converted)
Bitmap bitmap = new Bitmap(path);
System.Drawing.Imaging.BitmapData textureData = bitmap.LockBits(
new Rectangle(0, 0, bitmap.Width, bitmap.Height),
System.Drawing.Imaging.ImageLockMode.ReadOnly,
System.Drawing.Imaging.PixelFormat.Format8bppIndexed);
int srcmax = textureData.Height * textureData.Stride;
byte[] origBytes = new Byte[srcmax];
Marshal.Copy(textureData.Scan0, origBytes, 0, srcmax);
bitmap.UnlockBits(textureData);
this gives me the bitmap pixel data (the 1 byte index numbers) in textureData.
So now, I very slowly and very painfully, go through the data, as such....
//loop through all the pixels
byte[] data = new byte[(bitmap.Width * bitmap.Height) * 4];
int srcloc = 0;
int dstloc = 0;
byte index;
Color color;
for (int y = 0; y < textureData.Height; y++)
{
srcloc = y * textureData.Stride;
for (int x = 0; x < textureData.Width; x++)
{
index = origBytes[srcloc];
if (index == 0)
{
data[dstloc] = 0;
data[dstloc + 1] = 0;
data[dstloc + 2] = 0;
data[dstloc + 3] = 0;
}
else
{
color = bitmap.Palette.Entries[index];
data[dstloc] = color.R;
data[dstloc + 1] = color.G;
data[dstloc + 2] = color.B;
data[dstloc + 3] = color.A;
}
dstloc += 4;
srcloc++;
}
}
as you can see, I am looking at the color, pointed to, by each pixel index... and manually reversing the red, and blue values, and also, setting alpha to 0, when the index number is 0. This converted data is then used to create an opengl texture, as follows...
GL.Enable(EnableCap.Texture2D);
uint textureID = 0;
GL.GenTextures(1, out textureID);
GL.BindTexture(TextureTarget.Texture2D, ret.ID);
GL.TexParameter(TextureTarget.Texture2D, TextureParameterName.TextureWrapS, (float)TextureWrapMode.Clamp);
GL.TexParameter(TextureTarget.Texture2D, TextureParameterName.TextureWrapT, (float)TextureWrapMode.Clamp);
GL.TexParameter(TextureTarget.Texture2D, TextureParameterName.TextureMinFilter, (float)TextureMinFilter.Nearest);
GL.TexParameter(TextureTarget.Texture2D, TextureParameterName.TextureMagFilter, (float)TextureMagFilter.Nearest);
GL.TexImage2D(TextureTarget.Texture2D, 0, PixelInternalFormat.Rgba, width, height, 0,
PixelFormat.Rgba, PixelType.UnsignedByte, pixelData);
GL.Disable(EnableCap.Texture2D);
Now... this totally works, I end up with a rgba opengl texture2d, with transparency that can be used to texture a quad and it looks perfect.... only problem is the super slow speed of going through each pixel, as some of these images are > 800x800
So... If anyone knows of a better solution, something faster, or if you know of anything I seem to be doing wrong (opengl wise, as I am an opengl noob) please let me know.
Thanks