3D Text Rendering in Haskell with FTGL

Hi,

While I was writing a sort of password manager for my personal use (in Haskell) — actually, a friend of mine was doing the same in Java, so there was some competition :-) — I decided that just printing the password in the terminal wasn’t enough, at all. That’s why I decided to look at how it was possible to render text easily inside an OpenGL context, with possibly some depth given to each letter.

You know what ? Nearly like every time you look for some library in Haskell, you find it ! Mine was ftgl. You can, with only few lines, while in an OpenGL context, create some 3D text from given text and (TrueType) font and render it.

Since it is really easy to get working, here’s a little howto.

- be sure to have libftgl (the C version of the library), glut (often freeglut3 in distro repositories) and opengl correctly installed.
- be sure to have the Haskell OpenGL binding installed, and also GLUT (thus we can get a working 3D context in a (GLUT) window quite easily).
- get the Haskell binding of FTGL from hackage using cabal : cabal install ftgl.

Then you can try to play around the following code, that you may want to compile with ghc –make hs3dtext.hs -o hs3dtext.

?View Code HASKELL
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
module Main where
 
import Data.List
import Data.IORef
import Graphics.Rendering.OpenGL
import Graphics.Rendering.FTGL
import Graphics.UI.GLUT
import System.IO
 
main :: IO ()
main = do
  (_, _) <- getArgsAndInitialize
  initialDisplayMode $= [DoubleBuffered]
  createWindow "3D Text Renderer"
  angle <- newIORef 0.0
  font <- createExtrudeFont "FreeSans.ttf"
  setFontFaceSize font 7 7
  setFontDepth font 1.0
  displayCallback $= display "Haskell" angle font
  idleCallback $= Just (animate angle)
  mainLoop
 
display text angle font = do
  clear [ColorBuffer]
  loadIdentity
  scale 0.04 0.05 (0.5 :: GLfloat)
  a <- get angle
  rotate a $ Vector3 0 0 (1 :: GLfloat)
  renderFont font text All
  swapBuffers
 
animate angle = do
  a <- get angle
  case a > 179 of
    True  -> angle $= -180
    False -> angle $= a + 0.03
  postRedisplay Nothing

Don’t forget to get FreeSans.ttf from anywhere for it to work. The depth of the letters here is 1.0, you can play with it, but it doesn’t look as well as it does like I pasted.

Here is a cool screenshot :-)

Screen

Enjoy !


C++ introspection library and portable industrial graphical components for GPL and commercial use

Hi,

I’ve just found out two libraries which seem to be very interesting.

The first, CAMP, is an introspection library for C++. It appears to be well-thought and easily usable in concrete projects. Indeed, it isn’t (at all !) intrusive, which means you don’t have to modify existing classes to expose them to introspection. The example given in the documentation will be better than my words to explain that :

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
 #include <camp/camptype.hpp>
 #include <camp/class.hpp>
 #include <string>
 #include <iostream>
 
 // Let's define a class for handling persons
 class Person
 {
 public:
 
     // Construct a person from its name
     Person(const std::string& name) : m_name(name), m_age(0)
     {
     }
 
     // Retrieve the name of a person
     std::string name() const
     {
         return m_name;
     }
 
     // Retrieve the age of a person
     unsigned int age() const
     {
         return m_age;
     }
 
     // Set the age of a person
     void setAge(unsigned int age)
    {
         m_age = age;
     }
 
     // Make a person speak (tell about its name and age)
     void speak()
     {
         std::cout << "Hi! My name is " << m_name << " and I'm " << m_age << " years old." << std::endl;
     }
 
 private:
 
     std::string m_name;
     unsigned int m_age;
 };
 
 // Make the Person type available to CAMP
 CAMP_TYPE(Person);
 
 
 int main()
 {
     // Bind our Person class to CAMP
     camp::Class::declare<Person>("Person")
         .constructor1<std::string>()
         .property("name", &Person::name)
         .property("age", &Person::age, &Person::setAge)
         .function("speak", &Person::speak);
 
     // Retrieve it by its name
     const camp::Class& metaclass = camp::classByName("Person");
 
     // Construct a new person named John
     Person* john = metaclass.construct<Person>(camp::Args("John"));
 
     // Print its name
     std::string name = metaclass.property("name").get(john);
     std::cout << "John's name is: " << name << std::endl;
 
     // Set its age to 24
     metaclass.property("age").set(john, 24);
 
     // Make John say something
     metaclass.function("speak").call(john);
 
     // Kill John
     metaclass.destroy(john);
 
     return 0;
 }

