Gamma correction can create impressive visual effects, but we need to handle it carefully to avoid jarring changes. Here's how to implement some common effects:
A basic day/night cycle might look something like this:
#include <SDL.h>
#include <cmath>
class DayNightCycle {
SDL_Window* Window;
float TimeOfDay{0.0f}; // 0.0 to 24.0
public:
DayNightCycle(SDL_Window* W) : Window{W} {}
void Update(float DeltaTimeSeconds) {
// Progress time (1 game hour per
// real second)
TimeOfDay += DeltaTimeSeconds;
if (TimeOfDay >= 24.0f) TimeOfDay -= 24.0f;
// Calculate brightness based on time
float Brightness{CalculateBrightness()};
SDL_SetWindowBrightness(Window, Brightness);
}
private:
float CalculateBrightness() {
// Brightest at noon (12.0), darkest at
// midnight (0.0/24.0)
float NormalizedTime{
std::abs(TimeOfDay - 12.0f) / 12.0f};
// Smooth transition using cosine
return 1.0f + 0.5f * std::cos(
NormalizedTime * 3.14159f);
}
};
Below, we create a quick lighting flash effect using gamma correction:
#include <SDL.h>
class LightningEffect {
SDL_Window* Window;
float DefaultBrightness{1.0f};
bool IsFlashing{false};
Uint32 FlashStartTime{0};
public:
LightningEffect(SDL_Window* W) : Window{W} {}
void TriggerLightning() {
if (!IsFlashing) {
IsFlashing = true;
FlashStartTime = SDL_GetTicks();
// Bright flash
SDL_SetWindowBrightness(Window, 2.0f);
}
}
void Update() {
if (IsFlashing) {
Uint32 ElapsedTime{
SDL_GetTicks() - FlashStartTime};
// Flash duration in ms
if (ElapsedTime > 100) {
IsFlashing = false;
SDL_SetWindowBrightness(
Window, DefaultBrightness);
}
}
}
};
In this program, we adjust the color temperature of our output using gamma curves:
#include <SDL.h>
class ColorTemperature {
SDL_Window* Window;
public:
ColorTemperature(SDL_Window* W) : Window{W} {}
void SetTemperature(float Temperature) {
// Temperature range: 0.0 (cool) to 1.0 (warm)
Uint16 RedRamp[256];
Uint16 BlueRamp[256];
// Warmer colors emphasize red, reduce blue
// More red when warm
float RedGamma{2.0f - Temperature};
// Less blue when warm
float BlueGamma{1.0f + Temperature};
SDL_CalculateGammaRamp(RedGamma, RedRamp);
SDL_CalculateGammaRamp(BlueGamma, BlueRamp);
// Green stays neutral
Uint16 GreenRamp[256];
SDL_CalculateGammaRamp(1.0f, GreenRamp);
SDL_SetWindowGammaRamp(
Window, RedRamp, GreenRamp, BlueRamp);
}
};
Remember to restore default settings when your effects end, and consider platform limitations discussed in the lesson. For critical gameplay elements, consider using rendering-based effects instead of gamma correction.
Answers to questions are automatically generated and may not have been reviewed.
Learn how to control display brightness and gamma correction using SDL's window management functions