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 2700

Summary: SDL_RenderSetClipRect bug with openGL and a Texture as render target
Product: SDL Reporter: E. van Putten <edwinvp>
Component: renderAssignee: Sam Lantinga <slouken>
Status: RESOLVED FIXED QA Contact: Sam Lantinga <slouken>
Severity: normal    
Priority: P2 CC: alvinbeach, chinbillybilbo, diegoacevedo91, icculus, kometbomb, libsdl, martin.gerhardy, mna.bakker, rtrussell
Version: 2.0.1Keywords: target-2.0.4
Hardware: x86_64   
OS: Windows 7   
Attachments: Small program to reproduce bug on Raspberry Pi (and possible other systems)
Texture clipping test
Fixes clipping origin (may have side-effect with a viewport)
openGL renderer + texture as target + SDL_RenderSetClipRect
openGL renderer + texture as target + SDL_RenderSetClipRect
additional patch
test renderers with SDL_ClipRectangle

Description E. van Putten 2014-08-23 20:55:33 UTC
Noticed that SDL_RenderSetClipRect flips the Y-coordinates on some platforms.

Background: I'm using the clipping to implement some GUI 'windows' in my app. Found that SDL_RenderSetClipRect does not always clip where you'd expect it.

Further complications: I'm using a texture as render target. So I clip while rendering the off-screen texture. Then finally copy the entire texture to the screen (or output window).

Disclaimer: so it might be that SDL_RenderSetClipRect works completely fine when clipping the final screen (or output window) target. But I didn't try that.

Steps to reproduce:
- Create a texture that's also a render target
- Performing clipping with SDL_RenderSetClipRect 
- Draw some things using SDL_RenderCopy
- Copy the entire texture to the screen
- Observe correct or incorrect result (*)

* Try this on different machines!

Workaround:

You'd expect this code:
SDL_RenderSetClipRect(hRenderer,&MyWinRect);

But some platforms need this 'adjustment':

SDL_Rect rClip = MyWinRect;
if (ClipRectRpiFix) {
	rClip.y = ScreenHeight - rClip.y - rClip.h;
}
SDL_RenderSetClipRect(hRenderer,&rClip);

But I don't know when to apply it...
Nor which one I'd normally need.

I also don't know if it's expected to simply pass the unmodified 2D coordinates to SetClipRect as you would with other functions like FillRect and RenderCopy.

So far I've tried with 3 computers:

Raspberry Pi: 
YES (workaround needed)

Windows 7/x64 PC (with simple nVidia 9500 GT card): 
NO

Somebody elses laptop (Acer, but forgot to write down the specs): 
YES

Sorry for the lack of further information.
For me the workaround fixes things meanwhile, but I'm sure others must have been seeing this as well...
Comment 1 E. van Putten 2014-08-23 20:59:38 UTC
BTW: It might very well be that the bug is not in SDL at all.
But in underlying video card drivers.
Comment 2 Sam Lantinga 2014-08-24 07:05:18 UTC
The clip rect is intended to use top-left origin like all the other API calls. Can you attach a simple example and which renderers and operating systems are having the problem?

Thanks!
Comment 3 E. van Putten 2014-08-24 14:11:29 UTC
Created attachment 1847 [details]
Small program to reproduce bug on Raspberry Pi (and possible other systems)

This small program demonstrates the bug.

1)
Fills a texture using the red color, then clips a rectangle (top/left quadrant of the screen) and fills the clipped interior using a yellow color.
Then the texture is copied to the screen and the program waits for a few seconds.

2)
Same. But now without the texture (rendering directly to the screen).

In both cases you'd expect a yellow rectangle in the top/left area of the screen.
On the systems affected by the bug, you will see the first rectangle appearing at the bottom/left corner instead (incorrect),
followed by one appearing at the top/left corner (correct).
Comment 4 Tero Lindeman 2015-01-05 09:22:18 UTC
This is happening on a Linux/OpenGL setup when rendering to a texture. Might have something to do with the OpenGL coordinate system which indeed has (0,0) on bottom-left.
Comment 5 Alvin 2015-02-02 23:27:44 UTC
Created attachment 2016 [details]
Texture clipping test

I am also experiencing this bug as well. I have written a similar test program as the one already attached. However, this test program is not specific to the Raspberry PI.

The attached program sets a 100x100 clipping rectangle at the origin and fills the whole dimensions of the texture in red. Effectively making a 100x100 red square at the origin. Clipping is then turned off and a blue 50x50 square is drawn using SDL_RenderFillRect() at the origin. 

I have tested two Linux systems. One that uses the nvidia driver and another that uses the integrated intel driver (HD 4000). Both draw the red square at the bottom-left and the blue square at the top-left.

What I have noticed is that the issue does not occur when the renderer's default target is used directly (omitting the intermediate texture and set the clipping on the renderer's default target). Both the red and blue squares at drawn at the top-left.

