We are currently migrating Bugzilla to GitHub issues.
Any changes made to the bug tracker now will be lost, so please do not post new bugs or make changes to them.
When we're done, all bug URLs will redirect to their equivalent location on the new bug tracker.

Bug 3182

Summary: SDL_RenderDrawRect lower right corner pixel not drawn
Product: SDL Reporter: xyzdragon
Component: renderAssignee: Ryan C. Gordon <icculus>
Status: RESOLVED DUPLICATE QA Contact: Sam Lantinga <slouken>
Severity: major    
Priority: P2 CC: berendeanicolae, dogan.kurt, johanneskarl.dev, rtrussell, xyzdragon
Version: 2.0.4Keywords: target-2.0.12
Hardware: x86_64   
OS: Linux   
Attachments: upsized screenshot of bug
SDL_RenderDrawLines test
SDL_RenderDrawLine test
SDL_TTF with software renderer(left) vs. with OpenGL(right)
iymax=100,120,128,200

Description xyzdragon 2015-11-16 23:29:34 UTC
Created attachment 2304 [details]
upsized screenshot of bug

When trying to draw a simple rectangle the lower right corner is missing. Normally you maybe wouldn't see it if your aren't looking exactly, but in my case I called SDL_RenderDrawRect several times in order to achieve a thicker rectangle outline. The result of that can be seen in the attachment (the image is resized 4 times for better viewability).

I think this bug is closely related to https://bugzilla.libsdl.org/show_bug.cgi?id=3175 but he only mentions pixels drawn twice and no pixels missing (not sure how he detected that).
My guess is, that the left outline drawn accidentally wasn't shifted by 1 downwards and the bottom line also wasn't shifted 1 to the right. Furthermore the length of the left side seems to be 1 pixel too long, because else only the upper left pixel would have been redrawn twice.
Comment 1 xyzdragon 2015-11-17 16:28:23 UTC
Created attachment 2305 [details]
SDL_RenderDrawLines test
Comment 2 xyzdragon 2015-11-17 16:29:21 UTC
Created attachment 2306 [details]
SDL_RenderDrawLine test
Comment 3 xyzdragon 2015-11-17 16:34:33 UTC
Created attachment 2307 [details]
SDL_TTF with software renderer(left) vs. with OpenGL(right)
Comment 4 xyzdragon 2015-11-17 16:35:49 UTC
Actually this is a bug with SDL_RenderDrawLines. E.g. following code:

    SDL_Point points[3];
    const int x = 20, y = 20;

    /*      |     *
     *    --+     */
    points[0].x = x;
    points[0].y = y;
    points[1].x = points[0].x+10; // right
    points[1].y = points[0].y;
    points[2].x = points[1].x;
    points[2].y = points[1].y-10; // up
    SDL_RenderDrawLines( rpRenderer, points, 3);

    /*    --+     *
     *      |     */
    points[0].x = x;
    points[0].y = y+4;
    points[1].x = points[0].x+10; // right
    points[1].y = points[0].y;
    points[2].x = points[1].x;
    points[2].y = points[1].y+10; // down
    SDL_RenderDrawLines( rpRenderer, points, 3);

    /*    |       *
     *    +--     */
    points[0].x = x+24;
    points[0].y = y;
    points[1].x = points[0].x-10; // left
    points[1].y = points[0].y;
    points[2].x = points[1].x;
    points[2].y = points[1].y-10; // up
    SDL_RenderDrawLines( rpRenderer, points, 3);

    /*    +--     *
     *    |       */
    points[0].x = x+24;
    points[0].y = y+4;
    points[1].x = points[0].x-10; // left
    points[1].y = points[0].y;
    points[2].x = points[1].x;
    points[2].y = points[1].y+10; // down
    SDL_RenderDrawLines( rpRenderer, points, 3);

