Importing bitmaps then using them

Started by
9 comments, last by empirical2 15 years, 8 months ago
//SOLVED// I have been troubled with this opengl/C++ issue for sometime and I could use some help. I was able to get started on one a function to import and use bitmaps. I spent a week trying to find info on such a subject and very little seem helpful. I know that to import a bitmap into a program (C++,windows, opengl) you first need to tell the program to open the file, then gather info from it, then convert it to bytes so it can be used. That data is then bind to the program for further use. My issue is this: I've been having issues with the whole converting to bytes part of the process. I believe that the importing and opengl parts are correct but I know that the BYTE part is incomplete and I dont know where to go next. I temporarily put texture_obj in glTexImage2d as the last argument, I know that the byte info should go there not this. Any tips or advise? I am really stumped and could use some help. Just looking for a simple way of importing and using .bmp files in a opengl application. Thanks EDIT revised code:
bool ImportBMP(char *filename, int num_list)
{
     AUX_RGBImageRec * Tx=auxDIBImageLoad(filename);
     
     if (!Tx)
     {
          return false;  
     }
     
     glGenTextures(1,&texture_lib[num_list]);
     glBindTexture(GL_TEXTURE_2D,texture_lib[num_list]);
     glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_WRAP_S,GL_REPEAT);
     glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_WRAP_T,GL_REPEAT); 
     glTexImage2D(GL_TEXTURE_2D, 0, 3, Tx->sizeX, Tx->sizeY, 0, GL_RGB, GL_UNSIGNED_BYTE, Tx->data);
     
     if (Tx)
     {
	      if (Tx->data) 
          {
               free(Tx->data);
          }
	      free(Tx);
     } 
     return true;
}


[Edited by - snowfell on August 13, 2008 7:59:35 PM]
Advertisement
Well, you could always use an image library such as DevIL or SOIL. Those two are always suggested in many threads. I believe they support all common formats such as BMP, PNG, GIF, JPEG, etc.

Of course if you want to write your own, then take a look at the BMP file format Some things I remember from the BMP format is that the red and blue channels are swapped, so instead of RGB its actually BGR. The image is also upside down.

Here is my code for loading a BMP (C++):

unsigned char* BitmapLoader::Load(std::string filename){	std::ifstream file(filename.c_str(), std::ios::binary);	//if the file was opened successfully, read the data	if(file.is_open()){			//read the offset value to the data portion		unsigned int offset = 0;		file.seekg(10, std::ios::beg);		file.read((char*)&offset, sizeof(unsigned int));		//read the width and height of the image		file.seekg(18, std::ios::beg);		file.read((char*)&width, sizeof(unsigned int));		file.read((char*)&height, sizeof(unsigned int));			//create the image array		data = new unsigned char[height * width * 3];				//reposition the current file position to the image data		file.seekg(offset, std::ios::beg);				//read the image data		for(unsigned int i=0; i<height; i++){			for(unsigned int j=0; j<width*3; j+=3){				//read the R,G,B values (actually BGR)				unsigned char colour[3];				file.read((char *)&colour[0], 3 * sizeof(char));									data[i*width*3 + j] =   colour[2];    //red				data[i*width*3 + j+1] = colour[1];    //green				data[i*width*3 + j+2] = colour[0];    //blue				}		}				//close the file		file.close();		return data;	}	//else, the file didn't open successfully	else{		return NULL;	}		}[/SOURCE]



Bind to the texture you want to load into then....

AUX_RGBImageRec * Tx=auxDIBImageLoad(*FileName);if (!Tx) return 0;glTexImage2D(GL_TEXTURE_2D, 0, 3, Tx->sizeX, Tx->sizeY, 0, GL_RGB, GL_UNSIGNED_BYTE, Tx->data);if (Tx){	if (Tx->data) free(Tx->data);	free(Tx);}glEnable(GL_TEXTURE_2D);
Its getting their but not working correctly yet :( Ok I added a few changes are recommended above, but the code still isn't working. Good thing (and sorta a bad thing) is that my revised code gives back no errors. But the textured objects remain white. I tried a few different things (using different textures, reading files from a different folder, ect) but none seemed to help. I am sure their must be one minor mistake somewhere here, and its preventing the rest from working. Could it be that one of the opengl commands arent binding the texture to texture_lib (a GLuint variable that should be holding my texture data).

bool ImportBMP(char *filename, int num_list){     AUX_RGBImageRec * Tx=auxDIBImageLoad(filename);          if (!Tx)     {          return false;       }          glGenTextures(1,&texture_lib[num_list]);     glBindTexture(GL_TEXTURE_2D,texture_lib[num_list]);     glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_WRAP_S,GL_REPEAT);     glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_WRAP_T,GL_REPEAT);      glTexImage2D(GL_TEXTURE_2D, 0, 3, Tx->sizeX, Tx->sizeY, 0, GL_RGB, GL_UNSIGNED_BYTE, Tx->data);          if (Tx)     {	      if (Tx->data)           {               free(Tx->data);          }	      free(Tx);     }      return true;}


