Thursday, June 30, 2011

BItmap maping and texture map in OpenGL

This the sample code for texture map in teapot and bit map is used to draw chess board.Code is compiled in codeblocks you can copy and paste this code for your study or project.Please use your own image for texture map.Image must be in bmp formate.


#include <windows.h>
#include <GL/glut.h>
#include <stdio.h>
GLuint texture[2];
GLint slices=16;
GLint stacks=16;
struct Image {
    unsigned long sizeX;
    unsigned long sizeY;
    char *data;
};
typedef struct Image Image;



#define checkImageWidth 64
#define checkImageHeight 64
GLubyte checkImage[checkImageWidth][checkImageHeight][3];
void makeCheckImage(void)
{
    int i, j, c;
    for (i = 0; i < checkImageWidth; i++) {
    for (j = 0; j < checkImageHeight; j++) {
    c = ((((i&0x8)==0)^((j&0x8)==0)))*255;
    checkImage[i][j][0] = (GLubyte) c;
    checkImage[i][j][1] = (GLubyte) c;
    checkImage[i][j][2] = (GLubyte) c;
}
}
}
int ImageLoad(char *filename, Image *image) {
    FILE *file;
    unsigned long size; // size of the image in bytes.
    unsigned long i; // standard counter.
    unsigned short int plane; // number of planes in image

    unsigned short int bpp; // number of bits per pixel
    char temp; // temporary color storage for
// make sure the file is there.
if ((file = fopen(filename, "rb"))==NULL)
{
    printf("File Not Found : %s\n",filename);
    return 0;
}
// seek through the bmp header, up to the width/height:
fseek(file, 18, SEEK_CUR);
// read the width
    if ((i = fread(&image->sizeX, 4, 1, file)) != 1) {
    printf("Error reading width from %s.\n", filename);
    return 0;
}
//printf("Width of %s: %lu\n", filename, image->sizeX);
// read the height
if ((i = fread(&image->sizeY, 4, 1, file)) != 1) {
    printf("Error reading height from %s.\n", filename);
    return 0;
}
//printf("Height of %s: %lu\n", filename, image->sizeY);
// calculate the size (assuming 24 bits or 3 bytes per pixel).
size = image->sizeX * image->sizeY * 3;
// read the planes
if ((fread(&plane, 2, 1, file)) != 1) {
    printf("Error reading planes from %s.\n", filename);
    return 0;
}
if (plane != 1) {
        printf("Planes from %s is not 1: %u\n", filename, plane);
    return 0;
}
// read the bitsperpixel
if ((i = fread(&bpp, 2, 1, file)) != 1) {
    printf("Error reading bpp from %s.\n", filename);

return 0;
}
if (bpp != 24) {
    printf("Bpp from %s is not 24: %u\n", filename, bpp);
    return 0;
}
// seek past the rest of the bitmap header.
fseek(file, 24, SEEK_CUR);
// read the data.
image->data = (char *) malloc(size);
if (image->data == NULL) {
    printf("Error allocating memory for color-corrected image data");
    return 0;
}
if ((i = fread(image->data, size, 1, file)) != 1) {
    printf("Error reading image data from %s.\n", filename);
    return 0;
}
for (i=0;i<size;i+=3) { // reverse all of the colors. (bgr -> rgb)
    temp = image->data[i];
    image->data[i] = image->data[i+2];
    image->data[i+2] = temp;
}
// we're done.
return 1;
}
    Image * loadTexture()
{
Image *image1;
// allocate space for texture
    image1 = (Image *) malloc(sizeof(Image));
    if (image1 == NULL) {
    printf("Error allocating space for image");
    exit(0);
}
//pic.bmp is a 64x64 picture
if (!ImageLoad("image_name.bmp", image1)) {
    exit(1);
}
return image1;
}
void myinit(void)
{
    glClearColor (0.5, 0.5, 0.5, 0.0);
    glEnable(GL_DEPTH_TEST);
    glDepthFunc(GL_LESS);

Image *image1 = loadTexture();
if(image1 == NULL)
{
    printf("Image was not returned from loadTexture\n");
    exit(0);
}
makeCheckImage();
    glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
// Create Texture
    glGenTextures(2, texture);
    glBindTexture(GL_TEXTURE_2D, texture[0]);
    glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_LINEAR); //