produces SDL_RenderDrawLines-bug.png . I found this because I looked in the source code for SDL_RenderDrawRect and it looked correct. SDL_RenderDrawLine also calls SDL_RenderDrawLines, but SDL_RenderDrawLine seems to be not affected by that bug, see cross.png created with the following code:

    int x = 10;
    int y = 10;

    points[0].x = x+2;
    points[0].y = y;
    points[1].x = points[0].x+4; // right
    points[1].y = points[0].y;
    SDL_RenderDrawLines( rpRenderer, points, 2);

    points[0].x = x-2;
    points[0].y = y;
    points[1].x = points[0].x-4; // left
    points[1].y = points[0].y;
    SDL_RenderDrawLines( rpRenderer, points, 2);

    points[0].x = x;
    points[0].y = y+2;
    points[1].x = points[0].x;
    points[1].y = points[0].y+4; // down
    SDL_RenderDrawLines( rpRenderer, points, 2);

    points[0].x = x;
    points[0].y = y-2;
    points[1].x = points[0].x;
    points[1].y = points[0].y-4; // up
    SDL_RenderDrawLines( rpRenderer, points, 2);

SDL_RenderDrawLines is basically only a wrapper for SDL_Renderer::RenderDrawLines(renderer, fpoints, count) which is defined in SDL_sysrender.h

BTW: The source code really needs some in-code comments. Also new to me:
    int (*GetOutputSize) (SDL_Renderer * renderer, int *w, int *h);
http://stackoverflow.com/questions/6693970/ very interesting way to simulate classes :)

But where are the function pointers set? ... I guess in one of the backends, but who knows. This gives me incentive to test on which renderers the bug appears:

    const int numdrivers = SDL_GetNumRenderDrivers();
    std::cout << "Render driver count: " << numdrivers << "\n";
    for (int i=0; i<numdrivers; i++)
    {
        SDL_RendererInfo drinfo;
        SDL_GetRenderDriverInfo (i, &drinfo);
        std::cout << "Driver name ("<<i<<"): " << drinfo.name << " flags: ";
        if (drinfo.flags & SDL_RENDERER_SOFTWARE)      printf("Software ");
        if (drinfo.flags & SDL_RENDERER_ACCELERATED)   printf("Accelerated ");
        if (drinfo.flags & SDL_RENDERER_PRESENTVSYNC)  printf("VSync ");
        if (drinfo.flags & SDL_RENDERER_TARGETTEXTURE) printf("Textures ");
        printf("\n");
    }

returns the following renderers:

    Render driver count: 3
    Driver name (0): opengl flags: Accellerated VSync Textures
    Driver name (1): opengles2 flags: Accelerated VSync Textures
    Driver name (2): software flags: Software Textures

Now I try to set different renderers directly with:

    SDL_CreateRenderer( pWindow, [012], 0 );