[Edited by - snowfell on August 13, 2008 10:31:49 AM]
The only thing that I can think of is that you are not calling glEnable(GL_TEXTURE_2D) anywehere. And make sure that you call glBindTexture(GL_TEXTURE_2D, texture_lib[num_list]) before you start drawing.

If you think that some of the GL calls are failing, you can call glGetError() to see if they are failing.
Nope thats not it, I have glEnable(GL_TEXTURE_2D) right with the rest of my glEnables. And I have glBindTexture right before my build functions so I really doubt thats the problem. Any other things that could cause this problem? Are you sure that actual importing code and everything is correct? Please let me know of anything else that could be wrong or that I could check, I really need to get this working correctly.
You must bind to the texture first or it wont know which named texture your loading to.

1. Create a name
2. Bind to the texture
3. Do the glTexImage2D to copy your picture to the texture memory.
4. ENABLE textures.(Seems to require this to be recalled after loading)
5. Profit.


Also remember basic implementations must have the texture's width and height being one of the following values
2,4,8,16,32,64,128,256,512,1024,etc

(Width does not need to equal height)
Well I believe I have meet all the requirements above and still nothing... just white polygons. Are you guys sure that the code above is foolproof? I mean I not getting any error, and I know that the textures are being read, I just don't know if its successfully getting the date from the bmp files.

If their is any other information I need to give please let me know, I am in dire need of a answer here.

Should I be running this function as a bool type? Should I be using void or int?

[Edited by - snowfell on August 13, 2008 3:52:06 PM]
Ok this code below works for me. I just ran it in a test environment.

Some notes.
The order in which things done is clearly important since it didnt work when I tried your code above.

As well as the order I changed the texture name to a constant 1. This is because I use my own name generator (which is bad btw :) ) So i am not certain about your num_list thing.

It is important to remember to bind to this texture each frame and must be done outside of glBegin and glEnd.

Try this with one texture when you get it to work re-enable the name generator that way if it then breaks you know thats the problem. :)

bool ImportBMP(char *filename, int num_list){ 	glBindTexture(GL_TEXTURE_2D, 1);						AUX_RGBImageRec * Tx=auxDIBImageLoad(filename);	if (!Tx) {return 0;}	glTexImage2D(GL_TEXTURE_2D, 0, 3, Tx->sizeX, Tx->sizeY, 0, GL_RGB, GL_UNSIGNED_BYTE, Tx->data);	if (Tx)		{		if (Tx->data) free(Tx->data);		free(Tx);	}	glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);	glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);	glEnable(GL_TEXTURE_2D);					     return true;}
Dude now I got it running, I have no idea why it wasn't working before. Thanks tons empirical2 and everyone else. This was a big issue, now its fixed :)

This topic is closed to new replies.

Advertisement