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:
Alex Szpakowski
2017-02-25 17:52:27 -04:00
parent f3f6b10ac8
commit ff8358a979
5 changed files with 47 additions and 24 deletions
+13 -1
View File
@@ -174,12 +174,24 @@ void Shader::attachDefault()
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
{
const UniformInfo *info = getUniformInfo(BUILTIN_TEXTURE_MAIN);
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)
+1
View File
@@ -176,6 +176,7 @@ public:
**/
virtual void setVideoTextures(Texture *ytexture, Texture *cbtexture, Texture *crtexture) = 0;
TextureType getMainTextureType() const;
void checkMainTextureType(TextureType textype) const;
virtual ptrdiff_t getHandle() const = 0;
+1 -4
View File
@@ -134,10 +134,7 @@ void Mesh::drawInstanced(love::graphics::Graphics *gfx, const love::Matrix4 &m,
gl.useVertexAttribArrays(enabledattribs, instancedattribs);
if (texture.get())
gl.bindTextureToUnit(texture, 0, false);
else
gl.bindTextureToUnit(TEXTURE_2D, gl.getDefaultTexture(TEXTURE_2D), 0, false);
gl.bindTextureToUnit(texture, 0, false);
Graphics::TempTransform transform(gfx, m);
+19 -2
View File
@@ -867,8 +867,25 @@ void OpenGL::bindTextureToUnit(TextureType target, GLuint texture, int textureun
void OpenGL::bindTextureToUnit(Texture *texture, int textureunit, bool restoreprev)
{
GLuint handle = texture != nullptr ? (GLuint) texture->getHandle() : getDefaultTexture(TEXTURE_2D);
TextureType textype = texture != nullptr ? texture->getTextureType() : TEXTURE_2D;
TextureType textype = 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);
}
+13 -17
View File
@@ -262,15 +262,11 @@ void main() {
love_PixelColor = effect(VaryingColor, MainTex, VaryingTexCoord.st, love_PixelCoord);
}]],
MAIN_MULTI_CANVAS = [[
uniform sampler2D MainTex;
varying mediump vec4 VaryingTexCoord;
varying mediump vec4 VaryingColor;
void effects(vec4 vcolor, Image tex, vec2 texcoord, vec2 pixcoord);
MAIN_CUSTOM = [[
void effect();
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"
end
local function createShaderStageCode(stage, code, lang, gles, glsl1on3, gammacorrect, multicanvas)
local function createShaderStageCode(stage, code, lang, gles, glsl1on3, gammacorrect, custom)
stage = stage:upper()
local lines = {
GLSL.VERSION[lang][gles],
@@ -291,7 +287,7 @@ local function createShaderStageCode(stage, code, lang, gles, glsl1on3, gammacor
GLSL.UNIFORMS,
GLSL.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",
code,
}
@@ -305,8 +301,8 @@ end
local function isPixelCode(code)
if code:match("vec4%s+effect%s*%(") then
return true
elseif code:match("void%s+effects%s*%(") then
-- function for rendering to multiple canvases simultaneously
elseif code:match("void%s+effect%s*%(") then
-- custom effect function
return true, true
else
return false
@@ -315,17 +311,17 @@ end
function love.graphics._shaderCodeToGLSL(gles, arg1, arg2)
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 isVertexCode(arg1) then
vertexcode = arg1 -- first arg contains vertex shader code
end
local ispixel, isMultiCanvas = isPixelCode(arg1)
local ispixel, isCustomPixel = isPixelCode(arg1)
if ispixel then
pixelcode = arg1 -- first arg contains pixel shader code
is_multicanvas = isMultiCanvas
is_custompixel = isCustomPixel
end
end
@@ -334,10 +330,10 @@ function love.graphics._shaderCodeToGLSL(gles, arg1, arg2)
vertexcode = arg2 -- second arg contains vertex shader code
end
local ispixel, isMultiCanvas = isPixelCode(arg2)
local ispixel, isCustomPixel = isPixelCode(arg2)
if ispixel then
pixelcode = arg2 -- second arg contains pixel shader code
is_multicanvas = isMultiCanvas
is_custompixel = isCustomPixel
end
end
@@ -368,7 +364,7 @@ function love.graphics._shaderCodeToGLSL(gles, arg1, arg2)
vertexcode = createShaderStageCode("VERTEX", vertexcode, lang, gles, glsl1on3, gammacorrect)
end
if pixelcode then
pixelcode = createShaderStageCode("PIXEL", pixelcode, lang, gles, glsl1on3, gammacorrect, is_multicanvas)
pixelcode = createShaderStageCode("PIXEL", pixelcode, lang, gles, glsl1on3, gammacorrect, is_custompixel)
end
return vertexcode, pixelcode