问题
I am new to Haskell and I am building a chess game using OpenGL
(using Graphics.UI.GLUT
) for UI. I am trying to render PNG images for chess pieces.
I read that images can be converted to TextureObject
and then rendered, but could not find any helpful resources to know how to do it.
This is what my code looks like for generating the chess board
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
Can anyone help me render PNG image at any given x
and y
coordinates of the window with given file path?
回答1:
Suggestion: Since you are new to Haskell, instead of diving straight into raw OpenGL
for your chess game, have you looked at libraries that could help you make OpenGL
easier? I would recommend gloss and it looks like gloss-game has a helper function to load a .png
file into memory ready to be used for your game. Good luck! :-)
回答2:
Here is the way I use.
First, use the package gl-capture
. It is old but it works well. It generates ppm
images.
import Graphics.Rendering.OpenGL.Capture (capturePPM)
Do you need help to apply the package ? You need a keyboard callback. I can help if necessary, please just ask.
Now, once you have a ppm
image, you have two options: convert it with ImageMagick, or use a Haskell package to convert it. There is a good one: it is called hip
. Here is the module I use:
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
Do not hesitate if you need more help.
Here is the kind of keyboard callback I use:
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 ()
Then press 'c' to capture the image. Note that the conversion from ppm
to png
is slow. Especially if you intend to do some animations. For animations, I rather use ppm
only and then I convert with ImageMagick.
来源:https://stackoverflow.com/questions/43275665/render-png-images-using-opengl-in-haskell