For instance, commenting out lines 77 and 137 in my test program will use clipping on the renderer's default target.

Could this be an issue with how the SDL_Texture initialised internally?

I have tested the opengl, opengles and opengles2 renderers. All three exhibit the same behaviour: the texture's clipping origin is at the bottom-left.

My tests have used SDL2 from Mercurial, bb0b744fd1a6.
Comment 6 Alvin 2015-02-04 15:05:56 UTC
Created attachment 2017 [details]
Fixes clipping origin (may have side-effect with a viewport)

This is a patch that fixes the clipping origin (was bottom-left). The origin is now the top-left.

The patch applies only to the "opengl" and "opengles2" render drivers. It does work using the "opengles" render driver, however, the origin of the default render target appears to be the bottom-left. Therefore, this patch does not touch the "opengles".

There may be a side-effect when using a viewport. The patch uses the Y coordinate of the clipping rectangle verbatim. The origin line of code mapped the Y coordinate of the clipping rectangle to the bottom-left and took "renderer->viewport.h" into consideration. I tested with and without the patch and it appears that the clipping rectangle doesn't fully follow the viewport. Perhaps linked to bug 2535?

Someone more familiar with how the viewport interacts with and without a clipping rectangle may want to review the effect of this patch.
Comment 7 Marcel Bakker 2015-04-26 14:05:22 UTC
Created attachment 2136 [details]
openGL renderer + texture as target + SDL_RenderSetClipRect

I can also confirm that SDL_RenderSetClipRect() is broken
, when openGL is used with a Texture as rendering target.
As discussed above, the default target for openGL has a bottom-left origin.
But textures as target seem to use top-left as an origin.

SDL's current openGL clipping code assumes a default target, adjusting the clip-rect to a bottom-left origin.
, breaking SDL_RenderSetClipRect() when used with a Texture as rendering target.
Alvin's patch fixes the Texture as target problem
, but by removing the bottom-left origin code, this moves the clipping-bug to the default target.

This proposed patch checks for a default target and use bottom-left as origin
, else use top-left as origin.

note : only openGL was tested, assumed same behavior for GLES2...
Comment 8 Marcel Bakker 2015-04-26 15:12:03 UTC
Created attachment 2137 [details]
openGL renderer + texture as target + SDL_RenderSetClipRect

note : only openGL was tested, assuming same behavior for GLES/GLES2...
Comment 9 Marcel Bakker 2015-04-27 13:30:12 UTC
Changed the summary to better reflect the problem.
Comment 10 Sam Lantinga 2015-05-29 02:01:05 UTC
Fixed, thanks!
https://hg.libsdl.org/SDL/rev/1d13a878b066
Comment 11 Diego 2015-08-10 17:50:15 UTC
Why is the current patch using bottom-left for origin for default targets? To be consistent with SDL, shouldn't all origins be top-left?
Comment 12 Diego 2015-08-10 17:51:19 UTC
Reopening bug because I think all origins should be top-left.
Comment 13 Marcel Bakker 2015-10-28 16:07:42 UTC
Created attachment 2291 [details]
additional patch
Comment 14 Marcel Bakker 2015-10-28 16:08:56 UTC
Hello again,

I'm afraid Diego is correct, i never did test Sam's commit.
I worked from my own patch, only now whilst checking a new problem i noticed clip-rect was still broken.
Yes, silly me... but,..

The commit : https://hg.libsdl.org/SDL/rev/1d13a878b066
, is a mix of a viewport bug-fix and this clip-rect bug-fix into 1 commit.
That broke this patch for the clip-rect bug.

I think the additional patch gives the expected (with viewport)clipping behavior.
Comment 15 Diego 2015-11-05 01:09:31 UTC
I tested the patch using OpenGL and OpenGLES2. It works as expected from the top-left.
Comment 16 Ryan C. Gordon 2015-12-28 20:17:08 UTC
(In reply to Marcel Bakker from comment #13)
> Created attachment 2291 [details]
> additional patch

This patch is now https://hg.libsdl.org/SDL/rev/f9cd179cf50e, thanks!

--ryan.
Comment 17 Martin Gerhardy 2015-12-29 17:38:36 UTC
I'm still having problems with scissors on gl and gles2, the same cliprects works perfectly if I use the software renderer.
Comment 18 Martin Gerhardy 2015-12-29 17:40:40 UTC
Unfortunately I don't have a small code sample extracted - but compiling caveexpress and running it via "./caveexpress -ui_push editor" will render the selector ui elements on the left side empty. Doing the same with "./caveexpress -set renderer software -ui_push editor" will show the entries perfectly. Tested this on linux - will do a directx test in a few minutes
Comment 19 Martin Gerhardy 2015-12-29 17:51:33 UTC
DirectX renderer works fine when using clip rects with sdl renderers for caveexpress
Comment 20 Diego 2015-12-29 18:19:00 UTC
I just tested the latest from hg. It worked fine for me. The origin was from the top-left. I inserted the following code at line 274 of testdraw2.c to test gl, and at line 143 in happy.c to test gles2.

    SDL_Rect r = {10,20,100,200};
    SDL_RenderSetClipRect(renderer, &r);
Comment 21 Ryan C. Gordon 2015-12-30 06:37:35 UTC
Reopening for now.

--ryan.
Comment 22 Marcel Bakker 2016-03-05 23:45:45 UTC
hello,

Martin Gerhardy,
I don't know your project caveexpress also not much about openGL
, but after a quick look i suspect you are mixing openGL and SDL too much.

You set your own textures in FrameBuffer::bind(), but use SDL_RenderSetClipRect to set the scissors.
SDL doesnt known about your texture and will not detect it, only if you have set it via SDL_SetRenderTarget.
Comment 23 Richard Russell 2016-04-16 23:20:35 UTC
I'm pretty certain there's still something not right.  I'm seeing the clip rectangle inverted with 2.0.4 and GLES (OpenGL is OK; I've not tried GLES2), using a texture as the render target and rendering using SDL_RenderCopy.