The key part here is CAMP_TYPE(your_class). It exposes your_class to the introspection engine. Then, you bind anything you want from your class to the introspection engine, and you can play with all the CAMP API.

There’s also GICS, a portable library of industrial graphical components. Here are some screenshots :
Gauge
More complete example
Since it is based on Qt 4.5 and its QGraphicsView module, it is very efficient, scalable and easy to use. One can rely on that since Qt’s popularity and use is increasing, day after day.

Both are double-licensed : GPL and Commercial, depending on your usage. More informations and download links can be found on the products page of Tegesoft : http://www.tegesoft.com/products

I’m happy to see such good libraries, written in good C++, available under GPL !


Bouncing Ball in OCaml with OCamlSDL

Hi,

I’ve written a little boucing ball program in OCaml with OCamlSDL.
It can be used as a basis to write a Pong game, or any 2D game with a ball bouncing here and there on the screen.
You can download it (images, font, source code and Makefile included) here : bbsdl.tar.gz.

Don’t forget to tell me if you start using it.
By the way, I’ve put some comments in the code for learning purpose, as it has been my first OCamlSDL application so it may be of help for OCaml hackers.

Bouncing Ball in OCamlSDL

Enjoy.


Using OCaml’s module functors to provide monadic contexts for Batteries

Hi,

Several days ago, bluestorm and I started working on monads-related stuffs for Batteries, so that we’d be able to provide a good API for writing and using monads in Objective Caml.

Well, we’ve now written the basis of the future monad-related functions and modules in Batteries.

Of course, we’ve introduced two key monads, keeping Batteries’ spirit : the Option monad and the Enum monad. The first is the equivalent of Haskell’s Maybe monad, whereas the latter is somehow “equivalent” to Haskell’s List monad, with the difference that Batteries’ key data structure is Enum, whereas Haskell’s standard library’s is List.

We’ve also written two key functions for working with monads… If you are familiar with foldM and sequence in Haskell, working over lists, you won’t be lost when using our fold_monad and sequence functions, working over enums.

Hey, wait a minute…
Read the rest of this entry »


Review of OCaml Journal articles : Low-level optimization tips and tricks

Hi,

Jon Harrop has written many articles in his OCaml Journal, and some of them are related to low-level optimization, which is a very important topic for OCaml developers, as OCaml is a fast functional language and can race against mainstream languages if we help him with our way of writing code, using the compiler, etc.

These articles cover many aspects of optimizations, of different kind :

  • Architecture
  • Compiler manipulation (flags, etc)
  • Allocation
  • Deforesting (elimination of intermediate data structures)
  • Copies
  • Boxing
  • Mutation
  • Garbage collection
  • and so on…

As I’m often doing some “races” between OCaml and other languages (Haskell, C++, Java, …), it has been very interesting for me and I managed to write equivalent applications where OCaml was winning “the race”, together with C++, generally. I’ve been programming in C++ for 6 years now and know many optimizations-related stuffs in C++. But learning this kind of things for OCaml was very interesting but also important for me. Moreover, you know, when you like a programming language, you often want to discover its “underground”, know it just well so that you’ll exactly know what your code will generate.

With functional programming languages, however, it’s easier to have an idea of what will be generated by the compiler, but if you don’t read about such things, you’ll never be able to guess. I think as there’s not that much documentation about OCaml but the official reference manual, Jon’s work is really valuable and is (and would) be of help for many OCaml developers.

These articles have really helped me with discovering OCaml’s underground and were very useful for projects I’m working on, in OCaml of course. Why not for you ?

PS : Comments are closed. Don’t loose your time criticizing anyone. Thanks. But you can e-mail me for discussing it (same adress than on mailing lists).


Who thought OCaml was dead ?!

Hi,

I’m writing this post because I want to thank and encourage the OCaml community. Indeed, there are many really *great* news this week that you may have seen if you read either Planet OCaml(Core), the Caml mailing list or both.

