Part of the Khronos Group
OpenGL.org

The Industry's Foundation for High Performance Graphics

from games to virtual reality, mobile phones to supercomputers

Results 1 to 5 of 5

Thread: Texture dimensions not power of 2

  1. #1
    Intern Contributor
    Join Date
    Sep 2012
    Posts
    76

    Texture dimensions not power of 2

    Greetings:
    Red book 7th ed says:
    "For OpenGL implementations that do not support version 2.0 or greater, both width and height must have the form 2^m + 2b, ... For OpenGL implementations supporting version 2.0 and greater, textures may be of any size."

    My card support 3.3 but non-power-of-2 dimensioned textures (e.g., 480 x 480) don't come out right. Powers of 2 are fine though. My textures are in bmp format if that matters. Any idea why?

    Thanks in advance,
    Sam

  2. #2
    Member Regular Contributor Nowhere-01's Avatar
    Join Date
    Feb 2011
    Location
    Novosibirsk
    Posts
    251
    check your image loading algorithm. bmp uses padding. and specify what means "don't come out right", what happens and how does it look?

  3. #3
    Intern Contributor
    Join Date
    Sep 2012
    Posts
    76
    Hi Nowhere,
    Thanks for the response. Attached are grabs of what's drawn for a texture size 512x512 and then scaled to 480x480. Below is the part of the code that loads the image:
    Sam

    struct BitMapFile
    {
    int sizeX;
    int sizeY;
    unsigned char *data;
    };

    // Routine to read a bitmap file.
    // Works only for uncompressed bmp files of 24-bit color.
    BitMapFile *getBMPData(string filename)
    {
    BitMapFile *bmp = new BitMapFile;
    unsigned int size, offset, headerSize;

    // Read input file name.
    ifstream infile(filename.c_str(), ios::binary);

    // Get the starting point of the image data.
    infile.seekg(10);
    infile.read((char *) &offset, 4);

    // Get the header size of the bitmap.
    infile.read((char *) &headerSize,4);

    // Get width and height values in the bitmap header.
    infile.seekg(18);
    infile.read( (char *) &bmp->sizeX, 4);
    infile.read( (char *) &bmp->sizeY, 4);

    // Allocate buffer for the image.
    size = bmp->sizeX * bmp->sizeY * 24;
    bmp->data = new unsigned char[size];

    // Read bitmap data.
    infile.seekg(offset);
    infile.read((char *) bmp->data , size);

    // Reverse color from bgr to rgb.
    int temp;
    for (int i = 0; i < size; i += 3)
    {
    temp = bmp->data[i];
    bmp->data[i] = bmp->data[i+2];
    bmp->data[i+2] = temp;
    }

    return bmp;
    }

    BitMapFile *image[1];

    // Load the texture.
    image[0] = getBMPData("../Textures/launch.bmp");
    ...
    glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, image[0]->sizeX, image[0]->sizeY, 0,
    GL_RGB, GL_UNSIGNED_BYTE, image[0]->data);
    Attached Thumbnails Attached Thumbnails Click image for larger version. 

Name:	launch480x480.jpg 
Views:	61 
Size:	84.4 KB 
ID:	956   Click image for larger version. 

Name:	launch512x512.jpg 
Views:	52 
Size:	81.3 KB 
ID:	955  

  4. #4
    Member Regular Contributor Nowhere-01's Avatar
    Join Date
    Feb 2011
    Location
    Novosibirsk
    Posts
    251
    Quote Originally Posted by sam_thedancer View Post
    // Read bitmap data.
    infile.seekg(offset);
    infile.read((char *) bmp->data , size);
    as i said, you have padding issues. the problem is not your texture is NPOT, but it is 4-byte aligned(so at the end of every row it has zero-bytes to make row size multiple of 4). while you reading it as a continuous RGB-array.
    you can fix it dirty way, just to ensure i'm correct by placing these calls in your code(before passing image to opengl):

    Code :
    glPixelStorei ( GL_UNPACK_ALIGNMENT,   4 );
    glPixelStorei ( GL_UNPACK_ROW_LENGTH,  0 );
    glPixelStorei ( GL_UNPACK_SKIP_ROWS,   0 );
    glPixelStorei ( GL_UNPACK_SKIP_PIXELS, 0 );

    but you shouldn't use gl_unpack_* for that, you should parse bmp properly. that means you should take padding into account.
    Loading Bitmaps, Sections #3 and #4

    and also, this code is incorrect:

    // Allocate buffer for the image.
    size = bmp->sizeX * bmp->sizeY * 24;
    bmp->data = new unsigned char[size];
    it should be 3 instead of 24. 24 is bit depth, but you store data in bytes. 24 bit = 3 bytes, 1 per each RGB component.
    Last edited by Nowhere-01; 01-21-2013 at 08:53 PM.

  5. #5
    Intern Contributor
    Join Date
    Sep 2012
    Posts
    76
    Thanks, Nowhere-01!

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •