我创建了简单的 haskell-opengl 项目。使用命令构建成功:
cabal configure
cabal build
当我使用堆栈时:
stack build
我得到错误:
GLUT-2.7.0.1: configure
Progress
Configuring GLUT-2.7.0.1...
Setup.hs: Missing dependency on a foreign library:
* Missing C library: glut32
This problem can usually be solved by installing the system package that
provides this library (you may need the "-dev" version). If the library is
already installed but in a non-standard location then you can use the flags
--extra-include-dirs= and --extra-lib-dirs= to specify where it is.
如何使用stack glut.dll?
module Main where
import Graphics.UI.GLUT
import Foreign.Marshal.Array
import Foreign.Ptr
import Foreign.Storable()
import Foreign.C.Types()
import qualified Data.ByteString as BS
import Control.Monad
data State = State
{
vertexBuffer :: BufferObject,
gpuProgram :: Program
}
triangleVertexes :: [GLfloat]
triangleVertexes = [
0.0, 0.5, 0.0, 1.0,
0.5, -0.366, 0.0, 1.0,
-0.5, -0.366, 0.0, 1.0,
1.0, 0.0, 0.0, 1.0,
0.0, 1.0, 0.0, 1.0,
0.0, 0.0, 1.0, 1.0
]
main :: IO ()
main = do
(progName, _) <- getArgsAndInitialize
initialDisplayMode $= [ DoubleBuffered, RGBAMode, WithAlphaComponent, WithDepthBuffer ]
_ <- createWindow progName
state <- initializeState
displayCallback $= display state
reshapeCallback $= Just (reshape state)
mainLoop
fragmentShaderFilePath :: FilePath
fragmentShaderFilePath = "shader.frag"
vertexShaderFilePath :: FilePath
vertexShaderFilePath = "shader.vert"
createVertexBuffer :: [GLfloat] -> IO BufferObject
createVertexBuffer vertexes = do
bufferObject <- genObjectName
bindBuffer ArrayBuffer $= Just bufferObject
withArrayLen vertexes $ \count arr ->
bufferData ArrayBuffer $= (fromIntegral count * 4, arr, StaticDraw)
enableAttribLocations [0, 1]
setAttribPointers
return bufferObject
vertexNumComponents :: NumComponents
vertexNumComponents = 4
colorNumComponents :: NumComponents
colorNumComponents = 4
initializeState :: IO State
initializeState = do
bufferObject <- createVertexBuffer triangleVertexes
program <- initGPUProgram
return State
{
vertexBuffer = bufferObject,
gpuProgram = program
}
loadShader :: ShaderType -> FilePath -> IO Shader
loadShader t path = do
shader <- createShader t
source <- BS.readFile path
shaderSourceBS shader $= source
compileShader shader
status <- get (compileStatus shader)
unless status $ putStrLn . (("message" ++ " log: ") ++) =<< get (shaderInfoLog shader)
return shader
initGPUProgram :: IO Program
initGPUProgram = do
vertexShader <- loadShader VertexShader vertexShaderFilePath
fragmentShader <- loadShader FragmentShader fragmentShaderFilePath
let shaders = [vertexShader, fragmentShader]
program <- createProgram
mapM_ (attachShader program) shaders
linkProgram program
mapM_ (detachShader program) shaders
return program
display :: State -> DisplayCallback
display state = do
clearColor $= Color4 1.0 0.0 1.0 1.0
clear [ ColorBuffer ]
bindBuffer ArrayBuffer $= Just (vertexBuffer state)
enableAttribLocations [0, 1]
setAttribPointers
currentProgram $= Just (gpuProgram state)
drawArrays Triangles 0 3
disableAttribLocations [0, 1]
swapBuffers
checkError "display"
setCapabilityForAttribLocations :: Capability -> [GLuint] -> IO ()
setCapabilityForAttribLocations capability =
mapM_ (\location -> vertexAttribArray (AttribLocation location) $= capability)
disableAttribLocations :: [GLuint] -> IO ()
disableAttribLocations = setCapabilityForAttribLocations Disabled
enableAttribLocations :: [GLuint] -> IO ()
enableAttribLocations = setCapabilityForAttribLocations Enabled
setAttribPointers :: IO ()
setAttribPointers = do
vertexAttribPointer (AttribLocation 0) $= (ToFloat, VertexArrayDescriptor vertexNumComponents Float 0 nullPtr)
vertexAttribPointer (AttribLocation 1) $= (ToFloat, VertexArrayDescriptor colorNumComponents Float 0 (plusPtr nullPtr 48))
reshape :: State -> ReshapeCallback
reshape _ size =
viewport $= (Position 0 0, size)
checkError :: String -> IO ()
checkError functionName = get errors >>= mapM_ reportError
where reportError e = putStrLn (showError e ++ " detected in " ++ functionName)
showError (Error category message) = "GL error " ++ show category ++ " (" ++ message ++ ")"
-- 片段着色器
#version 330
smooth in vec4 theColor;
out vec4 outputColor;
void main()
{
outputColor = theColor;
}
-- 顶点着色器
#version 330
layout (location = 0) in vec4 position;
layout (location = 1) in vec4 color;
smooth out vec4 theColor;
void main()
{
gl_Position = position + vec4(0.5, 0.5, 0.0, 1.0);
theColor = color;
}