2017-04-07 56 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進行轉換。