Some thoughts about SG13's work

65 views
Skip to first unread message

Julien Bernard

unread,
Jan 21, 2014, 5:37:22 PM1/21/14
to grap...@isocpp.org
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

Klaim - Joël Lamotte

unread,
Jan 21, 2014, 5:51:59 PM1/21/14
to grap...@isocpp.org
Hi Julien, just a short question: could you clarify what you mean exactly by "no drawing" in SDL and SFML (and Cinder and OpenFrameworks etc.)?
They do provide drawing functions but they indeed don't draw directly to the surface, but combine different sources to build the final surface state. Is it what you mean?

jason zink

unread,
Jan 21, 2014, 9:27:34 PM1/21/14
to grap...@isocpp.org
Hi Julien,

Thanks for your comments.  Indeed there does seem to be two different styles of drawing APIs, which I think has also been touched on in a previous discussion (although probably not quite so clearly).  I'm not sure that the two styles can't be accomplished within the same API though. 

As both Michael and Herb have pointed out in some of the other threads, N3888 is the first proposal from which we can modify and build on.  This was the direction from the committee, and I think it is also a good way to start building some consensus.  Already there is a number of good change proposals (some of which were discussed previously, some not) which will provide a good series of steps to take in updating the API.

Regarding Beman's challenge and the lack of an input API - we need to be realistic about trying to get a proposal on the table.  Just look at all of the comments (good and bad) that this limited proposal has drawn.  It didn't make sense to try and put the entire proposal into the first shot, so input was left for a future update.  My own efforts will be directed at trying to corner out a subset of the changes that can be packaged into another proposal modification, in an attempt to incrementally shape where the API will end up.

I would also encourage you to try thinking about this style of changes, which should be more manageable than starting completely over.

Jason


On Tuesday, January 21, 2014 5:52 PM, Klaim - Joël Lamotte <mjk...@gmail.com> wrote:
Hi Julien, just a short question: could you clarify what you mean exactly by "no drawing" in SDL and SFML (and Cinder and OpenFrameworks etc.)?
They do provide drawing functions but they indeed don't draw directly to the surface, but combine different sources to build the final surface state. Is it what you mean?

--
You received this message because you are subscribed to the Google Groups "Graphics" group.
To unsubscribe from this group and stop receiving emails from it, send an email to graphics+u...@isocpp.org.
To post to this group, send email to grap...@isocpp.org.
Visit this group at http://groups.google.com/a/isocpp.org/group/graphics/.
To view this discussion on the web visit
https://groups.google.com/a/isocpp.org/d/msgid/graphics/CAOU91OOji1Z58CbDaB%2BK6M2bXhiOU%3Df1UgdRrvCru%3D7j0O9dgA%40mail.gmail.com
.


Julien Bernard

unread,
Jan 22, 2014, 4:50:03 AM1/22/14
to grap...@isocpp.org
I meant that there are no such primitives as lines, ellipses and so on,
the only primitive is "draw a portion of texture on the target". But I
realize that SDL2 has those primitives. Well, let's say I wanted to
emphasize these kind of functions:
- in SDL2 [1]

int SDL_RenderCopyEx(SDL_Renderer* renderer,
SDL_Texture* texture,
const SDL_Rect* srcrect,
const SDL_Rect* dstrect,
const double angle,
const SDL_Point* center,
const SDL_RendererFlip flip)

- in SFML2 in sf::RenderTarget class [2]:

void draw(const Drawable &drawable,
const RenderStates&states=RenderStates::Default)

void draw(const Vertex *vertices,
unsigned int vertexCount,
PrimitiveType type,
const RenderStates &states=RenderStates::Default)

and the sf::Vertex class [3] is just:

Vector2f position
Color color
Vector2f texCoords

- in Go, the Draw function [4]:

http://golang.org/pkg/image/draw/#Draw

- in Java, in the java.awt.Graphics2D class [5]:

boolean drawImage(Image img,
AffineTransform xform,
ImageObserver obs)

The Java documentation of Graphics2D gives a good synthesis describing
"three types of rendering operations":
- "shape operations": roughly what cairo provides
- "text operations": roughly what Pango+cairo provides
- "image operations": roughly what SDL2/SFML2 provides

Now, is it easy to add this kind of operation to the current proposal?
Maybe. In cairo, it would be implemented with a mix between
cairo_set_source_surface and cairo_clip, I think. But it deserves its
own method.


Julien


[1] http://wiki.libsdl.org/SDL_RenderCopyEx
[2] http://sfml-dev.org/documentation/2.1/classsf_1_1RenderTarget.php
[3] http://sfml-dev.org/documentation/2.1/classsf_1_1Vertex.php
[4] http://golang.org/pkg/image/draw/#Draw
[5]
http://docs.oracle.com/javase/6/docs/api/java/awt/Graphics2D.html#drawImage(java.awt.Image,
java.awt.geom.AffineTransform, java.awt.image.ImageObserver)

Reply all
Reply to author
Forward
0 new messages