handa-opengl-0.1.11.2: src/Graphics/Rendering/Handa/Shape.hs
{-|
Module : Graphics.Rendering.Handa.Shape
Copyright : (c) 2015 Brian W Bush
License : MIT
Maintainer : Brian W Bush <consult@brianwbush.info>
Stability : Stable
Portability : Portable
Functions and types for managing shapes represented as vertex buffer objects (VBOs).
-}
{-# LANGUAGE RecordWildCards #-}
module Graphics.Rendering.Handa.Shape (
-- * Types
Shape
-- * Functions
, makeShape
, remakeShape
, drawShape
) where
import Data.Array.Storable (newListArray, withStorableArray)
import Foreign.Ptr (nullPtr)
import Foreign.Storable (Storable, sizeOf)
import Graphics.Rendering.OpenGL (DataType, BufferObject, BufferTarget(ArrayBuffer), BufferUsage(StaticDraw), Capability(..), ClientArrayType(VertexArray), NumArrayIndices, NumComponents, PrimitiveMode, Stride, VertexArrayDescriptor(..), ($=), arrayPointer, bindBuffer, bufferData, drawArrays, clientState, genObjectNames)
-- | A shape stored as a vertex buffer object (VBO).
data Shape =
Shape
{
vbo :: BufferObject -- ^ The handle to the vertex buffer object.
, components :: NumComponents -- ^ The number of components for the shape's vertices.
, dataType :: DataType -- ^ The data type of the shape's vertices.
, stride :: Stride -- ^ The stride, the number of components between consecutive vertices.
, size :: NumArrayIndices -- ^ The number of vertices.
, mode :: PrimitiveMode -- ^ The type of primitive.
, priorAction :: IO () -- ^ The display action to be executed prior to rendering the shape.
}
-- | Construct a shape.
makeShape :: Storable a
=> NumComponents -- ^ The number of components per vertex.
-> DataType -- ^ The data type for the vertices' components.
-> PrimitiveMode -- ^ The type of primitive.
-> [a] -- ^ The vertices.
-> IO () -- ^ The display action to be executed prior to rendering the shape.
-> IO Shape -- ^ An action for the shape.
makeShape components dataType mode vertices priorAction =
let
stride = undefined
size = undefined
in do
vbo <- head <$> genObjectNames 1
remakeShape Shape{..} vertices
-- | Reconstruct a shape by replacing its vertices.
remakeShape :: Storable a
=> Shape -- ^ The shape.
-> [a] -- ^ The replacement vertices.
-> IO Shape -- ^ An action for the updated shape.
remakeShape shape@Shape{..} vertices =
let
n = length vertices
m =
if null vertices
then 0
else sizeOf $ head vertices
ptrSize = toEnum $ n * m
in do
bindBuffer ArrayBuffer $= Just vbo
vertices' <- newListArray (0, n - 1) vertices
withStorableArray vertices' $ \ptr -> bufferData ArrayBuffer $= (ptrSize, ptr, StaticDraw)
bindBuffer ArrayBuffer $= Nothing
return $ shape {size = toEnum n, stride = toEnum m}
-- | Render a shape.
drawShape :: Shape -- ^ The shape.
-> IO () -- ^ An action to render the shape, also executing its prior actions before rendering it.
drawShape Shape{..} =
do
clientState VertexArray $= Enabled
bindBuffer ArrayBuffer $= Just vbo
arrayPointer VertexArray $= VertexArrayDescriptor components dataType stride nullPtr
priorAction
drawArrays mode 0 size
bindBuffer ArrayBuffer $= Nothing
clientState VertexArray $= Disabled