Mercurial > love-experiments
diff src/scripts/graphics.lua @ 1399:fa3eabb3602a MRTs
Added MRT support to canvases via love.graphics.setCanvases(c1, c2, ...), and an 'effects' callback function in shaders.
- Simultanious rendering to multiple canvases requires all canvases to be the same size (limitation of pre-GL3.0 framebuffers)
- love.graphics.isSupported("mrtcanvas") was added
- love_Canvases[n] (0-based array of active canvases) can be written to in pixel shaders in the 'effects' callback function
- everything drawn to multiple canvases at once will be duplicated to all canvases if no shader is active or the standard 'effect' shader function is used
| author | Alex Szpakowski <slime73@gmail.com> |
|---|---|
| date | Sun, 24 Mar 2013 02:20:15 -0300 |
| parents | a742f6edaf92 |
| children | bee3f7b0dca0 |
line wrap: on
line diff
--- a/src/scripts/graphics.lua Thu Mar 21 12:21:13 2013 -0300 +++ b/src/scripts/graphics.lua Sun Mar 24 02:20:15 2013 -0300 @@ -1295,7 +1295,8 @@ #define number float #define Image sampler2D #define extern uniform -#define Texel texture2D]] +#define Texel texture2D +#define love_Canvases gl_FragData]] local GLSL_UNIFORMS = [[ #define ModelViewMatrix gl_ModelViewMatrix @@ -1332,10 +1333,17 @@ FOOTER = [[ void main() { - // fix weird crashing issue in OSX when _tex0_ is unused within effect() + // fix crashing issue in OSX when _tex0_ is unused within effect() float dummy = texture2D(_tex0_, vec2(.5)).r; gl_FragColor = effect(VaryingColor, _tex0_, VaryingTexCoord.st, gl_FragCoord.xy); }]], + + FOOTER_MRT = [[ +void main() { + // fix crashing issue in OSX when _tex0_ is unused within effect() + float dummy = texture2D(_tex0_, vec2(.5)).r; + effects(VaryingColor, _tex0_, VaryingTexCoord.st, gl_FragCoord.xy); +}]], } local function createVertexCode(vertexcode) @@ -1349,36 +1357,62 @@ return table_concat(vertexcodes, "\n") end - local function createPixelCode(pixelcode) + local function createPixelCode(pixelcode, is_mrt) local pixelcodes = { GLSL_VERSION, GLSL_SYNTAX, GLSL_PIXEL.HEADER, GLSL_UNIFORMS, "#line 0", pixelcode, - GLSL_PIXEL.FOOTER + is_mrt and GLSL_PIXEL.FOOTER_MRT or GLSL_PIXEL.FOOTER, } return table_concat(pixelcodes, "\n") end - function love.graphics._shaderCodeToGLSL(vertexcode, pixelcode) - if vertexcode then - local s = vertexcode:gsub("\r\n\t", " ") - s = s:gsub("(%w+)(%s+)%(", "%1(") - if s:match("vec4%s*effect%(") then - pixelcode = vertexcode -- first argument contains pixel shader code + local function isVertexCode(code) + return code:match("vec4%s*position%(") ~= nil + end + + local function isPixelCode(code) + if code:match("vec4%s*effect%(") then + return true + elseif code:match("void%s*effects%(") then -- multiple render targets (MRT) + return true, true + else + return false + end + end + + function love.graphics._shaderCodeToGLSL(arg1, arg2) + local vertexcode, pixelcode + local is_mrt = false -- whether pixel code has "effects" function instead of "effect" + + if arg1 then + local s = arg1:gsub("\r\n\t", " ") -- convert whitespace to spaces for parsing + s = s:gsub("(%w+)(%s+)%(", "%1(") -- convert "func ()" to "func()" + + if isVertexCode(s) then + vertexcode = arg1 -- first arg contains vertex shader code end - if not s:match("vec4%s*position%(") then - vertexcode = nil -- first argument doesn't contain vertex shader code + + local ispixel, isMRT = isPixelCode(s) + if ispixel then + pixelcode = arg1 -- first arg contains pixel shader code + is_mrt = isMRT end end - if pixelcode then - local s = pixelcode:gsub("\r\n\t", " ") - s = s:gsub("(%w+)(%s+)%(", "%1(") - if s:match("vec4%s*position%(") then - vertexcode = pixelcode -- second argument contains vertex shader code + + if arg2 then + local s = arg2:gsub("\r\n\t", " ") -- convert whitespace to spaces for parsing + s = s:gsub("(%w+)(%s+)%(", "%1(") -- convert "func ()" to "func()" + + if isVertexCode(s) then + vertexcode = arg2 -- second arg contains vertex shader code end - if not s:match("vec4%s*effect%(") then - pixelcode = nil -- second argument doesn't contain pixel shader code + + local ispixel, isMRT = isPixelCode(s) + if ispixel then + pixelcode = arg2 -- second arg contains pixel shader code + is_mrt = isMRT end end @@ -1386,7 +1420,7 @@ vertexcode = createVertexCode(vertexcode) end if pixelcode then - pixelcode = createPixelCode(pixelcode) + pixelcode = createPixelCode(pixelcode, is_mrt) end return vertexcode, pixelcode
