Yes, DPI scaling works differently with SDL_Renderer
and SDL_Texture
, offering some advantages over surface-based rendering. Let's explore how to implement DPI-aware rendering with these tools.
First, we need to create a renderer that's aware of our DPIÂ settings:
#include <SDL.h>
#include <iostream>
float GetDPIScale(SDL_Window* Window) {/*...*/}
int main() {
SDL_SetHint(
SDL_HINT_WINDOWS_DPI_SCALING, "1");
SDL_Init(SDL_INIT_VIDEO);
SDL_Window* Window{SDL_CreateWindow(
"Renderer DPI Demo",
SDL_WINDOWPOS_UNDEFINED,
SDL_WINDOWPOS_UNDEFINED,
800, 600,
SDL_WINDOW_ALLOW_HIGHDPI
)};
SDL_Renderer* Renderer{SDL_CreateRenderer(
Window,
-1,
SDL_RENDERER_ACCELERATED
)};
// Set logical size to match our design resolution
float Scale{GetDPIScale(Window)};
int DesignWidth{800};
int DesignHeight{600};
SDL_RenderSetLogicalSize(
Renderer,
DesignWidth,
DesignHeight
);
// Main loop
SDL_Event E;
bool Running{true};
while (Running) {
while (SDL_PollEvent(&E)) {
if (E.type == SDL_QUIT) Running = false;
}
// Clear and render
SDL_SetRenderDrawColor(
Renderer, 50, 50, 50, 255);
SDL_RenderClear(Renderer);
// Draw a rectangle that will maintain its physical size
SDL_SetRenderDrawColor(
Renderer, 150, 50, 50, 255);
SDL_Rect Rect{100, 100, 200, 100};
SDL_RenderFillRect(Renderer, &Rect);
SDL_RenderPresent(Renderer);
}
SDL_DestroyRenderer(Renderer);
SDL_DestroyWindow(Window);
SDL_Quit();
return 0;
}
Using SDL_Renderer
provides several advantages:
Textures also benefit from the renderer's DPIÂ handling:
SDL_Texture* CreateTexture(
SDL_Renderer* Renderer,
int Width,
int Height
) {
return SDL_CreateTexture(
Renderer,
SDL_PIXELFORMAT_RGBA8888,
SDL_TEXTUREACCESS_TARGET,
Width, Height
);
}
void RenderWithTexture(
SDL_Renderer* Renderer) {
// Create a texture at our design resolution
SDL_Texture* Target{CreateTexture(
Renderer, 800, 600)};
// Set it as the render target
SDL_SetRenderTarget(Renderer, Target);
// Render to texture...
SDL_SetRenderDrawColor(Renderer,
150, 50, 50, 255);
SDL_Rect Rect{100, 100, 200, 100};
SDL_RenderFillRect(Renderer, &Rect);
// Reset target and render the texture
SDL_SetRenderTarget(Renderer, nullptr);
SDL_RenderCopy(Renderer, Target, nullptr, nullptr);
}
The renderer's logical size setting automatically handles DPI scaling for all rendering operations, including texture rendering. This makes it easier to maintain consistent sizing across different display configurations.
Answers to questions are automatically generated and may not have been reviewed.
Learn how to create SDL applications that look great on modern displays across different platforms