Create Visual Effects with Gamma
Can I use gamma correction to create special effects like flashing lights or day/night transitions?
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:
Day/Night Cycle
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);
}
};
Lightning Flash Effect
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);
}
}
}
};
Color Temperature Shifts
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.
Brightness and Gamma
Learn how to control display brightness and gamma correction using SDL's window management functions