render: First shot at removing logical render target.

This commit is contained in:
Ryan C. Gordon 2024-09-16 13:33:16 -04:00
parent 95c3ee77c1
commit 947e9b7edd
No known key found for this signature in database
GPG Key ID: FA148B892AB48044
5 changed files with 108 additions and 159 deletions

View File

@ -24,11 +24,13 @@ SDL_AppResult SDL_AppInit(void **appstate, int argc, char *argv[])
return SDL_APP_FAILURE; return SDL_APP_FAILURE;
} }
if (!SDL_CreateWindowAndRenderer("examples/renderer/primitives", 640, 480, 0, &window, &renderer)) { if (!SDL_CreateWindowAndRenderer("examples/renderer/primitives", 640, 480, SDL_WINDOW_RESIZABLE, &window, &renderer)) {
SDL_ShowSimpleMessageBox(SDL_MESSAGEBOX_ERROR, "Couldn't create window/renderer!", SDL_GetError(), NULL); SDL_ShowSimpleMessageBox(SDL_MESSAGEBOX_ERROR, "Couldn't create window/renderer!", SDL_GetError(), NULL);
return SDL_APP_FAILURE; return SDL_APP_FAILURE;
} }
SDL_SetRenderLogicalPresentation(renderer, 640, 480, SDL_LOGICAL_PRESENTATION_LETTERBOX, SDL_SCALEMODE_NEAREST);
/* set up some random points */ /* set up some random points */
for (i = 0; i < SDL_arraysize(points); i++) { for (i = 0; i < SDL_arraysize(points); i++) {
points[i].x = (SDL_randf() * 440.0f) + 100.0f; points[i].x = (SDL_randf() * 440.0f) + 100.0f;
@ -53,7 +55,7 @@ SDL_AppResult SDL_AppIterate(void *appstate)
SDL_FRect rect; SDL_FRect rect;
/* as you can see from this, rendering draws over whatever was drawn before it. */ /* as you can see from this, rendering draws over whatever was drawn before it. */
SDL_SetRenderDrawColor(renderer, 0, 0, 0, 255); /* black, full alpha */ SDL_SetRenderDrawColor(renderer, 33, 33, 33, 255); /* black, full alpha */
SDL_RenderClear(renderer); /* start with a blank canvas. */ SDL_RenderClear(renderer); /* start with a blank canvas. */
/* draw a filled rectangle in the middle of the canvas. */ /* draw a filled rectangle in the middle of the canvas. */

View File

@ -431,10 +431,9 @@ static void UpdatePixelViewport(SDL_Renderer *renderer, SDL_RenderViewState *vie
static bool QueueCmdSetViewport(SDL_Renderer *renderer) static bool QueueCmdSetViewport(SDL_Renderer *renderer)
{ {
SDL_Rect viewport;
bool result = true; bool result = true;
viewport = renderer->view->pixel_viewport; SDL_Rect viewport = renderer->view->pixel_viewport;
if (!renderer->viewport_queued || if (!renderer->viewport_queued ||
SDL_memcmp(&viewport, &renderer->last_queued_viewport, sizeof(viewport)) != 0) { SDL_memcmp(&viewport, &renderer->last_queued_viewport, sizeof(viewport)) != 0) {
@ -467,11 +466,9 @@ static void UpdatePixelClipRect(SDL_Renderer *renderer, SDL_RenderViewState *vie
static bool QueueCmdSetClipRect(SDL_Renderer *renderer) static bool QueueCmdSetClipRect(SDL_Renderer *renderer)
{ {
SDL_Rect clip_rect;
bool result = true; bool result = true;
clip_rect = renderer->view->pixel_clip_rect; SDL_Rect clip_rect = renderer->view->pixel_clip_rect;
if (!renderer->cliprect_queued || if (!renderer->cliprect_queued ||
renderer->view->clipping_enabled != renderer->last_queued_cliprect_enabled || renderer->view->clipping_enabled != renderer->last_queued_cliprect_enabled ||
SDL_memcmp(&clip_rect, &renderer->last_queued_cliprect, sizeof(clip_rect)) != 0) { SDL_memcmp(&clip_rect, &renderer->last_queued_cliprect, sizeof(clip_rect)) != 0) {
@ -718,7 +715,6 @@ static bool QueueCmdGeometry(SDL_Renderer *renderer, SDL_Texture *texture,
cmd = PrepQueueCmdDraw(renderer, SDL_RENDERCMD_GEOMETRY, texture); cmd = PrepQueueCmdDraw(renderer, SDL_RENDERCMD_GEOMETRY, texture);
if (cmd) { if (cmd) {
cmd->data.draw.texture_address_mode = texture_address_mode; cmd->data.draw.texture_address_mode = texture_address_mode;
result = renderer->QueueGeometry(renderer, cmd, texture, result = renderer->QueueGeometry(renderer, cmd, texture,
xy, xy_stride, xy, xy_stride,
color, color_stride, uv, uv_stride, color, color_stride, uv, uv_stride,
@ -794,7 +790,7 @@ static void UpdateHDRProperties(SDL_Renderer *renderer)
UpdateColorScale(renderer); UpdateColorScale(renderer);
} }
static bool UpdateLogicalPresentation(SDL_Renderer *renderer); static void UpdateLogicalPresentation(SDL_Renderer *renderer);
int SDL_GetNumRenderDrivers(void) int SDL_GetNumRenderDrivers(void)
@ -835,6 +831,8 @@ static bool SDLCALL SDL_RendererEventWatch(void *userdata, SDL_Event *event)
if (event->type == SDL_EVENT_WINDOW_RESIZED || if (event->type == SDL_EVENT_WINDOW_RESIZED ||
event->type == SDL_EVENT_WINDOW_PIXEL_SIZE_CHANGED || event->type == SDL_EVENT_WINDOW_PIXEL_SIZE_CHANGED ||
event->type == SDL_EVENT_WINDOW_METAL_VIEW_RESIZED) { event->type == SDL_EVENT_WINDOW_METAL_VIEW_RESIZED) {
SDL_Log("Window is now %dx%d", event->window.data1, event->window.data2);
UpdateMainViewDimensions(renderer); UpdateMainViewDimensions(renderer);
UpdateLogicalPresentation(renderer); UpdateLogicalPresentation(renderer);
} else if (event->type == SDL_EVENT_WINDOW_HIDDEN) { } else if (event->type == SDL_EVENT_WINDOW_HIDDEN) {
@ -2485,7 +2483,7 @@ void SDL_UnlockTexture(SDL_Texture *texture)
texture->locked_surface = NULL; texture->locked_surface = NULL;
} }
static bool SDL_SetRenderTargetInternal(SDL_Renderer *renderer, SDL_Texture *texture) bool SDL_SetRenderTarget(SDL_Renderer *renderer, SDL_Texture *texture)
{ {
// texture == NULL is valid and means reset the target to the window // texture == NULL is valid and means reset the target to the window
if (texture) { if (texture) {
@ -2514,6 +2512,8 @@ static bool SDL_SetRenderTargetInternal(SDL_Renderer *renderer, SDL_Texture *tex
renderer->target = texture; renderer->target = texture;
if (texture) { if (texture) {
renderer->view = &texture->view; renderer->view = &texture->view;
} else if (renderer->logical_presentation_mode != SDL_LOGICAL_PRESENTATION_DISABLED) {
renderer->view = &renderer->logical_view;
} else { } else {
renderer->view = &renderer->main_view; renderer->view = &renderer->main_view;
} }
@ -2537,46 +2537,28 @@ static bool SDL_SetRenderTargetInternal(SDL_Renderer *renderer, SDL_Texture *tex
return true; return true;
} }
bool SDL_SetRenderTarget(SDL_Renderer *renderer, SDL_Texture *texture)
{
if (!texture && renderer->logical_target) {
return SDL_SetRenderTargetInternal(renderer, renderer->logical_target);
} else {
return SDL_SetRenderTargetInternal(renderer, texture);
}
}
SDL_Texture *SDL_GetRenderTarget(SDL_Renderer *renderer) SDL_Texture *SDL_GetRenderTarget(SDL_Renderer *renderer)
{ {
CHECK_RENDERER_MAGIC(renderer, NULL); CHECK_RENDERER_MAGIC(renderer, NULL);
if (!renderer->target) {
if (renderer->target == renderer->logical_target) {
return NULL; return NULL;
} else {
return (SDL_Texture *)SDL_GetPointerProperty(SDL_GetTextureProperties(renderer->target), SDL_PROP_TEXTURE_PARENT_POINTER, renderer->target);
} }
return (SDL_Texture *) SDL_GetPointerProperty(SDL_GetTextureProperties(renderer->target), SDL_PROP_TEXTURE_PARENT_POINTER, renderer->target);
} }
static bool UpdateLogicalPresentation(SDL_Renderer *renderer) static void UpdateLogicalPresentation(SDL_Renderer *renderer)
{ {
float logical_w = 1.0f, logical_h = 1.0f;
float output_w = (float)renderer->main_view.pixel_w;
float output_h = (float)renderer->main_view.pixel_h;
float want_aspect = 1.0f;
float real_aspect = 1.0f;
float scale;
if (renderer->logical_presentation_mode == SDL_LOGICAL_PRESENTATION_DISABLED) { if (renderer->logical_presentation_mode == SDL_LOGICAL_PRESENTATION_DISABLED) {
// All done! renderer->view = &renderer->main_view;
return true; return; // All done!
} }
if (!SDL_GetTextureSize(renderer->logical_target, &logical_w, &logical_h)) { const float output_w = (float)renderer->main_view.pixel_w;
goto error; const float output_h = (float)renderer->main_view.pixel_h;
} const float logical_w = renderer->logical_w;
const float logical_h = renderer->logical_h;
want_aspect = logical_w / logical_h; const float want_aspect = logical_w / logical_h;
real_aspect = output_w / output_h; const float real_aspect = output_w / output_h;
renderer->logical_src_rect.x = 0.0f; renderer->logical_src_rect.x = 0.0f;
renderer->logical_src_rect.y = 0.0f; renderer->logical_src_rect.y = 0.0f;
@ -2584,6 +2566,7 @@ static bool UpdateLogicalPresentation(SDL_Renderer *renderer)
renderer->logical_src_rect.h = logical_h; renderer->logical_src_rect.h = logical_h;
if (renderer->logical_presentation_mode == SDL_LOGICAL_PRESENTATION_INTEGER_SCALE) { if (renderer->logical_presentation_mode == SDL_LOGICAL_PRESENTATION_INTEGER_SCALE) {
float scale;
if (want_aspect > real_aspect) { if (want_aspect > real_aspect) {
scale = (float)((int)output_w / (int)logical_w); // This an integer division! scale = (float)((int)output_w / (int)logical_w); // This an integer division!
} else { } else {
@ -2609,7 +2592,7 @@ static bool UpdateLogicalPresentation(SDL_Renderer *renderer)
} else if (want_aspect > real_aspect) { } else if (want_aspect > real_aspect) {
if (renderer->logical_presentation_mode == SDL_LOGICAL_PRESENTATION_LETTERBOX) { if (renderer->logical_presentation_mode == SDL_LOGICAL_PRESENTATION_LETTERBOX) {
// We want a wider aspect ratio than is available - letterbox it // We want a wider aspect ratio than is available - letterbox it
scale = output_w / logical_w; const float scale = output_w / logical_w;
renderer->logical_dst_rect.x = 0.0f; renderer->logical_dst_rect.x = 0.0f;
renderer->logical_dst_rect.w = output_w; renderer->logical_dst_rect.w = output_w;
renderer->logical_dst_rect.h = SDL_floorf(logical_h * scale); renderer->logical_dst_rect.h = SDL_floorf(logical_h * scale);
@ -2619,7 +2602,7 @@ static bool UpdateLogicalPresentation(SDL_Renderer *renderer)
zoom so logical height matches the real height zoom so logical height matches the real height
and the width will grow off the screen and the width will grow off the screen
*/ */
scale = output_h / logical_h; const float scale = output_h / logical_h;
renderer->logical_dst_rect.y = 0.0f; renderer->logical_dst_rect.y = 0.0f;
renderer->logical_dst_rect.h = output_h; renderer->logical_dst_rect.h = output_h;
renderer->logical_dst_rect.w = SDL_floorf(logical_w * scale); renderer->logical_dst_rect.w = SDL_floorf(logical_w * scale);
@ -2628,7 +2611,7 @@ static bool UpdateLogicalPresentation(SDL_Renderer *renderer)
} else { } else {
if (renderer->logical_presentation_mode == SDL_LOGICAL_PRESENTATION_LETTERBOX) { if (renderer->logical_presentation_mode == SDL_LOGICAL_PRESENTATION_LETTERBOX) {
// We want a narrower aspect ratio than is available - use side-bars // We want a narrower aspect ratio than is available - use side-bars
scale = output_h / logical_h; const float scale = output_h / logical_h;
renderer->logical_dst_rect.y = 0.0f; renderer->logical_dst_rect.y = 0.0f;
renderer->logical_dst_rect.h = output_h; renderer->logical_dst_rect.h = output_h;
renderer->logical_dst_rect.w = SDL_floorf(logical_w * scale); renderer->logical_dst_rect.w = SDL_floorf(logical_w * scale);
@ -2638,7 +2621,7 @@ static bool UpdateLogicalPresentation(SDL_Renderer *renderer)
zoom so logical width matches the real width zoom so logical width matches the real width
and the height will grow off the screen and the height will grow off the screen
*/ */
scale = output_w / logical_w; const float scale = output_w / logical_w;
renderer->logical_dst_rect.x = 0.0f; renderer->logical_dst_rect.x = 0.0f;
renderer->logical_dst_rect.w = output_w; renderer->logical_dst_rect.w = output_w;
renderer->logical_dst_rect.h = SDL_floorf(logical_h * scale); renderer->logical_dst_rect.h = SDL_floorf(logical_h * scale);
@ -2646,97 +2629,58 @@ static bool UpdateLogicalPresentation(SDL_Renderer *renderer)
} }
} }
SDL_SetTextureScaleMode(renderer->logical_target, renderer->logical_scale_mode); renderer->logical_scale_x = (logical_w != 0.0f) ? renderer->logical_dst_rect.w / logical_w : 0.0f;
renderer->logical_scale_y = (logical_h != 0.0f) ? renderer->logical_dst_rect.h / logical_h : 0.0f;
if (!renderer->target) { renderer->logical_view.viewport.x = (int) SDL_roundf(renderer->logical_dst_rect.x);
SDL_SetRenderTarget(renderer, renderer->logical_target); renderer->logical_view.viewport.y = (int) SDL_roundf(renderer->logical_dst_rect.y);
} renderer->logical_view.viewport.w = (int) SDL_roundf(renderer->logical_dst_rect.w);
renderer->logical_view.viewport.h = (int) SDL_roundf(renderer->logical_dst_rect.h);
renderer->logical_view.pixel_w = renderer->logical_view.viewport.w;
renderer->logical_view.pixel_h = renderer->logical_view.viewport.h;
renderer->logical_view.scale.x = renderer->logical_scale_x;
renderer->logical_view.scale.y = renderer->logical_scale_y;
return true; SDL_copyp(&renderer->logical_view.pixel_viewport, &renderer->logical_view.viewport);
SDL_copyp(&renderer->logical_view.clip_rect, &renderer->logical_view.viewport);
UpdatePixelClipRect(renderer, &renderer->logical_view);
error: renderer->view = &renderer->logical_view;
SDL_SetRenderLogicalPresentation(renderer, 0, 0, SDL_LOGICAL_PRESENTATION_DISABLED, SDL_SCALEMODE_NEAREST);
return false;
} }
bool SDL_SetRenderLogicalPresentation(SDL_Renderer *renderer, int w, int h, SDL_RendererLogicalPresentation mode, SDL_ScaleMode scale_mode) bool SDL_SetRenderLogicalPresentation(SDL_Renderer *renderer, int w, int h, SDL_RendererLogicalPresentation mode, SDL_ScaleMode scale_mode)
{ {
CHECK_RENDERER_MAGIC(renderer, false); CHECK_RENDERER_MAGIC(renderer, false);
if (mode == SDL_LOGICAL_PRESENTATION_DISABLED) {
if (renderer->logical_target) {
SDL_DestroyTexture(renderer->logical_target);
}
} else {
if (renderer->logical_target) {
SDL_PropertiesID props = SDL_GetTextureProperties(renderer->logical_target);
if (!props) {
goto error;
}
int existing_w = (int)SDL_GetNumberProperty(props, SDL_PROP_TEXTURE_WIDTH_NUMBER, 0);
int existing_h = (int)SDL_GetNumberProperty(props, SDL_PROP_TEXTURE_HEIGHT_NUMBER, 0);
if (w != existing_w || h != existing_h) {
SDL_DestroyTexture(renderer->logical_target);
}
}
if (!renderer->logical_target) {
renderer->logical_target = SDL_CreateTexture(renderer, SDL_PIXELFORMAT_UNKNOWN, SDL_TEXTUREACCESS_TARGET, w, h);
if (!renderer->logical_target) {
goto error;
}
SDL_SetTextureBlendMode(renderer->logical_target, SDL_BLENDMODE_NONE);
}
}
renderer->logical_presentation_mode = mode; renderer->logical_presentation_mode = mode;
renderer->logical_scale_mode = scale_mode; renderer->logical_scale_mode = scale_mode;
renderer->logical_w = w;
renderer->logical_h = h;
return UpdateLogicalPresentation(renderer); UpdateLogicalPresentation(renderer);
SDL_copyp(&renderer->logical_view.clip_rect, &renderer->logical_view.viewport);
UpdatePixelClipRect(renderer, &renderer->logical_view);
error: return true;
SDL_SetRenderLogicalPresentation(renderer, 0, 0, SDL_LOGICAL_PRESENTATION_DISABLED, SDL_SCALEMODE_NEAREST);
return false;
} }
bool SDL_GetRenderLogicalPresentation(SDL_Renderer *renderer, int *w, int *h, SDL_RendererLogicalPresentation *mode, SDL_ScaleMode *scale_mode) bool SDL_GetRenderLogicalPresentation(SDL_Renderer *renderer, int *w, int *h, SDL_RendererLogicalPresentation *mode, SDL_ScaleMode *scale_mode)
{ {
if (w) { #define SETVAL(ptr, val) if (ptr) { *ptr = val; }
*w = 0;
} SETVAL(w, 0);
if (h) { SETVAL(h, 0);
*h = 0; SETVAL(mode, SDL_LOGICAL_PRESENTATION_DISABLED);
} SETVAL(scale_mode, SDL_SCALEMODE_NEAREST);
if (mode) {
*mode = SDL_LOGICAL_PRESENTATION_DISABLED;
}
if (scale_mode) {
*scale_mode = SDL_SCALEMODE_NEAREST;
}
CHECK_RENDERER_MAGIC(renderer, false); CHECK_RENDERER_MAGIC(renderer, false);
if (renderer->logical_target) { SETVAL(mode, renderer->logical_presentation_mode);
SDL_PropertiesID props = SDL_GetTextureProperties(renderer->logical_target); SETVAL(scale_mode, renderer->logical_scale_mode);
if (!props) { SETVAL(w, renderer->logical_w);
return false; SETVAL(h, renderer->logical_h);
}
if (w) { #undef SETVAL
*w = (int)SDL_GetNumberProperty(props, SDL_PROP_TEXTURE_WIDTH_NUMBER, 0);
}
if (h) {
*h = (int)SDL_GetNumberProperty(props, SDL_PROP_TEXTURE_HEIGHT_NUMBER, 0);
}
}
if (mode) {
*mode = renderer->logical_presentation_mode;
}
if (scale_mode) {
*scale_mode = renderer->logical_scale_mode;
}
return true; return true;
} }
@ -2814,12 +2758,14 @@ static void SDL_RenderLogicalBorders(SDL_Renderer *renderer)
static void SDL_RenderLogicalPresentation(SDL_Renderer *renderer) static void SDL_RenderLogicalPresentation(SDL_Renderer *renderer)
{ {
SDL_assert(renderer->target == NULL); if (renderer->logical_presentation_mode != SDL_LOGICAL_PRESENTATION_DISABLED) {
SDL_SetRenderViewport(renderer, NULL); renderer->view = &renderer->main_view;
SDL_SetRenderClipRect(renderer, NULL); SDL_SetRenderViewport(renderer, NULL); // !!! FIXME: do we need to set this back afterwards?
SDL_SetRenderScale(renderer, 1.0f, 1.0f); SDL_SetRenderClipRect(renderer, NULL);
SDL_RenderLogicalBorders(renderer); SDL_SetRenderScale(renderer, 1.0f, 1.0f);
SDL_RenderTexture(renderer, renderer->logical_target, &renderer->logical_src_rect, &renderer->logical_dst_rect); SDL_RenderLogicalBorders(renderer);
renderer->view = &renderer->logical_view;
}
} }
bool SDL_RenderCoordinatesFromWindow(SDL_Renderer *renderer, float window_x, float window_y, float *x, float *y) bool SDL_RenderCoordinatesFromWindow(SDL_Renderer *renderer, float window_x, float window_y, float *x, float *y)
@ -2834,7 +2780,7 @@ bool SDL_RenderCoordinatesFromWindow(SDL_Renderer *renderer, float window_x, flo
render_y = window_y * renderer->dpi_scale.y; render_y = window_y * renderer->dpi_scale.y;
// Convert from pixels within the window to pixels within the view // Convert from pixels within the window to pixels within the view
if (renderer->logical_target) { if (renderer->logical_presentation_mode != SDL_LOGICAL_PRESENTATION_DISABLED) {
const SDL_FRect *src = &renderer->logical_src_rect; const SDL_FRect *src = &renderer->logical_src_rect;
const SDL_FRect *dst = &renderer->logical_dst_rect; const SDL_FRect *dst = &renderer->logical_dst_rect;
render_x = ((render_x - dst->x) * src->w) / dst->w; render_x = ((render_x - dst->x) * src->w) / dst->w;
@ -2842,8 +2788,8 @@ bool SDL_RenderCoordinatesFromWindow(SDL_Renderer *renderer, float window_x, flo
} }
// Convert from pixels within the view to render coordinates // Convert from pixels within the view to render coordinates
if (renderer->logical_target) { if (renderer->logical_presentation_mode != SDL_LOGICAL_PRESENTATION_DISABLED) {
view = &renderer->logical_target->view; view = &renderer->logical_view;
} else { } else {
view = &renderer->main_view; view = &renderer->main_view;
} }
@ -2866,8 +2812,8 @@ bool SDL_RenderCoordinatesToWindow(SDL_Renderer *renderer, float x, float y, flo
CHECK_RENDERER_MAGIC(renderer, false); CHECK_RENDERER_MAGIC(renderer, false);
// Convert from render coordinates to pixels within the view // Convert from render coordinates to pixels within the view
if (renderer->logical_target) { if (renderer->logical_presentation_mode != SDL_LOGICAL_PRESENTATION_DISABLED) {
view = &renderer->logical_target->view; view = &renderer->logical_view;
} else { } else {
view = &renderer->main_view; view = &renderer->main_view;
} }
@ -2875,7 +2821,7 @@ bool SDL_RenderCoordinatesToWindow(SDL_Renderer *renderer, float x, float y, flo
y = (view->viewport.y + y) * view->scale.y; y = (view->viewport.y + y) * view->scale.y;
// Convert from pixels within the view to pixels within the window // Convert from pixels within the view to pixels within the window
if (renderer->logical_target) { if (renderer->logical_presentation_mode != SDL_LOGICAL_PRESENTATION_DISABLED) {
const SDL_FRect *src = &renderer->logical_src_rect; const SDL_FRect *src = &renderer->logical_src_rect;
const SDL_FRect *dst = &renderer->logical_dst_rect; const SDL_FRect *dst = &renderer->logical_dst_rect;
x = dst->x + ((x * dst->w) / src->w); x = dst->x + ((x * dst->w) / src->w);
@ -2911,15 +2857,15 @@ bool SDL_ConvertEventToRenderCoordinates(SDL_Renderer *renderer, SDL_Event *even
float scale = renderer->dpi_scale.x; float scale = renderer->dpi_scale.x;
// Convert from pixels within the window to pixels within the view // Convert from pixels within the window to pixels within the view
if (renderer->logical_target) { if (renderer->logical_presentation_mode != SDL_LOGICAL_PRESENTATION_DISABLED) {
const SDL_FRect *src = &renderer->logical_src_rect; const SDL_FRect *src = &renderer->logical_src_rect;
const SDL_FRect *dst = &renderer->logical_dst_rect; const SDL_FRect *dst = &renderer->logical_dst_rect;
scale = (scale * src->w) / dst->w; scale = (scale * src->w) / dst->w;
} }
// Convert from pixels within the view to render coordinates // Convert from pixels within the view to render coordinates
if (renderer->logical_target) { if (renderer->logical_presentation_mode != SDL_LOGICAL_PRESENTATION_DISABLED) {
view = &renderer->logical_target->view; view = &renderer->logical_view;
} else { } else {
view = &renderer->main_view; view = &renderer->main_view;
} }
@ -2934,15 +2880,15 @@ bool SDL_ConvertEventToRenderCoordinates(SDL_Renderer *renderer, SDL_Event *even
float scale = renderer->dpi_scale.y; float scale = renderer->dpi_scale.y;
// Convert from pixels within the window to pixels within the view // Convert from pixels within the window to pixels within the view
if (renderer->logical_target) { if (renderer->logical_presentation_mode != SDL_LOGICAL_PRESENTATION_DISABLED) {
const SDL_FRect *src = &renderer->logical_src_rect; const SDL_FRect *src = &renderer->logical_src_rect;
const SDL_FRect *dst = &renderer->logical_dst_rect; const SDL_FRect *dst = &renderer->logical_dst_rect;
scale = (scale * src->h) / dst->h; scale = (scale * src->h) / dst->h;
} }
// Convert from pixels within the view to render coordinates // Convert from pixels within the view to render coordinates
if (renderer->logical_target) { if (renderer->logical_presentation_mode != SDL_LOGICAL_PRESENTATION_DISABLED) {
view = &renderer->logical_target->view; view = &renderer->logical_view;
} else { } else {
view = &renderer->main_view; view = &renderer->main_view;
} }
@ -3043,15 +2989,19 @@ bool SDL_RenderViewportSet(SDL_Renderer *renderer)
static void GetRenderViewportSize(SDL_Renderer *renderer, SDL_FRect *rect) static void GetRenderViewportSize(SDL_Renderer *renderer, SDL_FRect *rect)
{ {
const bool islogical = (renderer->view == &renderer->logical_view);
const float logical_xscale = islogical ? renderer->logical_view.scale.x : 1.0f;
const float logical_yscale = islogical ? renderer->logical_view.scale.y : 1.0f;
rect->x = 0.0f; rect->x = 0.0f;
rect->y = 0.0f; rect->y = 0.0f;
if (renderer->view->viewport.w >= 0) { if (renderer->view->viewport.w >= 0) {
rect->w = (float)renderer->view->viewport.w; rect->w = (float)renderer->view->viewport.w / logical_xscale;
} else { } else {
rect->w = renderer->view->pixel_w / renderer->view->scale.x; rect->w = renderer->view->pixel_w / renderer->view->scale.x;
} }
if (renderer->view->viewport.h >= 0) { if (renderer->view->viewport.h >= 0) {
rect->h = (float)renderer->view->viewport.h; rect->h = (float)renderer->view->viewport.h / logical_yscale;
} else { } else {
rect->h = renderer->view->pixel_h / renderer->view->scale.y; rect->h = renderer->view->pixel_h / renderer->view->scale.y;
} }
@ -3600,9 +3550,8 @@ bool SDL_RenderLines(SDL_Renderer *renderer, const SDL_FPoint *points, int count
} }
#endif #endif
if (renderer->line_method == SDL_RENDERLINEMETHOD_POINTS) { const bool islogical = (renderer->view == &renderer->logical_view);
result = RenderLinesWithRectsF(renderer, points, count); if (islogical || (renderer->line_method == SDL_RENDERLINEMETHOD_GEOMETRY)) {
} else if (renderer->line_method == SDL_RENDERLINEMETHOD_GEOMETRY) {
bool isstack1; bool isstack1;
bool isstack2; bool isstack2;
const float scale_x = renderer->view->scale.x; const float scale_x = renderer->view->scale.x;
@ -3722,6 +3671,8 @@ bool SDL_RenderLines(SDL_Renderer *renderer, const SDL_FPoint *points, int count
SDL_small_free(xy, isstack1); SDL_small_free(xy, isstack1);
SDL_small_free(indices, isstack2); SDL_small_free(indices, isstack2);
} else if (renderer->line_method == SDL_RENDERLINEMETHOD_POINTS) {
result = RenderLinesWithRectsF(renderer, points, count);
} else if (renderer->view->scale.x != 1.0f || renderer->view->scale.y != 1.0f) { } else if (renderer->view->scale.x != 1.0f || renderer->view->scale.y != 1.0f) {
result = RenderLinesWithRectsF(renderer, points, count); result = RenderLinesWithRectsF(renderer, points, count);
} else { } else {
@ -5008,10 +4959,9 @@ bool SDL_RenderPresent(SDL_Renderer *renderer)
CHECK_RENDERER_MAGIC(renderer, false); CHECK_RENDERER_MAGIC(renderer, false);
if (renderer->logical_target) { // !!! FIXME: fail if using a render target? Or just implicitly set the render target to NULL now?
SDL_SetRenderTargetInternal(renderer, NULL);
SDL_RenderLogicalPresentation(renderer); SDL_RenderLogicalPresentation(renderer);
}
if (renderer->transparent_window) { if (renderer->transparent_window) {
SDL_RenderApplyWindowShape(renderer); SDL_RenderApplyWindowShape(renderer);
@ -5029,10 +4979,6 @@ bool SDL_RenderPresent(SDL_Renderer *renderer)
presented = false; presented = false;
} }
if (renderer->logical_target) {
SDL_SetRenderTargetInternal(renderer, renderer->logical_target);
}
if (renderer->simulate_vsync || if (renderer->simulate_vsync ||
(!presented && renderer->wanted_vsync)) { (!presented && renderer->wanted_vsync)) {
SDL_SimulateRenderVSync(renderer); SDL_SimulateRenderVSync(renderer);
@ -5053,22 +4999,12 @@ static bool SDL_DestroyTextureInternal(SDL_Texture *texture, bool is_destroying)
// Renderer get destroyed, avoid to queue more commands // Renderer get destroyed, avoid to queue more commands
} else { } else {
if (texture == renderer->target) { if (texture == renderer->target) {
SDL_SetRenderTargetInternal(renderer, NULL); // implies command queue flush SDL_SetRenderTarget(renderer, NULL); // implies command queue flush
if (texture == renderer->logical_target) {
// Complete any logical presentation
SDL_RenderLogicalPresentation(renderer);
FlushRenderCommands(renderer);
}
} else { } else {
FlushRenderCommandsIfTextureNeeded(texture); FlushRenderCommandsIfTextureNeeded(texture);
} }
} }
if (texture == renderer->logical_target) {
renderer->logical_target = NULL;
}
SDL_SetObjectValid(texture, SDL_OBJECT_TYPE_TEXTURE, false); SDL_SetObjectValid(texture, SDL_OBJECT_TYPE_TEXTURE, false);
if (texture->next) { if (texture->next) {

View File

@ -63,7 +63,6 @@ typedef struct SDL_RenderViewState
SDL_Rect pixel_clip_rect; SDL_Rect pixel_clip_rect;
bool clipping_enabled; bool clipping_enabled;
SDL_FPoint scale; SDL_FPoint scale;
} SDL_RenderViewState; } SDL_RenderViewState;
// Define the SDL texture structure // Define the SDL texture structure
@ -240,11 +239,13 @@ struct SDL_Renderer
Uint64 last_present; Uint64 last_present;
// Support for logical output coordinates // Support for logical output coordinates
SDL_Texture *logical_target;
SDL_RendererLogicalPresentation logical_presentation_mode; SDL_RendererLogicalPresentation logical_presentation_mode;
SDL_ScaleMode logical_scale_mode; SDL_ScaleMode logical_scale_mode;
int logical_w, logical_h;
SDL_FRect logical_src_rect; SDL_FRect logical_src_rect;
SDL_FRect logical_dst_rect; SDL_FRect logical_dst_rect;
float logical_scale_x, logical_scale_y;
SDL_RenderViewState logical_view;
SDL_RenderViewState *view; SDL_RenderViewState *view;
SDL_RenderViewState main_view; SDL_RenderViewState main_view;

View File

@ -81,10 +81,14 @@ static void MoveSprites(SDL_Renderer *renderer, SDL_Texture *sprite)
SDL_FRect *position, *velocity; SDL_FRect *position, *velocity;
/* Query the sizes */ /* Query the sizes */
viewport.x = viewport.y = 0;
viewport.w = 640;
viewport.h = 480;
/*
SDL_SetRenderViewport(renderer, NULL); SDL_SetRenderViewport(renderer, NULL);
SDL_GetRenderSafeArea(renderer, &viewport); SDL_GetRenderSafeArea(renderer, &viewport);
SDL_SetRenderViewport(renderer, &viewport); SDL_SetRenderViewport(renderer, &viewport);
*/
/* Cycle the color and alpha, if desired */ /* Cycle the color and alpha, if desired */
if (cycle_color) { if (cycle_color) {
current_color += cycle_direction; current_color += cycle_direction;
@ -495,6 +499,10 @@ SDL_AppResult SDL_AppInit(void **appstate, int argc, char *argv[])
return SDL_APP_FAILURE; return SDL_APP_FAILURE;
} }
for (i = 0; i < state->num_windows; i++) {
SDL_SetRenderLogicalPresentation(state->renderers[i], 640, 480, SDL_LOGICAL_PRESENTATION_LETTERBOX, SDL_SCALEMODE_NEAREST);
}
/* Create the windows, initialize the renderers, and load the textures */ /* Create the windows, initialize the renderers, and load the textures */
sprites = sprites =
(SDL_Texture **)SDL_malloc(state->num_windows * sizeof(*sprites)); (SDL_Texture **)SDL_malloc(state->num_windows * sizeof(*sprites));

View File

@ -117,11 +117,13 @@ int main(int argc, char *argv[])
goto quit; goto quit;
} }
if (!SDL_CreateWindowAndRenderer("testspriteminimal", WINDOW_WIDTH, WINDOW_HEIGHT, 0, &window, &renderer)) { if (!SDL_CreateWindowAndRenderer("testspriteminimal", WINDOW_WIDTH, WINDOW_HEIGHT, SDL_WINDOW_RESIZABLE, &window, &renderer)) {
return_code = 2; return_code = 2;
goto quit; goto quit;
} }
SDL_SetRenderLogicalPresentation(renderer, WINDOW_WIDTH, WINDOW_HEIGHT, SDL_LOGICAL_PRESENTATION_LETTERBOX, SDL_SCALEMODE_NEAREST);
sprite = CreateTexture(renderer, icon_bmp, icon_bmp_len, &sprite_w, &sprite_h); sprite = CreateTexture(renderer, icon_bmp, icon_bmp_len, &sprite_w, &sprite_h);
if (!sprite) { if (!sprite) {