Jagged edges on lines when using SDL_Rect, seemingly all of a sudden.

Hello Everyone,

I recently did a “dnf upgrade” on my Linux system where I’m developing an SDL2 application. It seems after the update, jagged edges are being shown when drawing lines using SDL_Rect’s. I checked with previous versions of my application and I receive the same result so I can be certain this issue isn’t related to a code change on my end.

My first guess is that this may be related to an update in SDL2?

Also note that I don’t see this problem in Windows which has an older version of SDL2 as I have to update the Libs in Windows manually. The Libs in Linux where I am seeing the problem are updated as I update the system.

Has anyone seen an issue like this before? Do you know where I can start to look to resolve this issue? I’m a little bit at a loss as to where to begin because it seems that this issue is not related to a particular code change that I have made.

jagged_edges

I am drawing the rectangle like this.

void ley::SimpleShape::drawRect(const SDL_Rect* r) {
SDL_RenderDrawRect(renderer,r);
}

And this is where I create the rectangles:

START_X_OFFSET_PX = 490;

firstSimpleShape.addShape(“nextboundry”,{ley::START_X_OFFSET_PX - 145,39,130,130});
firstSimpleShape.addShape(“testboundry”, {10,10,20,20});

Thanks,
electrosys

What version of SDL are you using? There has been an ongoing struggle to fix SDL_RenderDrawLine() so that it works as documented (i.e. drawing the line inclusive of both end-points) on all platforms with all renderers. This has proved difficult and there have been some regressions which might perhaps have affected SDL_RenderDrawRect().

It might be worth trying SDL_RenderDrawRectF() (which takes floating-point coordinates), in case that works better.

1 Like

On Windows I am using SDL version 2.0.12 and on Linux I am using SDL version 2.0.16.

I have tried the following, and I get the exact same result. SDL_RenderDrawRectF() seems to produce the same result as SDL_RenderDrawRect().

void ley::SimpleShape::drawRect(const SDL_Rect* r) {

SDL_FRect* fRect;

fRect->x = r->x;
fRect->y = r->y;
fRect->w = r->w;
fRect->h = r->h;

SDL_RenderDrawRectF(renderer,fRect);

}

1 Like

Hmm it seems now being a FAQ… DrawRect/Line is broken on some backend.

I had hoped it would be fixed in 2.0.16, but seemingly not. I like the comment at one of the linked bug reports that this is Ryan’s “favourite thing to fix”! I just don’t want it to be his epitaph…

I was able to downgrade this library in Fedora using dnf with the following command:

sudo dnf downgrade sdl2-devel

This seems like a perfectly viable workaround for now.

Thanks for all the insights.

It’s definitely going to be my epitaph.

2 Likes

Heads up, @icculus did a commit recently on SDL that appears to fix this

1 Like

Looking forward to seeing that fix in the next update of SDL2.

2 Likes

2.0.18 is out now with this fix, go update!!

1 Like

Unless I’m going mad (entirely possible) my tests suggest that this has got worse, not better, when running with OpenGL in Windows 10. SDL 2.0.18 seems not to be plotting the end point of a horizontal line at all, in that environment. So for example:

SDL_RenderDrawLine(renderer, 200, 300, 300, 300);

isn’t drawing the point 300,300 at all as far as I can see. Please don’t tell me this “fix” wasn’t tested with OpenGL in Windows…

You understand that the actual line drawing is up to the underlying OpenGL implementation and GPU, right? Which means it can vary between GPU vendors and even driver versions. SDL can only do so much to try to coerce them into pixel perfection.

I don’t accept that at all. SDL_RenderDrawLine() is explicitly documented as drawing the line to include both end points. If one is using it as a building block for drawing more complex objects, such as filled polygons (as does, for example, SDL2_gfx) it is essential that the exact pixels that will be plotted are predictable, at least in the case of horizontal and vertical lines.

If that could not be relied upon, to plot pixel-accurate (or anti-aliased) graphics one would have to fall back on using SDL_RenderDrawPoint() or SDL_RenderDrawPoints() instead, functions that are potentially much slower. Such a step is a counsel of despair, and it would mean SDL2_gfx being rewritten.

It clearly has been difficult to make SDL_RenderDrawLine() work in a reliable and consistent way across platforms, but that is precisely the job of SDL2 in providing an abstraction layer which hides such variability. If you look at the discussion at GitHub you will see that two proposals have been made which might solve this problem: drawing the line using triangles, and drawing it as a two-segment polyline.

2 Likes