2017-04-07 28 views
2

我是Haskell的新手,我正在使用OpenGL(使用Graphics.UI.GLUT)构建用于UI的国际象棋游戏。我试图呈现PNG图像的棋子。在Haskell中使用OpenGL渲染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图像?

+1

也许不是特定于你的问题,但你有看看nehe教程(Haskell端口:http://hackage.haskell.org/package/nehe-tuts,原始的C可以在http: //nehe.gamedev.net/)?我不知道,但也许这有助于... – MichaelO

+0

你想让它专门用于OpenGL,还是只想在屏幕上显示2D图形?如果是后者,SDL2是一个非常简单的选择,并且有很好的haskell绑定。 –

+0

带有键盘动作和游戏玩法的总棋盘在OpenGL中准备就绪。任何可以用OpenGL渲染PNG图像的东西都应该没问题,不需要在OpenGL中。 – codesome

回答

3

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

+1

是的,光泽会更简单。但是我首先偶然发现了OpenGL,并且除了图像渲染部分之外,整个游戏已经准备好了,我现在无法迁移到它(或者更像,我不想)。是否可以在OpenGL中使用该辅助函数? – codesome

+1

我对OpenGL Haskell绑定本身并不是很熟悉,这就是为什么我推荐类似光泽的原因。经过一番搜索后,看起来你需要加载2D纹理的函数是:'texImage2D'。这是非常低的水平(你必须传递一个指针,指向图像在内存中的位置)。 [Here](https://gist.github.com/danbst/470f7e23a14cab4e6e3e)是我在网上找到的一个要从'.bmp'加载纹理的要点。 [JuicyPixels](https://hackage.haskell.org/package/JuicyPixels)可能能够帮助你从'.png'文件中获取位图。祝你好运! :-) –

+0

谢谢你的资源:)希望这会帮助别人。无论如何,我们决定通过给顶点来绘制图形,而不是面对闪烁屏幕的任何问题。 – codesome

0

这是我使用的方式。

首先,使用包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进行转换。