在Haskell中使用OpenGL渲染PNG图像

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了在Haskell中使用OpenGL渲染PNG图像相关的知识,希望对你有一定的参考价值。

我是Haskell的新手,我正在使用OpenGL(使用Graphics.UI.GLUT)为UI构建一个国际象棋游戏。我正在尝试为棋子渲染PNG图像。

我读到图像可以转换为TextureObject然后渲染,但找不到任何有用的资源来知道如何做。

这就是我的代码生成国际象棋棋盘的样子

drawSquare :: BoardSquare -> IO ()
drawSquare ((x,y,z),(r,g,b)) = preservingMatrix $ do
    color $ Color3 r g b
    translate $ Vector3 x y z
    drawCube -- this will draw a square of appropriate size

-- Display Callback
display :: IORef GameState -> DisplayCallback
display gameState = do
    gstate <- get gameState
    clear [ColorBuffer]
    forM_ (getBoardPoints gstate) $ drawSquare -- drawing all 64 squares here
    flush

任何人都可以帮助我在给定文件路径的窗口的任何给定xy坐标处渲染PNG图像?

答案

建议:既然你是Haskell的新手,而不是直接潜入原始OpenGL为你的国际象棋游戏,你有没有看过可以帮助你更容易使OpenGL的库?我会推荐gloss,它看起来像gloss-game有一个helper function加载.png文件到内存准备用于您的游戏。祝好运! :-)

另一答案

这是我使用的方式。

首先,使用包gl-capture。它很旧,但效果很好。它生成ppm图像。

import           Graphics.Rendering.OpenGL.Capture (capturePPM)

申请包裹需要帮助吗?你需要一个键盘回调。如果有必要,我可以帮忙,请问。

现在,一旦你有了ppm图像,你有两个选择:用ImageMagick转换它,或者使用Haskell包来转换它。有一个很好的:它被称为hip。这是我使用的模块:

module Utils.ConvertPPM
  where
import           Control.Monad    (when)
import           Graphics.Image
import           System.Directory (removeFile)

convert :: FilePath -> FilePath -> Bool -> IO ()
convert input output remove = do
  ppm <- readImageRGBA VU input
  writeImage output ppm
  when remove $ removeFile input

如果您需要更多帮助,请不要犹豫。

这是我使用的那种键盘回调:

keyboard :: IORef GLfloat -> IORef GLfloat -> IORef GLfloat -> IORef GLint
         -> KeyboardCallback
keyboard rot1 rot2 rot3 capture c _ =
  case c of
    'r' -> rot1 $~! subtract 1
    't' -> rot1 $~! (+1)
    'f' -> rot2 $~! subtract 1
    'g' -> rot2 $~! (+1)
    'v' -> rot3 $~! subtract 1
    'b' -> rot3 $~! (+1)
    'c' -> do
      i <- get capture
      let ppm = printf "pic%04d.ppm" i
          png = printf "pic%04d.png" i
      (>>=) capturePPM (B.writeFile ppm)
      convert ppm png True
      capture $~! (+1)
    'q' -> leaveMainLoop
    _   -> return ()

然后按'c'捕捉图像。请注意,从ppmpng的转换很慢。特别是如果你打算做一些动画。对于动画,我宁愿只使用ppm然后我用ImageMagick转换。

以上是关于在Haskell中使用OpenGL渲染PNG图像的主要内容,如果未能解决你的问题,请参考以下文章

OpenGL渲染纹理全白

使用 libpng 将 OpenGL 屏幕像素保存为 PNG

使用 opengl 硬件渲染器导出带有颜色条的 MATLAB 冲浪图会导致损坏的 png 文件

OpenGL 加载和渲染 png 到屏幕

PNG 到 Opengl 的使用问题

如何在 OpenGL ES 2.0 中使用 png 图像纹理立方体?