| Summary: | SDL_RenderDrawRect lower right corner pixel not drawn | ||
|---|---|---|---|
| Product: | SDL | Reporter: | xyzdragon |
| Component: | render | Assignee: | 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.4 | Keywords: | 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 2305 [details]
SDL_RenderDrawLines test
Created attachment 2306 [details]
SDL_RenderDrawLine test
Created attachment 2307 [details]
SDL_TTF with software renderer(left) vs. with OpenGL(right)
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.
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.
More renderer end point problems for you, Ryan. Is there any plan to fix this? (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. Can you please fix for 2.0.10? Thanks! (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. 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. 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. 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. 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. |