comparison 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
comparison
equal deleted inserted replaced
1397:43f2b4936ca8 1399:fa3eabb3602a
1293 1293
1294 local GLSL_SYNTAX = [[ 1294 local GLSL_SYNTAX = [[
1295 #define number float 1295 #define number float
1296 #define Image sampler2D 1296 #define Image sampler2D
1297 #define extern uniform 1297 #define extern uniform
1298 #define Texel texture2D]] 1298 #define Texel texture2D
1299 #define love_Canvases gl_FragData]]
1299 1300
1300 local GLSL_UNIFORMS = [[ 1301 local GLSL_UNIFORMS = [[
1301 #define ModelViewMatrix gl_ModelViewMatrix 1302 #define ModelViewMatrix gl_ModelViewMatrix
1302 #define ProjectionMatrix gl_ProjectionMatrix 1303 #define ProjectionMatrix gl_ProjectionMatrix
1303 #define ModelViewProjectionMatrix gl_ModelViewProjectionMatrix 1304 #define ModelViewProjectionMatrix gl_ModelViewProjectionMatrix
1330 #define VaryingTexCoord gl_TexCoord[0] 1331 #define VaryingTexCoord gl_TexCoord[0]
1331 #define VaryingColor gl_Color]], 1332 #define VaryingColor gl_Color]],
1332 1333
1333 FOOTER = [[ 1334 FOOTER = [[
1334 void main() { 1335 void main() {
1335 // fix weird crashing issue in OSX when _tex0_ is unused within effect() 1336 // fix crashing issue in OSX when _tex0_ is unused within effect()
1336 float dummy = texture2D(_tex0_, vec2(.5)).r; 1337 float dummy = texture2D(_tex0_, vec2(.5)).r;
1337 gl_FragColor = effect(VaryingColor, _tex0_, VaryingTexCoord.st, gl_FragCoord.xy); 1338 gl_FragColor = effect(VaryingColor, _tex0_, VaryingTexCoord.st, gl_FragCoord.xy);
1339 }]],
1340
1341 FOOTER_MRT = [[
1342 void main() {
1343 // fix crashing issue in OSX when _tex0_ is unused within effect()
1344 float dummy = texture2D(_tex0_, vec2(.5)).r;
1345 effects(VaryingColor, _tex0_, VaryingTexCoord.st, gl_FragCoord.xy);
1338 }]], 1346 }]],
1339 } 1347 }
1340 1348
1341 local function createVertexCode(vertexcode) 1349 local function createVertexCode(vertexcode)
1342 local vertexcodes = { 1350 local vertexcodes = {
1347 GLSL_VERTEX.FOOTER, 1355 GLSL_VERTEX.FOOTER,
1348 } 1356 }
1349 return table_concat(vertexcodes, "\n") 1357 return table_concat(vertexcodes, "\n")
1350 end 1358 end
1351 1359
1352 local function createPixelCode(pixelcode) 1360 local function createPixelCode(pixelcode, is_mrt)
1353 local pixelcodes = { 1361 local pixelcodes = {
1354 GLSL_VERSION, 1362 GLSL_VERSION,
1355 GLSL_SYNTAX, GLSL_PIXEL.HEADER, GLSL_UNIFORMS, 1363 GLSL_SYNTAX, GLSL_PIXEL.HEADER, GLSL_UNIFORMS,
1356 "#line 0", 1364 "#line 0",
1357 pixelcode, 1365 pixelcode,
1358 GLSL_PIXEL.FOOTER 1366 is_mrt and GLSL_PIXEL.FOOTER_MRT or GLSL_PIXEL.FOOTER,
1359 } 1367 }
1360 return table_concat(pixelcodes, "\n") 1368 return table_concat(pixelcodes, "\n")
1361 end 1369 end
1362 1370
1363 function love.graphics._shaderCodeToGLSL(vertexcode, pixelcode) 1371 local function isVertexCode(code)
1364 if vertexcode then 1372 return code:match("vec4%s*position%(") ~= nil
1365 local s = vertexcode:gsub("\r\n\t", " ") 1373 end
1366 s = s:gsub("(%w+)(%s+)%(", "%1(") 1374
1367 if s:match("vec4%s*effect%(") then 1375 local function isPixelCode(code)
1368 pixelcode = vertexcode -- first argument contains pixel shader code 1376 if code:match("vec4%s*effect%(") then
1377 return true
1378 elseif code:match("void%s*effects%(") then -- multiple render targets (MRT)
1379 return true, true
1380 else
1381 return false
1382 end
1383 end
1384
1385 function love.graphics._shaderCodeToGLSL(arg1, arg2)
1386 local vertexcode, pixelcode
1387 local is_mrt = false -- whether pixel code has "effects" function instead of "effect"
1388
1389 if arg1 then
1390 local s = arg1:gsub("\r\n\t", " ") -- convert whitespace to spaces for parsing
1391 s = s:gsub("(%w+)(%s+)%(", "%1(") -- convert "func ()" to "func()"
1392
1393 if isVertexCode(s) then
1394 vertexcode = arg1 -- first arg contains vertex shader code
1369 end 1395 end
1370 if not s:match("vec4%s*position%(") then 1396
1371 vertexcode = nil -- first argument doesn't contain vertex shader code 1397 local ispixel, isMRT = isPixelCode(s)
1398 if ispixel then
1399 pixelcode = arg1 -- first arg contains pixel shader code
1400 is_mrt = isMRT
1372 end 1401 end
1373 end 1402 end
1374 if pixelcode then 1403
1375 local s = pixelcode:gsub("\r\n\t", " ") 1404 if arg2 then
1376 s = s:gsub("(%w+)(%s+)%(", "%1(") 1405 local s = arg2:gsub("\r\n\t", " ") -- convert whitespace to spaces for parsing
1377 if s:match("vec4%s*position%(") then 1406 s = s:gsub("(%w+)(%s+)%(", "%1(") -- convert "func ()" to "func()"
1378 vertexcode = pixelcode -- second argument contains vertex shader code 1407
1408 if isVertexCode(s) then
1409 vertexcode = arg2 -- second arg contains vertex shader code
1379 end 1410 end
1380 if not s:match("vec4%s*effect%(") then 1411
1381 pixelcode = nil -- second argument doesn't contain pixel shader code 1412 local ispixel, isMRT = isPixelCode(s)
1413 if ispixel then
1414 pixelcode = arg2 -- second arg contains pixel shader code
1415 is_mrt = isMRT
1382 end 1416 end
1383 end 1417 end
1384 1418
1385 if vertexcode then 1419 if vertexcode then
1386 vertexcode = createVertexCode(vertexcode) 1420 vertexcode = createVertexCode(vertexcode)
1387 end 1421 end
1388 if pixelcode then 1422 if pixelcode then
1389 pixelcode = createPixelCode(pixelcode) 1423 pixelcode = createPixelCode(pixelcode, is_mrt)
1390 end 1424 end
1391 1425
1392 return vertexcode, pixelcode 1426 return vertexcode, pixelcode
1393 end 1427 end
1394 1428