SDL 1.3 low resolution stretched texture displacement when using dst rect overflowing window (w/patch)

There’s seems to be a problem inside SDL 1.3 RenderCopy function, which by default clips source (texture) together with destination (window relative) rect, when destination rect is out of window bounds. I hit this problem when I am using stretched LOW resolution texture together with destination rect which overflows window rect (has negative coords for example).
RenderCopy is using both integers for destination and source (texture) coords. While it is OK using ints for destination coords, it isn’t for texture. Here goes the sample:

[1] Imagine I want to stretch 2x2 (two by two pixels) texture like that: (See ASCII art below ;P, You need to have fixed size font :>)±--------------------------------+
| |
±—|---±--------+ |
| : | | |<----- window
| : | 1 pixel |<— texture |
| : | | |
±—|---±--------+ |
| : | | |
| : | | |
| : | | |
±—|---±--------+ |
| |
±--------------------------------+

[2] Unfortunately RenderCopy will try to clip both destination and source (texture) rects to make destination rect not to overflow window. Both clippings (including texture coords) will be done using integers not floats so we will get following VERY INACCURATE output:

 +---------------------------------+
 |                                 |
 +---------+                       |
 |         |                       |<----- window
 | 1 pixel |<--- texture           |
 |         |                       |
 +---------+                       |
 |         |                       |
 |         |                       |
 |         |                       |
 +---------+                       |
 |                                 |
 +---------------------------------+

[3] Instead of this, if we have used floats (accurate source rect clipping).

 +---------------------------------+
 |                                 |
 |---+---------+                   |
 :   |         |                   |<----- window
 :   | 1 pixel |<--- texture       |
 :   |         |                   |
 |---+---------+                   |
 :   |         |                   |
 :   |         |                   |
 :   |         |                   |
 |---+---------+                   |
 |                                 |
 +---------------------------------+

Attaching some patch that adds SetTextureClipMode and GetTextureClipMode functions that controls (turns on/off src/dst clipping). By default it uses default behavior that clips. But we can turn off selectively src or dst clipping using SetTextureClipMode.

While having negative or overflowing destination coordinates (or texture source coords) is absolutely legal in OpenGL (D3D too I believe), I have absolutely no idea if it is legal in software renderer or others such as DirectFB or Windows GDI. So I have no idea if this simple fix is enough.
Anyway this patch does good job for me. And doesn’t break anything by default.

Alternatively (to my patch) internal renderer->RenderCopy implementation could take floats or doubles for texture (source coord) instead of ints, this would solve inaccuracy, keeping clipping as it was before. See image [3]

Waiting for your comments,

Adam Strzelecki | nanoant.com

-------------- next part --------------
A non-text attachment was scrubbed…
Name: SDL-SVN-SetTextureClipMode.patch
Type: application/octet-stream
Size: 4793 bytes
Desc: not available
URL: http://lists.libsdl.org/pipermail/sdl-libsdl.org/attachments/20091110/badd2bf2/attachment.obj

This is a great bug report and a well written patch. I’m not sure it
will work for the software renderer though. Can you check that out?

You can set the software renderer by setting the environment variable
SDL_VIDEO_RENDERER to “software”

See ya!On Tue, Nov 10, 2009 at 8:45 AM, Adam Strzelecki wrote:

There’s seems to be a problem inside SDL 1.3 RenderCopy function, which by default clips source (texture) together with destination (window relative) rect, when destination rect is out of window bounds. I hit this problem when I am using stretched LOW resolution texture together with destination rect which overflows window rect (has negative coords for example).
RenderCopy is using both integers for destination and source (texture) coords. While it is OK using ints for destination coords, it isn’t for texture. Here goes the sample:

