1

I don't really know what's wrong (mainly because I don't know what the line that gives me an error does).

I don't think I have to show you that much code. What I'm doing is that I'm trying to get the RGBA values of a pixel to see how great the Alpha value is. I'm using this to determine if there's a collision within their rectangles or not.

This is what I have:

bool Texture2D::GetPixelAlphaValue(Vector2 pixel)
{
int bpp = surface->format->BytesPerPixel;
Uint8* p = (Uint8*) surface->pixels + (int) pixel.y * surface->pitch + (int) pixel.x * bpp);

Uint32 pixelColor = *(Uint32*)p;

Uint8 red, green, blue, alpha;
SDL_GetRGBA(pixelColor, surface->format, &red, &green, &blue, &alpha);

return alpha > 250;
}

I'm pretty sure my collision is good up to this, what I do is I check if rectangle intersects, I create an rectangle of the intersection and then check every pixel within the intersect rectangle.

This results in once I have a pixel perfect collision in screen the game crashes and I get an arrow pointing at:

Uint32 pixelColor = *(Uint32*)p;

With the error:

 Unhandled exception at 0x000393b4 in OpenGLSDLTest.exe: 0xC0000005: Access violation      reading location 0x063b6fd0.

This is the line that I don't understand, could someone please explain what this line is doing and how I can solve this?

Kind regards

Markus

Orujimaru
  • 835
  • 2
  • 13
  • 18
  • 1
    Is this really your real code? Because I'm surprised that it compiles at all. In line 4, you are assigning an integer to a pointer to `Uint8`. – celtschk Nov 13 '11 at 11:39
  • p is jumping over surface->pixels? – joy Nov 13 '11 at 12:08
  • Your code looks very similar to this: [Pixel_Access](http://www.libsdl.org/cgi/docwiki.cgi/Pixel_Access) Did you lock the surface first like it says you need to? There's also an error in your code if you compare to the example code. You want to cast surface->pixels to a (Uint8*), not a (Uint8). – Retired Ninja Nov 13 '11 at 12:15
  • Sorry, you're correct, I missed * when I wrote the question, it's in my code. – Orujimaru Nov 13 '11 at 12:23
  • What are the x and y values you are passing in? Have you tried with 0,0? As a side note, the range of a Uint8 is 0-255, so alpha will never be greater than 255 and if it didn't crash this function would always return false as written. – Retired Ninja Nov 13 '11 at 12:34
  • I tried locking and unlocking the surface but it doesn't help – Orujimaru Nov 13 '11 at 12:35
  • Regarding the alpha value, sorry that's also a typo. I'm checking if the value is greater than 250. When I call the GetPixelAlphaData it looks like this: for (int y = 0; y < intersection.height; y++) { for (int x = 0; x < intersection.width; x++) { //This isn't exactly how my code looks, this should return a bool weather the pixel is transparent or not. texture->GetPixelAlphaData(Vector2(position.x + x, position.y + y) } } – Orujimaru Nov 13 '11 at 12:45
  • 1
    A hint: It's generally best to use copy/paste from the actual code. That way you don't add new errors (or in the extreme case even accidentally correct the actual error, leaving anyone puzzled what should be wrong with your code). – celtschk Nov 13 '11 at 13:52

1 Answers1

0

An access violation means you are trying to access memory which doesn't belong to you. In this case, you probably called that function with x or y out of range (larger than the size of the image, or negative).

You should check the values of x and y before doing pointer arithmetic with them, then you can handle that mistake more gracefully (which may just mean reporting which value was wrong, and then aborting anyway, or it might mean reporting that error back to the caller).

Another possible source of the error is at the he line where the error occurs. It is reinterpreting the pointer to Uint8 as a pointer to Uint32, and dereferencing it. In effect, it reads the four bytes staring at that address into pixelcolor. Note that this cast is only valid if bpp is 4 and additionally the pixel array is aligned suitably aligned for UInt32. The alignment issue is unlikely to cause an error on x86 based platforms (the x86 generally only causes a performance hit for misaligned pointers), but the bpp issue may hit at the end of the array. The clean (but generally slower) way would be to read the bytes separately and compose them using bit shifts, as follows:

UInt32 pixelcolor = 0;
for (int i = 0; i < bpp; ++i)
{
  pixelcolor <<= 8;
  pixelcolor += *p++;
}
celtschk
  • 19,311
  • 3
  • 39
  • 64
  • Hmm, all I can say is that the error only occurs once both pixelColors aren't 255 alpha. I've tried checking x and y but it doesn't make any difference. – Orujimaru Nov 13 '11 at 13:15