Line drawing in SDL 1.3

I recently added simple line drawing to the SDL API, and discovered
that most drawing APIs will not draw the one of the endpoints of the
line. The reason they do this is so that multiple line drawing calls
can be made to create a polygon without any overdraw.

I’m considering changing the SDL line drawing semantics to match this.
Any thoughts?

See ya!–
-Sam Lantinga, Founder and President, Galaxy Gameworks LLC

Seems very reasonable, especially if it is documented behavior in the SDL
docs.> ----- Original Message -----

From: sdl-bounces@lists.libsdl.org [mailto:sdl-bounces at lists.libsdl.org] On
Behalf Of Sam Lantinga
Sent: Monday, December 07, 2009 8:59 PM
To: SDL; Bob Pendleton; ??? ???
Subject: [SDL] Line drawing in SDL 1.3

I recently added simple line drawing to the SDL API, and discovered
that most drawing APIs will not draw the one of the endpoints of the
line. The reason they do this is so that multiple line drawing calls
can be made to create a polygon without any overdraw.

I’m considering changing the SDL line drawing semantics to match this.
Any thoughts?

See ya!

-Sam Lantinga, Founder and President, Galaxy Gameworks LLC


SDL mailing list
SDL at lists.libsdl.org
http://lists.libsdl.org/listinfo.cgi/sdl-libsdl.org

And what if one wants to just draw a line, not a polygon? I would think that
is the case 99% of the time.

JeffOn Monday 07 December 2009 18:59, Sam Lantinga wrote:

I recently added simple line drawing to the SDL API, and discovered
that most drawing APIs will not draw the one of the endpoints of the
line. The reason they do this is so that multiple line drawing calls
can be made to create a polygon without any overdraw.

I’m considering changing the SDL line drawing semantics to match this.
Any thoughts?

And what if one wants to just draw a line, not a polygon? I would think
that
is the case 99% of the time.

Annnnddd… just as a simple question - is saving that one pixel that large
of an optimization ? If it is, wouldn’t it be better off to obfuscate
matters more into separate calls for polygon vs unrelated line drawing ? If
I was just drawing lines and had to make a special case to handle this
single missing pixel, I’d be a bit miffed :slight_smile:

-Will

It’s not for optimization purposes; it’s to draw polygons correctly at alpha values less than FF.________________________________
From: unfies@gmail.com (William Langford)
Subject: Re: [SDL] Line drawing in SDL 1.3

And what if one wants to just draw a line, not a polygon? I would think that

is the case 99% of the time.

Annnnddd… just as a simple question - is saving that one pixel that large of an optimization ? If it is, wouldn’t it be better off to obfuscate matters more into separate calls for polygon vs unrelated line drawing ? If I was just drawing lines and had to make a special case to handle this single missing pixel, I’d be a bit miffed :slight_smile:

-Will

It’s not for optimization purposes; it’s to draw polygons correctly at
alpha values less than FF.

Sounds definitely like it’d be better off as an sdl_drawpolygon kind of call
(taking a null terminated or linked list of end points ?) rather than being
inherent to the line drawing algorithm, IMHO.

Or a flag value passed similar to ROP stuff so that the end-user coder can
specify what they want, leaving the SDL line stuff … well… simple :slight_smile:
(leaving combing over a list of vertexes up to end-user to design as they
see fit / needed ?)

Otherwise, to draw just an unattached line, I’d need to make two calls ? The
’regular’ one, and then a single-pixel length line / putpixel() at the end
(or beginning ?) to make sure the forced-missing-pixel gets filled ?

-WillOn Mon, Dec 7, 2009 at 10:25 PM, Mason Wheeler wrote:

Well, it’s already awkward, because that’s what I end up having to do
internally.

I don’t do a lot of line drawing in other APIs… how is this
typically handled? As far as I can tell you just place the end point
one pixel farther than where you want to draw, but this has to be done
at the app level and may require sub-pixel precision to get the right
slope for diagonal lines.

Bob, can you weigh in?On Mon, Dec 7, 2009 at 8:31 PM, Will Langford wrote:

On Mon, Dec 7, 2009 at 10:25 PM, Mason Wheeler wrote:

It’s not for optimization purposes; it’s to draw polygons correctly at
alpha values less than FF.

