SDL_RenderSetClipRect not working

I’m using v2.0.5, and I cannot seem to get SDL_RenderSetClipRect() to work. It’s not clipping any further rendering. Does it only work on RenderCopy’s? Drawing Text and lineColor() seem unaffected?

Points, lines, rectangles, and textures should always be properly clipped by SDL_RenderSetClipRect. I don’t remember any bugs with this function, but it may worth it to check if SDL 2.0.8 makes any difference.

Here’s a small test that draws the various primitives the render API provides. The lines, filled rectangles, and opaque texture should only be visible in the white area. Press C to deactivate clipping and press space to toggle the animation.

cliprecttest.c
#include <SDL.h>

#define NUM_POINTS 5

static int bounce(int x, int max)
{
	x = x % (max * 2);
	if (x < 0)
		x = -x;
	x -= max;
	return x < 0 ? -x : x;
}

int main(int argc, char * argv[])
{
	SDL_Window * window;
	int i, width, height;
	SDL_Renderer * renderer;
	SDL_RendererInfo info;
	SDL_Texture * texture;
	SDL_version version;
	SDL_Event e;
	int done = 0;
	int pause = 0;
	int clip = 1;
	Uint32 counter = 2048;
	Uint32 prevticks = SDL_GetTicks();

	SDL_Point points[NUM_POINTS];
	SDL_Rect rectbg, rect1, rect2, recttex;

	SDL_GetVersion(&version);
	SDL_Log("Using SDL %d.%d.%d\n", version.major, version.minor, version.patch);

	if (SDL_Init(SDL_INIT_VIDEO | SDL_INIT_EVENTS | SDL_INIT_TIMER) < 0) {
		SDL_Log("Failed to initialize SDL: %s", SDL_GetError());
		return 1;
	}

	window = SDL_CreateWindow("SDL_RenderSetClipRect test", SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED, 800, 500, SDL_WINDOW_RESIZABLE);
	if (window == NULL){
		SDL_Log("Failed to create window: %s", SDL_GetError());
		SDL_Quit();
		return 1;
	}

	renderer = SDL_CreateRenderer(window, -1, 0);
	if (renderer == NULL){
		SDL_Log("Failed to create renderer: %s", SDL_GetError());
		SDL_DestroyWindow(window);
		SDL_Quit();
		return 1;
	}

	if (SDL_GetRendererInfo(renderer, &info) == 0) {
		SDL_Log("Using renderer %s\n", info.name);
	}

	texture = SDL_CreateTexture(renderer, SDL_PIXELFORMAT_ARGB8888, SDL_TEXTUREACCESS_STATIC, 128, 128);
	if (texture != NULL) {
		int x, y;
		Uint8 data[128 * 128 * 4] = {0};

		for (y = -64; y < 63; y++) {
			for (x = -64; x < 63; x++) {
				int d = x*x + y*y;
				if (d <= 3500) {
					int o = (y + 64) * 128 * 4 + (x + 64) * 4;
					data[o + 0] = bounce(d / 3 - 64, 128) + 127;
					data[o + 1] = bounce(d / 2 + y * d / 100, 255);
					data[o + 2] = bounce(d / 2 + x * d / 200, 255);
					data[o + 3] = d > 3245 ? 3500 - d : 255;
				}
			}
		}

		SDL_UpdateTexture(texture, NULL, data, 128 * 4);
	} else {
		SDL_Log("Failed to create texture: %s", SDL_GetError());
		SDL_DestroyRenderer(renderer);
		SDL_DestroyWindow(window);
		SDL_Quit();
		return 1;
	}
	SDL_SetTextureBlendMode(texture, SDL_BLENDMODE_BLEND);

	SDL_GetWindowSize(window, &width, &height);

	while (!done) {
		if (!pause) {
			Uint32 now = SDL_GetTicks();
			counter += now - prevticks;
			prevticks = now;
		}

		while (SDL_PollEvent(&e)) {
			if (e.type == SDL_QUIT) {
				done = 1;
			} else if (e.type == SDL_KEYDOWN) {
			} else if (e.type == SDL_KEYUP) {
				Uint32 sym = e.key.keysym.sym;
				if (sym == SDLK_ESCAPE) {
					done = 1;
				} else if (sym == SDLK_c) {
					clip = !clip;
					prevticks = SDL_GetTicks();
				} else if (sym == SDLK_SPACE) {
					pause = !pause;
					prevticks = SDL_GetTicks();
				} else if (sym == SDLK_f) {
					if (SDL_GetWindowFlags(window) & SDL_WINDOW_FULLSCREEN) {
						SDL_SetWindowFullscreen(window, SDL_FALSE);
					} else {
						SDL_SetWindowFullscreen(window, SDL_WINDOW_FULLSCREEN_DESKTOP);
					}
				}
			} else if (e.type == SDL_WINDOWEVENT) {
				if (e.window.event == SDL_WINDOWEVENT_RESIZED || e.window.event == SDL_WINDOWEVENT_SIZE_CHANGED) {
					SDL_GetWindowSize(window, &width, &height);
				}
			}
		}

		rectbg.x = width / 4 - 4;
		rectbg.y = height / 4 - 4;
		rectbg.w = width / 2 + 8;
		rectbg.h = height / 2 + 8;

		for (i = 0; i < NUM_POINTS; i++) {
			points[i].x = bounce(counter * (i + 1) * 9 / (bounce(i - 3, 7) + 20), 4096) * (width - 1) / 4096;
			points[i].y = bounce(counter * (i + 1) * 8 / (bounce(-i - 4, 8) + 20), 4096) * (height - 1) / 4096;
		}

		rect1.w = (width < height ? width : height) / 3;
		rect1.h = rect1.w;
		rect1.x = bounce(counter * 9 / 3, 4096) * (width - rect1.w) / 4096;
		rect1.y = bounce(counter * 9 / 5, 4096) * (height - rect1.h) / 4096;

		rect2.w = (width < height ? width : height) / 5;
		rect2.h = rect2.w;
		rect2.x = bounce(counter * 9 / 13, 4096) * (width - rect2.w) / 4096;
		rect2.y = bounce(counter * 9 / 9, 4096) * (height - rect2.h) / 4096;

		recttex.w = (width < height ? width : height) / 4;
		recttex.h = recttex.w;
		recttex.x = bounce(counter * -2 / 5, 4096) * (width - recttex.w) / 4096;
		recttex.y = bounce(counter * 3 / 5, 4096) * (height - recttex.h) / 4096;


		SDL_SetRenderDrawColor(renderer, 100, 50, 50, 255);
		SDL_RenderClear(renderer);


		SDL_SetRenderDrawColor(renderer, 0, 255, 0, 255);
		SDL_RenderFillRect(renderer, &rectbg);

		rectbg.x += 4;
		rectbg.y += 4;
		rectbg.w -= 8;
		rectbg.h -= 8;

		SDL_SetRenderDrawColor(renderer, 255, 255, 255, 255);
		SDL_RenderFillRect(renderer, &rectbg);

		/* Clip on */
		if (clip) {
			SDL_RenderSetClipRect(renderer, &rectbg);
		}

		SDL_SetTextureAlphaMod(texture, 255);
		SDL_RenderCopyEx(renderer, texture, NULL, &recttex, counter / 8.5, NULL, SDL_FLIP_NONE);

		SDL_SetRenderDrawColor(renderer, 255, 0, 255, 255);
		SDL_RenderDrawLines(renderer, points, NUM_POINTS);

		SDL_SetRenderDrawColor(renderer, 100, 100, 255, 255);
		SDL_RenderFillRect(renderer, &rect1);

		SDL_SetRenderDrawColor(renderer, 255, 100, 0, 255);
		SDL_RenderFillRect(renderer, &rect2);

		/* Clip off */
		SDL_RenderSetClipRect(renderer, NULL);

		SDL_SetTextureAlphaMod(texture, 10);
		SDL_RenderCopyEx(renderer, texture, NULL, &recttex, counter / 8.5, NULL, SDL_FLIP_NONE);

		SDL_SetRenderDrawColor(renderer, 255, 255, 255, 255);
		SDL_RenderDrawPoints(renderer, points, NUM_POINTS);

		SDL_SetRenderDrawColor(renderer, 200, 200, 255, 255);
		SDL_RenderDrawRect(renderer, &rect1);

		SDL_SetRenderDrawColor(renderer, 255, 200, 100, 255);
		SDL_RenderDrawRect(renderer, &rect2);


		SDL_RenderPresent(renderer);
	}

	SDL_DestroyTexture(texture);
	SDL_DestroyRenderer(renderer);
	SDL_DestroyWindow(window);
	SDL_Quit();

	return 0;
}

Should look like this:

cliprecttest