C Board  

Go Back   C Board > General Programming Boards > Game Programming

Reply
 
LinkBack Thread Tools Display Modes
Old 06-29-2008, 10:55 AM   #1
Registered User
 
Join Date: Mar 2007
Posts: 335
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
}
__________________
home page (new layout)
scwizzo is offline   Reply With Quote
Old 06-29-2008, 11:48 AM   #2
Registered User
 
Join Date: Feb 2008
Location: Rochester, NY
Posts: 27
Load the BMP files as you are doing before the render loop. In the render loop you are going to have to bind the texture for use before drawing the specific shape.

Essentially you'll do:
Code:
InitGL()
Render()
{
     glBindTexture(GL_TEXTURE_2D, texture1);
     DrawCube();
     glBindTexture(GL_TEXTURE_2D, texture2);
     DrawCube();
}
CornyKorn21 is offline   Reply With Quote
Old 06-29-2008, 01:19 PM   #3
Registered User
 
Join Date: Mar 2007
Posts: 335
I tried that and it still behaves the same as before. I even switched the glBindTexture() to have the same array variable which was not the last one loaded (the crate.bmp). Does this have something to do with the glBindTexture() being inside the CustomLoadBitmap() ?
__________________
home page (new layout)
scwizzo is offline   Reply With Quote
Old 06-30-2008, 02:42 PM   #4
Registered User
 
Join Date: Feb 2008
Location: Rochester, NY
Posts: 27
Code:
//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

    glBindTexture(GL_TEXTURE_2D, texture[0]);
    DrawCrateNear(); //this is in a header file so the .cpp file stays cleaner
    glBindTexture(GL_TEXTURE_2D, texture[1]);
    DrawCrateFar(); //same here

    xrot = xspeed;
    yrot = yspeed;

    return TRUE; // Everything Went OK
}
I'm almost positive this is how your code should look. Other than that everything else should be fine. I'm not sure what code you have in the two DrawCrate functions. There might be something which messes up textures at that point.
CornyKorn21 is offline   Reply With Quote
Old 06-30-2008, 10:22 PM   #5
Registered User
 
Join Date: Mar 2007
Posts: 335
I moved the glBindTexture() inside the DrawCrate functions and it will still only show the last of the loaded textures put in the InitGL(). The DrawCrate functions are simply just coordinates for how the boxes should be drawn. Here is one of the functions (these are in header files by the way).

EDIT: if this helps any, i changed the texture[] array number from 0 and 1 to 1 and 2 where it gets binded to the box i want, and the second box shows up white without texture. I think it has something to do with the way the bitmap is loaded in the loading function.

Code:
bool DrawCrateNear(void){

    glBindTexture(GL_TEXTURE_2D,texture[0]);

    glBegin(GL_QUADS);
//-----FRONT------------
        //glColor3f(1.0f,0.0f,0.0f);
        glTexCoord2f(1.0f,1.0f); glVertex3f(1.0,1.0,0.0);

        //glColor3f(0.0f,1.0f,0.0f);
        glTexCoord2f(1.0f,0.0f); glVertex3f(1.0,-1.0,0.0);

        //glColor3f(1.0f,0.0f,0.0f);
        glTexCoord2f(0.0f,0.0f); glVertex3f(-1.0,-1.0,0.0);

        //glColor3f(0.0f,1.0f,0.0f);
        glTexCoord2f(0.0f,1.0f); glVertex3f(-1.0,1.0,0.0);

//..... after a ton of coords....

//-----BOTTOM-----------------
        glTexCoord2f(1.0f,1.0f); glVertex3f(-1.0,-1.0,-2.0);

        //glColor3f(0.0f,1.0f,0.0f);
        glTexCoord2f(1.0f,0.0f); glVertex3f(-1.0,-1.0,0.0);

        //glColor3f(1.0f,0.0f,0.0f);
        glTexCoord2f(0.0f,0.0f); glVertex3f(1.0,-1.0,0.0);

        //glColor3f(0.0f,1.0f,0.0f);
        glTexCoord2f(0.0f,1.0f); glVertex3f(1.0,-1.0,-2.0);
    glEnd();

    return true;
}
EDIT 2: I figured it out! The CustomLoadBitmap() was not generating the textures with glGenTextures() like it should have. The final loader for the bitmaps is the following code.

Code:
bool CustomLoadBitmap(char *filename, GLuint &num_texture)
{
    int i, j=0,count=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;

    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

    num_texture++; // The counter of the current texture is increased

    // 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

    glGenTextures(1, &num_texture);

    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

    count++;

    return (num_texture); // Returns the current texture OpenGL ID
}
__________________
home page (new layout)

Last edited by scwizzo; 07-01-2008 at 10:16 AM.
scwizzo is offline   Reply With Quote
Old 07-01-2008, 11:02 AM   #6
Registered User
 
Join Date: Feb 2008
Location: Rochester, NY
Posts: 27
Good to hear you solved the issue.

Yeah I completely overlooked that you didn't call glGenTextures.
CornyKorn21 is offline   Reply With Quote
Reply

Thread Tools
Display Modes

Forum Jump

Similar Threads
Thread Thread Starter Forum Replies Last Post
Why only 32x32? (OpenGL) [Please help] Queatrix Game Programming 2 01-23-2006 02:39 PM
Linking OpenGL in Dev-C++ linkofazeroth Game Programming 4 09-13-2005 10:17 AM
Pong is completed!!! Shamino Game Programming 11 05-26-2005 10:50 AM
OpenGL Window Morgul Game Programming 1 05-15-2005 12:34 PM
OpenGL and Windows sean345 Game Programming 5 06-24-2002 10:14 PM


All times are GMT -6. The time now is 01:38 AM.


Powered by vBulletin® Version 3.8.1
Copyright ©2000 - 2009, Jelsoft Enterprises Ltd.
Search Engine Optimization by vBSEO 3.3.0 RC2

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22