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
Comprehensive course covering advanced concepts, and how to use them on large-scale projects.
View Course