//scale linearly when image bigger than texture
    glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_LINEAR); //
//scale linearly when image smalled than texture
    glTexImage2D(GL_TEXTURE_2D, 0, 3, image1->sizeX, image1->sizeY, 0,
    GL_RGB, GL_UNSIGNED_BYTE, image1->data);
    glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_DECAL);
    glBindTexture(GL_TEXTURE_2D, texture[1]);
    glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP);
    glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP);
    glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
    glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
    glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_DECAL);
    glTexImage2D(GL_TEXTURE_2D, 0, 3, checkImageWidth,
    checkImageHeight, 0, GL_RGB, GL_UNSIGNED_BYTE,
    &checkImage[0][0][0]);
    glEnable(GL_TEXTURE_2D);
    glShadeModel(GL_FLAT);
}
void display(void)
{
    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
    glBindTexture(GL_TEXTURE_2D, texture[0]);
    glutSolidTeapot(1.0);
    glBindTexture(GL_TEXTURE_2D, texture[1]);
    glBegin(GL_QUADS);
    glTexCoord2f(0.0, 0.0);
    glVertex3f(1.0, -1.0, 0.0);
    glTexCoord2f(1.0, 0.0);
    glVertex3f(1.0, 1.0, 0.0);
    glTexCoord2f(1.0, 1.0);
    glVertex3f(2.41421, 1.0, -1.41421);
    glTexCoord2f(0.0, 1.0);
    glVertex3f(2.41421, -1.0, -1.41421);
    glEnd();
    glutSwapBuffers();
}
void myReshape(int w, int h)
{
    glViewport(0, 0, w, h);
    glMatrixMode(GL_PROJECTION);
    glLoadIdentity();
    gluPerspective(60.0, 1.0*(GLfloat)w/(GLfloat)h, 1.0, 30.0);
    glMatrixMode(GL_MODELVIEW);
    glLoadIdentity();
    glTranslatef(0.0, 0.0, -3.6);
}
void keyboard (unsigned char key, int x, int y)
{
    switch (key) {
    case 27: // “esc” on keyboard
    exit(0);
    break;
    default: // “a” on keyboard
    break;
}
}
int main(int argc, char** argv)
{
    glutInit(&argc, argv);
    glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGB | GLUT_DEPTH);
        glutCreateWindow("Texture Mapping");
    myinit();
    glutReshapeFunc (myReshape);
    glutDisplayFunc(display);
    glutKeyboardFunc(keyboard);
    glutMainLoop();
return 0;
}

9 comments:

  1. This comment has been removed by the author.

    ReplyDelete
    Replies
    1. put the bmp image with executable(.exe) file.

      Delete
    2. This comment has been removed by the author.

      Delete
    3. This comment has been removed by the author.

      Delete
    4. Look the source code carefully bmp Image size is 64*64. So your bmp image must be 64 by 64 pixel.

      Delete
  2. This comment has been removed by the author.

    ReplyDelete
  3. Hai Sir..I have loaded the bmp in .exe path and the output comes in .exe but not within the codeblocks.It is coming as File not found:earth.bmp.How to make the output come inside codeblock.

    ReplyDelete
  4. I tried to put a glutSolidSphere instead the teapot but it is not working, the texture is not applied, it just changes the color.
    Any idea how to fix this ?

    ReplyDelete
    Replies
    1. By this method texture doesn't apply on glutSolidSphere. You have to use different technique. I have written article for texture mapping on sphere too...here..
      http://www.codeincodeblock.com/2012/05/simple-method-for-texture-mapping-on.html
      http://www.codeincodeblock.com/2011/06/texture-map-in-solid-sphere-using.html

      Delete