correction: Re: [HOpenGL] vector/vertex specification stuff

Marc Ziegert coeus@gmx.de
Wed, 8 Jan 2003 13:19:13 +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 GLVertex v where
    glVertex :: v -> IO ()

%fun glVertex1s :: GLshort -> IO ()
%fun glVertex2s :: GLshort  -> GLshort -> IO ()
%fun glVertex3s :: GLshort  -> GLshort  -> GLshort -> IO ()
%fun glVertex4s :: GLshort  -> GLshort  -> GLshort  -> GLshort -> IO ()

instance GLVertex (Vector1 GLShort) where
    glVertex (Vector (x `VEnd`)) = glVertex1s x

instance GLVertex (Vector2 GLShort) where
    glVertex (Vector (x `VSep` y `VEnd`)) = glVertex2s x y

instance GLVertex (Vector3 GLShort) where
    glVertex (Vector (x `VSep` y `VSep` z `VEnd`)) = glVertex3s x y z

instance GLVertex (Vector4 GLShort) where
    glVertex (Vector (x `VSep` y `VSep` z `VSep` w `VEnd`)) = glVertex4s 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`)

glVertex1 :: GLShort -> IO ()
glVertex2 :: GLShort -> GLShort -> IO ()
glVertex3 :: GLShort -> GLShort -> GLShort -> IO ()
glVertex4 :: GLShort -> GLShort -> GLShort -> GLShort -> IO ()

glVertex1 x = glVertex $ vector1 x
glVertex2 x y = glVertex $ vector2 x y
glVertex3 x y z = glVertex $ vector3 x y z
glVertex4 x y z w = glVertex $ vector4 x y z w

-- examples:
-- glVertex (vector3 x y z)
-- glVertex3 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?