使用堆栈构建简单的opengl项目?

时间:2015-07-27 17:54:10

标签: haskell haskell-stack

我创建了简单的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;
}

0 个答案:

没有答案