Original Post
*** read my reply below for a small update, managed to fix the colors, it's an awkward 'hack' i think... i'll try to come up with better, i think i can just come up with an ugly hack to fix the skewing, i don't like either solutions. *** I'll keep this simple and clean, this is the result of my bitmap loader, and below that is all of my source code implementing the bitmap loader. The bitmap loader source originated from a tutorial on this site I think... but what I did is I tried to figure out how to get the pixel color at any given (x, y) coordinate since that wasn't implemented. It came out buggy, or at least not as I expected. So maybe someone can take a look. Original: http://www.threeam.info/tmp/664170_136_full.bmp Rendered: http://www.threeam.info/tmp/664170_136_full_bug.bmp ** Fixed color results: http://www.threeam.info/tmp/664170_136_full_bug_kindof.bmp ** The code I added to the bitmap loader: Bitmap Loader class: App using the loader class (cut it down a bit from original): (opengl screen coords are -1 -> +1 for both x, and y axis.) [Edited by - aevanthony on October 15, 2007 3:54:29 PM]
void Bitmap::getRGB(int x, int y)
{
if (rgb == NULL)
{ rgb = new int[3]; }
int i = ((y * width) + x) * RGB_BYTE_SIZE;
rgb[0] = *(data + i + 2);
rgb[1] = *(data + i + 1);
rgb[2] = *(data + i);
}
const short BITMAP_MAGIC_NUMBER = 19778;
const int RGB_BYTE_SIZE = 3;
#pragma pack(push,bitmap_data,1)
typedef struct tagRGBQuad
{
char rgbBlue;
char rgbGreen;
char rgbRed;
char rgbReserved;
} RGBQuad;
typedef struct tagBitmapFileHeader
{
unsigned short bfType;
unsigned int bfSize;
unsigned short bfReserved1;
unsigned short bfReserved2;
unsigned int bfOffBits;
} BitmapFileHeader;
typedef struct tagBitmapInfoHeader
{
unsigned int biSize;
int biWidth;
int biHeight;
unsigned short biPlanes;
unsigned short biBitCount;
unsigned int biCompression;
unsigned int biSizeImage;
int biXPelsPerMeter;
int biYPelsPerMeter;
unsigned int biClrUsed;
unsigned int biClrImportant;
} BitmapInfoHeader;
#pragma pack(pop,bitmap_data)
class Bitmap
{
public:
RGBQuad *colours;
char *data;
bool loaded;
int width, height;
unsigned short bpp;
int *rgb;
Bitmap (void);
Bitmap (char *);
~Bitmap ();
bool loadBMP (char *);
void getRGB (int x, int y);
private:
BitmapFileHeader bmfh;
BitmapInfoHeader bmih;
int byteWidth; //the width in bytes of the image
int padWidth; //the width in bytes of the added image
unsigned int dataSize; //size of the data in the file
void reset(void);
bool convert24 (char *); //convert to 24bit RGB bottom up data
bool convert8 (char *); //convert to 8bit RGB bottom up data
};
void Bitmap::getRGB(int x, int y)
{
rgb = new int[3];
int offset = padWidth - byteWidth,
i = (width * (y * RGB_BYTE_SIZE)) + (x * RGB_BYTE_SIZE);
if ((i+1)%padWidth == 0)
{ i += offset; }
rgb[0] = *(data + i + 2);
rgb[1] = *(data + i + 1);
rgb[2] = *(data + i);
}
Bitmap::Bitmap()
{
reset();
}
Bitmap::Bitmap(char *file)
{
reset();
loadBMP(file);
}
Bitmap::~Bitmap()
{
if (colours!=0)
{ delete[] colours; }
if (data!=0)
{ delete[] data; }
}
bool Bitmap::loadBMP(char *file)
{
FILE *in; //file stream for reading
char *tempData; //temp storage for image data
int numColours; //total available colours
loaded = false;
if (colours != 0)
{ delete[] colours; }
if (data!=0)
{ delete[] data; }
in = fopen(file,"rb");
if (in == NULL)
{
fclose(in);
return false;
}
fread(&bmfh, sizeof(BitmapFileHeader), 1, in);
if (bmfh.bfType != BITMAP_MAGIC_NUMBER)
{
fclose(in);
return false;
}
fread(&bmih, sizeof(BitmapInfoHeader), 1, in);
width = bmih.biWidth;
height = bmih.biHeight;
bpp = bmih.biBitCount;
dataSize = (width * height * (unsigned int)(bmih.biBitCount/8.0));
numColours = (1 << bmih.biBitCount);
if (bpp < 8)
{
fclose(in);
return false;
}
if (bpp == 8)
{
colours = new RGBQuad[numColours];
fread(colours, sizeof(RGBQuad), numColours, in);
}
tempData = new char[dataSize];
if (tempData == NULL)
{
fclose(in);
return false;
}
fread(tempData, sizeof(char), dataSize, in);
fclose(in);
byteWidth = padWidth = (int)((float)width * (float)bpp / 8.0);
while (padWidth%4 != 0)
{ ++padWidth; }
if (bpp == 8)
{ loaded = convert8(tempData); }
else if (bpp == 24)
{ loaded = convert24(tempData); }
delete[] tempData;
return loaded;
}
void Bitmap::reset(void)
{
loaded = false;
colours = 0;
data = 0;
}
bool Bitmap::convert24(char* tempData)
{
int offset, diff;
diff = width * height * RGB_BYTE_SIZE;
data = new char[diff];
if (data == NULL)
{
delete[] data;
return false;
}
if (height > 0)
{
offset = padWidth - byteWidth;
for (int i=0; i<dataSize; i+=RGB_BYTE_SIZE)
{
if ((i+1)%padWidth == 0)
{ i += offset; }
*(data+i+2) = *(tempData+i);
*(data+i+1) = *(tempData+i+1);
*(data+i) = *(tempData+i+2);
}
}
else
{
offset = padWidth - byteWidth;
for (int i=0, j=dataSize-RGB_BYTE_SIZE; i<dataSize; i+=RGB_BYTE_SIZE, j-=3)
{
if ((i+1)%padWidth == 0)
{ i += offset; }
*(data+j+2) = *(tempData+i);
*(data+j+1) = *(tempData+i+1);
*(data+j) = *(tempData+i+2);
}
}
return true;
}
bool Bitmap::convert8(char* tempData)
{
int offset, diff;
diff = width * height * RGB_BYTE_SIZE;
data = new char[diff];
if (data == NULL)
{
delete[] data;
return false;
}
if (height>0)
{
offset = padWidth - byteWidth;
for (int i=0, j=0; i<dataSize*RGB_BYTE_SIZE; i+=RGB_BYTE_SIZE, ++j)
{
if ((i+1)%padWidth==0)
{ i += offset; }
*(data+i) = colours[*(tempData+j)].rgbRed;
*(data+i+1) = colours[*(tempData+j)].rgbGreen;
*(data+i+2) = colours[*(tempData+j)].rgbBlue;
}
}
else
{
offset = padWidth - byteWidth;
for (int i=0, j=dataSize-1; i<dataSize*RGB_BYTE_SIZE; i+=RGB_BYTE_SIZE, --j)
{
if ((i+1)%padWidth==0)
{ i += offset; }
*(data+i) = colours[*(tempData+j)].rgbRed;
*(data+i+1) = colours[*(tempData+j)].rgbGreen;
*(data+i+2) = colours[*(tempData+j)].rgbBlue;
}
}
return true;
}
Bitmap *lbmp;
static void display(void)
{
if (keypress)
{
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glLoadIdentity();
glPushMatrix();
glBegin(GL_POINTS);
static int x, y;
static float r, g, b, cx, cy;
for (x=0; x<lbmp->width; ++x)
for (y=0; y<lbmp->height; ++y)
{
lbmp->getRGB(x, y);
r = lbmp->rgb[0] / 255.0;
g = lbmp->rgb[1] / 255.0;
b = lbmp->rgb[2] / 255.0;
cx = (x / float(lbmp->width / 2.0)) - 1.0;
cy = (y / float(lbmp->height / 2.0)) - 1.0;
glColor3f (r, g, b);
glVertex3f (cx, cy, 0.0);
}
glEnd();
glPopMatrix();
keypress = false;
}
glutSwapBuffers();
Sleep(1);
}
int main(int argc, char *argv[])
{
lbmp = new Bitmap("664170_136_full.bmp");
//...
}