graphics.lua 7.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256
  1. --[[
  2. Copyright (c) 2006-2015 LOVE Development Team
  3. This software is provided 'as-is', without any express or implied
  4. warranty. In no event will the authors be held liable for any damages
  5. arising from the use of this software.
  6. Permission is granted to anyone to use this software for any purpose,
  7. including commercial applications, and to alter it and redistribute it
  8. freely, subject to the following restrictions:
  9. 1. The origin of this software must not be misrepresented; you must not
  10. claim that you wrote the original software. If you use this software
  11. in a product, an acknowledgment in the product documentation would be
  12. appreciated but is not required.
  13. 2. Altered source versions must be plainly marked as such, and must not be
  14. misrepresented as being the original software.
  15. 3. This notice may not be removed or altered from any source distribution.
  16. --]]
  17. local table_concat = table.concat
  18. -- SHADERS
  19. local GLSL = {}
  20. GLSL.VERSION = "#version 120"
  21. GLSL.VERSION_ES = "#version 100"
  22. GLSL.SYNTAX = [[
  23. #ifndef GL_ES
  24. #define lowp
  25. #define mediump
  26. #define highp
  27. #endif
  28. #define number float
  29. #define Image sampler2D
  30. #define extern uniform
  31. #define Texel texture2D
  32. #pragma optionNV(strict on)]]
  33. -- Uniforms shared by the vertex and pixel shader stages.
  34. GLSL.UNIFORMS = [[
  35. #ifdef GL_ES
  36. // According to the GLSL ES 1.0 spec, uniform precision must match between stages,
  37. // but we can't guarantee that highp is always supported in fragment shaders...
  38. // We *really* don't want to use mediump for these in vertex shaders though.
  39. #if defined(VERTEX) || defined(GL_FRAGMENT_PRECISION_HIGH)
  40. #define LOVE_UNIFORM_PRECISION highp
  41. #else
  42. #define LOVE_UNIFORM_PRECISION mediump
  43. #endif
  44. uniform LOVE_UNIFORM_PRECISION mat4 TransformMatrix;
  45. uniform LOVE_UNIFORM_PRECISION mat4 ProjectionMatrix;
  46. uniform LOVE_UNIFORM_PRECISION mat4 TransformProjectionMatrix;
  47. #else
  48. #define TransformMatrix gl_ModelViewMatrix
  49. #define ProjectionMatrix gl_ProjectionMatrix
  50. #define TransformProjectionMatrix gl_ModelViewProjectionMatrix
  51. #endif
  52. uniform mediump vec4 love_ScreenSize;]]
  53. GLSL.VERTEX = {
  54. HEADER = [[
  55. #define VERTEX
  56. attribute vec4 VertexPosition;
  57. attribute vec4 VertexTexCoord;
  58. attribute vec4 VertexColor;
  59. varying vec4 VaryingTexCoord;
  60. varying vec4 VaryingColor;
  61. #ifdef GL_ES
  62. uniform mediump float love_PointSize;
  63. #endif]],
  64. FOOTER = [[
  65. void main() {
  66. VaryingTexCoord = VertexTexCoord;
  67. VaryingColor = VertexColor;
  68. #ifdef GL_ES
  69. gl_PointSize = love_PointSize;
  70. #endif
  71. gl_Position = position(TransformProjectionMatrix, VertexPosition);
  72. }]],
  73. }
  74. GLSL.PIXEL = {
  75. HEADER = [[
  76. #define PIXEL
  77. #ifdef GL_ES
  78. precision mediump float;
  79. #endif
  80. varying mediump vec4 VaryingTexCoord;
  81. varying lowp vec4 VaryingColor;
  82. #define love_Canvases gl_FragData
  83. uniform sampler2D _tex0_;]],
  84. FOOTER = [[
  85. void main() {
  86. // fix crashing issue in OSX when _tex0_ is unused within effect()
  87. float dummy = Texel(_tex0_, vec2(.5)).r;
  88. // See Shader::checkSetScreenParams in Shader.cpp.
  89. vec2 pixelcoord = vec2(gl_FragCoord.x, (gl_FragCoord.y * love_ScreenSize.z) + love_ScreenSize.w);
  90. gl_FragColor = effect(VaryingColor, _tex0_, VaryingTexCoord.st, pixelcoord);
  91. }]],
  92. FOOTER_MULTI_CANVAS = [[
  93. void main() {
  94. // fix crashing issue in OSX when _tex0_ is unused within effect()
  95. float dummy = Texel(_tex0_, vec2(.5)).r;
  96. // See Shader::checkSetScreenParams in Shader.cpp.
  97. vec2 pixelcoord = vec2(gl_FragCoord.x, (gl_FragCoord.y * love_ScreenSize.z) + love_ScreenSize.w);
  98. effects(VaryingColor, _tex0_, VaryingTexCoord.st, pixelcoord);
  99. }]],
  100. }
  101. local function createVertexCode(vertexcode, lang)
  102. local vertexcodes = {
  103. lang == "glsles" and GLSL.VERSION_ES or GLSL.VERSION,
  104. GLSL.SYNTAX, GLSL.VERTEX.HEADER, GLSL.UNIFORMS,
  105. lang == "glsles" and "#line 1" or "#line 0",
  106. vertexcode,
  107. GLSL.VERTEX.FOOTER,
  108. }
  109. return table_concat(vertexcodes, "\n")
  110. end
  111. local function createPixelCode(pixelcode, is_multicanvas, lang)
  112. local pixelcodes = {
  113. lang == "glsles" and GLSL.VERSION_ES or GLSL.VERSION,
  114. GLSL.SYNTAX, GLSL.PIXEL.HEADER, GLSL.UNIFORMS,
  115. lang == "glsles" and "#line 1" or "#line 0",
  116. pixelcode,
  117. is_multicanvas and GLSL.PIXEL.FOOTER_MULTI_CANVAS or GLSL.PIXEL.FOOTER,
  118. }
  119. return table_concat(pixelcodes, "\n")
  120. end
  121. local function isVertexCode(code)
  122. return code:match("vec4%s+position%s*%(") ~= nil
  123. end
  124. local function isPixelCode(code)
  125. if code:match("vec4%s+effect%s*%(") then
  126. return true
  127. elseif code:match("void%s+effects%s*%(") then
  128. -- function for rendering to multiple canvases simultaneously
  129. return true, true
  130. else
  131. return false
  132. end
  133. end
  134. function love.graphics._shaderCodeToGLSL(arg1, arg2)
  135. local vertexcode, pixelcode
  136. local is_multicanvas = false -- whether pixel code has "effects" function instead of "effect"
  137. local lang = "glsl"
  138. if (love.graphics.getRendererInfo()) == "OpenGL ES" then
  139. lang = "glsles"
  140. end
  141. if arg1 then
  142. if isVertexCode(arg1) then
  143. vertexcode = arg1 -- first arg contains vertex shader code
  144. end
  145. local ispixel, isMultiCanvas = isPixelCode(arg1)
  146. if ispixel then
  147. pixelcode = arg1 -- first arg contains pixel shader code
  148. is_multicanvas = isMultiCanvas
  149. end
  150. end
  151. if arg2 then
  152. if isVertexCode(arg2) then
  153. vertexcode = arg2 -- second arg contains vertex shader code
  154. end
  155. local ispixel, isMultiCanvas = isPixelCode(arg2)
  156. if ispixel then
  157. pixelcode = arg2 -- second arg contains pixel shader code
  158. is_multicanvas = isMultiCanvas
  159. end
  160. end
  161. if vertexcode then
  162. vertexcode = createVertexCode(vertexcode, lang)
  163. end
  164. if pixelcode then
  165. pixelcode = createPixelCode(pixelcode, is_multicanvas, lang)
  166. end
  167. return vertexcode, pixelcode
  168. end
  169. function love.graphics._transformGLSLErrorMessages(message)
  170. local shadertype = message:match("Cannot compile (%a+) shader code")
  171. if not shadertype then return message end
  172. local lines = {"Cannot compile "..shadertype.." shader code:"}
  173. for l in message:gmatch("[^\n]+") do
  174. -- nvidia compiler message:
  175. -- 0(<linenumber>) : error/warning [NUMBER]: <error message>
  176. local linenumber, what, message = l:match("^0%((%d+)%)%s*:%s*(%w+)[^:]+:%s*(.+)$")
  177. if not linenumber then
  178. -- ati compiler message:
  179. -- ERROR 0:<linenumber>: error/warning(#[NUMBER]) [ERRORNAME]: <errormessage>
  180. linenumber, what, message = l:match("^%w+: 0:(%d+):%s*(%w+)%([^%)]+%)%s*(.+)$")
  181. if not linenumber then
  182. -- OSX compiler message (?):
  183. -- ERROR: 0:<linenumber>: <errormessage>
  184. what, linenumber, message = l:match("^(%w+): %d+:(%d+): (.+)$")
  185. end
  186. end
  187. if linenumber and what and message then
  188. lines[#lines+1] = ("Line %d: %s: %s"):format(linenumber, what, message)
  189. end
  190. end
  191. -- did not match any known error messages
  192. if #lines == 1 then return message end
  193. return table_concat(lines, "\n")
  194. end
  195. local defaultcode = {
  196. vertex = [[
  197. vec4 position(mat4 transform_proj, vec4 vertpos) {
  198. return transform_proj * vertpos;
  199. }]],
  200. pixel = [[
  201. vec4 effect(lowp vec4 vcolor, Image tex, vec2 texcoord, vec2 pixcoord) {
  202. return Texel(tex, texcoord) * vcolor;
  203. }]]
  204. }
  205. local defaults = {
  206. opengl = {
  207. createVertexCode(defaultcode.vertex, "glsl"),
  208. createPixelCode(defaultcode.pixel, false, "glsl"),
  209. },
  210. opengles = {
  211. createVertexCode(defaultcode.vertex, "glsles"),
  212. createPixelCode(defaultcode.pixel, false, "glsles"),
  213. },
  214. }
  215. love.graphics._setDefaultShaderCode(defaults)