diff --git a/include/SDL3/SDL_render.h b/include/SDL3/SDL_render.h index 4d7e8ab12c..16cffb8619 100644 --- a/include/SDL3/SDL_render.h +++ b/include/SDL3/SDL_render.h @@ -110,6 +110,9 @@ typedef enum SDL_TextureAccess * * This affects how texture coordinates are interpreted outside of [0, 1] * + * Texture wrapping is always supported for power of two texture sizes, + * and is supported for other texture sizes if SDL_PROP_RENDERER_TEXTURE_WRAPPING_BOOLEAN is set to true. + * * \since This enum is available since SDL 3.4.0. */ typedef enum SDL_TextureAddressMode @@ -474,6 +477,7 @@ extern SDL_DECLSPEC const char * SDLCALL SDL_GetRendererName(SDL_Renderer *rende * - `SDL_PROP_RENDERER_TEXTURE_FORMATS_POINTER`: a (const SDL_PixelFormat *) * array of pixel formats, terminated with SDL_PIXELFORMAT_UNKNOWN, * representing the available texture formats for this renderer. + * - `SDL_PROP_RENDERER_TEXTURE_WRAPPING_BOOLEAN`: true if the renderer supports SDL_TEXTURE_ADDRESS_WRAP on non-power-of-two textures. * - `SDL_PROP_RENDERER_OUTPUT_COLORSPACE_NUMBER`: an SDL_Colorspace value * describing the colorspace for output to the display, defaults to * SDL_COLORSPACE_SRGB. @@ -550,6 +554,7 @@ extern SDL_DECLSPEC SDL_PropertiesID SDLCALL SDL_GetRendererProperties(SDL_Rende #define SDL_PROP_RENDERER_VSYNC_NUMBER "SDL.renderer.vsync" #define SDL_PROP_RENDERER_MAX_TEXTURE_SIZE_NUMBER "SDL.renderer.max_texture_size" #define SDL_PROP_RENDERER_TEXTURE_FORMATS_POINTER "SDL.renderer.texture_formats" +#define SDL_PROP_RENDERER_TEXTURE_WRAPPING_BOOLEAN "SDL.renderer.texture_wrapping" #define SDL_PROP_RENDERER_OUTPUT_COLORSPACE_NUMBER "SDL.renderer.output_colorspace" #define SDL_PROP_RENDERER_HDR_ENABLED_BOOLEAN "SDL.renderer.HDR_enabled" #define SDL_PROP_RENDERER_SDR_WHITE_POINT_FLOAT "SDL.renderer.SDR_white_point" diff --git a/src/render/SDL_render.c b/src/render/SDL_render.c index 4a7bd01717..496300c793 100644 --- a/src/render/SDL_render.c +++ b/src/render/SDL_render.c @@ -1219,6 +1219,7 @@ SDL_Renderer *SDL_CreateRendererWithProperties(SDL_PropertiesID props) SDL_SetPointerProperty(new_props, SDL_PROP_RENDERER_SURFACE_POINTER, surface); } SDL_SetNumberProperty(new_props, SDL_PROP_RENDERER_OUTPUT_COLORSPACE_NUMBER, renderer->output_colorspace); + SDL_SetBooleanProperty(new_props, SDL_PROP_RENDERER_TEXTURE_WRAPPING_BOOLEAN, !renderer->npot_texture_wrap_unsupported); if (window) { UpdateHDRProperties(renderer); @@ -4581,8 +4582,8 @@ bool SDL_RenderTextureTiled(SDL_Renderer *renderer, SDL_Texture *texture, const (!srcrect || (real_srcrect.x == 0.0f && real_srcrect.y == 0.0f && real_srcrect.w == (float)texture->w && real_srcrect.h == (float)texture->h)); - if (do_wrapping && !renderer->npot_texture_wrap_unsupported) { - if (renderer->npot_texture_wrap_unsupported && (IsNPOT(texture->w) || IsNPOT(texture->h))) { + if (do_wrapping && renderer->npot_texture_wrap_unsupported) { + if (IsNPOT(texture->w) || IsNPOT(texture->h)) { do_wrapping = false; } } @@ -5351,8 +5352,16 @@ bool SDL_RenderGeometryRaw(SDL_Renderer *renderer, } } - texture_address_mode_u = renderer->texture_address_mode_u; - texture_address_mode_v = renderer->texture_address_mode_v; + if (renderer->npot_texture_wrap_unsupported && IsNPOT(texture->w)) { + texture_address_mode_u = SDL_TEXTURE_ADDRESS_CLAMP; + } else { + texture_address_mode_u = renderer->texture_address_mode_u; + } + if (renderer->npot_texture_wrap_unsupported && IsNPOT(texture->h)) { + texture_address_mode_v = SDL_TEXTURE_ADDRESS_CLAMP; + } else { + texture_address_mode_v = renderer->texture_address_mode_v; + } if (texture && (texture_address_mode_u == SDL_TEXTURE_ADDRESS_AUTO || texture_address_mode_v == SDL_TEXTURE_ADDRESS_AUTO)) { @@ -5428,12 +5437,6 @@ bool SDL_SetRenderTextureAddressMode(SDL_Renderer *renderer, SDL_TextureAddressM { CHECK_RENDERER_MAGIC(renderer, false); - if ((u_mode == SDL_TEXTURE_ADDRESS_WRAP || v_mode == SDL_TEXTURE_ADDRESS_WRAP) && - renderer->npot_texture_wrap_unsupported) { - // Technically it's supported on power of two textures, but we're assuming that non-power-of-two textures are going to be used. - return SDL_SetError("SDL_TEXTURE_ADDRESS_WRAP not supported"); - } - renderer->texture_address_mode_u = u_mode; renderer->texture_address_mode_v = v_mode; return true;