Open brainstream opened 3 weeks ago
Want to say no here, unless @slouken feels strongly about it.
Getting degrees from radians is just:
degrees = radians * (180.0f / SDL_PI_F);
I think we'll pass on this.
Want to say no here, unless @slouken feels strongly about it.
Getting degrees from radians is just:
degrees = radians * (180.0f / SDL_PI_F);
When I use box2d, I have a cosine and a sine. So, I need to call atan2
to get radians, and then I need to convert them to degrees. But SDL will perform the reverse operations and calculate radians from degrees, and then sine and cosine. It looks like an overhead.
@brainstream Trying to warp SDL to bend around box2d's limitations doesn't seem like a good solution. I ended up making my own angle system, which ends up passing an angle to SDL as: angle / ANGLE_DIVISOR. Angle overhead is something you can solve outside of SDL.
That's an interesting optimization. We do convert the angle to sin/cos in every path that handles rotation. We're not going to change the API for the 3.2.0 release, but we can consider this in the future.
For use cases like this where you already have the rotation basis vectors, it make more sense to just let the user specify the affine parallelogram directly.
This allows them to encompass all of flipping, mirroring, stretching, rotating and shearing.
Hhere's how you could use the proposed SDL_RenderTextureAffine
with raw cosine and sines, adapted from examples/renderer/08-rotating-textures.c:
SDL_AppResult SDL_AppIterate(void *appstate) {
const float winspan = SDL_min(WINDOW_WIDTH, WINDOW_HEIGHT);
const float texspan = SDL_sqrt((float)(texture_width*texture_width + texture_height*texture_height));
const float scale = winspan / texspan;
SDL_FRect dst_rect;
dst_rect.x = 0.5f * WINDOW_WIDTH;
dst_rect.y = 0.5f * WINDOW_HEIGHT;
dst_rect.w = 0.5f * texture_width * scale;
dst_rect.h = 0.5f * texture_height * scale;
const Uint64 now = SDL_GetTicks();
const float rad = (((float) ((int) (now % 4000))) / 4000.0f) * SDL_PI_F * 2;
const float cos = SDL_cos(rad);
const float sin = SDL_sin(rad);
const float xx = cos * dst_rect.w;
const float xy = sin * dst_rect.w;
const float yx = -sin * dst_rect.h;
const float yy = cos * dst_rect.h;
SDL_FPoint origin, right, down;
origin.x = dst_rect.x - xx - yx;
origin.y = dst_rect.y - xy - yy;
right.x = dst_rect.x + xx - yx;
right.y = dst_rect.y + xy - yy;
down.x = dst_rect.x - xx + yx;
down.y = dst_rect.y - xy + yy;
SDL_SetRenderDrawColor(renderer, 0, 0, 0, SDL_ALPHA_OPAQUE);
SDL_RenderClear(renderer);
SDL_RenderTextureAffine(renderer, texture, NULL, &origin, &right, &down);
SDL_RenderPresent(renderer);
return SDL_APP_CONTINUE;
}
@expikr It looks great!
Currently this function only accepts angle in degrees, however most applications already have angles in radians. Also, box2d 3.0 returns rotation as a pair of sine and cosine. So SDL3 could improve performance if
SDL_RenderTextureRotated
also accepted a pair of sine and cosine. For this purpose, two helper functions should be added that will build such a structure from degrees and radians.In case of box2d 3.0 we can use pre-calculated value.