Texture Binding with OpenGL
I am trying to bind two different textures (BMP pictures really) to two different cubes. I went by NeHe's tutorial on binding/loading bitmaps and found the glaux.lib is not recommended, and a long time ago (year or so) I found a snippet for loading bitmaps that worked well without needing extra libraries/files. Now my problem is binding more than one texture, to more than one area. I can do it, but it is essentially loading the bitmap everytime it scans the screen, and this causes it to run very very very slow (like half a frame per second). I would like to know if there is a better, more efficient way to bind textures to more than one surface.
EDIT: If I load the bitmaps before I begin the glBegin(QUADS) it will load the correct texture to the correct cube, however that is what causes the screen to run extremely slow. I have also searched around in numerous places and I keep coming up with "don't use glaux.lib" stuff, and nothing useful.
Code:
//BITMAP LOADER
bool CustomLoadBitmap(char *filename, GLuint &num_texture)
{
int i, j=0; //Index variables
FILE *l_file; //File pointer
unsigned char *l_texture; //The pointer to the memory zone in which we will load the texture
// windows.h gives us these types to work with the Bitmap files
BITMAPFILEHEADER fileheader;
BITMAPINFOHEADER infoheader;
RGBTRIPLE rgb;
num_texture++; // The counter of the current texture is increased
if((l_file = fopen(filename, "rb"))==NULL) return (-1); // Open the file for reading
fread(&fileheader, sizeof(fileheader), 1, l_file); // Read the fileheader
fseek(l_file, sizeof(fileheader), SEEK_SET); // Jump the fileheader
fread(&infoheader, sizeof(infoheader), 1, l_file); // and read the infoheader
// Now we need to allocate the memory for our image (width * height * color deep)
l_texture = (byte *) malloc(infoheader.biWidth * infoheader.biHeight * 4);
// And fill it with zeros
memset(l_texture, 0, infoheader.biWidth * infoheader.biHeight * 4);
// At this point we can read every pixel of the image
for (i=0; i < infoheader.biWidth*infoheader.biHeight; i++)
{
// We load an RGB value from the file
fread(&rgb, sizeof(rgb), 1, l_file);
// And store it
l_texture[j+0] = rgb.rgbtRed; // Red component
l_texture[j+1] = rgb.rgbtGreen; // Green component
l_texture[j+2] = rgb.rgbtBlue; // Blue component
l_texture[j+3] = 255; // Alpha value
j += 4; // Go to the next position
}
fclose(l_file); // Closes the file stream
glBindTexture(GL_TEXTURE_2D, num_texture); // Bind the ID texture specified by the 2nd parameter
// The next commands sets the texture parameters
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT); // If the u,v coordinates overflow the range 0,1 the image is repeated
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); // The magnification function ("linear" produces better results)
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_NEAREST); //The minifying function
glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE); // We don't combine the color with the original surface color, use only the texture map.
// Finally we define the 2d texture
glTexImage2D(GL_TEXTURE_2D, 0, 4, infoheader.biWidth, infoheader.biHeight, 0, GL_RGBA, GL_UNSIGNED_BYTE, l_texture);
// And create 2d mipmaps for the minifying function
gluBuild2DMipmaps(GL_TEXTURE_2D, 4, infoheader.biWidth, infoheader.biHeight, GL_RGBA, GL_UNSIGNED_BYTE, l_texture);
free(l_texture); // Free the memory we used to load the texture
//return (num_texture); // Returns the current texture OpenGL ID
}
//WHERE THE BITMAP IS LOADED, IF ONE IS LOADED THE SCREEN RUNS FINE WITH NO
//SIGNS OF SLOWING DOWN. IF TWO ARE LOADED IT WILL ONLY DISPLAY THE LAST ONE.
int InitGL(GLvoid) // All Setup For OpenGL Goes Here
{
if(!CustomLoadBitmap("data/guitar.bmp",texture[0])){
return false;
}
if(!CustomLoadBitmap("data/Crate.bmp",texture[1])){
return false;
}
glShadeModel(GL_SMOOTH); // Enable Smooth Shading
glClearColor(0.0f, 0.0f, 0.0f, 0.5f); // Black Background
glClearDepth(1.0f); // Depth Buffer Setup
glEnable(GL_TEXTURE_2D);
glEnable(GL_DEPTH_TEST); // Enables Depth Testing
glDepthFunc(GL_LEQUAL); // The Type Of Depth Testing To Do
glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST); // Really Nice Perspective Calculations
glEnable(GL_LIGHT1);
//SetCursorPos(mid_x, mid_y);
return TRUE; // Initialization Went OK
}
//THE DRAWING PORTION
int DrawGLScene(GLvoid) // Here's Where We Do All The Drawing
{
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); // Clear Screen And Depth Buffer
glLoadIdentity();
heading = 360.0f - lookdir; // Reset The Current Modelview Matrix
glRotatef(heading,0,1.0f,0);
glTranslatef(xpos,jump,zpos); //moves the starting position
DrawCrateNear(); //this is in a header file so the .cpp file stays cleaner
DrawCrateFar(); //same here
xrot = xspeed;
yrot = yspeed;
return TRUE; // Everything Went OK
}