Re: [Haskell-cafe] Decoupling OpenAL/ALUT packages from OpenGL

Sven Panne schrieb:
* a tiny "ObjectName" package, consisting only of OpenGL's ObjectName class (In "Data.ObjectName"? I'm not very sure about a good place in the hierarchy here.)
How about Data.GraphicsObjects ?
* a package containing most of the data types/newtypes in OpenGL's VertexSpec module (Vertex{2,3,4}, Color{3,4}, etc.) plus instances for the base classes like Eq, Ord, Show, etc. I really don't know a good name for this package and what a good place in the hierarchy would be (probably something like "Data.Foo", but what is Foo?)
Now that you mention it. I just looked through haskell hierachical libraries and there seems to be no standard data types for vector math. Am I getting something wrong or is every library that is using linear algebra stuff using its own data types? So if I use a numeric library for matrices inside HOpenGL I have to convert around? I think it would be nice to have data types and functions for dot produkt, scalar product, norms, ... together with HOpenGL types. Currently I am trying to embed a triangulation library from a ten year old diploma thesis (http://www.dinkla.net/fp/cglib.html) in my libary (I know that glu has tesselation). The author has developed a quite big and abstract type structure for all sorts of computer graphics algorithms and I didn't wanted to copy this into my library just for triangulation. But it is reasonable. It could be combined with HOpenGL types to maybe Data.VectorMath or Data.LinearAlgebra . I would favour the second.
The point is: The first two package would be very small. Would this be OK? Does anybody see other alternatives? What would be good names for those packages and where in the naming hierarchy should they really go?
Cheers, S. _______________________________________________ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe

Am Sonntag, 3. Mai 2009 00:56:00 schrieb Tillmann Vogt:
Sven Panne schrieb:
* a tiny "ObjectName" package, consisting only of OpenGL's ObjectName class (In "Data.ObjectName"? I'm not very sure about a good place in the hierarchy here.)
How about Data.GraphicsObjects ? [...]
Thanks for all the suggestions so far, a few remarks from my side (I just picked the last mail for the reply, no strong reason for this...): "Data.GraphicsObjects" is a bit misleading, because OpenAL's Buffers and Sources are instances, too, and they have nothing to do with graphics. Instances of ObjectName are just opaque resources from an external API, which you have to allocate and deallocate explicitly.
I think it would be nice to have data types and functions for dot produkt, scalar product, norms, ... together with HOpenGL types.
I fear that this might open a can of worms and could lead to even longer discussions than the ones about a collection framework. The design space for a vector math package is quite large, and I fear that e.g. a mathematician trying to implement some linear algebra package has vastly different requirements than somebody trying to implement the n-th incarnation of the Quake engine. Some points to consider: * Should the components of vectors etc. be strict? In OpenGL they are, and Data.Complex is similar in this respect. In my experience non-strict components lead to space leaks too easily, and I guess this is the rationale behind Complex, too. But non-strict components have some benefits, too, of course, especially if you do symbolic computation. * Should we abstract over the number of dimension of vectors, etc.? If yes, how strong can our compile-time type checking be? * If we really make this a more general vector math package, things like colors etc. should probably stay in the OpenGL package. But there are a few other packages needing color data types, too... * If the package is not general enough, it might be a bad idea to steal names/hierarchy locations which *are* general. Nevertheless, I'd be happy to see some proposals for a sensible, compact vector math package. Probably we can fulfill most of the common use cases with something simple. And one word about lumping the 3 packages together: Any function, module, and package should have *one* clearly defined task, this is crucial for every SW design. I would have a hard time explaining what this "super package" is all about, even if we throw only 2 of the 3 packages together. Personally I feel that this is a strong argument for 3 separate packages.
(I know that glu has tesselation). [...]
But GLU is basically dead with OpenGL 3.x. :-) Cheers, S.