[1] Imagine I want to stretch 2x2 (two by two pixels) texture like that: (See ASCII art below ;P, You need to have fixed size font :>)
? ? ±--------------------------------+
? ? | ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? |
±—|---±--------+ ? ? ? ? ? ? ? ? ? |
| ? ?: ? | ? ? ? ? | ? ? ? ? ? ? ? ? ? |<----- window
| ? ?: ? | 1 pixel |<— texture ? ? ? |
| ? ?: ? | ? ? ? ? | ? ? ? ? ? ? ? ? ? |
±—|---±--------+ ? ? ? ? ? ? ? ? ? |
| ? ?: ? | ? ? ? ? | ? ? ? ? ? ? ? ? ? |
| ? ?: ? | ? ? ? ? | ? ? ? ? ? ? ? ? ? |
| ? ?: ? | ? ? ? ? | ? ? ? ? ? ? ? ? ? |
±—|---±--------+ ? ? ? ? ? ? ? ? ? |
? ? | ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? |
? ? ±--------------------------------+

[2] Unfortunately RenderCopy will try to clip both destination and source (texture) rects to make destination rect not to overflow window. Both clippings (including texture coords) will be done using integers not floats so we will get following VERY INACCURATE output:

? ? ±--------------------------------+
? ? | ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? |
? ? ±--------+ ? ? ? ? ? ? ? ? ? ? ? |
? ? | ? ? ? ? | ? ? ? ? ? ? ? ? ? ? ? |<----- window
? ? | 1 pixel |<— texture ? ? ? ? ? |
? ? | ? ? ? ? | ? ? ? ? ? ? ? ? ? ? ? |
? ? ±--------+ ? ? ? ? ? ? ? ? ? ? ? |
? ? | ? ? ? ? | ? ? ? ? ? ? ? ? ? ? ? |
? ? | ? ? ? ? | ? ? ? ? ? ? ? ? ? ? ? |
? ? | ? ? ? ? | ? ? ? ? ? ? ? ? ? ? ? |
? ? ±--------+ ? ? ? ? ? ? ? ? ? ? ? |
? ? | ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? |
? ? ±--------------------------------+

[3] Instead of this, if we have used floats (accurate source rect clipping).

? ? ±--------------------------------+
? ? | ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? |
? ? |—±--------+ ? ? ? ? ? ? ? ? ? |
? ? : ? | ? ? ? ? | ? ? ? ? ? ? ? ? ? |<----- window
? ? : ? | 1 pixel |<— texture ? ? ? |
? ? : ? | ? ? ? ? | ? ? ? ? ? ? ? ? ? |
? ? |—±--------+ ? ? ? ? ? ? ? ? ? |
? ? : ? | ? ? ? ? | ? ? ? ? ? ? ? ? ? |
? ? : ? | ? ? ? ? | ? ? ? ? ? ? ? ? ? |
? ? : ? | ? ? ? ? | ? ? ? ? ? ? ? ? ? |
? ? |—±--------+ ? ? ? ? ? ? ? ? ? |
? ? | ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? |
? ? ±--------------------------------+

Attaching some patch that adds SetTextureClipMode and GetTextureClipMode functions that controls (turns on/off src/dst clipping). By default it uses default behavior that clips. But we can turn off selectively src or dst clipping using SetTextureClipMode.

While having negative or overflowing destination coordinates (or texture source coords) is absolutely legal in OpenGL (D3D too I believe), I have absolutely no idea if it is legal in software renderer or others such as DirectFB or Windows GDI. So I have no idea if this simple fix is enough.
Anyway this patch does good job for me. And doesn’t break anything by default.

Alternatively (to my patch) internal renderer->RenderCopy implementation could take floats or doubles for texture (source coord) instead of ints, this would solve inaccuracy, keeping clipping as it was before. See image [3]

Waiting for your comments,

Adam Strzelecki | nanoant.com


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

This is a great bug report and a well written patch. I’m not sure it
will work for the software renderer though. Can you check that out?

No it doesn’t work well with SW renderer.

Okay maybe we can drop the idea of SDL_SetTextureClipMode, since it is pretty obscure, and move clipping itself just to renderers’ RenderCopy method that need the clipping, those would be all non-accelerated renderers such as SW, Windows GDI, all HW-accelerated renderers such as OpenGL and D3D won’t suffer any performance drops if we don’t do clipping, but we gonna fix displacement there.

