mirror of
https://github.com/love2d/love.git
synced 2026-08-19 20:19:42 +02:00
Fixed per-vertex colors (e.g. spritebatch colors) improperly applying gamma correction when the default shader is used and gamma correction is requested but not supported on OpenGL ES.
This commit is contained in:
@@ -317,18 +317,20 @@ bool Graphics::setMode(int width, int height)
|
|||||||
pixelSizeStack.reserve(5);
|
pixelSizeStack.reserve(5);
|
||||||
pixelSizeStack.push_back(1);
|
pixelSizeStack.push_back(1);
|
||||||
|
|
||||||
|
int gammacorrect = isGammaCorrect() ? 1 : 0;
|
||||||
|
|
||||||
// We always need a default shader.
|
// We always need a default shader.
|
||||||
if (!Shader::defaultShader)
|
if (!Shader::defaultShader)
|
||||||
{
|
{
|
||||||
Renderer renderer = GLAD_ES_VERSION_2_0 ? RENDERER_OPENGLES : RENDERER_OPENGL;
|
Renderer renderer = GLAD_ES_VERSION_2_0 ? RENDERER_OPENGLES : RENDERER_OPENGL;
|
||||||
Shader::defaultShader = newShader(Shader::defaultCode[renderer]);
|
Shader::defaultShader = newShader(Shader::defaultCode[renderer][gammacorrect]);
|
||||||
}
|
}
|
||||||
|
|
||||||
// and a default video shader.
|
// and a default video shader.
|
||||||
if (!Shader::defaultVideoShader)
|
if (!Shader::defaultVideoShader)
|
||||||
{
|
{
|
||||||
Renderer renderer = GLAD_ES_VERSION_2_0 ? RENDERER_OPENGLES : RENDERER_OPENGL;
|
Renderer renderer = GLAD_ES_VERSION_2_0 ? RENDERER_OPENGLES : RENDERER_OPENGL;
|
||||||
Shader::defaultVideoShader = newShader(Shader::defaultVideoCode[renderer]);
|
Shader::defaultVideoShader = newShader(Shader::defaultVideoCode[renderer][gammacorrect]);
|
||||||
}
|
}
|
||||||
|
|
||||||
// A shader should always be active, but the default shader shouldn't be
|
// A shader should always be active, but the default shader shouldn't be
|
||||||
|
|||||||
@@ -66,8 +66,8 @@ Shader *Shader::current = nullptr;
|
|||||||
Shader *Shader::defaultShader = nullptr;
|
Shader *Shader::defaultShader = nullptr;
|
||||||
Shader *Shader::defaultVideoShader = nullptr;
|
Shader *Shader::defaultVideoShader = nullptr;
|
||||||
|
|
||||||
Shader::ShaderSource Shader::defaultCode[Graphics::RENDERER_MAX_ENUM];
|
Shader::ShaderSource Shader::defaultCode[Graphics::RENDERER_MAX_ENUM][2];
|
||||||
Shader::ShaderSource Shader::defaultVideoCode[Graphics::RENDERER_MAX_ENUM];
|
Shader::ShaderSource Shader::defaultVideoCode[Graphics::RENDERER_MAX_ENUM][2];
|
||||||
|
|
||||||
std::vector<int> Shader::textureCounters;
|
std::vector<int> Shader::textureCounters;
|
||||||
|
|
||||||
@@ -250,9 +250,10 @@ bool Shader::loadVolatile()
|
|||||||
|
|
||||||
std::vector<GLuint> shaderids;
|
std::vector<GLuint> shaderids;
|
||||||
|
|
||||||
const ShaderSource *defaults = &defaultCode[Graphics::RENDERER_OPENGL];
|
bool gammacorrect = graphics::isGammaCorrect();
|
||||||
|
const ShaderSource *defaults = &defaultCode[Graphics::RENDERER_OPENGL][gammacorrect ? 1 : 0];
|
||||||
if (GLAD_ES_VERSION_2_0)
|
if (GLAD_ES_VERSION_2_0)
|
||||||
defaults = &defaultCode[Graphics::RENDERER_OPENGLES];
|
defaults = &defaultCode[Graphics::RENDERER_OPENGLES][gammacorrect ? 1 : 0];
|
||||||
|
|
||||||
// The shader program must have both vertex and pixel shader stages.
|
// The shader program must have both vertex and pixel shader stages.
|
||||||
const std::string &vertexcode = shaderSource.vertex.empty() ? defaults->vertex : shaderSource.vertex;
|
const std::string &vertexcode = shaderSource.vertex.empty() ? defaults->vertex : shaderSource.vertex;
|
||||||
|
|||||||
@@ -95,8 +95,8 @@ public:
|
|||||||
static Shader *defaultVideoShader;
|
static Shader *defaultVideoShader;
|
||||||
|
|
||||||
// Default shader code (a shader is always required internally.)
|
// Default shader code (a shader is always required internally.)
|
||||||
static ShaderSource defaultCode[Graphics::RENDERER_MAX_ENUM];
|
static ShaderSource defaultCode[Graphics::RENDERER_MAX_ENUM][2];
|
||||||
static ShaderSource defaultVideoCode[Graphics::RENDERER_MAX_ENUM];
|
static ShaderSource defaultVideoCode[Graphics::RENDERER_MAX_ENUM][2];
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Creates a new Shader using a list of source codes.
|
* Creates a new Shader using a list of source codes.
|
||||||
|
|||||||
@@ -1346,41 +1346,36 @@ int w_getShader(lua_State *L)
|
|||||||
int w_setDefaultShaderCode(lua_State *L)
|
int w_setDefaultShaderCode(lua_State *L)
|
||||||
{
|
{
|
||||||
luaL_checktype(L, 1, LUA_TTABLE);
|
luaL_checktype(L, 1, LUA_TTABLE);
|
||||||
|
luaL_checktype(L, 2, LUA_TTABLE);
|
||||||
|
|
||||||
lua_getfield(L, 1, "opengl");
|
for (int i = 0; i < 2; i++)
|
||||||
lua_rawgeti(L, -1, 1);
|
{
|
||||||
lua_rawgeti(L, -2, 2);
|
bool gammacorrect = i > 0;
|
||||||
lua_rawgeti(L, -3, 3);
|
|
||||||
|
|
||||||
Shader::ShaderSource openglcode;
|
for (int renderer = 0; renderer < Graphics::RENDERER_MAX_ENUM; renderer++)
|
||||||
openglcode.vertex = luax_checkstring(L, -3);
|
{
|
||||||
openglcode.pixel = luax_checkstring(L, -2);
|
const char *lang = renderer == Graphics::RENDERER_OPENGLES ? "glsles" : "glsl";
|
||||||
|
|
||||||
Shader::ShaderSource openglVideocode;
|
lua_getfield(L, i + 1, lang);
|
||||||
openglVideocode.vertex = luax_checkstring(L, -3);
|
|
||||||
openglVideocode.pixel = luax_checkstring(L, -1);
|
|
||||||
|
|
||||||
lua_pop(L, 4);
|
lua_getfield(L, -1, "vertex");
|
||||||
|
lua_getfield(L, -2, "pixel");
|
||||||
|
lua_getfield(L, -3, "videopixel");
|
||||||
|
|
||||||
lua_getfield(L, 1, "opengles");
|
Shader::ShaderSource code;
|
||||||
lua_rawgeti(L, -1, 1);
|
code.vertex = luax_checkstring(L, -3);
|
||||||
lua_rawgeti(L, -2, 2);
|
code.pixel = luax_checkstring(L, -2);
|
||||||
lua_rawgeti(L, -3, 3);
|
|
||||||
|
|
||||||
Shader::ShaderSource openglescode;
|
Shader::ShaderSource videocode;
|
||||||
openglescode.vertex = luax_checkstring(L, -3);
|
videocode.vertex = luax_checkstring(L, -3);
|
||||||
openglescode.pixel = luax_checkstring(L, -2);
|
videocode.pixel = luax_checkstring(L, -1);
|
||||||
|
|
||||||
Shader::ShaderSource openglesVideocode;
|
lua_pop(L, 4);
|
||||||
openglesVideocode.vertex = luax_checkstring(L, -3);
|
|
||||||
openglesVideocode.pixel = luax_checkstring(L, -1);
|
|
||||||
|
|
||||||
lua_pop(L, 4);
|
Shader::defaultCode[renderer][i] = code;
|
||||||
|
Shader::defaultVideoCode[renderer][i] = videocode;
|
||||||
Shader::defaultCode[Graphics::RENDERER_OPENGL] = openglcode;
|
}
|
||||||
Shader::defaultCode[Graphics::RENDERER_OPENGLES] = openglescode;
|
}
|
||||||
Shader::defaultVideoCode[Graphics::RENDERER_OPENGL] = openglVideocode;
|
|
||||||
Shader::defaultVideoCode[Graphics::RENDERER_OPENGLES] = openglesVideocode;
|
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -23,6 +23,7 @@ misrepresented as being the original software.
|
|||||||
--]]
|
--]]
|
||||||
|
|
||||||
local table_concat = table.concat
|
local table_concat = table.concat
|
||||||
|
local ipairs = ipairs
|
||||||
|
|
||||||
-- SHADERS
|
-- SHADERS
|
||||||
|
|
||||||
@@ -139,6 +140,8 @@ varying vec4 VaryingColor;
|
|||||||
uniform mediump float love_PointSize;
|
uniform mediump float love_PointSize;
|
||||||
#endif]],
|
#endif]],
|
||||||
|
|
||||||
|
FUNCTIONS = "",
|
||||||
|
|
||||||
FOOTER = [[
|
FOOTER = [[
|
||||||
void main() {
|
void main() {
|
||||||
VaryingTexCoord = VertexTexCoord;
|
VaryingTexCoord = VertexTexCoord;
|
||||||
@@ -210,33 +213,21 @@ void main() {
|
|||||||
}]],
|
}]],
|
||||||
}
|
}
|
||||||
|
|
||||||
local function createVertexCode(vertexcode, lang)
|
local function createShaderStageCode(stage, code, lang, gammacorrect, multicanvas)
|
||||||
local vertexcodes = {
|
stage = stage:upper()
|
||||||
|
local lines = {
|
||||||
lang == "glsles" and GLSL.VERSION_ES or GLSL.VERSION,
|
lang == "glsles" and GLSL.VERSION_ES or GLSL.VERSION,
|
||||||
GLSL.SYNTAX,
|
GLSL.SYNTAX,
|
||||||
love.graphics.isGammaCorrect() and "#define LOVE_GAMMA_CORRECT 1" or "",
|
gammacorrect and "#define LOVE_GAMMA_CORRECT 1" or "",
|
||||||
GLSL.VERTEX.HEADER, GLSL.UNIFORMS,
|
GLSL[stage].HEADER,
|
||||||
|
GLSL.UNIFORMS,
|
||||||
GLSL.FUNCTIONS,
|
GLSL.FUNCTIONS,
|
||||||
|
GLSL[stage].FUNCTIONS,
|
||||||
lang == "glsles" and "#line 1" or "#line 0",
|
lang == "glsles" and "#line 1" or "#line 0",
|
||||||
vertexcode,
|
code,
|
||||||
GLSL.VERTEX.FOOTER,
|
multicanvas and GLSL[stage].FOOTER_MULTI_CANVAS or GLSL[stage].FOOTER,
|
||||||
}
|
}
|
||||||
return table_concat(vertexcodes, "\n")
|
return table_concat(lines, "\n")
|
||||||
end
|
|
||||||
|
|
||||||
local function createPixelCode(pixelcode, is_multicanvas, lang)
|
|
||||||
local pixelcodes = {
|
|
||||||
lang == "glsles" and GLSL.VERSION_ES or GLSL.VERSION,
|
|
||||||
GLSL.SYNTAX,
|
|
||||||
love.graphics.isGammaCorrect() and "#define LOVE_GAMMA_CORRECT 1" or "",
|
|
||||||
GLSL.PIXEL.HEADER, GLSL.UNIFORMS,
|
|
||||||
GLSL.FUNCTIONS,
|
|
||||||
GLSL.PIXEL.FUNCTIONS,
|
|
||||||
lang == "glsles" and "#line 1" or "#line 0",
|
|
||||||
pixelcode,
|
|
||||||
is_multicanvas and GLSL.PIXEL.FOOTER_MULTI_CANVAS or GLSL.PIXEL.FOOTER,
|
|
||||||
}
|
|
||||||
return table_concat(pixelcodes, "\n")
|
|
||||||
end
|
end
|
||||||
|
|
||||||
local function isVertexCode(code)
|
local function isVertexCode(code)
|
||||||
@@ -258,11 +249,6 @@ function love.graphics._shaderCodeToGLSL(arg1, arg2)
|
|||||||
local vertexcode, pixelcode
|
local vertexcode, pixelcode
|
||||||
local is_multicanvas = false -- whether pixel code has "effects" function instead of "effect"
|
local is_multicanvas = false -- whether pixel code has "effects" function instead of "effect"
|
||||||
|
|
||||||
local lang = "glsl"
|
|
||||||
if (love.graphics.getRendererInfo()) == "OpenGL ES" then
|
|
||||||
lang = "glsles"
|
|
||||||
end
|
|
||||||
|
|
||||||
if arg1 then
|
if arg1 then
|
||||||
if isVertexCode(arg1) then
|
if isVertexCode(arg1) then
|
||||||
vertexcode = arg1 -- first arg contains vertex shader code
|
vertexcode = arg1 -- first arg contains vertex shader code
|
||||||
@@ -287,11 +273,18 @@ function love.graphics._shaderCodeToGLSL(arg1, arg2)
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
local lang = "glsl"
|
||||||
|
if love.graphics.getRendererInfo() == "OpenGL ES" then
|
||||||
|
lang = "glsles"
|
||||||
|
end
|
||||||
|
|
||||||
|
local gammacorrect = love.graphics.isGammaCorrect()
|
||||||
|
|
||||||
if vertexcode then
|
if vertexcode then
|
||||||
vertexcode = createVertexCode(vertexcode, lang)
|
vertexcode = createShaderStageCode("VERTEX", vertexcode, lang, gammacorrect)
|
||||||
end
|
end
|
||||||
if pixelcode then
|
if pixelcode then
|
||||||
pixelcode = createPixelCode(pixelcode, is_multicanvas, lang)
|
pixelcode = createShaderStageCode("PIXEL", pixelcode, lang, gammacorrect, is_multicanvas)
|
||||||
end
|
end
|
||||||
|
|
||||||
return vertexcode, pixelcode
|
return vertexcode, pixelcode
|
||||||
@@ -339,20 +332,21 @@ vec4 effect(mediump vec4 vcolor, Image tex, vec2 texcoord, vec2 pixcoord) {
|
|||||||
}]],
|
}]],
|
||||||
}
|
}
|
||||||
|
|
||||||
local defaults = {
|
local defaults = {}
|
||||||
opengl = {
|
local defaults_gammacorrect = {}
|
||||||
createVertexCode(defaultcode.vertex, "glsl"),
|
|
||||||
createPixelCode(defaultcode.pixel, false, "glsl"),
|
|
||||||
createPixelCode(defaultcode.videopixel, false, "glsl"),
|
|
||||||
},
|
|
||||||
opengles = {
|
|
||||||
createVertexCode(defaultcode.vertex, "glsles"),
|
|
||||||
createPixelCode(defaultcode.pixel, false, "glsles"),
|
|
||||||
createPixelCode(defaultcode.videopixel, false, "glsles"),
|
|
||||||
},
|
|
||||||
}
|
|
||||||
|
|
||||||
love.graphics._setDefaultShaderCode(defaults)
|
for _, lang in ipairs{"glsl", "glsles"} do
|
||||||
|
for _, gammacorrect in ipairs{false, true} do
|
||||||
|
local t = gammacorrect and defaults_gammacorrect or defaults
|
||||||
|
t[lang] = {
|
||||||
|
vertex = createShaderStageCode("VERTEX", defaultcode.vertex, lang, gammacorrect),
|
||||||
|
pixel = createShaderStageCode("PIXEL", defaultcode.pixel, lang, gammacorrect, false),
|
||||||
|
videopixel = createShaderStageCode("PIXEL", defaultcode.videopixel, lang, gammacorrect, false),
|
||||||
|
}
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
love.graphics._setDefaultShaderCode(defaults, defaults_gammacorrect)
|
||||||
|
|
||||||
function love.graphics.newVideo(file, loadaudio)
|
function love.graphics.newVideo(file, loadaudio)
|
||||||
local video = love.graphics._newVideo(file)
|
local video = love.graphics._newVideo(file)
|
||||||
|
|||||||
Reference in New Issue
Block a user