The RgbImage C++ class provides the following functionalities:
The class members are described below; it should be straightforward to use them. For examples of programs that use RgbImage, see the TextureBmpModern and FourTexturesModern programs.
There are three constructors and one destructor:
RgbImage();
RgbImage(const char* filename);
RgbImage(int numRows, int numCols); // Allocate a bitmap (uninitialized) of this size.
~RgbImage();
RgbImage()
sets up a null texture map.
RgbImage(const char* filename);
reads
a texture map from the file. The file must be
a 24-bit RGB bitmap file.
RgbImage(int numRows, int numCols)
allocates
space for a texture map of the indicated size: its contents
are uninitialized. However,
use of this third constructor is not recommended (see the discussion below).
bool LoadBmpFile( const char *filename ); // Loads the bitmap from the specified file
bool WriteBmpFile( const char* filename ); // Write the bitmap to the specified file
bool LoadFromOpenglBuffer(); // Load the bitmap from the current OpenGL buffer
bool AllocateImageData(int numRows, int numCols); // Allocate a bitmap (uninitialized) of this size.
void Reset(); // Frees image data memory
These routines return true
if they succeed, but false
otherwise; errors can be obtained with GetError()
.
These routines (and all the routines documented below) are RgbImage member functions; that is, they need to be used with in conjunction with an RgbImage. For example, a file could be loaded by either
RgbImage texMap("myTexture.bmp");
or
RgbImage texMap;
texMap.LoadBmpFile("myTexture.bmp");
The routines LoadBmpFile()
and WriteBmpFile
read from and write a 24 RGB bitmap file. There is no
need to preallocate space for the texture map: the LoadBmpFile
always reallocates the image data buffer in the correct size for the texture
map contained in the bitmap file.
LoadFromOpenglBuffer
reads the RGB image
data from the current (front, center) OpenGL frame buffer.
This is a great way to save a rendered image to a
texture map. If there is no current allocation
of memory to hold the texture map,
LoadFromOpenglBuffer
automatically allocates
just enough space to hold the framebuffer contents.
If the current row and column dimensions
of the texture map allocation do not match the size
of the frame buffer, LoadFromOpenglBuffer
just loads what will fit.
If you want to use RgbImage without
using OpenGL, you should add #define RGBIMAGE_DONT_USE_OPENGL
to the header file: this disables the compilation
of LoadFromOpenglBuffer
.
Reset()
deallocates any space used for
holding a texture map data.
Use AllocateImageData
to allocate space
for a texture map of the indicated size. You probably should
never call this routine; instead let
LoadBmpFile()
or
LoadFromOpenglBuffer
do the allocation for you. AllocateImageData
does not deallocate any existing data; to avoid memory leaks,
you may need to call Reset()
before calling AllocateImageData
.
The function ImageData
gives you a pointer to the
texture map in a format suitable for specifying an OpenGL texture.
The function prototype is:
const void* ImageData() const { return (void*)ImagePtr; }
The RgbImage data is stored with pixels (texels) in row order, one byte per pixel, with row starting on word-aligned positions. As shown in the programs TextureBmpModern and FourTexturesModern, the RgbImage can be loaded into an OpenGL texture map with:
int textureWidth = texMap.GetNumCols();
int textureHeight = texMap.GetNumRows();
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, textureWidth, textureWidth, 0, GL_RGB, GL_UNSIGNED_BYTE, texMap.ImageData());
For more information, see the documentation for TextureBmpModern and FourTexturesModern.
The following routines let you query the status of the image data in the texture map:
long GetNumRows() const { return NumRows; } // Returns the width of the texture map
long GetNumCols() const { return NumCols; } // Returns the height of the texture map
// Rows are word aligned
long GetNumBytesPerRow() const { return ((3*NumCols+3)>>2)<<2; }
bool ImageLoaded() const { return (ImagePtr!=0); } // Is an image loaded?
The following routines let you access the
image data in the texture map. The texture map pixels (texels)
are stored as R,G,B values; each RGB value is an integer
between 0 and 255, namely an
unsigned char
. They can also be set or retrieved
as floating point numbers.
const unsigned char* GetRgbPixel( long row, long col ) const;
unsigned char* GetRgbPixel( long row, long col );
void GetRgbPixel( long row, long col, float* red, float* green, float* blue ) const;
void GetRgbPixel( long row, long col, double* red, double* green, double* blue ) const;
void SetRgbPixelf( long row, long col, double red, double green, double blue );
void SetRgbPixelc( long row, long col,
unsigned char red, unsigned char green, unsigned char blue );
If an error is encountered, a message is written to stderr. The
error codes can also be queried by
GetError()
. The possible error codes are
listed below.
int GetErrorCode() const { return ErrorCode; }
enum {
NoError = 0,
OpenError = 1, // Unable to open file for reading
FileFormatError = 2, // Not recognized as a 24 bit BMP file
MemoryError = 3, // Unable to allocate memory for image data
ReadError = 4, // End of file reached prematurely
WriteError = 5 // Unable to write out data (or no data to write out)
};