Sven, Decoupling basic primitives for geometric modelling from OpenGL would be useful. For our work on data visualization (www.comp.leeds.ac.uk/funvis/) we introduced our own coordinate primitives for 2D and 3D (Coord2D and Coord3D), along with a simple typeclass for vector-like operations. As with HOpenGL, the constructors are strict. In addition to abstracting from spatial dimension, we were also thinking about different coordinate systems, e.g. polar, spherical, although we never developed this direction.
Nevertheless, I'd be happy to see some proposals for a sensible, compact vector math package. Probably we can fulfill most of the common use cases with something simple.
Even just data constructors and instances of these within Functor and Applicative are a useful starting point. If you wanted a type class to support vector maths, most of the standard graphics texts have an annex on vector operations; if your aim is a compact set of operations sufficient for OpenGL/AL, these would seem a sensible starting point - happy to summarise the contents of the texts on my shelf, but I doubt the list is surprising. regards, David -- Dr. David Duke E: djd@comp.leeds.ac.uk School of Computing W: www.comp.leeds.ac.uk/djd/ University of Leeds T: +44 113 3436800 Leeds, LS2 9JT, U.K.

Am Montag, 4. Mai 2009 13:33:33 schrieb David Duke:
Decoupling basic primitives for geometric modelling from OpenGL would be useful. [...] Even just data constructors and instances of these within Functor and Applicative are a useful starting point. [...]
I've taken a closer look at the available packages for vector math/linear algebra. They differ in a lot of respects, starting from their representations of vectors and matrices, use of the type system and its extensions, strictness, structure of their type classes, etc. This leads me to the conclusion that I should only lift the data types for vectors and matrices out of the OpenGL package, including only instances for standard type classes like Eq, Ord, Functor, etc. This means that the new package will *not* include type classes for things like scalars, vector spaces, etc. These can be defined by the other packages in their own "type class language". I really fail to see a common ground in this respect, even for basic things: Keeping things H98-compliant is a must for me, so putting things like fundeps or associated types in this new package is a no-go for me. Nevertheless, having a common set of (strict) data types for vector math will probably be very useful, even if it won't fulfill everybody's needs. What standard instances should be defined for those vectors and matrices? Things coming to mind are Eq, Ord, Show, Storable, Typeable1, Functor and Applicative. Have I missed some type classes? Regarding Functor/Applicative: The obvious instances for e.g. a 2-dimensional vertex are: data Vertex2 a = Vertex2 a a instance Functor Vertex2 where fmap f (Vertex2 x y) = Vertex2 (f x) (f y) instance Applicative Vertex2 where pure a = Vertex2 a a Vertex2 f g <*> Vertex2 x y = Vertex2 (f x) (g y) They fulfill all required laws, but are these the only possible instances? If not, are they at least the most "canonical" ones in a given sense? And finally: Does somebody have a real-world example where the Applicative instance is useful? Usages of the Functor instance are much more obvious for me. Cheers, S.

On Sun, May 10, 2009 at 01:50:08PM +0200, Sven Panne wrote:
Nevertheless, having a common set of (strict) data types for vector math will probably be very useful, even if it won't fulfill everybody's needs.
I can say that it would be useful at least for Hipmunk, specially being able to pass the same vector between the physics and the graphics code. Also, one suggestion: lots of SPECIALIZE pragmas for Floats and Doubles. Thanks, -- Felipe.

