mirror of
https://github.com/love2d/love.git
synced 2026-08-19 20:19:42 +02:00
Removed void effects(…) pixel shader prototype. Added void effect(). Allows calling love.graphics.draw with textures of different types with a custom shader without having an extra sampler2D.
effect() takes no arguments and returns nothing, you are responsible for assigning a value to either love_PixelColor or love_Canvases[n] in the function. You can declare ‘MainTex’, which will be whatever texture is used with any Drawable drawn with love.graphics.draw. You can also declare ‘VaryingColor’ and ‘VaryingTexCoord’, which are passed down from the vertex shader by love automatically. love_PixelCoord is also available. --HG-- branch : minor
This commit is contained in:
@@ -174,12 +174,24 @@ void Shader::attachDefault()
|
|||||||
current = nullptr;
|
current = nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
TextureType Shader::getMainTextureType() const
|
||||||
|
{
|
||||||
|
const UniformInfo *info = getUniformInfo(BUILTIN_TEXTURE_MAIN);
|
||||||
|
return info != nullptr ? info->textureType : TEXTURE_MAX_ENUM;
|
||||||
|
}
|
||||||
|
|
||||||
void Shader::checkMainTextureType(TextureType textype) const
|
void Shader::checkMainTextureType(TextureType textype) const
|
||||||
{
|
{
|
||||||
const UniformInfo *info = getUniformInfo(BUILTIN_TEXTURE_MAIN);
|
const UniformInfo *info = getUniformInfo(BUILTIN_TEXTURE_MAIN);
|
||||||
|
|
||||||
if (info != nullptr && info->textureType != TEXTURE_MAX_ENUM && info->textureType != textype)
|
if (info != nullptr && info->textureType != TEXTURE_MAX_ENUM && info->textureType != textype)
|
||||||
throw love::Exception("Texture's type must match the type of the shader's main texture.");
|
{
|
||||||
|
const char *textypestr = "unknown";
|
||||||
|
const char *shadertextypestr = "unknown";
|
||||||
|
Texture::getConstant(textype, textypestr);
|
||||||
|
Texture::getConstant(info->textureType, shadertextypestr);
|
||||||
|
throw love::Exception("Texture's type (%s) must match the type of the shader's main texture type (%s).", textypestr, shadertextypestr);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Shader::validate(Graphics *gfx, bool gles, const ShaderSource &source, bool checkWithDefaults, std::string &err)
|
bool Shader::validate(Graphics *gfx, bool gles, const ShaderSource &source, bool checkWithDefaults, std::string &err)
|
||||||
|
|||||||
@@ -176,6 +176,7 @@ public:
|
|||||||
**/
|
**/
|
||||||
virtual void setVideoTextures(Texture *ytexture, Texture *cbtexture, Texture *crtexture) = 0;
|
virtual void setVideoTextures(Texture *ytexture, Texture *cbtexture, Texture *crtexture) = 0;
|
||||||
|
|
||||||
|
TextureType getMainTextureType() const;
|
||||||
void checkMainTextureType(TextureType textype) const;
|
void checkMainTextureType(TextureType textype) const;
|
||||||
|
|
||||||
virtual ptrdiff_t getHandle() const = 0;
|
virtual ptrdiff_t getHandle() const = 0;
|
||||||
|
|||||||
@@ -134,10 +134,7 @@ void Mesh::drawInstanced(love::graphics::Graphics *gfx, const love::Matrix4 &m,
|
|||||||
|
|
||||||
gl.useVertexAttribArrays(enabledattribs, instancedattribs);
|
gl.useVertexAttribArrays(enabledattribs, instancedattribs);
|
||||||
|
|
||||||
if (texture.get())
|
gl.bindTextureToUnit(texture, 0, false);
|
||||||
gl.bindTextureToUnit(texture, 0, false);
|
|
||||||
else
|
|
||||||
gl.bindTextureToUnit(TEXTURE_2D, gl.getDefaultTexture(TEXTURE_2D), 0, false);
|
|
||||||
|
|
||||||
Graphics::TempTransform transform(gfx, m);
|
Graphics::TempTransform transform(gfx, m);
|
||||||
|
|
||||||
|
|||||||
@@ -867,8 +867,25 @@ void OpenGL::bindTextureToUnit(TextureType target, GLuint texture, int textureun
|
|||||||
|
|
||||||
void OpenGL::bindTextureToUnit(Texture *texture, int textureunit, bool restoreprev)
|
void OpenGL::bindTextureToUnit(Texture *texture, int textureunit, bool restoreprev)
|
||||||
{
|
{
|
||||||
GLuint handle = texture != nullptr ? (GLuint) texture->getHandle() : getDefaultTexture(TEXTURE_2D);
|
TextureType textype = TEXTURE_2D;
|
||||||
TextureType textype = texture != nullptr ? texture->getTextureType() : TEXTURE_2D;
|
GLuint handle = 0;
|
||||||
|
|
||||||
|
if (texture != nullptr)
|
||||||
|
{
|
||||||
|
textype = texture->getTextureType();
|
||||||
|
handle = (GLuint) texture->getHandle();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (textureunit == 0 && Shader::current != nullptr)
|
||||||
|
{
|
||||||
|
TextureType shadertex = Shader::current->getMainTextureType();
|
||||||
|
if (shadertex != TEXTURE_MAX_ENUM)
|
||||||
|
textype = shadertex;
|
||||||
|
}
|
||||||
|
|
||||||
|
handle = getDefaultTexture(textype);
|
||||||
|
}
|
||||||
|
|
||||||
bindTextureToUnit(textype, handle, textureunit, restoreprev);
|
bindTextureToUnit(textype, handle, textureunit, restoreprev);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -262,15 +262,11 @@ void main() {
|
|||||||
love_PixelColor = effect(VaryingColor, MainTex, VaryingTexCoord.st, love_PixelCoord);
|
love_PixelColor = effect(VaryingColor, MainTex, VaryingTexCoord.st, love_PixelCoord);
|
||||||
}]],
|
}]],
|
||||||
|
|
||||||
MAIN_MULTI_CANVAS = [[
|
MAIN_CUSTOM = [[
|
||||||
uniform sampler2D MainTex;
|
void effect();
|
||||||
varying mediump vec4 VaryingTexCoord;
|
|
||||||
varying mediump vec4 VaryingColor;
|
|
||||||
|
|
||||||
void effects(vec4 vcolor, Image tex, vec2 texcoord, vec2 pixcoord);
|
|
||||||
|
|
||||||
void main() {
|
void main() {
|
||||||
effects(VaryingColor, MainTex, VaryingTexCoord.st, love_PixelCoord);
|
effect();
|
||||||
}]],
|
}]],
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -279,7 +275,7 @@ local function getLanguageTarget(code)
|
|||||||
return (code:match("^%s*#pragma language (%w+)")) or "glsl1"
|
return (code:match("^%s*#pragma language (%w+)")) or "glsl1"
|
||||||
end
|
end
|
||||||
|
|
||||||
local function createShaderStageCode(stage, code, lang, gles, glsl1on3, gammacorrect, multicanvas)
|
local function createShaderStageCode(stage, code, lang, gles, glsl1on3, gammacorrect, custom)
|
||||||
stage = stage:upper()
|
stage = stage:upper()
|
||||||
local lines = {
|
local lines = {
|
||||||
GLSL.VERSION[lang][gles],
|
GLSL.VERSION[lang][gles],
|
||||||
@@ -291,7 +287,7 @@ local function createShaderStageCode(stage, code, lang, gles, glsl1on3, gammacor
|
|||||||
GLSL.UNIFORMS,
|
GLSL.UNIFORMS,
|
||||||
GLSL.FUNCTIONS,
|
GLSL.FUNCTIONS,
|
||||||
GLSL[stage].FUNCTIONS,
|
GLSL[stage].FUNCTIONS,
|
||||||
multicanvas and GLSL[stage].MAIN_MULTI_CANVAS or GLSL[stage].MAIN,
|
custom and GLSL[stage].MAIN_CUSTOM or GLSL[stage].MAIN,
|
||||||
(lang == "glsl3" or gles) and "#line 1" or "#line 0",
|
(lang == "glsl3" or gles) and "#line 1" or "#line 0",
|
||||||
code,
|
code,
|
||||||
}
|
}
|
||||||
@@ -305,8 +301,8 @@ end
|
|||||||
local function isPixelCode(code)
|
local function isPixelCode(code)
|
||||||
if code:match("vec4%s+effect%s*%(") then
|
if code:match("vec4%s+effect%s*%(") then
|
||||||
return true
|
return true
|
||||||
elseif code:match("void%s+effects%s*%(") then
|
elseif code:match("void%s+effect%s*%(") then
|
||||||
-- function for rendering to multiple canvases simultaneously
|
-- custom effect function
|
||||||
return true, true
|
return true, true
|
||||||
else
|
else
|
||||||
return false
|
return false
|
||||||
@@ -315,17 +311,17 @@ end
|
|||||||
|
|
||||||
function love.graphics._shaderCodeToGLSL(gles, arg1, arg2)
|
function love.graphics._shaderCodeToGLSL(gles, arg1, arg2)
|
||||||
local vertexcode, pixelcode
|
local vertexcode, pixelcode
|
||||||
local is_multicanvas = false -- whether pixel code has "effects" function instead of "effect"
|
local is_custompixel = false -- whether pixel code has "effects" function instead of "effect"
|
||||||
|
|
||||||
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
|
||||||
end
|
end
|
||||||
|
|
||||||
local ispixel, isMultiCanvas = isPixelCode(arg1)
|
local ispixel, isCustomPixel = isPixelCode(arg1)
|
||||||
if ispixel then
|
if ispixel then
|
||||||
pixelcode = arg1 -- first arg contains pixel shader code
|
pixelcode = arg1 -- first arg contains pixel shader code
|
||||||
is_multicanvas = isMultiCanvas
|
is_custompixel = isCustomPixel
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
@@ -334,10 +330,10 @@ function love.graphics._shaderCodeToGLSL(gles, arg1, arg2)
|
|||||||
vertexcode = arg2 -- second arg contains vertex shader code
|
vertexcode = arg2 -- second arg contains vertex shader code
|
||||||
end
|
end
|
||||||
|
|
||||||
local ispixel, isMultiCanvas = isPixelCode(arg2)
|
local ispixel, isCustomPixel = isPixelCode(arg2)
|
||||||
if ispixel then
|
if ispixel then
|
||||||
pixelcode = arg2 -- second arg contains pixel shader code
|
pixelcode = arg2 -- second arg contains pixel shader code
|
||||||
is_multicanvas = isMultiCanvas
|
is_custompixel = isCustomPixel
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
@@ -368,7 +364,7 @@ function love.graphics._shaderCodeToGLSL(gles, arg1, arg2)
|
|||||||
vertexcode = createShaderStageCode("VERTEX", vertexcode, lang, gles, glsl1on3, gammacorrect)
|
vertexcode = createShaderStageCode("VERTEX", vertexcode, lang, gles, glsl1on3, gammacorrect)
|
||||||
end
|
end
|
||||||
if pixelcode then
|
if pixelcode then
|
||||||
pixelcode = createShaderStageCode("PIXEL", pixelcode, lang, gles, glsl1on3, gammacorrect, is_multicanvas)
|
pixelcode = createShaderStageCode("PIXEL", pixelcode, lang, gles, glsl1on3, gammacorrect, is_custompixel)
|
||||||
end
|
end
|
||||||
|
|
||||||
return vertexcode, pixelcode
|
return vertexcode, pixelcode
|
||||||
|
|||||||
Reference in New Issue
Block a user