lambdacube-engine-0.2.1: Graphics/LambdaCube/HardwareVertexBuffer.hs
module Graphics.LambdaCube.HardwareVertexBuffer where
import Data.IntMap
import Data.Word
import Foreign.C.Types
import Foreign.Storable
import Graphics.LambdaCube.HardwareBuffer
class HardwareBuffer a => HardwareVertexBuffer a where
getVertexSize :: a -> Int -- ^ Gets the size in bytes of a single vertex in this buffer
getNumVertices :: a -> Int -- ^ Get the number of vertices in this buffer
-- | Vertex element semantics, used to identify the meaning of vertex buffer contents
data VertexElementSemantic
= VES_POSITION -- ^ Position, 3 reals per vertex
| VES_BLEND_WEIGHTS -- ^ Blending weights
| VES_BLEND_INDICES -- ^ Blending indices
| VES_NORMAL -- ^ Normal, 3 reals per vertex
| VES_DIFFUSE -- ^ Diffuse colours
| VES_SPECULAR -- ^ Specular colours
| VES_TEXTURE_COORDINATES -- ^ Texture coordinates
| VES_BINORMAL -- ^ Binormal (Y axis if normal is Z)
| VES_TANGENT -- ^ Tangent (X axis if normal is Z)
deriving (Enum,Eq,Ord,Show)
-- | Vertex element type, used to identify the base types of the vertex contents
data VertexElementType
= VET_FLOAT1
| VET_FLOAT2
| VET_FLOAT3
| VET_FLOAT4
| VET_SHORT1
| VET_SHORT2
| VET_SHORT3
| VET_SHORT4
| VET_UBYTE4
| VET_COLOUR_ARGB -- ^ D3D style compact colour
| VET_COLOUR_ABGR -- ^ GL style compact colour
deriving (Eq,Ord,Show)
data VertexElement
= VertexElement
{ veSource :: Int -- ^ The source vertex buffer, as bound to an index using VertexBufferBinding
, veOffset :: Int -- ^ The offset in the buffer that this element starts at
, veType :: VertexElementType -- ^ The type of element
, veSemantic :: VertexElementSemantic -- ^ The meaning of the element
, veIndex :: Int -- ^ Index of the item, only applicable for some elements like texture coords
}
deriving (Eq,Ord,Show)
-- | Utility method for helping to calculate offsets
getTypeSize :: VertexElementType -> Int
getTypeSize etype = case etype of
VET_COLOUR_ABGR -> sizeOf (undefined::Word32) -- sizeof(RGBA);
VET_COLOUR_ARGB -> sizeOf (undefined::Word32) -- sizeof(RGBA);
VET_FLOAT1 -> sizeOf (undefined::CFloat) -- sizeof(float);
VET_FLOAT2 -> 2 * sizeOf (undefined::CFloat) -- sizeof(float)*2;
VET_FLOAT3 -> 3 * sizeOf (undefined::CFloat) -- sizeof(float)*3;
VET_FLOAT4 -> 4 * sizeOf (undefined::CFloat) -- sizeof(float)*4;
VET_SHORT1 -> sizeOf (undefined::CShort) -- sizeof(short);
VET_SHORT2 -> 2 * sizeOf (undefined::CShort) -- sizeof(short)*2;
VET_SHORT3 -> 3 * sizeOf (undefined::CShort) -- sizeof(short)*3;
VET_SHORT4 -> 4 * sizeOf (undefined::CShort) -- sizeof(short)*4;
VET_UBYTE4 -> 4 * sizeOf (undefined::CUChar) -- sizeof(unsigned char)*4;
-- | Utility method which returns the count of values in a given type
getTypeCount :: VertexElementType -> Int
getTypeCount etype = case etype of
VET_COLOUR_ABGR -> 4
VET_COLOUR_ARGB -> 4
VET_FLOAT1 -> 1
VET_FLOAT2 -> 2
VET_FLOAT3 -> 3
VET_FLOAT4 -> 4
VET_SHORT1 -> 1
VET_SHORT2 -> 2
VET_SHORT3 -> 3
VET_SHORT4 -> 4
VET_UBYTE4 -> 4
-- | Simple converter function which will turn a single-value type into a multi-value type based on a parameter.
multiplyTypeCount :: VertexElementType -> Int -> VertexElementType
multiplyTypeCount baseType count = case baseType of
VET_FLOAT1 -> case count of
1 -> VET_FLOAT1
2 -> VET_FLOAT2
3 -> VET_FLOAT3
4 -> VET_FLOAT4
_ -> error $ "multiplyTypeCount: Invalid VET_FLOAT type " ++ show count
VET_SHORT1 -> case count of
1 -> VET_SHORT1
2 -> VET_SHORT2
3 -> VET_SHORT3
4 -> VET_SHORT4
_ -> error $ "multiplyTypeCount: Invalid VET_FLOAT type " ++ show count
_ -> error $ "multiplyTypeCount: Invalid base type " ++ show baseType
-- | Simple converter function which will convert a type into its
-- single-value equivalent to make switches on type easier.
getBaseType :: VertexElementType -> VertexElementType
getBaseType multiType = case multiType of
VET_FLOAT1 -> VET_FLOAT1
VET_FLOAT2 -> VET_FLOAT1
VET_FLOAT3 -> VET_FLOAT1
VET_FLOAT4 -> VET_FLOAT1
VET_SHORT1 -> VET_SHORT1
VET_SHORT2 -> VET_SHORT1
VET_SHORT3 -> VET_SHORT1
VET_SHORT4 -> VET_SHORT1
mt -> mt
data VertexDeclaration
= VertexDeclaration
{ vdElementList :: [VertexElement] -- ^ The list of vertex elements that makes up this declaration
}
deriving (Eq,Ord,Show)
data HardwareVertexBuffer vb => VertexBufferBinding vb
= VertexBufferBinding
{ vbbBindingMap :: IntMap vb
}
deriving (Eq,Ord)