2013-04-03 4 views
5

En me basant sur this post, j'essayais de comprendre comment utiliser les VBO dans Haskell. J'ai essayé de remplir les bits qui ne sont pas couverts là:OpenGL VBO dans Haskell

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 

Vous pouvez trouver le code complet here, dans le cas où vous avez besoin.

Sur le master branch, la même fonction utilise vertex appels normaux pour dessiner le Sprites et il fonctionne parfaitement. Mais en utilisant les VBO, le sprite n'est tout simplement pas là; Je reçois un écran vide. Est-ce que quelqu'un peut m'expliquer ce que j'ai mal fait ici?

+1

Pourriez-vous nous expliquer ce qui ne va pas? Est-ce qu'il compile et se comporte mal? –

+0

@ ThomasM.DuBuisson: Oh oui, désolé. Il compile parfaitement, mais l'écran reste vide. Le sprite n'apparaît pas - et il doit être dans la partie VBO ci-dessus parce que la même chose sans VBO fonctionne bien. – Lanbo

Répondre

1

Vous utilisez un tampon pour les sommets et les uvs. Utilisez deux tampons, un pour les sommets et un pour les uvs.