The decision to provide multiple image versions depends on your specific needs. Let's explore the options and their implications:
The simplest approach is to provide a single high-resolution image and scale it down when needed:
#include <SDL.h>
#include <SDL_image.h>
#include <iostream>
float GetDPIScale(SDL_Window* Window) {/*...*/}
class Sprite {
SDL_Surface* Image;
int BaseWidth;
int BaseHeight;
public:
Sprite(const char* Path) {
Image = IMG_Load(Path);
BaseWidth = Image->w;
BaseHeight = Image->h;
}
void Draw(SDL_Surface* Target,
int x, int y, float Scale
) {
SDL_Rect Dest{
x,
y,
int(BaseWidth * Scale),
int(BaseHeight * Scale)
};
SDL_BlitScaled(Image, nullptr, Target, &Dest);
}
~Sprite() {
SDL_FreeSurface(Image);
}
};
This approach is simple but has drawbacks:
For better quality, you can provide multiple resolutions:
class MultiResSprite {
std::vector<SDL_Surface*> Images;
std::vector<float> Scales{
1.0f, 1.5f, 2.0f, 4.0f};
int BaseWidth;
int BaseHeight;
public:
MultiResSprite(
const std::vector<const char*>& Paths) {
for (auto Path : Paths) {
Images.push_back(IMG_Load(Path));
}
BaseWidth = Images[0]->w;
BaseHeight = Images[0]->h;
}
void Draw(
SDL_Surface* Target,
int x, int y, float Scale
) {
// Find best matching image
size_t Best{0};
float BestDiff{std::abs(Scales[0] - Scale)};
for (size_t i = 1; i < Scales.size(); ++i) {
float Diff{std::abs(Scales[i] - Scale)};
if (Diff < BestDiff) {
Best = i;
BestDiff = Diff;
}
}
SDL_Rect Dest{
x, y,
int(BaseWidth * Scale),
int(BaseHeight * Scale)
};
SDL_BlitScaled(
Images[Best], nullptr, Target, &Dest);
}
~MultiResSprite() {
for (auto Image : Images) {
SDL_FreeSurface(Image);
}
}
};
The best approach depends on your game:
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