So SDL_RenderCopy won’t clip anything, but only fill rects with right values when they are NULL and SW renderers should be responsible for doing clipping.

What do you think?

Regards,–
Adam Strzelecki | nanoant.com

That sounds reasonable. Do you have a patch that implements that?On Wed, Nov 25, 2009 at 7:48 AM, Adam Strzelecki wrote:

This is a great bug report and a well written patch. ?I’m not sure it
will work for the software renderer though. ?Can you check that out?

No it doesn’t work well with SW renderer.

Okay maybe we can drop the idea of SDL_SetTextureClipMode, since it is pretty obscure, and move clipping itself just to renderers’ RenderCopy method that need the clipping, those would be all non-accelerated renderers such as SW, Windows GDI, all HW-accelerated renderers such as OpenGL and D3D won’t suffer any performance drops if we don’t do clipping, but we gonna fix displacement there.

So SDL_RenderCopy won’t clip anything, but only fill rects with right values when they are NULL and SW renderers should be responsible for doing clipping.

What do you think?

Regards,

Adam Strzelecki | nanoant.com


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

That sounds reasonable. Do you have a patch that implements that?

Here it is… I’ve added SDL_RENDERER_BLITCLIP renderer flag that tells that Renderer does the clipping into window itself (himself?). This flag is set for OpenGL, OpenGLES, D3D, WinGDI. This should guarantee precise texture mapping for overflowing dstrect or those renderers, on others we get what was before.

SDL_RenderCopy checks for this flag and clips the dstrect when renderer does not have this flag. So this patch is pretty minimal.

Probably this problem should be noted in SDL_RenderCopy documentation so everybody knows that OpenGL, OpenGLES, D3D, WinGDI (those with SDL_RENDERER_BLITCLIP) will only map textures precisely on overflowing dstrect, and others will suffer shifts (as described in first mail).

Regards,–
Adam Strzelecki
-------------- next part --------------
A non-text attachment was scrubbed…
Name: SDL-SVN-RenderCopy-clip-srcrect-for-renderers-that-do-not-clip-themselves.patch
Type: application/octet-stream
Size: 7158 bytes
Desc: not available
URL: http://lists.libsdl.org/pipermail/sdl-libsdl.org/attachments/20091126/2cdc72e2/attachment.obj

Hmm, what I’d really like is a solution that fixes the software
renderer to do the right thing and eliminate clipping entirely from
SDL_RenderCopy(). I took a quick poke at it, but it seems extremely
non-trivial.On Thu, Nov 26, 2009 at 5:18 AM, Adam Strzelecki wrote:

That sounds reasonable. ?Do you have a patch that implements that?

Here it is… I’ve added SDL_RENDERER_BLITCLIP renderer flag that tells that Renderer does the clipping into window itself (himself?). This flag is set for OpenGL, OpenGLES, D3D, WinGDI. This should guarantee precise texture mapping for overflowing dstrect or those renderers, on others we get what was before.

SDL_RenderCopy checks for this flag and clips the dstrect when renderer does not have this flag. So this patch is pretty minimal.

Probably this problem should be noted in SDL_RenderCopy documentation so everybody knows that OpenGL, OpenGLES, D3D, WinGDI (those with SDL_RENDERER_BLITCLIP) will only map textures precisely on overflowing dstrect, and others will suffer shifts (as described in first mail).

Regards,

Adam Strzelecki


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

Hmm, what I’d really like is a solution that fixes the software
renderer to do the right thing and eliminate clipping entirely from
SDL_RenderCopy(). I took a quick poke at it, but it seems extremely
non-trivial.

Any chances to revisit removing entirely clipping from SDL_RenderCopy /or just moving this clipping check to sw renderer only?
It does still produce bad displacement when textures are overflowing view box, and it doesn’t really makes sense to waste CPU cycles that is anyway optimized by HW.

Cheers,–
Adam Strzelecki

P.S. Sorry for sending so many mails on the list, but I just started moving our project to latest HG version :slight_smile: