Mapping an image from a BMP file onto an OpenGL polygon

I’m currently learning how to perform texture mapping. But I’m not certain how to map an image (stored in a separate BMP file) onto an OpenGL polygon. If I was to create the texture image myself, I would simply pass a pointer to that texture image to the glTexture2D function… but what if I want to load an image in a separate BMP file? Is there a C/C++ function that reads in a BMP file and returns a pointer to it? Can anyone supply me with a link where I can find sample code that reads in a BMP image, creates a texture object and maps it onto a polygon?

thanx =)

A C/C++ function that does it? Nope. I’ll assume you’re using Windows; the Win32 API has at least a couple functions dedicated to loading up BMPs. I’m more of a do-it-myself kind of guy so I can’t help you out with them right now. Try MSDN. What I did (and another thing you might do) is write your own BMP loading routine. You can get one with pretty basic functionality running with not an extreme amount of effort.

Yeah, you’re right… I checked MSDN and there are a couple (i.e. LoadBitmap) functions that do it. But, like you, I’m trying to keep my program platform-independant (although I am developing on a PC) so I’m not crazy about using MFC in my code.

I would definitely like to write my own loading routine, but I don’t know anything about the internal structure of bitmap files. IS there a tutorial or info-sheet on the internal structure (i.e. headers/enders/data/where they are/how big each portion is) of bitmap files?

thanx a lot =)

My BMGLib project can read several different file formats (including BMP). There is an example application that shows you how to apply the image as a texture. The BMGLib project can be obtained from my web site. Source code is included.

Regards,
Scott http://members.home.net/~scottheiman

You can find info on a wide variety of file formats (including BMP) at www.wotsit.org

unsigned int texture[1];

// Structure for holding bitmap info
struct Image{
long SizeX;
long SizeY;
char *data;
};
typedef struct Image Image;

void LoadBMP(char *filename, Image *image){
FILE *file;
short int bpp;
short int planes;
long i;
long size;
char temp;

file = fopen(filename, “rb”);
fseek(file, 18, SEEK_CUR);
i = fread(&image->SizeX, 4, 1, file);
i = fread(&image->SizeY, 4, 1, file);
size = image->SizeX * image->SizeY * 3;
i = fread(&bpp, 2, 1, file);
i = fread(&planes, 2, 1, file);
fseek(file, 24, SEEK_CUR);
image->data = (char *)malloc(size);
i = fread(image->data, size, 1, file);
for(i = 0; i < size; i+=3){
temp = image->data[i];
image->data[i] = image->data[i+2];
image->data[i+2] = temp;
}
fclose(file);
free(image);
}

void LoadTextures(void){
Image *image1;

image1 = (Image *)malloc(sizeof(Image));
LoadBMP(“whatever.bmp”, image1);
glGenTextures(1, &texture[0]);
glBindTexture(GL_TEXTURE_2D, texture[0]);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_NEAREST);
gluBuild2DMipmaps(GL_TEXTURE_2D, 3, image1->SizeX, image1->SizeY, GL_RGB, GL_UNSIGNED_BYTE, image1->data);
}

Then to use it just like this:

glBindTexture(GL_TEXTURE_2D, texture[0]);
glBegin(GL_QUADS);
glTexCoord2f(0.0, 0.0); glVertex3f(-1.0, -1.0, -1.0);

glTexCoord2f(0.0, 1.0); glVertex3f(-1.0, 1.0, -1.0);

glTexCoord2f(1.0, 1.0); glVertex3f(1.0, 1.0, -1.0);

glTexCoord2f(1.0, 0.0); glVertex3f(1.0, -1.0, -1.0);

  • This is based more or less on the NeHe Loading code but it is simplified quite a bit
    **Could be some syntax mistakes since i did this quickly.

[This message has been edited by MrShoe (edited 01-08-2002).]

hey guys, thanx a lot for the great advice =)
I still have a couple points I’d like to clear up…

I heard that in order to perform texture mapping correctly, the size of the texture image is restricted to certain sizes only. FOr example, one guy told me that the length/width of the texture image MUST be 2N+2 where N is an integer. Another guy tells me that the length/width of the texture image MUST be 2^N (2 to the Nth power) where N is an integer. Which one is the correct one?

Is there really a size restriction such as this? If so, why does this restriction exist?
I find it hard to believe that the people in the graphic arts department are going to able to draw me a texture that exactly matches these size restrictions… in this case what can I do to the image in order to make it meet the requirements? Is there an OpenGL scaling function? Or do I have to manually omit part of the image in order to satisfy the restriction?

Textures must be of size 2^N x 2^N
there are ways around this, but its not as bad a restriction as you might imagine

To clarify the previous post, textures need not be square in OpenGL so the dimensions should really fit 2^n x 2^m.

Just let your artists create their art within some upper size limits (like no images larger than 512x512) then you can simply make the determination to either resample the image to fit the 2^n x 2^m requirement, or you can pad the image to do so. Textures for sprites look best padded (unless they are already made to size of course). Material textures usually look fine resampled, again barring some exceptions.

[This message has been edited by DFrey (edited 01-08-2002).]