From ff8358a9797438ee554e606a97e0a105219c056b Mon Sep 17 00:00:00 2001 From: Alex Szpakowski Date: Sat, 25 Feb 2017 17:52:27 -0400 Subject: [PATCH] =?UTF-8?q?Removed=20void=20effects(=E2=80=A6)=20pixel=20s?= =?UTF-8?q?hader=20prototype.=20Added=20void=20effect().=20Allows=20callin?= =?UTF-8?q?g=20love.graphics.draw=20with=20textures=20of=20different=20typ?= =?UTF-8?q?es=20with=20a=20custom=20shader=20without=20having=20an=20extra?= =?UTF-8?q?=20sampler2D.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 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 --- src/modules/graphics/Shader.cpp | 14 +++++++++++- src/modules/graphics/Shader.h | 1 + src/modules/graphics/opengl/Mesh.cpp | 5 +---- src/modules/graphics/opengl/OpenGL.cpp | 21 ++++++++++++++++-- src/modules/graphics/wrap_Graphics.lua | 30 +++++++++++--------------- 5 files changed, 47 insertions(+), 24 deletions(-) diff --git a/src/modules/graphics/Shader.cpp b/src/modules/graphics/Shader.cpp index d4751f475..ed67ef263 100644 --- a/src/modules/graphics/Shader.cpp +++ b/src/modules/graphics/Shader.cpp @@ -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) diff --git a/src/modules/graphics/Shader.h b/src/modules/graphics/Shader.h index 1589ec5ff..37905eeae 100644 --- a/src/modules/graphics/Shader.h +++ b/src/modules/graphics/Shader.h @@ -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; diff --git a/src/modules/graphics/opengl/Mesh.cpp b/src/modules/graphics/opengl/Mesh.cpp index 76fc2eb75..9173ebdcd 100644 --- a/src/modules/graphics/opengl/Mesh.cpp +++ b/src/modules/graphics/opengl/Mesh.cpp @@ -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); diff --git a/src/modules/graphics/opengl/OpenGL.cpp b/src/modules/graphics/opengl/OpenGL.cpp index 26bc61a2d..553ede222 100644 --- a/src/modules/graphics/opengl/OpenGL.cpp +++ b/src/modules/graphics/opengl/OpenGL.cpp @@ -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); } diff --git a/src/modules/graphics/wrap_Graphics.lua b/src/modules/graphics/wrap_Graphics.lua index b42408960..fb2594ddf 100644 --- a/src/modules/graphics/wrap_Graphics.lua +++ b/src/modules/graphics/wrap_Graphics.lua @@ -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