Чтение пикселей из SDL_Surface и преобразование в цветовые значения - PullRequest
1 голос
/ 13 ноября 2011

Я действительно не знаю, что не так (в основном потому, что я не знаю, что делает строка, выдающая мне ошибку).

Не думаю, что мне нужно показывать вам столько кода. Я пытаюсь получить значения RGBA пикселя, чтобы увидеть, насколько велико значение Alpha. Я использую это, чтобы определить, есть ли столкновение внутри их прямоугольников или нет.

Вот что у меня есть:

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;
}

Я почти уверен, что мое столкновение хорошо, что я делаю, я проверяю, пересекается ли прямоугольник, я создаю прямоугольник пересечения, а затем проверяю каждый пиксель в прямоугольнике пересечения.

Это приводит к тому, что когда у меня на экране появляется идеальное столкновение с пикселем, игра вылетает, и я получаю стрелку, указывающую на:

Uint32 pixelColor = *(Uint32*)p;

С ошибкой:

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

Это строка, которую я не понимаю, может кто-нибудь объяснить, что делает эта строка и как я могу решить эту проблему?

С уважением

Markus

1 Ответ

0 голосов
/ 13 ноября 2011

Нарушение доступа означает, что вы пытаетесь получить доступ к памяти, которая не принадлежит вам. В этом случае вы, вероятно, вызывали эту функцию с x или y вне диапазона (больше, чем размер изображения или отрицательное значение).

Вы должны проверить значения x и y, прежде чем выполнять арифметику с ними, затем вы можете обработать эту ошибку более изящно (что может означать просто сообщение , какое значение было неправильным, и затем в любом случае прерывание, или это может означать сообщение об ошибке обратно вызывающей стороне).

Другой возможный источник ошибки - в строке, где происходит ошибка. Он интерпретирует указатель на Uint8 как указатель на Uint32 и разыменовывает его. По сути, он считывает четыре байта, начиная с этого адреса, в pixelcolor. Обратите внимание, что это приведение действительно только в том случае, если bpp равно 4 и, кроме того, массив пикселей выровнен соответствующим образом для UInt32. Проблема выравнивания вряд ли вызовет ошибку на платформах на базе x86 (x86 обычно вызывает только снижение производительности для смещенных указателей), но проблема bpp может возникнуть в конце массива. Чистым (но обычно более медленным) способом было бы прочитать байты отдельно и составить их, используя сдвиги битов, следующим образом:

UInt32 pixelcolor = 0;
for (int i = 0; i < bpp; ++i)
{
  pixelcolor <<= 8;
  pixelcolor += *p++;
}
...