OCaml and Debian — The first one is a very good one for making OCaml more popular, more easy to install, etc : The OCaml 3.11 Debian package is now in Debian’s official testing repository ! Yeah ! I really congratulate the debian-ocaml maintainer team for the huge work. Considering nearly all installations of Debian stable are for server-like usages, having the package in testing make it easier to install OCaml and get it installed and configured in two seconds for all desktop users of Debian (and Debian-based distributions). Indeed, everything will be done with a single root command :

1
# aptitude install ocaml

That’s all.

OCaml Batteries IncludedOCaml Batteries Included Beta 1 is out ! If you still don’t know about it, you should quickly go on its website on OCamlCore, download it and install it and then read the documentation for an introduction and a reference manual of Batteries. You can also take the ocaml-batteries-included package on Debian’s unstable repos.
The Beta 1 is already having its first feedbacks and already provide a huge amount of necessary modules and functions, with some syntax extensions and tools for making programming with Batteries the easier possible ! OCaml was criticized because of its standard library, lacking of many additional stuffs that are in Haskell’s SL. Now, it’s over. Batteries is easy to install, easy to use and provide a great new-standard-library. Come on, test it and give some feedback.

Cheers guys !

BTW, the French government still ignores problem related to the reforms about Universities and Research. They’re killing the whole University concept and system and still ignoring that great Researchers are working for a really bad salary, in bad conditions even if they’ve studied 8 years long at least and that there are people paid much more than what Researchers are, for much easier and cool works… Strikes goes on, we must save our Universities !


An OCaml IRC toplevel - Some other news

Hi,

It’s been some days I was working on a very interesting project…
Many of you probably know Internet Relay Chat (IRC), in particular the Freenode network. You can access it through an IRC Client, the most known being XChat. The host is irc.freenode.net, on port 6667.
Some of you are used to bots on IRC, often provided by regular IRC users, for their prefered language/tool/etc. There is lambdabot on the #haskell channel, geordi on the ##C++ channel, etc. I’ve also seen that Richard WM Jones had worked on a similar bot for the #ocaml channel, xavierbot. But I wasn’t quite satisfied with it as it was nearly not written in OCaml, and I also wanted to develop one myself.

And… it’s done ! I’m proud to introduce you mlbot, written in OCaml, for OCaml, in 144 LoC for the moment. The code will be online soon on mlbot’s webpage : http://mestan.fr/ocaml/mlbot/

Here is an example of interaction with mlbot :

