PDA

View Full Version : Access violation in function gluScaleImage.



Fraktalius
08-08-2008, 02:56 AM
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, &amp;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,&amp;bitmap,128,128,GL_UNSIGNE D_BYTE,&amp;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, &amp;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.

dletozeun
08-08-2008, 03:34 AM
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.

Fraktalius
08-08-2008, 04:05 AM
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,&amp;bitmap,128,128,GL_UNSIGNE D_BYTE,&amp;bitmap2);


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

eSight Dude
09-08-2008, 07:42 AM
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.

Zengar
09-08-2008, 12:01 PM
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.

Simon Arbon
09-08-2008, 06:10 PM
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.

Fraktalius
09-09-2008, 04:54 PM
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.