我的代码在Haskell中,尽管我认为对问题的高级描述可能足以向有SDL经验的人(而不是Haskell)解释该问题-如果没有,我将在后续编辑中尝试做得更好。我正在尝试按比例放大图像,但是要做到这一点,我需要创建一个新的表面。要创建新表面,我需要可行的像素格式。寻找可行的像素格式似乎是问题所在。我认为使用SDL_GetWindowPixelFormat是实现此目的的一种好方法,因为在其他方向也有一些错误的开始。
我的代码运行时,我得到:
SDLCallFailed {sdlExceptionCaller = "SDL.Video.blitSurface", sdlFunction = "SDL_BlitSurface", sdlExceptionError = "Blit combination not supported"}
对于所有熟悉Haskell的人来说,我下面两个相关的缩放函数:
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进行了所有显式转换,我承认这可能是我代码库中最讨厌的代码,并且也许有一些方法可以改善此问题(尽管不是我的核心问题,也可以提出建议)。
完整的代码在this branch和this revision中可用;有问题的可执行文件是“跳转”。如果您没有要测试的OpenGL硬件渲染,请使用jump --software_rndr
。 注意:当前代码要求在与hico repo相同级别上检出haskell sdl2;在撰写本文时为this revision。