Sounds definitely like it’d be better off as an sdl_drawpolygon kind of call
(taking a null terminated or linked list of end points ?) rather than being
inherent to the line drawing algorithm, IMHO.
Or a flag value passed similar to ROP stuff so that the end-user coder can
specify what they want, leaving the SDL line stuff … well… simple :slight_smile:
(leaving combing over a list of vertexes up to end-user to design as they
see fit / needed ?)
Otherwise, to draw just an unattached line, I’d need to make two calls ? The
’regular’ one, and then a single-pixel length line / putpixel() at the end
(or beginning ?) to make sure the forced-missing-pixel gets filled ?
-Will


SDL mailing list
SDL at lists.libsdl.org
http://lists.libsdl.org/listinfo.cgi/sdl-libsdl.org


-Sam Lantinga, Founder and President, Galaxy Gameworks LLC

I’ve always considered SDL’s ability to draw lines as useful in
debugging / testing situations. There are a lot of really interesting
conversations to have about drawing. It can get really hairy. I think
the drawing APIs in SDL should either go in a very powerful,
sophisticated direction; or just retain a straightforward test/debug
specialization and obey the Principle of Least Surprise.

This proposal seems like it might introduce surprises. A random
example of something that might be surprising: having graphics
disappear prematurely when scaling down to being 1px in size.
Principally though the main thing is that you might not guess that a
line-drawing method was really a polygon drawing method.On Mon, Dec 7, 2009 at 9:59 PM, Sam Lantinga wrote:

I recently added simple line drawing to the SDL API, and discovered
that most drawing APIs will not draw the one of the endpoints of the
line. ?The reason they do this is so that multiple line drawing calls
can be made to create a polygon without any overdraw.


http://codebad.com/

I’m not Bob, but all the “modern” APIs I’ve used (MIDP, .NET, …) paint
both endpoints of a line and have a separate command for drawing a line
loop (or hollow polygon).

IMO that’s the “Simple” way.–
Jukka-Pekka Manninen

-----Original Message-----
From: sdl-bounces at lists.libsdl.org
[mailto:sdl-bounces at lists.libsdl.org]
On Behalf Of Sam Lantinga
Sent: 8. joulukuuta 2009 7:22
To: SDL Development List; Bob Pendleton
Subject: Re: [SDL] Line drawing in SDL 1.3

Well, it’s already awkward, because that’s what I end up having to do
internally.

I don’t do a lot of line drawing in other APIs… how is this
typically handled? As far as I can tell you just place the end point
one pixel farther than where you want to draw, but this has to be done
at the app level and may require sub-pixel precision to get the right
slope for diagonal lines.

Bob, can you weigh in?

On Mon, Dec 7, 2009 at 8:31 PM, Will Langford wrote:

On Mon, Dec 7, 2009 at 10:25 PM, Mason Wheeler wrote:

It’s not for optimization purposes; it’s to draw polygons correctly
at

alpha values less than FF.

Sounds definitely like it’d be better off as an sdl_drawpolygon kind
of
call

(taking a null terminated or linked list of end points ?) rather
than
being

inherent to the line drawing algorithm, IMHO.
Or a flag value passed similar to ROP stuff so that the end-user
coder
can

specify what they want, leaving the SDL line stuff … well… simple
:slight_smile:

(leaving combing over a list of vertexes up to end-user to design as
they
see fit / needed ?)
Otherwise, to draw just an unattached line, I’d need to make two
calls ?
The

‘regular’ one, and then a single-pixel length line / putpixel() at
the
end

(or beginning ?) to make sure the forced-missing-pixel gets filled ?
-Will


SDL mailing list
SDL at lists.libsdl.org
http://lists.libsdl.org/listinfo.cgi/sdl-libsdl.org


-Sam Lantinga, Founder and President, Galaxy Gameworks LLC


SDL mailing list
SDL at lists.libsdl.org
http://lists.libsdl.org/listinfo.cgi/sdl-libsdl.org

+1, FWIW.

The “missing endpoint” is not an optimization, but it doesn’t logically belong
in the API for drawing single lines either.

BTW, there is one case that sort of mix these two: “open chains” of lines, as
in start != end. You’d want to avoid overdraw for correctness when blending,
but you probably still want to draw the last pixel of the last line in the
chain.

As to the API, how about the OpenGL approach? GL_LINES, GL_LINE_STRIP and
GL_LINE_LOOP would handle the three cases mentioned so far.On Tuesday 08 December 2009, at 08.36.24, “Jukka-Pekka Manninen” wrote:

