Using the DevIL library should be the easiest way, especially if you plan to feed OpenGL with the BMP data.
class CBitmap{private: unsigned short width; unsigned short height; unsigned char* data; public: // Constructor inline CBitmap() { data = NULL; } // Overloaded constructor inline CBitmap( char *fileName ) { data = NULL; // Set data to NULL so createBitmap won''t think we alredy have a bitmap createBitmap( fileName ); } // Destructor inline ~CBitmap() { destroyBitmap(); } // Create a new 24-bits RGB-bitmap from a bmp file bool createBitmap( char *fileName ) { if ( data != NULL ) return false; FILE *file; BITMAPFILEHEADER fileHeader; BITMAPINFOHEADER infoHeader; RGBQUAD *palette = NULL; // = NULL for ( ''palette'' may be used without having been initialized ). file = fopen( fileName, "rb" ); if ( file == NULL ) return false; // Read the header fread( &fileHeader, sizeof( BITMAPFILEHEADER ), 1, file ); // Check if it is a real bitmap if ( fileHeader.bfType != bitmapId() ) { fclose( file ); return false; } // read the info header fread( &infoHeader, sizeof( BITMAPINFOHEADER ), 1, file ); // We can only read RGB bitmaps if ( infoHeader.biCompression != BI_RGB ) { fclose( file ); return false; } // We can read 8-bit ( 256 colors ) bitmaps, if ( infoHeader.biBitCount == 8 ) { if ( infoHeader.biClrUsed == 0 ) // This means a palette of 256 colors. infoHeader.biClrUsed = 256; // Create and read the palette. palette = new RGBQUAD[ infoHeader.biClrUsed ]; fread( palette, infoHeader.biClrUsed * sizeof( RGBQUAD ), 1, file ); } else if (( infoHeader.biBitCount != 24 ) && ( infoHeader.biBitCount != 1 )) // And we can read 24-bits ( 2^24 colors ) and 1-bits ( 2 color ) bitmaps. { fclose( file ); return false; } // Go to the picture bits. fseek( file, fileHeader.bfOffBits, SEEK_SET ); width = (unsigned short)abs( infoHeader.biWidth ); height = (unsigned short)abs( infoHeader.biHeight ); // Store the size of the bitmap. int size = ( width * height * 3 ); data = new unsigned char[ size ]; if ( infoHeader.biBitCount == 24 ) { fread( data, size, 1, file ); // We can just read the bitmap. // Swap the R and B values to get RGB since the bitmap color format is in BGR. swapColors( data, size ); } else if ( infoHeader.biBitCount == 8 ) // With 8 bit we need to create the colors with the palette. { // We only read 1 byte per RGB so it 3 times smaller. int tempSize = size / 3; unsigned char *tempData = new unsigned char[ tempSize ]; fread( tempData, tempSize, 1, file ); // Create the bitmap with the palette and the data we read. int j = 0; for ( int i = 0; i < tempSize; i++ ) { data[j+0] = palette[ tempData[i] ].rgbRed; data[j+1] = palette[ tempData[i] ].rgbGreen; data[j+2] = palette[ tempData[i] ].rgbBlue; j += 3; } // Delete the palette and the tempdata. delete [] palette; delete [] tempData; } else if ( infoHeader.biBitCount == 1 ) // With 1 bit we need to create the colors from 1 bit. { // We only read 1 bit per RGB so it ((size/3)/8) times smaller. int tempSize = (size / 3) / 8; unsigned char *tempData = new unsigned char[ tempSize ]; fread( tempData, tempSize, 1, file ); // Create the bitmap with the data we read. int j = 0; for ( int i = 0; i < tempSize; i++ ) { // We need to go through all the 8 bits for ( int n = 7; n >= 0; n-- ) { if ( tempData[i] & (1<<n) ) // Black { data[j+0] = 0; data[j+1] = 0; data[j+2] = 0; j += 3; } else // White { data[j+0] = 255; data[j+1] = 255; data[j+2] = 255; j += 3; } } } // Delete the palette and the tempdata. delete [] tempData; } // We don''t need the file anymore. fclose( file ); return true; } // Save the bitmap to a file bool saveBitmap( char *fileName ) // TODO: Bitmaps won''t show as thumbnails in winXP? { if ( data == NULL ) return false; FILE *file; BITMAPFILEHEADER fileHeader; BITMAPINFOHEADER infoHeader; file = fopen( fileName, "wb" ); // Check if we could open the file if ( file == NULL ) return false; // Fill the BITMAPFILEHEADER struct fileHeader.bfSize = sizeof( BITMAPFILEHEADER ); fileHeader.bfType = bitmapId(); fileHeader.bfReserved1 = 0; fileHeader.bfReserved2 = 0; fileHeader.bfOffBits = sizeof( BITMAPFILEHEADER ) + sizeof( BITMAPINFOHEADER ); // Write the BITMAPFILEHEADER struct fwrite( &fileHeader, sizeof( BITMAPFILEHEADER ), 1, file ); int size = ( width * height * 3 ); // Fill the BITMAPINFOHEADER struct to the file infoHeader.biSize = sizeof( BITMAPINFOHEADER ); infoHeader.biPlanes = 1; infoHeader.biBitCount = 24; infoHeader.biCompression = BI_RGB; infoHeader.biSizeImage = size; infoHeader.biXPelsPerMeter = 0; infoHeader.biYPelsPerMeter = 0; infoHeader.biClrUsed = 0; infoHeader.biClrImportant = 0; infoHeader.biWidth = width; infoHeader.biHeight = height; // Write the BITMAPINFOHEADER struct to the file fwrite( &infoHeader, sizeof( BITMAPINFOHEADER ), 1, file ); // Create a new buffer which will hold the data we are going to save // We need a new buffer because we have to swap RGB to BGR unsigned char *tempData = new unsigned char[ size ]; // Copy the data to the buffer memcpy( tempData, data, size ); // Swap the R and B values to get BGR. swapColors( tempData, size ); fwrite( tempData, size, 1, file ); fclose( file ); // Delete the temporary buffer delete [] tempData; return true; } // Destroy a window if we have one inline void destroyBitmap() { if ( data == NULL ) return; delete [] data; data = NULL; } // Return the bitmaps data inline unsigned char *getData() { return data; } // Return the bitmaps width inline unsigned short getWidth() { return width; } // Return the bitmaps width inline unsigned short getHeight() { return height; } // Return the Universal bitmap identifier 0x4D42 static unsigned short bitmapId() { return 0x4D42; } // Swap the red and blue bytes. // Windows stores bitmaps in BGR ( Blue, Green, Red ) static void swapColors( void* buffer, int size ) { int s = size / 3; __asm { mov ecx, s mov ebx, buffer label: mov al, [ebx+0] xchg al, [ebx+2] mov [ebx+0], al add ebx,3 loop label } }};
so... then what? i mean, you then have a bmp in your memory, but how do you convert it into a texture?
You go to NeHe''s main site and study tutorial 6. It has loading bitmaps and displaying it as texture.
// to create the textureGLuint t;CBitmap b;b.createBitmap("thatexture.bmp");glGenTextures(1, &t);glBindTexture(GL_TEXTURE_2D, t);\glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);glTexImage2D(GL_TEXTURE_2D, 0, 3, b.getWidth(), b.getHeight(), 0, GL_RGB, GL_UNSIGNED_BYTE, b.getData());b.destroyBitmap(); // you won''t need this anymore// to use the textureglBindTexture(GL_TEXTURE_2D, t);glBegin(GL_TRIANGLES);... // render stufglEnd();// to destroy the textureglDeleteTextures(1, &t);[/code]
ah I misunderstood the entire thing... since the tutor already uses LoadBMP, what is the advantage of creating this class? purely getting rid of AUX_RGBImageRec? and does that mean you can get rid of the header glaux?
quote:Original post by Ruudje
ah I misunderstood the entire thing... since the tutor already uses LoadBMP, what is the advantage of creating this class? purely getting rid of AUX_RGBImageRec? and does that mean you can get rid of the header glaux?
Precisely
This topic is closed to new replies.
Advertisement
Popular Topics
Advertisement