[HOpenGL] vector/vertex specification stuff

Marc Ziegert coeus@gmx.de
Wed, 8 Jan 2003 13:05:59 +0100


--Last weeks I've played with ObjectIO-GUIs (until I realised the
one-button-mouse implementation and that it still runs only on Win). They
are very fascinating designed.
--Inspired by them...
--To unify 1D/2D/3D/4D vectors/vertices, I would try to implement the
following:
--(I did not test it - I hope this is Haskell98 and "%precompiler" conform.)

class VectorClass v where
    dotVec :: (VectorTyp a) => v a -> v a -> a

class VectorTyp va where
    addVec :: va -> va -> va
    subVec :: va -> va -> va
    negVec :: va -> va

data Vector b a = (VectorContainer b) => Vector (b a)

instance VectorClass (Vector b) where
    dotVec :: (VectorTyp a) => Vector b a -> Vector b a -> a
    dotVec (Vector ba1) (Vector ba2) = dotVecCont ba1 ba2

instance VectorTyp (Vector b a) where
    addVec :: Vector b a -> Vector b a -> Vector b a
    addVec (Vector ba1) (Vector ba2) = addVecCont ba1 ba2
    ....

instance (Num v) => VectorTyp v where
    addVec = (+)
    ...

class VectorContainer b where
    addVecCont :: (VectorTyp a) => b a -> b a -> b a
    subVecCont :: (VectorTyp a) => b a -> b a -> b a
    negVecCont :: (VectorTyp a) => b a -> b a
    dotVecCont :: (VectorTyp a) => b a -> b a -> a

infixr 8 `VSep`, `VEnd`
-- (Vector $ x `VSep` y `VSep` z `VEnd`)

data VectorContainerPart b a = (VectorContainer b,VectorTyp a) => VSep a (b
a)
data VectorContainerEnd a = (VectorTyp a) => VEnd a

instance VectorContainer VectorContainerEnd where
    addVecCont :: (VectorTyp a) => VectorContainerEnd a ->
VectorContainerEnd a -> VectorContainerEnd a
    addVecCont (a1 `VEnd`) (a2 `VEnd`) = (a1 `addVec` a2) `VEnd`
    ...

instance (VectorContainer b) => VectorContainer (VectorContainerPart b)
where
    addVecCont :: (VectorTyp a) => VectorContainerPart b a ->
VectorContainerPart b a -> VectorContainerPart b a
    addVecCont (a1 `VSep` ba1) (a2 `VSep` ba2) = (a1 àddVec` a2) `VSep` (ba1
`addVecCont` ba2)
    ...


type Vector1 a = Vector (VectorContainerEnd a) a
type Vector2 a = Vector (VectorContainerPart (VectorContainerEnd a) a) a
type Vector3 a = Vector (VectorContainerPart (VectorContainerPart
(VectorContainerEnd a) a) a) a
type Vector4 a = Vector (VectorContainerPart (VectorContainerPart
(VectorContainerPart (VectorContainerEnd a) a) a) a) a


class GLVector v where
    glVector :: v -> IO ()

%fun glVector1s :: GLshort -> IO ()
%fun glVector2s :: GLshort  -> GLshort -> IO ()
%fun glVector3s :: GLshort  -> GLshort  -> GLshort -> IO ()
%fun glVector4s :: GLshort  -> GLshort  -> GLshort  -> GLshort -> IO ()

instance GLVector (Vector1 GLShort) where
    glVector (Vector (x `VEnd`)) = glVector1s x

instance GLVector (Vector2 GLShort) where
    glVector (Vector (x `VSep` y `VEnd`)) = glVector2s x y

instance GLVector (Vector3 GLShort) where
    glVector (Vector (x `VSep` y `VSep` z `VEnd`)) = glVector3s x y z

instance GLVector (Vector4 GLShort) where
    glVector (Vector (x `VSep` y `VSep` z `VSep` w `VEnd`)) = glVector4s x y
z w


vector1 :: (VectorTyp a) => a -> (Vector1 a)
vector2 :: (VectorTyp a) => a -> a -> (Vector2 a)
vector3 :: (VectorTyp a) => a -> a -> a -> (Vector3 a)
vector4 :: (VectorTyp a) => a -> a -> a -> a -> (Vector4 a)

vector1 x = (Vector $ x `VEnd`)
vector2 x y = (Vector $ x `VSep` y `VEnd`)
vector3 x y z = (Vector $ x `VSep` y `VSep` z `VEnd`)
vector4 x y z w = (Vector $ x `VSep` y `VSep` z `VSep` w `VEnd`)

glVector1 :: GLShort -> IO ()
glVector2 :: GLShort -> GLShort -> IO ()
glVector3 :: GLShort -> GLShort -> GLShort -> IO ()
glVector4 :: GLShort -> GLShort -> GLShort -> GLShort -> IO ()

glVector1 x = (glVector . vector1)
glVector2 x = (glVector . vector2)
glVector3 x = (glVector . vector3)
glVector4 x = (glVector . vector4)

-- examples:
-- glVector (vector3 x y z)
-- glVector3 x y z



----- Original Message -----
From: "Sven Panne" <Sven_Panne@BetaResearch.de>
Sent: Wednesday, January 08, 2003 9:00 AM
Subject: Re: [HOpenGL] GLUT.MouseButton
> While I'm at it: I really like to hear opinions and improvements of the
> API, e.g. the vertex specification stuff like
>
>    class Vertex a where
>       vertex :: a -> IO ()
>
>    data Vertex2 a = Vertex2 a a
>
>    instance Vertex (Vertex2 GLshort) where   -- complex instance head!!!
>       vertex (Vertex2 x y) = vertex2s x y
>
>    %fun glVertex2s :: GLshort  -> GLshort -> IO ()
>
> is not Haskell98. How can we do better, i.e. unify 1D/2D/3D/4D vertices
> with differing component types in pure Haskell98?