Access violation in function gluScaleImage.

I need to bind a texture on a sphere, and my main problem is scaling an image. The program executing succeffully, and a test 128*128 textures binding succefully, too. But if i matching in a OpenDialog a texture, length and width of what isn’t a power of 2, program terminating after function gluScaleImage(…) vith an “Access violation” message. My texture-binding function is (on C++ Builder):


void __fastcall TFormMain::SetTexture()
{
    glEnable(GL_TEXTURE_2D);
    bitmap = new Graphics::TBitmap;
    bitmap->LoadFromFile(OpenDialog1->FileName);
    GLubyte bits[128][128][4];
    Graphics::TBitmap *bitmap2;
    if (div(bitmap->Width,2).rem == 0 && div(bitmap->Width,2).rem == 0)
{
    for(int i = 0; i < 128; i++)
    {
    	for(int j = 0; j < 128; j++)
        {
            bits[i][j][0]= (GLbyte)GetRValue(bitmap->Canvas->Pixels[i][j]);
            bits[i][j][1]= (GLbyte)GetGValue(bitmap->Canvas->Pixels[i][j]);
            bits[i][j][2]= (GLbyte)GetBValue(bitmap->Canvas->Pixels[i][j]);
            bits[i][j][3]= (GLbyte)255;
        }
    }
    glGenTextures(1, &texture1);
    glBindTexture(GL_TEXTURE_2D, texture1);
   
    glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, bitmap->Width, bitmap->Height, 0, GL_RGBA, GL_UNSIGNED_BYTE, bits);
    glPixelStorei(GL_UNPACK_ALIGNMENT, 4);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
    glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_DECAL);
    }

    else
    {
        gluScaleImage(GL_RGBA,bitmap->Width,bitmap->Height,GL_UNSIGNED_BYTE,&bitmap,128,128,GL_UNSIGNED_BYTE,&bitmap2);
        for(int i = 0; i < 128; i++)
    {
    	for(int j = 0; j < 128; j++)
        {
            bits[i][j][0]= (GLbyte)GetRValue(bitmap2->Canvas->Pixels[i][j]);
            bits[i][j][1]= (GLbyte)GetGValue(bitmap2->Canvas->Pixels[i][j]);
            bits[i][j][2]= (GLbyte)GetBValue(bitmap2->Canvas->Pixels[i][j]);
            bits[i][j][3]= (GLbyte)255;
        }
    }
    glGenTextures(1, &texture1);
    glBindTexture(GL_TEXTURE_2D, texture1);
    
    glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, bitmap2->Width,bitmap2->Height, 0, GL_RGBA, GL_UNSIGNED_BYTE, bits);
    glPixelStorei(GL_UNPACK_ALIGNMENT, 4);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
    glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_DECAL);

    }
}

You also can see this code in Examples/OpenGL/glSkeleton folder on a C++ Builder main folder.

This looks like an row alignment problem.


glPixelStorei(GL_UNPACK_ALIGNMENT, 4);

This is useless since it is the default row alignment. Are you sure that your texture data has a 4 bytes row alignment? If not try glPixelStorei(GL_UNPACK_ALIGNMENT, 1); instead.

No, it isn’t solve of a problem.

An “Access violation” appears in a string



gluScaleImage(GL_RGBA,bitmap->Width,bitmap->Height,GL_UNSIGNED_BYTE,&bitmap,128,128,GL_UNSIGNED_BYTE,&bitmap2);


So, perhaps I forget something on a function gluScaleImage(…)?

One suggestion for your Access violation bug is that your bitmap variable seems to be a structure (Graphics::TBitmap) (forgive me if I’m mistaken, I’m not very experienced in windows programming). So by providing a structure as the datain or dataout parameters, wouldn’t that be a potential cause of the access violation? You’re data is probably violating the boundaries of your structure expecting to find a memory buffer.

The ScaleImage function needs a pointer to the raw image data, not to a structure of any kind. Now, I have no idea what this TBitmap thing is (sounds like Borland to me), but you will have to get a pointer to the actual bitmap data it references.

TBitmap is an encapsulation of a windows Bitmap, and bitmap->Canvas encapsulates a device context that contains the pixels of the bitmap.
Neither of these can be used with gluScaleImage which expects pointers to two simple arrays of color values.

You could make a second bits array and use:
gluScaleImage(GL_RGBA,bitmap->Width,bitmap->Height,GL_UNSIGNED_BYTE,&bits,128,128,GL_UNSIGNED_BYTE,&bits2);
after copying the data into bits.

OR use the bitmap2->Canvas->CopyRect function to scale bitmap to bitmap2
(But shouldn’t you have bitmap2 = new Graphics::TBitmap; ?)

OR do the scaling yourself in the for loop when you copy the data from the bitmap canvas to the bits array.

Thank you for help and useful information. I used a Simon Arbon’s variant #1 (to create second bits array), and it is working. I don’t like use a canvas, therefore I started learning OpenGL.