Brightness and Gamma

Creating a Gamma Curve Visualisation

How can I draw a chart to visualise an SDL gamma ramp?

Abstract art representing computer programming

This program creates a visual representation of a gamma ramp with a gamma value of 2.0. Here are the key components:

Part 1: We create a 256x256 pixel window - wide enough to show all 256 possible input values, and tall enough to show the complete output range.

Part 2: For each x-coordinate from 0 to 255:

  • We get the corresponding gamma ramp value and convert it from the SDL range (0-65535) to our visualization range (0-255)
  • We draw a white vertical line up to that height
  • The background is drawn in dark blue to make the curve stand out
  • A gray reference line is drawn to show what a gamma value of 1.0 would look like

Part 3: We write directly to the window's surface pixels for performance and to avoid dependencies on SDL's renderer.

Part 4: We keep the window open until the user closes it, so they can study the curve.

#include <SDL.h>
#include <iostream>

int main(int argc, char* argv[]) {
  SDL_Init(SDL_INIT_VIDEO);

  SDL_Window* Window{
    SDL_CreateWindow("Gamma Ramp Visualizer",
                     SDL_WINDOWPOS_UNDEFINED,
                     SDL_WINDOWPOS_UNDEFINED,
                     256, 256,
                     SDL_WINDOW_SHOWN)};

  SDL_Surface* WindowSurface{
    SDL_GetWindowSurface(Window)};

  // Create our gamma ramp with gamma = 2.0
  Uint16 Ramp[256];
  SDL_CalculateGammaRamp(2, Ramp);

  // Lock surface for pixel access
  SDL_LockSurface(WindowSurface);

  // Get pixel format information
  const auto Format{WindowSurface->format};
  Uint32* Pixels{
    static_cast<Uint32*>(WindowSurface->
      pixels)};

  // Draw the gamma ramp visualization
  for (int x{0}; x < 256; ++x) {
    // Convert gamma ramp value (0-65535) to
    // height (0-255)
    int Height{
      static_cast<int>((Ramp[x] * 255) /
        65535)};

    // Draw vertical line
    for (int y{0}; y < 256; ++y) {
      Uint32 Color;

      if (255 - y <= Height) {
        // Part of the curve - white pixel
        Color = SDL_MapRGB(
          Format, 255, 255, 255);
      } else {
        // Background - dark blue
        Color = SDL_MapRGB(Format, 0, 0, 40);
      }

      // Draw pixel at (x,y)
      Pixels[y * WindowSurface->w + x] = Color;
    }

    // Draw reference line in gray
    if (255 - x >= 0) {
      Pixels[(255 - x) * WindowSurface->w + x] =
        SDL_MapRGB(Format, 128, 128, 128);
    }
  }

  SDL_UnlockSurface(WindowSurface);
  SDL_UpdateWindowSurface(Window);

  // Wait for window close
  SDL_Event Event;
  bool Running{true};
  while (Running) {
    while (SDL_PollEvent(&Event)) {
      if (Event.type == SDL_QUIT) {
        Running = false;
      }
    }
  }

  SDL_DestroyWindow(Window);
  SDL_Quit();
  return 0;
}

The resulting visualization shows how a gamma value of 2.0 affects brightness - the curve drops more steeply at first compared to the reference line, meaning darker input values become even darker in the output.

Try modifying the gamma value passed to SDL_CalculateGammaRamp() to see how different gamma values affect the curve:

  • Values less than 1.0 will curve above the reference line, brightening the image
  • Values greater than 1.0 will curve below the reference line, darkening the image
  • A value of exactly 1.0 will match the reference line perfectly

Answers to questions are automatically generated and may not have been reviewed.

sdl2-promo.jpg
Part of the course:

Game Dev with SDL2

Learn C++ and SDL development by creating hands on, practical projects inspired by classic retro games

Free, unlimited access

This course includes:

  • 71 Lessons
  • 100+ Code Samples
  • 91% Positive Reviews
  • Regularly Updated
  • Help and FAQ
Free, Unlimited Access

Professional C++

Comprehensive course covering advanced concepts, and how to use them on large-scale projects.

Screenshot from Warhammer: Total War
Screenshot from Tomb Raider
Screenshot from Jedi: Fallen Order
Contact|Privacy Policy|Terms of Use
Copyright © 2024 - All Rights Reserved