<Alpounet> > List.fold_right (+) [1;2;3;4;5] 0 ;;
<mlbot> - : int = 15
<Alpounet> > “1″ + 1 ;;
<mlbot> Type Error
<Yoric[DT]> > ” *_o/* MLBot, c’est cool, *\\o_*”;;
<mlbot> - : string = ” *_o/* MLBot, c’est cool, *\\o_*”

For the moment, mlbot is only on the following channels, still on Freenode : #ocaml-fr and #mlbot, but will be soon on #ocaml when I’ll have finished some security improvements.

By the way, my Jane Street Summer Project application has been sent this morning, after many discussions with many people of the OCaml community that have helped and encouraged me : David Teller, Jon Harrop, Xavier Leroy and my computability professor, Grégory Lafitte.
This project will be about HLVM (http://hlvm.forge.ocamlcore.org/) and the OCaml language. Stay tuned !


OCaml and -dlambda #1

Hi,

Have you ever tried compiling with either ocamlc or ocamlopt with the -dlambda option ?

Compiling the following code :

1
2
3
4
5
let f = List.map (fun x -> x+1)
 
let print_list = List.iter (fun x -> Printf.printf " %d " x)
 
let _ = print_list ( f [1;2;3;4;5] )

give the following “lambda code” :

?View Code LAMBDA
1
2
3
4
5
6
7
8
9
10
11
12
13
(* $ ocamlc -dlambda test.ml *)
(setglobal Test!
  (let
    (f/58
       (function l/59
         (apply (field 10 (global List!)) (function x/60 (+ x/60 1)) l/59))
     print_list/61
       (apply (field 9 (global List!))
         (function x/62 (apply (field 1 (global Printf!)) " %d " x/62))))
    (seq
      (apply print_list/61
        (apply f/58 [0: 1 [0: 2 [0: 3 [0: 4 [0: 5 0a]]]]]))
      (makeblock 0 f/58 print_list/61))))
?View Code LAMBDA
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
(* $ ocamlopt -dlambda las.ml *)
(seq
  (let
    (f/58
       (function l/59
         (apply (field 10 (global List!)) (function x/60 (+ x/60 1)) l/59)))
    (setfield_imm 0 (global Test!) f/58))
  (let
    (print_list/61
       (apply (field 9 (global List!))
         (function x/62 (apply (field 1 (global Printf!)) " %d " x/62))))
    (setfield_imm 1 (global Test!) print_list/61))
  (apply (field 1 (global Test!))
    (apply (field 0 (global Test!)) [0: 1 [0: 2 [0: 3 [0: 4 [0: 5 0a]]]]]))
  0a)

There are many phases in the compilation process, and the lambda generation phase is the last before either bytecode/native code generation.

‘global’ keyword seems to reference modules (Test is the module of my file, because of the name, test.ml).
‘apply’ just does function calls.
‘field’ seems to reference function in modules, like index references values in arrays.

More in the next exploration of the -dlambda option !


Diving into Batteries #2 : Heavyweight strings

Today, we’ll give a whirl at the Rope module of OCaml Batteries Included.

What are ropes ?

Ropes are better strings (but heavyweight) :

    • The length of a rope can be determined in constant time
      appending or prepending a small rope to an arbitrarily large one in amortized constant time
      concat, substring, insert, remove operations in amortized logarithmic time
      access to and modification of ropes in logarithmic time
  • Moreover, functional purity is preserved, we do never modify the original rope when appending, inserting, removing, etc.
    There’ll just be as much as possible data shared between the resulting string and the original one.

    However, world is not pink-made. I quote the documentation :

    However, Rope is an amortized data structure, and its use in a persistent setting can easily degrade its amortized time bounds. It is thus mainly intended to be used ephemerally. In some cases, it is possible to use Rope persistently with the same amortized bounds by explicitly rebalancing ropes to be reused using balance. Special care must be taken to avoid calling balance too frequently; in the limit, calling balance after each modification would defeat the purpose of amortization.

    First, you have to know that a syntax extension is included in Batteries, such that you can create literal ropes instead of strings just by prefixing the litteral string with ‘r’. Let’s now see how we can create a rope containing the “OCaml Batteries Included” string.

    1
    
    let my_first_rope = r"OCaml Batteries Included" ;;

    The type of ‘my_first_rope’ is Batteries.Rope.t, that’s to say a rope.

    Of course, there are many conversions possible from and to ropes. from/to_string, from/to_ustring, of_char, of_uchar, of_latin1, and also many interactions possible with the Enum module. You can also lowercase and uppercase a rope, make a rope of ‘n’ times a given character ‘c’.

    As you may expect, there are many string operations included in this module. You can explode a string into a character list, you can split a rope using a given separator, get the character at a given position, remove characters, insert characters, concatenate ropes,

    OCaml programming, and more generally functional programming, is empowered by higher order functions. The Rope module uses it, providing us higher order functions like iter[...], range_iter[...], fold, map, filter, filter_map, etc. This way, we can express shortly in our code very complex operations with these higher order functions, which let us work on strings with power, speed and elegance.

    There are many other functions that fulfill (personally) all the needs I have from a string manipulation module.

    To conclude, there are many “bulk” variants of functions that let us work more efficiently for large chunks of string data.

    I think it is useless to give code using Batteries’ ropes, you should rather go to the corresponding documentation page and try it out !


    Writing powerful concurrent video-games with ACCLib in C++

    I’ve been recently involve in an amazing project, the first multithreaded game engine with real performance on multicore processors.
    We are all aware of the lack of video game performance on multicore, this engine claim linear performance scaling on manycore processors.
    About x4 performance gain on a quadcore HT corei7 (see here) . Independent results with cinebench and PovRay show amost the same results (4.38 at best). That means one thing : ACCLib is a great product, their video game demo shows the same performance results of easy to parallel applications. Free lunch is not over for video game.

    Benchmark

    I highly recommend to visit this site : ACCLib.com to get more informations.