Mercurial > love-experiments
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 |
