OCaml native library to draw, scale, rotate shapes on screen

Is there any library to easily draw shapes (circle, rectangles, etc.) and rotate or scale them, and that also supports some alpha layer.

I know Graphics, but it does not look like you can rotate/scale/alpha easily shapes.
I know Cairo but it depends on lablgtk to draw things on the screen and I don’t need any widgets and I’d rather avoid dependencies to gtk.

For context I’m trying to port elm-playgound which allows to super easily code pictures, animations, or games (see https://package.elm-lang.org/packages/evancz/elm-playground/latest/ for its API).
I am almost done porting it in a Web context thanks to js_of_ocaml, ocaml-vdom, and the SVG support in a browser, but I’d like now to port it in a native context.

1 Like

I’m using the ocaml-cairo in a project, and it works relatively well. The library is also very nicely documented (there’s an ocaml translation of the cairo tutorial, and various examples). Note that it corresponds to the cairo2 package in opam, which does not depend on lablgtk!
(the downside being, I think, that the API provided by the cairo ( C) library is very imperative and can be a bit tricky to use at times).

I also know of the vg library for vector graphics, which has the virtue of being pure ocaml code. It is also very well documented. I suspect that it has a smaller feature set and number of supported backends than Cairo, but has a nicer API.
Actually, it seems that you can use Cairo as a backend for Vg (https://erratique.ch/software/vg/doc/Vgr_cairo/index.html), which might give you the best of both worlds, in the case where you want to use Vg with a backend only supported by Cairo.

5 Likes

ocaml-cairo depends on lablgtk. Here are the prerequisites on the github page of ocaml-cairo:

Prerequisites

You need the development files of Cairo (see the conf-cairo package) and the OCaml package lablgtk2 (in the OPAM package lablgtk ).

All the examples/ generate PNG; they don’t draw anything on the screen.
I was actually hoping a library like SDL would allow to draw things on the screen without any gtk dependencies, but looks like you can’t rotate/scale shapes in SDL.

Well, you can install the cairo2 opam package without having to install lablgtk. But indeed, in that case, you don’t get a way of drawing the pictures on the screen. As I understand it, the job of cairo/vg is only to turn geometric shapes into pixels. The job of writing these pixels in a file, or drawing them on the screen, is the job of a separate library/backend (and lablgtk can be one of these, but for instance I’ve also used X11 surfaces instead).

Wrt SDL: it should be in principle possible to use SDL as a cairo backend, but it seems you’d need to write some glue code yourself between ocaml-cairo and tsdl. https://www.cairographics.org/SDL/ seems relevant.

1 Like

Oh, and I should note that I know of a third option: https://github.com/let-def/wall

It also has a nice vector-graphics API, and can render to Tsdl (see the example).
(downside: it’s maybe a bit less mature and less documented than the other two, but seems to correspond to what you’re looking for.)

5 Likes

How do you draw on X11 surfaces without lablgtk?
In cairo.mli it’s written:
Surfaces that Cairo supports but for which no OCaml binding has
been created (yet, please contribute!):
- {!XLib}: XLib Surfaces — X Window System rendering using XLib.
- {!Win32}: Win32 Surfaces — Microsoft Windows surface support.
- {!Quartz}: Quartz Surfaces — Rendering to Quartz surfaces.

You an use e.g. Cairo.Image.create_for_data32 to create a Cairo RGBA surface from a bigarray (that can be then shared with Sdl or whatever other lib for displaying).

1 Like

Oh you’re right. I just found this example to transfer pictures from cairo to graphics:

@igarnier do you have sample code doing that? I’ve found some examples to do that between Cairo and the Graphics library, but could not find anything for SDL (via ocamlsdl2 or tsdl).

I do but it’s code I’m not particularly proud of: tread lightly. Have a look there: https://github.com/igarnier/vplot/blob/master/lib/display.ml

2 Likes

parfait! Merci beaucoup.

It worked! I was getting blocked with Graphics with the way it handles
the keyboard. With SDL I can get all the events I want.

1 Like

You can scale and rotate with SDL2 and it’s bindings.
Use the function Render.copyEx to copy a sprite on screen. Use the angle parameter to rotate and use rectangles of different width and height to scale.
SDL2 doesn’t permit to draw much shapes though, only rectangles by default, because it’s made for gamedev, but you can use the SDL2_gfx lib in addition with SDL2, with its template bindings OCamlSDL2_Gfx.

1 Like

SFML and its bindings ocaml-sfml allow more shapes drawing than SDL2.

You will probably be able to do everything you want with it, any shapes, rotate, scale, translate and more!
Have a look at its api-doc, and in particular the SFShape module.

(Also please notice that SDL and SDL2 are 2 different libs, that don’t share any code, and have 2 different licenses, and with different implementations, SDL 1.2 uses software render, and SDL2 uses OpenGL inside.)

If someone wants to make ctype bindings to SFML, there is the lib CSFML which is a C wrapper lib around the C++ SFML lib.


(can not make more than 3 messages, so let’s edit this one)

If you already have your code with Graphics and want more events you can also use GraphicsX11 and get the window ID.

Then with this window ID you can pass it to another lib, like for example ocaml-xlib and get more user events.

(Every windowing lib is supposed to provide this window ID for interactions with other libs.)