| Summary: | SDL_RenderCopyEx off by one when rotating by 90 and -90. | ||
|---|---|---|---|
| Product: | SDL | Reporter: | chasesan |
| Component: | render | Assignee: | Sam Lantinga <slouken> |
| Status: | RESOLVED FIXED | QA Contact: | Sam Lantinga <slouken> |
| Severity: | normal | ||
| Priority: | P2 | CC: | jizc, ngolbaz, sylvain.becker, trygve.vea |
| Version: | HG 2.1 | ||
| Hardware: | x86_64 | ||
| OS: | Windows 7 | ||
| Attachments: |
Test case, cycle through renderers with n
Image used by test case patch to solve this issue in for renderer opengles D3D patch Updated patch for direct3d renderers test case for rotations screenshot with software renderer |
||
|
Description
chasesan
2014-02-26 17:08:22 UTC
Can you attach a minimal example with images, and describe which platforms work and which don't? Thanks! Created attachment 1698 [details]
Test case, cycle through renderers with n
Requires sdl-bug-2421.bmp to run
Created attachment 1699 [details]
Image used by test case
I'm not the original poster for this bug, but I've run into it myself. I work around the bug by forcing the OpenGL renderer. I've run some tests. As far as I can tell, OpenGL is the only renderer that work as expected. The tests I've made can be viewed here: https://www.dropbox.com/sh/n44e2jvg7dydd3m/AAA5inPLrWLZ36ncjX_C5fz9a Used test case attached. I tried your test case, and it's nice to switch renderer so easily.
On my linux, this is working for : software, opengl, opengles2.
opengles1 is not working, because the rendered failed and I see garbage. To double check the test case, I would just recommend to check to the Window/Render creation :
27 w = SDL_CreateWindow(i.name, 32, 32, 320, 240, 0);
28 if (w == NULL)
29 {
30 printf("Failed to create windows: %s\n", SDL_GetError());
31 }
32 r = SDL_CreateRenderer(w, cur_renderer, SDL_RENDERER_ACCELERATED|SDL_RENDERER_PRESENTVSYNC);
33 if (r == NULL)
34 {
35 printf("Failed to create render: %s\n", SDL_GetError());
36 }
(In reply to Sylvain from comment #5) > I tried your test case, and it's nice to switch renderer so easily. > On my linux, this is working for : software, opengl, opengles2. From what I read, you got a different result than me when using the software renderer in Linux. That's very odd. When I tested SDL 2.0.3, I got this result: https://www.dropbox.com/sh/n44e2jvg7dydd3m/AAB_uJDLmNn08Aj3FGTTPVqUa/linux-software.png And, you are not supposed to see the red squares if the white square is rendered in the correct position. Can you verify what your result was? > opengles1 is not working, because the rendered failed and I see garbage. To > double check the test case, I would just recommend to check to the > Window/Render creation : > > 27 w = SDL_CreateWindow(i.name, 32, 32, 320, 240, 0); > 28 if (w == NULL) > 29 { > 30 printf("Failed to create windows: %s\n", SDL_GetError()); > 31 } > 32 r = SDL_CreateRenderer(w, cur_renderer, > SDL_RENDERER_ACCELERATED|SDL_RENDERER_PRESENTVSYNC); > 33 if (r == NULL) > 34 { > 35 printf("Failed to create render: %s\n", SDL_GetError()); > 36 } That makes sense. If SDL_CreateRenderer fails, it may be a new bug. Have you posted information about that somewhere? Trygve, I am not using 2.0.3 but the SDL trunk directly. For the renderers software / opengl and opengles2, it is fine : I see the white squares rotated (I changed a little bit the image so I see the rotation!), and no "red" frame, which means the rotation is correctly positioned. So it's working correctly for me on linux. For, opengles, I got an error : "Failed to create render: Could not create GL context GLXBadProfileARB" That happens in X11_GL_CreateContext. It seems to create a 3.0 context? That's fore sure a different issue. (I will report it) Trying with older version, it seems it was broken (red square). But latest trunk, it seems fine. Trygve, give a try with the latest trunk. Gabriel solved my "opengles" creation problem. So I can give the result : I see the red-square for the "opengles" renderer, which means the problem is there for this renderer. Created attachment 1719 [details]
patch to solve this issue in for renderer opengles
It appears the RenderCopyEx is done as expected,
this is the red rectangle which is not correctly positionned !
So, here's patch with a 0.5 float increment, like for opengles2, for DrawLines, and also Draw Points.
Maybe same patch to apply to Direct3D renderers. Sylvain, I applied your patch, thanks! https://hg.libsdl.org/SDL/rev/bc47cf4c679d Direct3D doesn't have this issue, due to coordinate definition differences. Please reopen this bug if it's still active for any other renderer. (In reply to Sam Lantinga from comment #12) > Sylvain, I applied your patch, thanks! > https://hg.libsdl.org/SDL/rev/bc47cf4c679d > > Direct3D doesn't have this issue, due to coordinate definition differences. > > Please reopen this bug if it's still active for any other renderer. I'm quite sure that this bug is still valid, also for Direct3D. Have you checked the attached test case? I just ran it against a newly built SDL2.dll, and it returns the same results as it did with the screenshots I link to earlier in this report. I should probably write a proper test for this, it's a very subtle thing - but not as subtle if you render to a texture with low resolution. I see this also fails for the software renderer. I'll investigate when I have time. Thanks! Created attachment 1782 [details]
D3D patch
(In reply to Nader Golbaz from comment #15) > Created attachment 1782 [details] > D3D patch I just tested the patch, and can confirm that it works for direct3d. I can not confirm that it works for direct3d11. I applied the patch to current trunk; while testing, I also noticed that this looks like less of a problem on the software renderer now - only the top right box is rendered at the wrong position. Patch for d3d11 is not correct. apparently there is another bug in D3D11_RenderDrawLines. Created attachment 1800 [details]
Updated patch for direct3d renderers
Created attachment 2545 [details]
test case for rotations
Here's a test-case to see an offset of 1, when rotating with software renderer.
It fails for the "software" renderer: offset on x/y of +2, and also the texture seems sometime truncated.
But it works for opengl, opengles and opengles2 renderers.
Created attachment 2546 [details]
screenshot with software renderer
Here's a screenshot:
1st: initial texture.
2nd: 90deg : shifted +1 on x axis. truncated last column.
3rd: 180deg: shifted +2 on x axis, shifted +2 on y axis.
4th: 270deg: shifted +2 on x axis.
The software rendering part is fixed by this commit: https://hg.libsdl.org/SDL/rev/1e1ce9f6d215 Verified test case with direct3d, direct3d11, opengl, opengles2, and software renderers. Thanks! In the case of D3D11, we need drawing last point separately.
--- SDL_render_d3d11.c
+++ SDL_render_d3d11.c
@@ -2576,7 +2576,12 @@
NULL);
D3D11_RenderFinishDrawOp(renderer, D3D11_PRIMITIVE_TOPOLOGY_LINESTRIP, count);
- D3D11_RenderFinishDrawOp(renderer, D3D11_PRIMITIVE_TOPOLOGY_POINTLIST, count);
+
+ if (points[0].x != points[count - 1].x || points[0].y != points[count - 1].y) {
+ ID3D11DeviceContext_IASetPrimitiveTopology(rendererData->d3dContext, D3D11_PRIMITIVE_TOPOLOGY_POINTLIST);
+ ID3D11DeviceContext_Draw(rendererData->d3dContext, 1, count - 1);
+ }
+
SDL_stack_free(vertices);
return 0;
}
Got it, thanks! https://hg.libsdl.org/SDL/rev/f781e05bcfb5 |