45 {
47 if (loaded_surface == nullptr) {
49 }
50
51 SDL_Surface *
surface = SDL_ConvertSurface(loaded_surface, SDL_PIXELFORMAT_RGBA32);
52 SDL_DestroySurface(loaded_surface);
55 }
56
57 const SDL_PixelFormatDetails *format_details = SDL_GetPixelFormatDetails(surface->format);
58 if (format_details == nullptr) {
59 SDL_DestroySurface(surface);
60 throw mxvk::Exception("Failed to query pixel format details for: " + path);
61 }
62
63 if (!SDL_LockSurface(surface)) {
64 SDL_DestroySurface(surface);
65 throw mxvk::Exception("Failed to lock PNG surface: " + path);
66 }
67
68 auto *pixels = static_cast<std::uint32_t *>(surface->pixels);
69 const int pixel_count = surface->w * surface->h;
70 for (int i = 0; i < pixel_count; ++i) {
71 std::uint8_t r = 0;
72 std::uint8_t g = 0;
73 std::uint8_t b = 0;
74 std::uint8_t a = 0;
75 SDL_GetRGBA(pixels[i], format_details, nullptr, &r, &g, &b, &a);
76
77 const int brightness = std::max({static_cast<int>(r), static_cast<int>(g), static_cast<int>(b)});
78 if (brightness <= threshold) {
79 a = 0;
80 } else if (brightness < static_cast<int>(threshold) + static_cast<int>(softness)) {
81 const float fade = static_cast<float>(brightness - threshold) / static_cast<float>(std::max<int>(1, softness));
82 a = static_cast<std::uint8_t>(std::clamp(static_cast<int>(std::lround(static_cast<float>(a) * fade)), 0, 255));
83 }
84
85 pixels[i] = SDL_MapRGBA(format_details, nullptr, r, g, b, a);
86 }
87
88 SDL_UnlockSurface(surface);
89 return surface;
90 }
SDL_Surface * LoadPNG(const char *file)
Load a PNG file into an SDL_Surface.