PDA

View Full Version : How to Draw a 8-bits DIB in OpenGL?



Keddy
05-24-2002, 06:45 AM
I just know it's related with something like palette.But I don't know how to define and implement it.
I'm a newbie in opengl and my correlative knowledge is not rich,so if you would give your reply,please write down it in details.
All advices are welcome.
Thank you very much!

[This message has been edited by Keddy (edited 05-24-2002).]

Robbo
05-24-2002, 07:39 AM
This certainly isn't the quickest method, but I'm using it at present (NOTE: I'm using a texture library manager here, but essentially what I'm doing is creating RGB triples by using the DIB pixel value to look up R, G and B in the DIB palette. The final result is basically an array of RGB values that is then bound as a texture. I'm also using my own `CDib' class here - you should be able to get the idea though http://www.opengl.org/discussion_boards/ubb/wink.gif

//
// Re-generate a texture from the given dib - only works on 8 or 24 bit source DIB and 32 bit destination texture.
//

void CTextureMaps :: Regenerate ( CDib& Source, const tstring& Name )

{
//
// Bitmap info.
//

const BITMAPINFO *pInfo = Source.BitmapInfo ();

assert ( pInfo != 0 );
assert ( pInfo->bmiHeader.biBitCount == 8 | | pInfo->bmiHeader.biBitCount == 24 );

//
// Get the texture `name'.
//

CTextureMap& Destination = Get ( Name );
//assert ( Destination.GetFormat () == GL_RGBA );

//
// Destroy the texture, creating a new texture the same size as our dib.
//

if ( Destination.GetX () != Source.Width () | | Destination.GetY () != Source.Height () )
{
Destination.Create ( Name, Source.Width (), Source.Height (), GL_RGBA, Destination.GetBindX (), Destination.GetBindY () );
}

//
// Ok, now we need to transfer the pixels across, using the palette information as a look-up.
//

BYTE *pPixels = Source.Pixels ();

assert ( pPixels != 0 );

//
// Get map texels (should all be blank).
//

CTexels& Map = const_cast<CTexels&>(Destination.Map ());

//
// Get the number of colour indexes.
//

int nColours;

if ( pInfo->bmiHeader.biClrUsed == 0 )
{
nColours = ( 1 << pInfo->bmiHeader.biBitCount );
}
else
{
nColours = pInfo->bmiHeader.biClrUsed;
}

//
// and the palette entry array.
//

PALETTEENTRY *pPalette = ( PALETTEENTRY *) &pInfo->bmiColors;

//
// Get information about bitmap - remember DWORD aligned pitch (just to comlicate things for us).
//

int Size = Destination.GetSize (), Width = Source.Width (), Height = Source.Height (), Pitch = Source.Pitch ();

//
// Iterate.
//

if ( pInfo->bmiHeader.biBitCount == 8 )
{
for ( int y = 0, d = 0; y < Height; y++, pPixels += Pitch )
{
for ( int s = 0; s < Width; s++, d += 4 )
{
PALETTEENTRY *pEntry = &pPalette [pPixels[s]];

Map [d] = pEntry->peBlue;
Map [d+1] = pEntry->peGreen;
Map [d+2] = pEntry->peRed;
Map [d+3] = 255;
}
}
}
else if ( pInfo->bmiHeader.biBitCount == 24 )
{
for ( int y = 0, d = 0; y < Height; y++, pPixels += Pitch )
{
for ( int s = 0, q = 0; s < Width; s++, d += 4, q += 3 )
{
Map [d] = pPixels [q+2];
Map [d+1] = pPixels [q+1];
Map [d+2] = pPixels [q+0];
Map [d+3] = 255;
}
}
}

//
// Now, rebind the texture.
//

Destination.Bind ();
}