I’m not Bob, but all the “modern” APIs I’ve used (MIDP, .NET, …) paint
both endpoints of a line and have a separate command for drawing a line
loop (or hollow polygon).

IMO that’s the “Simple” way.


//David Olofson - Developer, Artist, Open Source Advocate

.— Games, examples, libraries, scripting, sound, music, graphics —.
| http://olofson.net http://kobodeluxe.com http://audiality.org |
| http://eel.olofson.net http://zeespace.net http://reologica.se |
’---------------------------------------------------------------------’

Unfortunately GL_LINES has the behavior I described of not rendering
the final pixel. It’s actually worse than that, it doesn’t render a
final pixel, and which one is left undefined and is implementation
dependent. :)On Tue, Dec 8, 2009 at 12:33 AM, David Olofson wrote:

On Tuesday 08 December 2009, at 08.36.24, “Jukka-Pekka Manninen” wrote:

I’m not Bob, but all the “modern” APIs I’ve used (MIDP, .NET, …) paint
both endpoints of a line and have a separate command for drawing a line
loop (or hollow polygon).

IMO that’s the “Simple” way.

+1, FWIW.

The “missing endpoint” is not an optimization, but it doesn’t logically belong
in the API for drawing single lines either.

BTW, there is one case that sort of mix these two: “open chains” of lines, as
in start != end. You’d want to avoid overdraw for correctness when blending,
but you probably still want to draw the last pixel of the last line in the
chain.

As to the API, how about the OpenGL approach? GL_LINES, GL_LINE_STRIP and
GL_LINE_LOOP would handle the three cases mentioned so far.


//David Olofson - Developer, Artist, Open Source Advocate

.— Games, examples, libraries, scripting, sound, music, graphics —.
| ?http://olofson.net ? http://kobodeluxe.com ? http://audiality.org ?|
| ?http://eel.olofson.net ?http://zeespace.net ? http://reologica.se ?|
’---------------------------------------------------------------------’


SDL mailing list
SDL at lists.libsdl.org
http://lists.libsdl.org/listinfo.cgi/sdl-libsdl.org


-Sam Lantinga, Founder and President, Galaxy Gameworks LLC

Hi,

Stumbled upon this problem a year ago. In my situation it always ignored
the last point on the right side, independent of the drawing direction
(left->right, right->left).
http://www.opengl.org/discussion_boards/ubbthreads.php?ubb=showflat&Number=250877
Very unsatisfying this behavior :\

Related topic:
What type of “end caps” for not axis-aligned lines do you prefer?

Sam Lantinga schrieb:> Unfortunately GL_LINES has the behavior I described of not rendering

the final pixel. It’s actually worse than that, it doesn’t render a
final pixel, and which one is left undefined and is implementation
dependent. :slight_smile:

On Tue, Dec 8, 2009 at 12:33 AM, David Olofson wrote:

On Tuesday 08 December 2009, at 08.36.24, “Jukka-Pekka Manninen” wrote:

I’m not Bob, but all the “modern” APIs I’ve used (MIDP, .NET, …) paint
both endpoints of a line and have a separate command for drawing a line
loop (or hollow polygon).

IMO that’s the “Simple” way.

+1, FWIW.

The “missing endpoint” is not an optimization, but it doesn’t logically belong
in the API for drawing single lines either.

BTW, there is one case that sort of mix these two: “open chains” of lines, as
in start != end. You’d want to avoid overdraw for correctness when blending,
but you probably still want to draw the last pixel of the last line in the
chain.

As to the API, how about the OpenGL approach? GL_LINES, GL_LINE_STRIP and
GL_LINE_LOOP would handle the three cases mentioned so far.

Ah… Nasty. :slight_smile:

Anyway, I was rather thinking about the general API design, and specifically
supporting the three cases; individual lines, line strips and polygons. All
three variants should render the final pixels, but line strips and polygons
should not generate overdraw, except when lines are crossed.

Now, unless we’re switching to a Begin/…/End style interface, this would
mean something like this:

SDL_RenderLines(int npoints, int *x, int *y);
SDL_RenderLineStrip(int npoints, int *x, int *y);
SDL_RenderLinePolygon(int npoints, int *x, int *y);

(An odd number for ‘npoints’ to SDL_RenderLines() would be an error.)

