Как масштабировать изображение в SDL, используя getWindowPixelFormat (или альтернативу)? - PullRequest
0 голосов
/ 22 декабря 2018

Мой код написан на Haskell, хотя я думаю, что описания проблемы на высоком уровне может быть достаточно для объяснения проблемы кому-то, имеющему опыт работы с SDL (но не на Haskell) - если нет, я постараюсь добиться большего успеха в последующих изменениях.Я пытаюсь увеличить изображение, но для этого мне нужно создать новую поверхность.Чтобы создать новую поверхность, мне нужен жизнеспособный формат пикселей.Поиск жизнеспособного формата пикселей, кажется, является проблемой.Я подумал, что использование SDL_GetWindowPixelFormat будет хорошим способом сделать это после нескольких неудачных попыток в других направлениях.

Когда мой код запускается, я получаю:

SDLCallFailed {sdlExceptionCaller = "SDL.Video.blitSurface", sdlFunction = "SDL_BlitSurface", sdlExceptionError = "Blit combination not supported"} 

Для всех, кто знаком с Хаскеллом, читающим это, мои две соответствующие функции масштабирования приведены ниже:

scaleSurface :: SDL.Surface -> Maybe ImageBox -> Int -> 
  HicoProgram state (SDL.Surface, Maybe ImageBox)
scaleSurface surfIn box scale = do
  surfInDims <- SDL.surfaceDimensions surfIn
  boxOut <- return $ getBoxFinal surfInDims
  boxOutScaled <- return $ fmap (*scale) boxOut
  boxOutScaledC <- return $ fmap fromIntegral boxOutScaled
  sizeCIntScaled <- return $ boxSize boxOutScaledC
  surfOut <- createScreenSurface sizeCIntScaled
  _ <- SDL.surfaceBlitScaled surfIn (Just (fmap fromIntegral boxOut)) surfOut (Just boxOutScaledC)
  return (surfOut, return boxOutScaled)
  where
    getBoxFinal :: SDL.V2 CInt -> ImageBox
    getBoxFinal surfDims = case box of
      Just b -> b
      Nothing -> do
        SDL.Rectangle origin (fmap fromIntegral surfDims)
    origin :: SDL.Point SDL.V2 Int
    origin = SDL.P (SDL.V2 0 0)

createScreenSurface :: Integral a => SDL.V2 a -> HicoProgram state SDL.Surface
createScreenSurface size = do
  window   <- _window <$> getSDLGameState
  rawPixFmt <- getWindowPixelFormat $ rawWindow window
  let pixFmt :: SDL.Video.Renderer.PixelFormat = fromNumber rawPixFmt
  SDL.createRGBSurface sizeCInt pixFmt
  where
    sizeCInt = fmap fromIntegral size
    rawWindow :: SDL.Window -> SDL.Raw.Window
    rawWindow win = rw
      where SDL.Internal.Types.Window (rw) = win

Код вызова с ошибкой и без нее (с попыткой масштабирования и без нее) выглядит следующим образом:

scaleImage :: HicoImage -> Int -> HicoProgram state HicoImage
scaleImage imgIn scale = do
  -- FIXME: working:     <- return (surf, box)
  -- FIXME: NOT working: <- scaleSurface surf box scale
  (surfOut, mBoxOut) <- scaleSurface surf box scale

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

Полный код доступен в этой ветви с этой ревизией ;рассматриваемый исполняемый файл - «переход».Используйте jump --software_rndr, если у вас нет аппаратного рендеринга OpenGL для тестирования. Примечание : текущий код требует проверки haskell sdl2 на том же уровне, что и hico-репо;на момент написания статьи это эта редакция .

...