mirror of
https://github.com/love2d/love.git
synced 2026-08-15 15:51:12 +02:00
Added sRGB (gamma-correct) support for Images, Canvases, and the main screen.
love.graphics.newImage(path, “srgb”) creates a new Image whose texels are treated as being in the sRGB color space, so they are linearized when drawing/sampling from the image. love.graphics.newCanvas(w, h, “srgb”) creates a new Canvas whose texels are treated as being in the sRGB color space, so drawing to the Canvas does a linear->sRGB conversion (but blends linearly), and sampling from it (drawing it or using it in a shader) converts from sRGB to linear space. The "srgb" window flag does the same as Canvases for the main screen.
This commit is contained in:
@@ -50,6 +50,7 @@ WindowSettings::WindowSettings()
|
||||
, centered(true)
|
||||
, display(0)
|
||||
, highdpi(false)
|
||||
, sRGB(false)
|
||||
{
|
||||
}
|
||||
|
||||
@@ -86,6 +87,7 @@ StringMap<Window::Setting, Window::SETTING_MAX_ENUM>::Entry Window::settingEntri
|
||||
{"centered", SETTING_CENTERED},
|
||||
{"display", SETTING_DISPLAY},
|
||||
{"highdpi", SETTING_HIGHDPI},
|
||||
{"srgb", SETTING_SRGB},
|
||||
};
|
||||
|
||||
StringMap<Window::Setting, Window::SETTING_MAX_ENUM> Window::settings(Window::settingEntries, sizeof(Window::settingEntries));
|
||||
|
||||
@@ -57,6 +57,7 @@ public:
|
||||
SETTING_CENTERED,
|
||||
SETTING_DISPLAY,
|
||||
SETTING_HIGHDPI,
|
||||
SETTING_SRGB,
|
||||
SETTING_MAX_ENUM
|
||||
};
|
||||
|
||||
@@ -157,6 +158,7 @@ struct WindowSettings
|
||||
bool centered; // = true
|
||||
int display; // = 0
|
||||
bool highdpi; // false
|
||||
bool sRGB; // false
|
||||
|
||||
}; // WindowSettings
|
||||
|
||||
|
||||
@@ -154,7 +154,7 @@ bool Window::setWindow(int width, int height, WindowSettings *settings)
|
||||
if (!window)
|
||||
{
|
||||
// In Windows and Linux, some GL attributes are set on window creation.
|
||||
setWindowGLAttributes(f.fsaa);
|
||||
setWindowGLAttributes(f.fsaa, f.sRGB);
|
||||
|
||||
const char *title = windowTitle.c_str();
|
||||
int pos = f.centered ? centeredpos : uncenteredpos;
|
||||
@@ -190,7 +190,7 @@ bool Window::setWindow(int width, int height, WindowSettings *settings)
|
||||
|
||||
SDL_RaiseWindow(window);
|
||||
|
||||
if (!setContext(f.fsaa, f.vsync))
|
||||
if (!setContext(f.fsaa, f.vsync, f.sRGB))
|
||||
return false;
|
||||
|
||||
created = true;
|
||||
@@ -206,7 +206,7 @@ bool Window::setWindow(int width, int height, WindowSettings *settings)
|
||||
SDL_GL_GetDrawableSize(window, &width, &height);
|
||||
#endif
|
||||
|
||||
gfx->setMode(width, height);
|
||||
gfx->setMode(width, height, curMode.settings.sRGB);
|
||||
}
|
||||
|
||||
// Make sure the mouse keeps its previous grab setting.
|
||||
@@ -226,7 +226,7 @@ bool Window::onWindowResize(int width, int height)
|
||||
return true;
|
||||
}
|
||||
|
||||
bool Window::setContext(int fsaa, bool vsync)
|
||||
bool Window::setContext(int fsaa, bool vsync, bool sRGB)
|
||||
{
|
||||
// We would normally only need to recreate the context if FSAA changes or
|
||||
// SDL_GL_MakeCurrent is unsuccessful, but in Windows MakeCurrent can
|
||||
@@ -238,7 +238,7 @@ bool Window::setContext(int fsaa, bool vsync)
|
||||
}
|
||||
|
||||
// Make sure the proper attributes are set.
|
||||
setWindowGLAttributes(fsaa);
|
||||
setWindowGLAttributes(fsaa, sRGB);
|
||||
|
||||
context = SDL_GL_CreateContext(window);
|
||||
|
||||
@@ -290,7 +290,7 @@ bool Window::setContext(int fsaa, bool vsync)
|
||||
return true;
|
||||
}
|
||||
|
||||
void Window::setWindowGLAttributes(int fsaa) const
|
||||
void Window::setWindowGLAttributes(int fsaa, bool sRGB) const
|
||||
{
|
||||
// Set GL window attributes.
|
||||
SDL_GL_SetAttribute(SDL_GL_RED_SIZE, 8);
|
||||
@@ -304,6 +304,10 @@ void Window::setWindowGLAttributes(int fsaa) const
|
||||
SDL_GL_SetAttribute(SDL_GL_MULTISAMPLEBUFFERS, (fsaa > 0) ? 1 : 0);
|
||||
SDL_GL_SetAttribute(SDL_GL_MULTISAMPLESAMPLES, (fsaa > 0) ? fsaa : 0);
|
||||
|
||||
#if SDL_VERSION_ATLEAST(2,0,1)
|
||||
SDL_GL_SetAttribute(SDL_GL_FRAMEBUFFER_SRGB_CAPABLE, sRGB ? 1 : 0);
|
||||
#endif
|
||||
|
||||
// Do we want a debug context?
|
||||
const char *debugenv = SDL_GetHint("LOVE_GRAPHICS_DEBUG");
|
||||
if (debugenv && *debugenv == '1')
|
||||
@@ -370,6 +374,8 @@ void Window::updateSettings(const WindowSettings &newsettings)
|
||||
else
|
||||
#endif
|
||||
SDL_SetHint(SDL_HINT_VIDEO_MINIMIZE_ON_FOCUS_LOSS, "0");
|
||||
|
||||
curMode.settings.sRGB = newsettings.sRGB;
|
||||
}
|
||||
|
||||
void Window::getWindow(int &width, int &height, WindowSettings &settings)
|
||||
|
||||
@@ -90,8 +90,8 @@ public:
|
||||
|
||||
private:
|
||||
|
||||
bool setContext(int fsaa, bool vsync);
|
||||
void setWindowGLAttributes(int fsaa) const;
|
||||
bool setContext(int fsaa, bool vsync, bool sRGB);
|
||||
void setWindowGLAttributes(int fsaa, bool sRGB) const;
|
||||
|
||||
// Update the saved window settings based on the window's actual state.
|
||||
void updateSettings(const WindowSettings &newsettings);
|
||||
|
||||
@@ -96,6 +96,7 @@ int w_setMode(lua_State *L)
|
||||
settings.centered = luax_boolflag(L, 3, settingName(Window::SETTING_CENTERED), true);
|
||||
settings.display = luax_intflag(L, 3, settingName(Window::SETTING_DISPLAY), 1);
|
||||
settings.highdpi = luax_boolflag(L, 3, settingName(Window::SETTING_HIGHDPI), false);
|
||||
settings.sRGB = luax_boolflag(L, 3, settingName(Window::SETTING_SRGB), false);
|
||||
|
||||
// Display index is 1-based in Lua and 0-based internally.
|
||||
settings.display--;
|
||||
@@ -151,6 +152,9 @@ int w_getMode(lua_State *L)
|
||||
luax_pushboolean(L, settings.highdpi);
|
||||
lua_setfield(L, -2, settingName(Window::SETTING_HIGHDPI));
|
||||
|
||||
luax_pushboolean(L, settings.sRGB);
|
||||
lua_setfield(L, -2, settingName(Window::SETTING_SRGB));
|
||||
|
||||
return 3;
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user