Of course, one could keep the current SDL_RenderLine() as a convenient
shortcut for drawing a single line, or drop SDL_RenderLines() entirely. It’s
mostly a performance hack for certain backends.On Tuesday 08 December 2009, at 10.03.38, Sam Lantinga wrote:

Unfortunately GL_LINES has the behavior I described of not rendering
the final pixel. It’s actually worse than that, it doesn’t render a
final pixel, and which one is left undefined and is implementation
dependent. :slight_smile:


//David Olofson - Developer, Artist, Open Source Advocate

.— Games, examples, libraries, scripting, sound, music, graphics —.
| http://olofson.net http://kobodeluxe.com http://audiality.org |
| http://eel.olofson.net http://zeespace.net http://reologica.se |
’---------------------------------------------------------------------’

David Olofson wrote:> On Tuesday 08 December 2009, at 10.03.38, Sam Lantinga wrote:

Unfortunately GL_LINES has the behavior I described of not rendering
the final pixel. It’s actually worse than that, it doesn’t render a
final pixel, and which one is left undefined and is implementation
dependent. :slight_smile:

Ah… Nasty. :slight_smile:

Anyway, I was rather thinking about the general API design, and specifically
supporting the three cases; individual lines, line strips and polygons. All
three variants should render the final pixels, but line strips and polygons
should not generate overdraw, except when lines are crossed.

Now, unless we’re switching to a Begin/…/End style interface, this would
mean something like this:

SDL_RenderLines(int npoints, int *x, int *y);
SDL_RenderLineStrip(int npoints, int *x, int *y);
SDL_RenderLinePolygon(int npoints, int *x, int *y);

(An odd number for ‘npoints’ to SDL_RenderLines() would be an error.)

How about just passing a parameter which tells the renderer to draw or
omit the final point?

SDL_DrawLine(SDL_Surface * dst, int x1, int y1, int x2, int y2, Uint32
color, SDL_bool draw_final_point);

David Olofson wrote:
[…]

SDL_RenderLines(int npoints, int *x, int *y);
SDL_RenderLineStrip(int npoints, int *x, int *y);
SDL_RenderLinePolygon(int npoints, int *x, int *y);

(An odd number for ‘npoints’ to SDL_RenderLines() would be an error.)

How about just passing a parameter which tells the renderer to draw or
omit the final point?

SDL_DrawLine(SDL_Surface * dst, int x1, int y1, int x2, int y2, Uint32
color, SDL_bool draw_final_point);

That would indeed solve the problem, but the point with these "npoints"
variants is that in some cases, you can avoid per-line call and setup overhead
all the way down to the hardware.

This gets increasingly important as the individual operations become more
lightweight. The extreme example would be a call that renders single pixels.
SDL 1.2 doesn’t even have one of those, as it would just be function call
overhead and no actual work.

What you do is provide an API that allows the implementation to do the "setup"
once, and then process tens, hundreds or thousands of these lightweight
operations in the inner loop.On Tuesday 08 December 2009, at 18.55.24, Gato <miston.drirr at gmail.com> wrote:


//David Olofson - Developer, Artist, Open Source Advocate

.— Games, examples, libraries, scripting, sound, music, graphics —.
| http://olofson.net http://kobodeluxe.com http://audiality.org |
| http://eel.olofson.net http://zeespace.net http://reologica.se |
’---------------------------------------------------------------------’

I agree. Each API should do the same for all platforms and all renderers.

Mike

2009/12/8 Ken Rogoway > Seems very reasonable, especially if it is documented behavior in the SDL

docs.

-----Original Message-----
From: sdl-bounces at lists.libsdl.org [mailto:sdl-bounces at lists.libsdl.org]
On
Behalf Of Sam Lantinga
Sent: Monday, December 07, 2009 8:59 PM
To: SDL; Bob Pendleton; ??? ???
Subject: [SDL] Line drawing in SDL 1.3

I recently added simple line drawing to the SDL API, and discovered
that most drawing APIs will not draw the one of the endpoints of the
line. The reason they do this is so that multiple line drawing calls
can be made to create a polygon without any overdraw.

I’m considering changing the SDL line drawing semantics to match this.
Any thoughts?

See ya!

   -Sam Lantinga, Founder and President, Galaxy Gameworks LLC

SDL mailing list
SDL at lists.libsdl.org
http://lists.libsdl.org/listinfo.cgi/sdl-libsdl.org