2013-04-03 5 views
5

Basierend auf this post, versuchte ich herauszufinden, wie VBO in Haskell zu verwenden. Ich habe versucht, in den Bits zu füllen, die dort nicht abgedeckt wurden:OpenGL VBO in 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 

Sie können den vollständigen Code here, falls finden Sie benötigen.

Auf der master branch, verwendet die gleiche Funktion normale vertex Aufrufe, um die Sprites zu zeichnen und es funktioniert perfekt. Aber mit VBOs ist das Sprite einfach nicht da; Ich bekomme einen leeren Bildschirm.

Kann mir jemand erklären, was ich hier falsch gemacht habe?

+1

Können Sie uns erklären, was in erster Linie falsch ist? Kompiliert es sich und benimmt sich schlecht? –

+0

@ ThomasM.DuBuisson: Oh ja, tut mir leid. Es kompiliert perfekt, aber der Bildschirm bleibt leer. Das Sprite erscheint nicht - und es muss oben im VBO-Teil sein, weil dasselbe ohne VBO gut funktioniert. – Lanbo

Antwort

1

Sie verwenden einen Puffer für Vertices und UVs. Verwenden Sie zwei Puffer, einen für Vertices und einen für UVs.