2013-09-01 2 views
-1

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

В конце, я делаю обычный SDL_RenderClear(), SDL_RenderCopy() и SDL_RenderPresent() согласно migration guide.

Это работает отлично, за исключением того, что, если я позвоню SDL_UpdateTexture() до 3 делают вызовы выше, я получаю перепутались изображение:

Messed up image

Я зову SDL_UpdateTexture(), как это:

SDL_UpdateTexture(texture, NULL, image->pixels, image->pitch) 

Где image - это поверхность, которую я загрузил для изображения, и texture - это текстура, которую я создал из этого. Попытки изменить высоту тона приведут к по-разному испорченным изображениям. Я также попытался использовать rect для второго параметра, но результаты одинаковы, если прямоугольник имеет те же размеры, что и изображение. Если размеры больше (например, такие же, как у окна), обновление не происходит, но ошибок нет.

Доступен full code.

Я хотел бы манипулировать пикселями поверхности непосредственно через image->pixels, а затем позвонить SDL_UpdateTexture(), но просто позвонить SDL_UpdateTexture() без каких-либо вмешательств достаточно, чтобы портить вещи.

ответ

0

Не могли бы вы попробовать следующее. Он должен заменить прозрачные пиксели (r = 255, g = 0, b = 255). Вы бы просто изменили манипуляцию pixel32, чтобы удовлетворить ваши потребности.

SDL_Surface* image = IMG_Load(filename); 

SDL_Surface* imageFomatted = SDL_ConvertSurfaceFormat(image, 
                 SDL_PIXELFORMAT_RGBA8888, 
                 NULL); 

texture = SDL_CreateTexture(renderer, 
          SDL_PIXELFORMAT_RGBA8888, 
          SDL_TEXTUREACCESS_STREAMING, 
          imageFomatted->w, imageFomatted->h); 

void* pixels = NULL; 
int pitch = 0; 

SDL_LockTexture(texture, &imageFomatted->clip_rect, &pixels, &pitch); 

memcpy(pixels, imageFomatted->pixels, (imageFomatted->pitch * imageFomatted->h)); 

int width = imageFomatted->w; 
int height = imageFomatted->h; 

Uint32* pixels32 = (Uint32*)pixels; 
int  pixelCount = (pitch/4) * height; 

Uint32 colorKey  = SDL_MapRGB(imageFomatted->format, 0xFF, 0x00, 0xFF); 
Uint32 transparent = SDL_MapRGBA(imageFomatted->format, 0xFF, 0x00, 0xFF, 0x00); 

for (int i = 0; i < pixelCount; i++) { 
    if (pixels32[i] == colorKey) { 
    pixels32[i] = transparent; 
    } 
} 

SDL_UnlockTexture(texture); 

SDL_FreeSurface(imageFormatted); 
SDL_FreeSurface(image); 

pixels = NULL; 
pitch = 0; 
width = 0; 
height = 0; 
+0

Спасибо за ваш ответ. Это происходит на memcpy, но работает, если вы замените image-> pitch только тональным сигналом. Я прокомментировал строку colorKey до конца цикла for, так как formattedSurf нигде не определен. Кажется, я не могу использовать пиксели без сбоев программы. – Gigi

+0

@Gigi жаль, что я сделал пару ошибок, поскольку я адаптировал свой код, чтобы он соответствовал вашим, так что пропустили пару имен переменных. Не могли бы вы снова попробовать полный код (включая memcopy). Я думаю, что это, возможно, было испорчено, не преобразовывая формат поверхности перед созданием текстуры, поэтому я добавил это. – Zammalad

+0

Вы пропустили декларацию текстуры, а также опечатали в imageFormatted (отсутствует «r») - поэтому SDL_FreeSurface (imageFormatted) несовместим. После их исправления, я все еще получаю сбои на memcpy. Можете ли вы попробовать протестировать код, прежде чем публиковать его? – Gigi

1

Я думаю, что есть что-то не так с шагом или SDL_Rect параметров, но есть другая SDL функция, которая может помочь:

SDL_Texture* SDL_CreateTextureFromSurface(SDL_Renderer* renderer, 
             SDL_Surface* surface) 
Смежные вопросы