The bug only appears for renderer 0 and 1, not for 2, but 2 fucks up SDL_TTF, see ttf.png (note that TTF isn't completely broken, it still display something, it seems, like blend mode and/or alpha is just not supported by the software renderer, should I open a new bug about this ?)

Sooo, I guess the culprits are SDL_render_gl.c and SDL_render_gles.c with GL_RenderDrawLines and GLES_RenderDrawLines .
Actually these functions differ between 2 and more than 2 points and for only 1 line i.e. 2 points there are interesting comments:
    /* GL_LINE_LOOP takes care of the final segment */
    /* Mac OS X and Windows seem to always leave the last point open */
    /* Linux seems to leave the right-most or bottom-most point open */
This also may be the reason, why there are no errors with SDL_DrawLine, because only for more than 2 points these exceptions described in the comments are not applied.

Well I don't know how to proceed from here. But maybe this helps to persuade someone with the abilities to solve the problem.
Comment 5 xyzdragon 2015-11-18 01:47:47 UTC
Created attachment 2308 [details]
iymax=100,120,128,200

Using Windows 7 and Cygwin with XWin the problem is even less predictable. Depending on the position and width and height where to draw the rectangle the upper right or the lower right corner pixels may be missing, see iymax100,120,128,200.png In that picture I started filling an area by drawing rectangles beginning from 1x1, then 3x3, and so on:

    int iymax = 128;
    for (int iy = 0; iy <= iymax; iy++ )
    {
        SDL_Rect rect = { iymax-iy,iymax-iy,1+2*iy,1+2*iy };
        SDL_RenderDrawRect( pRenderer, &rect );
    }

So is this a problem with OpenGL? Should I report this with OpenGL instead?
Because of this system dependent randomness, my best guess would be to just draw the pixels of every corner after drawing the rectangle, just to be save. Better save than performant.
Comment 6 Sam Lantinga 2017-08-12 22:49:10 UTC
More renderer end point problems for you, Ryan.
Comment 7 Dogan Kurt 2018-10-21 21:07:35 UTC
Is there any plan to fix this?
Comment 8 Ryan C. Gordon 2018-10-23 07:29:36 UTC
(In reply to Dogan Kurt from comment #7)
> Is there any plan to fix this?

I'll look into this, but I think this will miss 2.0.9.

--ryan.
Comment 9 Sam Lantinga 2018-11-02 23:47:44 UTC
Can you please fix for 2.0.10?

Thanks!
Comment 10 Ryan C. Gordon 2019-07-30 17:49:37 UTC
(Sorry if you get several emails like this, we're marking a bunch of bugs.)

We're hoping to ship SDL 2.0.11 on a much shorter timeframe than we have historically done releases, so I'm starting to tag bugs we hope to have closed in this release cycle.

Note that this tag means we just intend to scrutinize this bug for the 2.0.11 release: we may fix it, reject it, or even push it back to a later release for now, but this helps give us both a goal and a wishlist for the next release.

If this bug has been quiet for a few months and you have new information (such as, "this is definitely still broken" or "this got fixed at some point"), please feel free to retest and/or add more notes to the bug.

--ryan.
Comment 11 Ryan C. Gordon 2019-09-20 20:47:38 UTC
We're changing how we do SDL release versions; now releases will be even numbers (2.0.10, 2.0.12, etc), and as soon as we tag a release, we'll move the internal version number to an odd number (2.0.12 ships, we tag the latest in revision control as 2.0.13 immediately, which will become 2.0.14 on release, etc).

As such, I'm moving the bugs tagged with target-2.0.11 to target 2.0.12. Sorry if you get a lot of email from this change!

Thanks,
--ryan.
Comment 12 Ryan C. Gordon 2019-09-20 20:48:38 UTC
We're changing how we do SDL release versions; now releases will be even numbers (2.0.10, 2.0.12, etc), and as soon as we tag a release, we'll move the internal version number to an odd number (2.0.12 ships, we tag the latest in revision control as 2.0.13 immediately, which will become 2.0.14 on release, etc).

As such, I'm moving the bugs tagged with target-2.0.11 to target 2.0.12. Sorry if you get a lot of email from this change!

Thanks,
--ryan.
Comment 13 Nicolae Berendea 2020-01-23 22:13:02 UTC
Hello!
This bug is linked with https://bugzilla.libsdl.org/show_bug.cgi?id=2711
From what I've observed on all of my machines (1 win7x64 & 1 win10x64), SDL_RenderDrawLine draws the last point twice (I detected this by using a color with alpha channel and the last point had a different color).
On a virtual machine (win7x64) the line was drawn correctly. Please let me know if I can help with any info.
Comment 14 Ryan C. Gordon 2020-02-10 18:04:27 UTC
This is fixed in https://hg.libsdl.org/SDL/rev/0c915d307499 ... I couldn't test the GLES1 renderer here, but the GL and GLES2 are both confirmed working with this patch, and the GLES1 renderer's code is largely identical to the GLES2 code in this regard.

--ryan.
Comment 15 Ryan C. Gordon 2020-02-12 20:15:28 UTC

Going to mark several bugs as "duplicates" of Bug #2711, since they're all "render API lines are off by a pixel in one way or another," so we're all looking at the same thing. We'll discuss further over there!

--ryan.

*** This bug has been marked as a duplicate of bug 2711 ***