Haskell 中的 OpenGL VBO

Posted

技术标签:

【中文标题】Haskell 中的 OpenGL VBO【英文标题】:OpenGL VBO's in Haskell 【发布时间】:2013-03-25 15:20:34 【问题描述】:

基于this post,我试图弄清楚如何在 Haskell 中使用 VBO。我试图填写那里没有涵盖的位:

data Sprite = Sprite  spriteImage :: Image
                     , spritePosition :: Position
                      deriving (Show, Eq)

spriteBatch :: [Sprite] -> [(TextureObject, [Sprite])]
spriteBatch = (map f) . toList . (groupedBy (imageTexture . spriteImage))
    where f (t, s) = (t, s)

offset = plusPtr nullPtr

renderSprites :: [Sprite] -> IO ()
renderSprites l = (flip mapM_) (spriteBatch l) $ \(t, sps) -> do
        textureBinding Texture2D $= Just t
        let l = concat $ map sprToList sps
        vbo <- vboOfList ((length l)*4) l
        displayVbo vbo $ fromIntegral $ length sps
    where
        sprToList :: Sprite -> [GLfloat]
        sprToList (Sprite (Image _ (TexCoord2 u0 v0) (TexCoord2 u1 v1) (Size w h) _) (Position x y)) = 
            [fromIntegral x, fromIntegral y, u0, v0
            ,fromIntegral (x+w), fromIntegral y, u1, v0
            ,fromIntegral (x+w), fromIntegral (y+h), u1, v1
            ,fromIntegral x, fromIntegral (y+h), u0, v1
            ]

vboOfList :: Int -> [GLfloat] -> IO BufferObject
vboOfList size elems = do
    let ptrsize = toEnum $ size * 4
        arrayType = ElementArrayBuffer
    (array:_) <- genObjectNames 1
    bindBuffer arrayType $= Just array
    arr <- newListArray (0, size - 1) elems
    withStorableArray arr $ \ptr -> bufferData arrayType $= (ptrsize, ptr, StaticDraw)
    bindBuffer ArrayBuffer $= Nothing
    return array

displayVbo buff size = do
    let stride = 2*(2*4)
        vxDesc = VertexArrayDescriptor 2 Float stride $ offset 0
        texCoo = VertexArrayDescriptor 2 Float stride $ offset 8
    bindBuffer ArrayBuffer $= Just buff

    arrayPointer VertexArray $= vxDesc
    arrayPointer TextureCoordArray $= texCoo

    clientState VertexArray $= Enabled
    clientState TextureCoordArray $= Enabled

    drawArrays Quads 0 size
    bindBuffer ArrayBuffer $= Nothing

您可以找到完整代码here,以备不时之需。

在master branch 上,同样的函数使用普通的vertex 调用来绘制Sprites,并且效果很好。但是使用 VBO,精灵就不存在了。我得到一个空白屏幕。

谁能向我解释我在这里做错了什么?

【问题讨论】:

您能先向我们解释一下出了什么问题吗?它是否编译和行为不端? @ThomasM.DuBuisson:哦,是的,对不起。它编译完美,但屏幕保持空白。精灵不显示 - 它必须在上面的 VBO 部分,因为没有 VBO 的相同效果很好。 【参考方案1】:

您正在为顶点和 uv 使用一个缓冲区。使用两个缓冲区,一个用于顶点,一个用于 uvs。

【讨论】:

以上是关于Haskell 中的 OpenGL VBO的主要内容,如果未能解决你的问题,请参考以下文章

Haskell OpenGL 和 GLUT 不明确的发生

VBO/FBO/DisplayLists 如何在 Haskell 的 OpenGL 绑定中工作?

在Haskell中使用OpenGL渲染PNG图像

Haskell openGL 和 GLUT 在 Mac OS X 上冻结?我可以在 GLUT 上使用 GLFW 吗?

Haskell手撸Softmax回归实现MNIST手写识别

Scala中的Haskell“forall”翻译