Sven Panne wrote:
Regarding Functor/Applicative: The obvious instances for e.g. a 2-dimensional vertex are:
data Vertex2 a = Vertex2 a a
instance Functor Vertex2 where fmap f (Vertex2 x y) = Vertex2 (f x) (f y)
instance Applicative Vertex2 where pure a = Vertex2 a a Vertex2 f g <*> Vertex2 x y = Vertex2 (f x) (g y)
They fulfill all required laws, but are these the only possible instances? If not, are they at least the most "canonical" ones in a given sense? And finally: Does somebody have a real-world example where the Applicative instance is useful? Usages of the Functor instance are much more obvious for me.
I'd say those are the right instances. Some obvious uses (perhaps more useful for Vector2 than Vertex2, but still) are: liftA2 (+) (Vertex2 1 3) (Vertex2 4 5) == Vertex2 5 8 pure 0 == Vertex2 0 0 The latter being a useful shorthand to get a vertex for the origin. Also, if you define Foldable: foldl1 (+) . liftA2 (*) v w == dotProduct v w The useful thing being that that definition of dotProduct is the same for 2-, 3- and 4- dimensional things, and for vertexes and vectors. So possible additions to your type-class list are Foldable and maybe Traversable (no harm, although I'd have to reach further for an example for this). I guess the tricky decision might be whether to provide a Num instance (again, probably more suitable for Vector2)? instance Num a => Num (Vertex2 a) where (+) = liftA2 (+) (-) = liftA2 (-) (*) = liftA2 (*) abs = fmap abs signum = fmap signum negate = fmap negate fromInteger = pure . fromInteger Even if you don't want to define Num, note how easy having the Applicative instance makes defining some of the operators :-) Thanks, Neil.

Am Montag, 11. Mai 2009 12:04:07 schrieb Neil Brown:
[...] So possible additions to your type-class list are Foldable and maybe Traversable (no harm, although I'd have to reach further for an example for this). I guess the tricky decision might be whether to provide a Num instance (again, probably more suitable for Vector2)? [...]
OK, I've added a bunch of instances for all vertex attribute types in the OpenGL 2.2.3.0 package. Let me know if there are standard classes for which you would like to see instances, too. I've deliberately omitted instances for Num, because they are not correct from a mathematical point of view: You can't e.g. add two points (only a point and a vector), the difference between two points is not a point (it's a vector), etc. Cheers, S.

Am Montag, 4. Mai 2009 13:33:33 schrieb David Duke:
Decoupling basic primitives for geometric modelling from OpenGL would be useful. [...] Even just data constructors and instances of these within Functor and Applicative are a useful starting point. [...]
This leads me to the conclusion that I should only lift the data types for vectors and matrices out of the OpenGL package, including only instances for standard type classes like Eq, Ord, Functor, etc. This means that the new package will *not* include type classes for things like scalars, vector spaces, etc. These can be defined by the other packages in their own "type class language". That seems a reasonable step. If and when consensus does emerge on
Sven, packaging vector & matrix operations, that could be added as a further package.
Regarding Functor/Applicative: The obvious instances for e.g. a 2-dimensional vertex are:
data Vertex2 a = Vertex2 a a
instance Functor Vertex2 where fmap f (Vertex2 x y) = Vertex2 (f x) (f y)
instance Applicative Vertex2 where pure a = Vertex2 a a Vertex2 f g <*> Vertex2 x y = Vertex2 (f x) (g y)
They fulfill all required laws, but are these the only possible instances? If not, are they at least the most "canonical" ones in a given sense? And finally: Does somebody have a real-world example where the Applicative instance is useful? Usages of the Functor instance are much more obvious for me.
The Vertex constructor and Applicative operators don't seem to admit anything different that is also sensible (unless someone has a use for <*> with function and/or args permuted). As to real-world example, if you interpret a vertex as a (position) vector and want to apply that to another vertex, liftA2 (+) is neat. For working with sampled data, we have something like class Interp b where interpolate :: Float -> b -> b -> b with suitable instances for types in the numeric hierarchy, and then instance (Interp a, Applicative f) => Interp (f a) where interp t = liftA2 (interp t) If vertex is an instance of applicative, we then immediately have interpolation between coordinates (we use it in contour and surface extraction, others may find it useful in animation or distortion). David -- Dr. David Duke E: djd@comp.leeds.ac.uk School of Computing W: www.comp.leeds.ac.uk/djd/ University of Leeds T: +44 113 3436800 Leeds, LS2 9JT, U.K.
participants (5)
-
David Duke
-
Felipe Lessa
-
Neil Brown
-
Sven Panne
-
Tillmann Vogt