Мой код написан на 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-репо;на момент написания статьи это эта редакция .