Added SDL_RotateSurface()

Fixes https://github.com/libsdl-org/SDL/issues/14269
This commit is contained in:
Sam Lantinga
2025-10-22 17:28:34 -07:00
parent a402af506c
commit e18d63a4e2
15 changed files with 286 additions and 33 deletions

View File

@@ -393,6 +393,7 @@ if(WIN32 AND CMAKE_SIZEOF_VOID_P EQUAL 4)
add_sdl_test_executable(pretest SOURCES pretest.c NONINTERACTIVE NONINTERACTIVE_TIMEOUT 60)
endif()
add_sdl_test_executable(testrendertarget NEEDS_RESOURCES TESTUTILS SOURCES testrendertarget.c)
add_sdl_test_executable(testrotate SOURCES testrotate.c)
add_sdl_test_executable(testscale NEEDS_RESOURCES TESTUTILS SOURCES testscale.c)
add_sdl_test_executable(testsem NONINTERACTIVE DISABLE_THREADS_ARGS "--no-threads" NONINTERACTIVE_ARGS 10 NONINTERACTIVE_TIMEOUT 30 SOURCES testsem.c)
add_sdl_test_executable(testsensor SOURCES testsensor.c)

205
test/testrotate.c Normal file
View File

@@ -0,0 +1,205 @@
/*
Copyright (C) 1997-2025 Sam Lantinga <slouken@libsdl.org>
This software is provided 'as-is', without any express or implied
warranty. In no event will the authors be held liable for any damages
arising from the use of this software.
Permission is granted to anyone to use this software for any purpose,
including commercial applications, and to alter it and redistribute it
freely.
*/
#define SDL_MAIN_USE_CALLBACKS 1
#include <SDL3/SDL_test.h>
#include <SDL3/SDL_test_common.h>
#include <SDL3/SDL_main.h>
#define IMAGE_SIZE 256
static SDLTest_CommonState *state;
static SDL_Surface *image;
static SDL_Texture *texture;
static int format_index = -1;
static SDL_PixelFormat formats[] = {
SDL_PIXELFORMAT_RGBA32,
SDL_PIXELFORMAT_ARGB32,
SDL_PIXELFORMAT_RGBX32,
SDL_PIXELFORMAT_XRGB32,
SDL_PIXELFORMAT_ARGB1555,
SDL_PIXELFORMAT_INDEX8
};
static int angle;
static int direction = 1;
static bool UpdateImageFormat(void)
{
static const SDL_Color colors[] = {
{ 255, 255, 255, SDL_ALPHA_TRANSPARENT }, /* Colorkey - white with transparent alpha */
{ 255, 0, 0, SDL_ALPHA_OPAQUE }, /* Red */
{ 255, 255, 0, SDL_ALPHA_OPAQUE }, /* Yellow */
{ 0, 255, 0, SDL_ALPHA_OPAQUE }, /* Green */
{ 0, 0, 255, SDL_ALPHA_OPAQUE }, /* Blue */
};
SDL_Rect rect;
Uint32 color;
++format_index;
if (format_index == SDL_arraysize(formats)) {
format_index = 0;
}
SDL_DestroySurface(image);
image = SDL_CreateSurface(IMAGE_SIZE, IMAGE_SIZE, formats[format_index]);
if (!image) {
SDL_Log("Couldn't create surface: %s\n", SDL_GetError());
return false;
}
if (image->format == SDL_PIXELFORMAT_INDEX8) {
/* Set the palette and colorkey */
SDL_Palette *palette = SDL_CreateSurfacePalette(image);
SDL_SetPaletteColors(palette, colors, 0, SDL_arraysize(colors));
SDL_SetSurfaceColorKey(image, true, 0);
}
/* Upper left */
rect.x = 0;
rect.y = 0;
rect.w = IMAGE_SIZE / 2;
rect.h = IMAGE_SIZE / 2;
color = SDL_MapSurfaceRGB(image, colors[1].r, colors[1].g, colors[1].b);
SDL_FillSurfaceRect(image, &rect, color);
/* Upper right */
rect.x += rect.w;
color = SDL_MapSurfaceRGB(image, colors[2].r, colors[2].g, colors[2].b);
SDL_FillSurfaceRect(image, &rect, color);
/* Lower left */
rect.x = 0;
rect.y += rect.h;
color = SDL_MapSurfaceRGB(image, colors[3].r, colors[3].g, colors[3].b);
SDL_FillSurfaceRect(image, &rect, color);
/* Lower right */
rect.x += rect.w;
color = SDL_MapSurfaceRGB(image, colors[4].r, colors[4].g, colors[4].b);
SDL_FillSurfaceRect(image, &rect, color);
return true;
}
static bool UpdateRotation(SDL_Renderer *renderer)
{
SDL_Surface *rotated;
angle += direction;
rotated = SDL_RotateSurface(image, (float)angle);
if (!rotated) {
SDL_Log("Couldn't rotate surface: %s", SDL_GetError());
return false;
}
SDL_DestroyTexture(texture);
texture = SDL_CreateTextureFromSurface(renderer, rotated);
SDL_DestroySurface(rotated);
if (!texture) {
SDL_Log("Couldn't create texture: %s", SDL_GetError());
return false;
}
return true;
}
static void Draw(SDL_Renderer *renderer)
{
int w, h;
SDL_FRect dst;
/* Clear the screen */
SDL_SetRenderDrawColor(renderer, 0, 0, 0, SDL_ALPHA_OPAQUE);
SDL_RenderClear(renderer);
UpdateRotation(renderer);
/* Draw the rotated image */
SDL_GetCurrentRenderOutputSize(renderer, &w, &h);
dst.x = (w - texture->w) / 2.0f;
dst.y = (h - texture->h) / 2.0f;
dst.w = (float)texture->w;
dst.h = (float)texture->h;
SDL_RenderTexture(renderer, texture, NULL, &dst);
/* Show the current format */
SDL_SetRenderDrawColor(renderer, 255, 255, 255, SDL_ALPHA_OPAQUE);
SDL_RenderDebugTextFormat(renderer, 4.0f, 4.0f, "Format: %s, press SPACE to cycle", SDL_GetPixelFormatName(formats[format_index]));
/* All done! */
SDL_RenderPresent(renderer);
}
void SDL_AppQuit(void *appstate, SDL_AppResult result)
{
SDLTest_CommonQuit(state);
}
SDL_AppResult SDL_AppInit(void **appstate, int argc, char *argv[])
{
/* Initialize test framework */
state = SDLTest_CommonCreateState(argv, SDL_INIT_VIDEO);
if (!state) {
return SDL_APP_FAILURE;
}
if (!SDLTest_CommonInit(state)) {
return SDL_APP_FAILURE;
}
/* Create the spinning image */
UpdateImageFormat();
return SDL_APP_CONTINUE;
}
SDL_AppResult SDL_AppEvent(void *appstate, SDL_Event *event)
{
switch (event->type) {
case SDL_EVENT_KEY_UP:
switch (event->key.key) {
case SDLK_SPACE:
UpdateImageFormat();
break;
case SDLK_LEFT:
direction = -1;
break;
case SDLK_RIGHT:
direction = 1;
break;
default:
break;
}
break;
default:
break;
}
return SDLTest_CommonEventMainCallbacks(state, event);
}
SDL_AppResult SDL_AppIterate(void *appstate)
{
int i;
for (i = 0; i < state->num_windows; ++i) {
Draw(state->renderers[i]);
}
/* Wait a bit so we don't spin too quickly to see */
SDL_Delay(10);
return SDL_APP_CONTINUE;
}