wrap_Graphics.lua 16 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513
  1. R"luastring"--(
  2. -- DO NOT REMOVE THE ABOVE LINE. It is used to load this file as a C++ string.
  3. -- There is a matching delimiter at the bottom of the file.
  4. --[[
  5. Copyright (c) 2006-2017 LOVE Development Team
  6. This software is provided 'as-is', without any express or implied
  7. warranty. In no event will the authors be held liable for any damages
  8. arising from the use of this software.
  9. Permission is granted to anyone to use this software for any purpose,
  10. including commercial applications, and to alter it and redistribute it
  11. freely, subject to the following restrictions:
  12. 1. The origin of this software must not be misrepresented; you must not
  13. claim that you wrote the original software. If you use this software
  14. in a product, an acknowledgment in the product documentation would be
  15. appreciated but is not required.
  16. 2. Altered source versions must be plainly marked as such, and must not be
  17. misrepresented as being the original software.
  18. 3. This notice may not be removed or altered from any source distribution.
  19. --]]
  20. local table_concat = table.concat
  21. local ipairs = ipairs
  22. -- SHADERS
  23. local GLSL = {}
  24. GLSL.VERSION = { -- index using [target][gles]
  25. glsl1 = {[false]="#version 120", [true]="#version 100"},
  26. glsl3 = {[false]="#version 330 core", [true]="#version 300 es"},
  27. }
  28. GLSL.SYNTAX = [[
  29. #if !defined(GL_ES) && __VERSION__ < 140
  30. #define lowp
  31. #define mediump
  32. #define highp
  33. #endif
  34. #if defined(VERTEX) || __VERSION__ > 100 || defined(GL_FRAGMENT_PRECISION_HIGH)
  35. #define LOVE_HIGHP_OR_MEDIUMP highp
  36. #else
  37. #define LOVE_HIGHP_OR_MEDIUMP mediump
  38. #endif
  39. #define number float
  40. #define Image sampler2D
  41. #define ArrayImage sampler2DArray
  42. #define CubeImage samplerCube
  43. #define VolumeImage sampler3D
  44. #if __VERSION__ >= 300 && !defined(LOVE_GLSL1_ON_GLSL3)
  45. #define DepthImage sampler2DShadow
  46. #define DepthArrayImage sampler2DArrayShadow
  47. #define DepthCubeImage samplerCubeShadow
  48. #endif
  49. #define extern uniform
  50. #ifdef GL_EXT_texture_array
  51. #extension GL_EXT_texture_array : enable
  52. #endif
  53. #ifdef GL_OES_texture_3D
  54. #extension GL_OES_texture_3D : enable
  55. #endif
  56. #ifdef GL_OES_standard_derivatives
  57. #extension GL_OES_standard_derivatives : enable
  58. #endif
  59. ]]
  60. -- Uniforms shared by the vertex and pixel shader stages.
  61. GLSL.UNIFORMS = [[
  62. // According to the GLSL ES 1.0 spec, uniform precision must match between stages,
  63. // but we can't guarantee that highp is always supported in fragment shaders...
  64. // We *really* don't want to use mediump for these in vertex shaders though.
  65. uniform LOVE_HIGHP_OR_MEDIUMP mat4 ViewSpaceFromLocal;
  66. uniform LOVE_HIGHP_OR_MEDIUMP mat4 ClipSpaceFromView;
  67. uniform LOVE_HIGHP_OR_MEDIUMP mat4 ClipSpaceFromLocal;
  68. uniform LOVE_HIGHP_OR_MEDIUMP mat3 ViewNormalFromLocal;
  69. uniform LOVE_HIGHP_OR_MEDIUMP vec4 love_ScreenSize;
  70. // Compatibility
  71. #define TransformMatrix ViewSpaceFromLocal
  72. #define ProjectionMatrix ClipSpaceFromView
  73. #define TransformProjectionMatrix ClipSpaceFromLocal
  74. #define NormalMatrix ViewNormalFromLocal
  75. ]]
  76. GLSL.FUNCTIONS = [[
  77. #ifdef GL_ES
  78. #if __VERSION__ >= 300 || defined(GL_EXT_texture_array)
  79. precision lowp sampler2DArray;
  80. #endif
  81. #if __VERSION__ >= 300 || defined(GL_OES_texture_3D)
  82. precision lowp sampler3D;
  83. #endif
  84. #if __VERSION__ >= 300
  85. precision lowp sampler2DShadow;
  86. precision lowp samplerCubeShadow;
  87. precision lowp sampler2DArrayShadow;
  88. #endif
  89. #endif
  90. #if __VERSION__ >= 130 && !defined(LOVE_GLSL1_ON_GLSL3)
  91. #define Texel texture
  92. #else
  93. #if __VERSION__ >= 130
  94. #define texture2D Texel
  95. #define texture3D Texel
  96. #define textureCube Texel
  97. #define texture2DArray Texel
  98. #define love_texture2D texture
  99. #define love_texture3D texture
  100. #define love_textureCube texture
  101. #define love_texture2DArray texture
  102. #else
  103. #define love_texture2D texture2D
  104. #define love_texture3D texture3D
  105. #define love_textureCube textureCube
  106. #define love_texture2DArray texture2DArray
  107. #endif
  108. vec4 Texel(sampler2D s, vec2 c) { return love_texture2D(s, c); }
  109. vec4 Texel(samplerCube s, vec3 c) { return love_textureCube(s, c); }
  110. #if __VERSION__ > 100 || defined(GL_OES_texture_3D)
  111. vec4 Texel(sampler3D s, vec3 c) { return love_texture3D(s, c); }
  112. #endif
  113. #if __VERSION__ >= 130 || defined(GL_EXT_texture_array)
  114. vec4 Texel(sampler2DArray s, vec3 c) { return love_texture2DArray(s, c); }
  115. #endif
  116. #ifdef PIXEL
  117. vec4 Texel(sampler2D s, vec2 c, float b) { return love_texture2D(s, c, b); }
  118. vec4 Texel(samplerCube s, vec3 c, float b) { return love_textureCube(s, c, b); }
  119. #if __VERSION__ > 100 || defined(GL_OES_texture_3D)
  120. vec4 Texel(sampler3D s, vec3 c, float b) { return love_texture3D(s, c, b); }
  121. #endif
  122. #if __VERSION__ >= 130 || defined(GL_EXT_texture_array)
  123. vec4 Texel(sampler2DArray s, vec3 c, float b) { return love_texture2DArray(s, c, b); }
  124. #endif
  125. #endif
  126. #define texture love_texture
  127. #endif
  128. float gammaToLinearPrecise(float c) {
  129. return c <= 0.04045 ? c * 0.077399380804954 : pow((c + 0.055) * 0.9478672985782, 2.4);
  130. }
  131. vec3 gammaToLinearPrecise(vec3 c) {
  132. bvec3 leq = lessThanEqual(c, vec3(0.04045));
  133. c.r = leq.r ? c.r * 0.077399380804954 : pow((c.r + 0.055) * 0.9478672985782, 2.4);
  134. c.g = leq.g ? c.g * 0.077399380804954 : pow((c.g + 0.055) * 0.9478672985782, 2.4);
  135. c.b = leq.b ? c.b * 0.077399380804954 : pow((c.b + 0.055) * 0.9478672985782, 2.4);
  136. return c;
  137. }
  138. vec4 gammaToLinearPrecise(vec4 c) { return vec4(gammaToLinearPrecise(c.rgb), c.a); }
  139. float linearToGammaPrecise(float c) {
  140. return c < 0.0031308 ? c * 12.92 : 1.055 * pow(c, 1.0 / 2.4) - 0.055;
  141. }
  142. vec3 linearToGammaPrecise(vec3 c) {
  143. bvec3 lt = lessThanEqual(c, vec3(0.0031308));
  144. c.r = lt.r ? c.r * 12.92 : 1.055 * pow(c.r, 1.0 / 2.4) - 0.055;
  145. c.g = lt.g ? c.g * 12.92 : 1.055 * pow(c.g, 1.0 / 2.4) - 0.055;
  146. c.b = lt.b ? c.b * 12.92 : 1.055 * pow(c.b, 1.0 / 2.4) - 0.055;
  147. return c;
  148. }
  149. vec4 linearToGammaPrecise(vec4 c) { return vec4(linearToGammaPrecise(c.rgb), c.a); }
  150. // http://chilliant.blogspot.com.au/2012/08/srgb-approximations-for-hlsl.html?m=1
  151. mediump float gammaToLinearFast(mediump float c) { return c * (c * (c * 0.305306011 + 0.682171111) + 0.012522878); }
  152. mediump vec3 gammaToLinearFast(mediump vec3 c) { return c * (c * (c * 0.305306011 + 0.682171111) + 0.012522878); }
  153. mediump vec4 gammaToLinearFast(mediump vec4 c) { return vec4(gammaToLinearFast(c.rgb), c.a); }
  154. mediump float linearToGammaFast(mediump float c) { return max(1.055 * pow(max(c, 0.0), 0.41666666) - 0.055, 0.0); }
  155. mediump vec3 linearToGammaFast(mediump vec3 c) { return max(1.055 * pow(max(c, vec3(0.0)), vec3(0.41666666)) - 0.055, vec3(0.0)); }
  156. mediump vec4 linearToGammaFast(mediump vec4 c) { return vec4(linearToGammaFast(c.rgb), c.a); }
  157. #define gammaToLinear gammaToLinearFast
  158. #define linearToGamma linearToGammaFast
  159. #ifdef LOVE_GAMMA_CORRECT
  160. #define gammaCorrectColor gammaToLinear
  161. #define unGammaCorrectColor linearToGamma
  162. #define gammaCorrectColorPrecise gammaToLinearPrecise
  163. #define unGammaCorrectColorPrecise linearToGammaPrecise
  164. #define gammaCorrectColorFast gammaToLinearFast
  165. #define unGammaCorrectColorFast linearToGammaFast
  166. #else
  167. #define gammaCorrectColor
  168. #define unGammaCorrectColor
  169. #define gammaCorrectColorPrecise
  170. #define unGammaCorrectColorPrecise
  171. #define gammaCorrectColorFast
  172. #define unGammaCorrectColorFast
  173. #endif]]
  174. GLSL.VERTEX = {
  175. HEADER = [[
  176. #define love_Position gl_Position
  177. #if __VERSION__ >= 130
  178. #define attribute in
  179. #define varying out
  180. #ifndef LOVE_GLSL1_ON_GLSL3
  181. #define love_VertexID gl_VertexID
  182. #define love_InstanceID gl_InstanceID
  183. #endif
  184. #endif
  185. #ifdef GL_ES
  186. uniform mediump float love_PointSize;
  187. #endif]],
  188. FUNCTIONS = [[
  189. void setPointSize() {
  190. #ifdef GL_ES
  191. gl_PointSize = love_PointSize;
  192. #endif
  193. }]],
  194. MAIN = [[
  195. attribute vec4 VertexPosition;
  196. attribute vec4 VertexTexCoord;
  197. attribute vec4 VertexColor;
  198. attribute vec4 ConstantColor;
  199. varying vec4 VaryingTexCoord;
  200. varying vec4 VaryingColor;
  201. vec4 position(mat4 clipSpaceFromLocal, vec4 localPosition);
  202. void main() {
  203. VaryingTexCoord = VertexTexCoord;
  204. VaryingColor = gammaCorrectColor(VertexColor) * ConstantColor;
  205. setPointSize();
  206. love_Position = position(ClipSpaceFromLocal, VertexPosition);
  207. }]],
  208. }
  209. GLSL.PIXEL = {
  210. HEADER = [[
  211. #ifdef GL_ES
  212. precision mediump float;
  213. #endif
  214. #define love_MaxCanvases gl_MaxDrawBuffers
  215. #if __VERSION__ >= 130
  216. #define varying in
  217. layout(location = 0) out vec4 love_Canvases[love_MaxCanvases];
  218. #define love_PixelColor love_Canvases[0]
  219. #else
  220. #define love_Canvases gl_FragData
  221. #define love_PixelColor gl_FragColor
  222. #endif
  223. // See Shader::updateScreenParams in Shader.cpp.
  224. #define love_PixelCoord (vec2(gl_FragCoord.x, (gl_FragCoord.y * love_ScreenSize.z) + love_ScreenSize.w))]],
  225. FUNCTIONS = [[
  226. uniform sampler2D love_VideoYChannel;
  227. uniform sampler2D love_VideoCbChannel;
  228. uniform sampler2D love_VideoCrChannel;
  229. vec4 VideoTexel(vec2 texcoords) {
  230. vec3 yuv;
  231. yuv[0] = Texel(love_VideoYChannel, texcoords).r;
  232. yuv[1] = Texel(love_VideoCbChannel, texcoords).r;
  233. yuv[2] = Texel(love_VideoCrChannel, texcoords).r;
  234. yuv += vec3(-0.0627451017, -0.501960814, -0.501960814);
  235. vec4 color;
  236. color.r = dot(yuv, vec3(1.164, 0.000, 1.596));
  237. color.g = dot(yuv, vec3(1.164, -0.391, -0.813));
  238. color.b = dot(yuv, vec3(1.164, 2.018, 0.000));
  239. color.a = 1.0;
  240. return gammaCorrectColor(color);
  241. }]],
  242. MAIN = [[
  243. uniform sampler2D MainTex;
  244. varying LOVE_HIGHP_OR_MEDIUMP vec4 VaryingTexCoord;
  245. varying mediump vec4 VaryingColor;
  246. vec4 effect(vec4 vcolor, Image tex, vec2 texcoord, vec2 pixcoord);
  247. void main() {
  248. love_PixelColor = effect(VaryingColor, MainTex, VaryingTexCoord.st, love_PixelCoord);
  249. }]],
  250. MAIN_CUSTOM = [[
  251. varying LOVE_HIGHP_OR_MEDIUMP vec4 VaryingTexCoord;
  252. varying mediump vec4 VaryingColor;
  253. void effect();
  254. void main() {
  255. effect();
  256. }]],
  257. }
  258. local function getLanguageTarget(code)
  259. if not code then return nil end
  260. return (code:match("^%s*#pragma language (%w+)")) or "glsl1"
  261. end
  262. local function createShaderStageCode(stage, code, lang, gles, glsl1on3, gammacorrect, custom)
  263. stage = stage:upper()
  264. local lines = {
  265. GLSL.VERSION[lang][gles],
  266. "#define "..stage,
  267. glsl1on3 and "#define LOVE_GLSL1_ON_GLSL3 1" or "",
  268. gammacorrect and "#define LOVE_GAMMA_CORRECT 1" or "",
  269. GLSL.SYNTAX,
  270. GLSL[stage].HEADER,
  271. GLSL.UNIFORMS,
  272. GLSL.FUNCTIONS,
  273. GLSL[stage].FUNCTIONS,
  274. custom and GLSL[stage].MAIN_CUSTOM or GLSL[stage].MAIN,
  275. ((lang == "glsl1" or glsl1on3) and not gles) and "#line 0" or "#line 1",
  276. code,
  277. }
  278. return table_concat(lines, "\n")
  279. end
  280. local function isVertexCode(code)
  281. return code:match("vec4%s+position%s*%(") ~= nil
  282. end
  283. local function isPixelCode(code)
  284. if code:match("vec4%s+effect%s*%(") then
  285. return true
  286. elseif code:match("void%s+effect%s*%(") then
  287. -- custom effect function
  288. return true, true
  289. else
  290. return false
  291. end
  292. end
  293. function love.graphics._shaderCodeToGLSL(gles, arg1, arg2)
  294. local vertexcode, pixelcode
  295. local is_custompixel = false -- whether pixel code has "effects" function instead of "effect"
  296. if arg1 then
  297. if isVertexCode(arg1) then
  298. vertexcode = arg1 -- first arg contains vertex shader code
  299. end
  300. local ispixel, isCustomPixel = isPixelCode(arg1)
  301. if ispixel then
  302. pixelcode = arg1 -- first arg contains pixel shader code
  303. is_custompixel = isCustomPixel
  304. end
  305. end
  306. if arg2 then
  307. if isVertexCode(arg2) then
  308. vertexcode = arg2 -- second arg contains vertex shader code
  309. end
  310. local ispixel, isCustomPixel = isPixelCode(arg2)
  311. if ispixel then
  312. pixelcode = arg2 -- second arg contains pixel shader code
  313. is_custompixel = isCustomPixel
  314. end
  315. end
  316. local supportsGLSL3 = love.graphics.getSupported().glsl3
  317. local gammacorrect = love.graphics.isGammaCorrect()
  318. local targetlang = getLanguageTarget(pixelcode or vertexcode)
  319. if getLanguageTarget(vertexcode or pixelcode) ~= targetlang then
  320. error("vertex and pixel shader languages must match", 2)
  321. end
  322. if targetlang == "glsl3" and not supportsGLSL3 then
  323. error("GLSL 3 shaders are not supported on this system!", 2)
  324. end
  325. if targetlang ~= nil and not GLSL.VERSION[targetlang] then
  326. error("Invalid shader language: " .. targetlang, 2)
  327. end
  328. local lang = targetlang or "glsl1"
  329. local glsl1on3 = false
  330. if lang == "glsl1" and supportsGLSL3 then
  331. lang = "glsl3"
  332. glsl1on3 = true
  333. end
  334. if vertexcode then
  335. vertexcode = createShaderStageCode("VERTEX", vertexcode, lang, gles, glsl1on3, gammacorrect)
  336. end
  337. if pixelcode then
  338. pixelcode = createShaderStageCode("PIXEL", pixelcode, lang, gles, glsl1on3, gammacorrect, is_custompixel)
  339. end
  340. return vertexcode, pixelcode
  341. end
  342. function love.graphics._transformGLSLErrorMessages(message)
  343. local compiling = true
  344. local shadertype = message:match("Cannot compile (%a+) shader code")
  345. if not shadertype then
  346. compiling = false
  347. shadertype = message:match("Error validating (%a+) shader")
  348. end
  349. if not shadertype then return message end
  350. local lines = {}
  351. if compiling then
  352. lines[#lines+1] = "Cannot compile "..shadertype.." shader code:"
  353. else
  354. lines[#lines+1] = "Error validating "..shadertype.." shader code:"
  355. end
  356. for l in message:gmatch("[^\n]+") do
  357. -- nvidia compiler message:
  358. -- 0(<linenumber>) : error/warning [NUMBER]: <error message>
  359. local linenumber, what, message = l:match("^0%((%d+)%)%s*:%s*(%w+)[^:]+:%s*(.+)$")
  360. if not linenumber then
  361. -- ati compiler message:
  362. -- ERROR 0:<linenumber>: error/warning(#[NUMBER]) [ERRORNAME]: <errormessage>
  363. linenumber, what, message = l:match("^%w+: 0:(%d+):%s*(%w+)%([^%)]+%)%s*(.+)$")
  364. end
  365. if not linenumber then
  366. -- OSX compiler message (?):
  367. -- ERROR: 0:<linenumber>: <errormessage>
  368. what, linenumber, message = l:match("^(%w+): %d+:(%d+): (.+)$")
  369. end
  370. if not linenumber and l:match("^ERROR:") then
  371. what = l
  372. end
  373. if linenumber and what and message then
  374. lines[#lines+1] = ("Line %d: %s: %s"):format(linenumber, what, message)
  375. elseif what then
  376. lines[#lines+1] = what
  377. end
  378. end
  379. -- did not match any known error messages
  380. if #lines == 1 then return message end
  381. return table_concat(lines, "\n")
  382. end
  383. local defaultcode = {
  384. vertex = [[
  385. vec4 position(mat4 clipSpaceFromLocal, vec4 localPosition) {
  386. return clipSpaceFromLocal * localPosition;
  387. }]],
  388. pixel = [[
  389. vec4 effect(vec4 vcolor, Image tex, vec2 texcoord, vec2 pixcoord) {
  390. return Texel(tex, texcoord) * vcolor;
  391. }]],
  392. videopixel = [[
  393. void effect() {
  394. love_PixelColor = VideoTexel(VaryingTexCoord.xy) * VaryingColor;
  395. }]],
  396. arraypixel = [[
  397. uniform ArrayImage MainTex;
  398. void effect() {
  399. love_PixelColor = Texel(MainTex, VaryingTexCoord.xyz) * VaryingColor;
  400. }]],
  401. }
  402. local defaults = {}
  403. local defaults_gammacorrect = {}
  404. local langs = {
  405. glsl1 = {target="glsl1", gles=false},
  406. essl1 = {target="glsl1", gles=true},
  407. glsl3 = {target="glsl3", gles=false},
  408. essl3 = {target="glsl3", gles=true},
  409. }
  410. for lang, info in pairs(langs) do
  411. for _, gammacorrect in ipairs{false, true} do
  412. local t = gammacorrect and defaults_gammacorrect or defaults
  413. t[lang] = {
  414. vertex = createShaderStageCode("VERTEX", defaultcode.vertex, info.target, info.gles, false, gammacorrect),
  415. pixel = createShaderStageCode("PIXEL", defaultcode.pixel, info.target, info.gles, false, gammacorrect, false),
  416. videopixel = createShaderStageCode("PIXEL", defaultcode.videopixel, info.target, info.gles, false, gammacorrect, true),
  417. arraypixel = createShaderStageCode("PIXEL", defaultcode.arraypixel, info.target, info.gles, false, gammacorrect, true),
  418. }
  419. end
  420. end
  421. love.graphics._setDefaultShaderCode(defaults, defaults_gammacorrect)
  422. function love.graphics.newVideo(file, settings)
  423. settings = settings == nil and {} or settings
  424. if type(settings) ~= "table" then error("bad argument #2 to newVideo (expected table)", 2) end
  425. local video = love.graphics._newVideo(file, settings.dpiscale)
  426. local source, success
  427. if settings.audio ~= false and love.audio then
  428. success, source = pcall(love.audio.newSource, video:getStream():getFilename(), "stream")
  429. end
  430. if success then
  431. video:setSource(source)
  432. elseif settings.audio == true then
  433. if love.audio then
  434. error("Video had no audio track", 2)
  435. else
  436. error("love.audio was not loaded", 2)
  437. end
  438. else
  439. video:getStream():setSync()
  440. end
  441. return video
  442. end
  443. -- DO NOT REMOVE THE NEXT LINE. It is used to load this file as a C++ string.
  444. --)luastring"--"