There's a remark in comment #6 about GLES needing different treatment, but I'm unsure of the details.
Comment 24 Richard Russell 2016-04-17 11:09:55 UTC
Actually on further investigation I don't think what I'm seeing is a problem with the clip rectangle at all, but another manifestation of bug #3233.  Because that bug causes graphics to be plotted upside-down, I am inverting my y-coordinate.  In 2.0.3 this worked around *both* #3233 and #2700 and all was well.  However in 2.0.4 #2700 is fixed, but #3233 isn't, so my workaround is causing the clip rectangle to appear to be inverted!
Comment 25 BQ 2016-05-20 11:33:09 UTC
Hi, I still seem to be having an issue with this. I'm using SDL2 HEAD via Homebrew on OSX. I have a cross-platform GUI library with implementations in SDL2, OpenGL, SFML2 and Allegro5. I only see this issue in SDL2, the others clip fine. The GUI library assumes top-left screen origin. It seems this isn't at driver level as GL and SFML2 work fine.

Library: https://github.com/billyquith/GWork
If you'd like to see this then the following BASH script will build and run the SDL2, GL and SFML2. SFML2 uses GL.

---->8---->8---->8---->8---->8---->8---->8----
#!/usr/bin/env bash
git clone -b SDL2 --depth=1 https://github.com/billyquith/GWork.git gwork
cd gwork
mkdir build_sdl2 && cd build_sdl2
cmake -G Ninja -D RENDER_SDL2=ON ..
ninja
cd ..
mkdir build_gl && cd build_gl
cmake -G Ninja -D RENDER_OPENGL=ON ..
ninja
cd ..
mkdir build_sfml2 && cd build_sfml2
cmake -G Ninja -D RENDER_SFML2=ON ..
ninja
cd ..
cd build/bin
./GworkSDL2Sample&
./GworkOpenGLSample&
./GworkSFML2Sample&
---->8---->8---->8---->8---->8---->8---->8----
Comment 26 BQ 2017-03-12 13:00:11 UTC
(In reply to BQ from comment #25)
> Hi, I still seem to be having an issue with this. I'm using SDL2 HEAD via
> Homebrew on OSX. I have a cross-platform GUI library with implementations in
> SDL2, OpenGL, SFML2 and Allegro5. I only see this issue in SDL2, the others
> clip fine. The GUI library assumes top-left screen origin. It seems this
> isn't at driver level as GL and SFML2 work fine.

The following workaround, as mentioned above, works for me.

SDL_Rect rClip = MyWinRect;
if (ClipRectRpiFix) {
	rClip.y = ScreenHeight - rClip.y - rClip.h;
}
SDL_RenderSetClipRect(hRenderer,&rClip);
Comment 27 Marcel Bakker 2017-03-20 16:23:30 UTC
Created attachment 2706 [details]
test renderers with SDL_ClipRectangle

Hello BQ,
Could you provide a test case?
Don't think people here will use your library to debug the problem.
I attached a small test, but it might not cover your use case.

* The test file yields a new bug in the software renderer clipping
  , not related to this bug entry.
Comment 28 BQ 2017-08-05 08:58:39 UTC
As of version 2.0.5, this bug appears to have been fixed. I do not know the reason for this.

Notes on bug ticket on my project:
https://github.com/billyquith/GWork/issues/18

My fix:
https://github.com/billyquith/GWork/commit/501782979212171703b3d08bc02c76f9fcb38c43
Comment 29 Sam Lantinga 2017-08-14 05:14:02 UTC
This bug should be fixed. If there are any cases that are still not correct, please enter a new bug with a test case so we can reproduce it.

Thanks!