Hi everyone,
I would like to share some thoughts about this (good) idea of having a
2D graphics API in the C++ standard. I am a C++ enthusiast, and a user
of some of the APIs that have been mentioned: I have already used (in
real programs) SFML2, SDL2, cairo, Qt5. I am not really an expert in 2D
graphics but a simple high level user that sometimes need 2D drawings
(so I am perfectly in the target audience of the proposal).
First of all, I think the APIs I mentioned can be divided into two
different groups.
The first group is what I would call the game APIs. SFML2 and SDL2 are
very young libraries that have old ancestors (respectively SFML and SDL)
so they are at the state of the art regarding this type of APIs that
target gaming. If I make a summary, the heart of these API is to give an
abstraction of a rendering target (a window or a texture) and a way to
display (part of) textures on a position of the rendering target. That's
all, no drawing at all. These APIs are meant to be used in a loop where
you prepare the next frame and then display it. An important point is a
clear separation between an image (in main memory) and a texture (in GPU
memory) with functions to transform one into the other.
The second group is what I would call the vector drawing APIs. cairo and
Qt5 are good examples, I would also add Skia [1] (which has not been
mentioned so far) which is used by Google in Chrome and can easily
qualify as a portable library. These library are based on the PDF model,
i.e. they implement all that is necessary to be able to render PDF. If
you look at the PDF standard, you will find some great similarities with
cairo (cairo was designed with PS and PDF in mind). This type of API is
meant to be used for general vector 2D drawing on any rendering targets.
Generally that means raster images (PNG, JPG), vector images (PS, PDF,
SVG) and screens.
Merging these two groups may not be easy as they have different
constraints and goals. Or it may be two sides of a resulting API.
Second, when talking about a drawing API, it seems that there are a lot
of other things that must be clearly defined first, as it will have an
impact on the drawing API and beyond. The color concept is just an
example that already have been discussed, we could add font, point, 3x3
matrix, image. I am not suggesting to split SG13 into subgroups, I am
just saying that defining such things in the standard may have great
(and positive) consequences on many existing codes as they could rely on
types from the standard library. Doors would be open to extensions: a 2D
geometry library (like Boost.Geometry) or a raster image manipulation
and filtering library (like G'MIC [2]).
Third, my opinion about the N3888 proposal is that it is too early to
make such a proposal. Cairo is a good API and the translation to C++ was
very well done. But I really wonder if the proposal is not missing the
point. For example, N3791 give the example of "Beman's challenge" that
can easily be done with SFML2 or SDL2, but that can not be done with
cairo at all because the input part is totally missing. If the strategy
is to add an input API to cairo, I think it goes to a disaster. I think
(and I may be wrong) that the good strategy is to try to mix the two
groups I discussed previouly, see the basic needs and then build on top
of that.
As I want to be constructive, here are some more thoughts about what
such an API could be. First there are different levels of drawing:
simple (such as the one in SDL2 and SFML2, i.e. copying part of a
texture to a destination on the target), vector (like the context API in
N3888), raster (individual access to "pixels"). There would be different
rendering targets, not all available through all drawing API: image
(i.e. an abstraction of a 2D matrix of "pixels"), texture (an image in
the GPU memory), screen (a window), files (PDF, SVG, PNG, JPG, etc). To
have a decent API, fonts should be added. Fonts can be abstracted with a
name and some additional information (bold, italic, size, etc) and maybe
more. For this point, maybe the guys from Pango [3] could help. The
choice for the representation of colors is essential as it may have
consequences (for example regarding OpenGL). Images could be templated
with the format. The Go language has a good abstraction of images and
colors [4] (See also [5] for a very simple example of drawing API,
looking like SDL2/SFML2, but only on images). Finally, inputs (keyboard,
mouse, joystick, etc) is another big and difficult part because an
abstraction for an input device may not be good for another input
device. SFML2 has a class (and events) for each device type. That's all
for now.
I hope this can help.
Julien
[1]
https://code.google.com/p/skia/
[2]
http://gmic.sourceforge.net/
[3]
http://www.pango.org/
[4]
http://golang.org/pkg/image/draw/
[5]
http://blog.golang.org/go-imagedraw-package