123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520 |
- R"luastring"--(
- -- DO NOT REMOVE THE ABOVE LINE. It is used to load this file as a C++ string.
- -- There is a matching delimiter at the bottom of the file.
- --[[
- Copyright (c) 2006-2020 LOVE Development Team
- This software is provided 'as-is', without any express or implied
- warranty. In no event will the authors be held liable for any damages
- arising from the use of this software.
- Permission is granted to anyone to use this software for any purpose,
- including commercial applications, and to alter it and redistribute it
- freely, subject to the following restrictions:
- 1. The origin of this software must not be misrepresented; you must not
- claim that you wrote the original software. If you use this software
- in a product, an acknowledgment in the product documentation would be
- appreciated but is not required.
- 2. Altered source versions must be plainly marked as such, and must not be
- misrepresented as being the original software.
- 3. This notice may not be removed or altered from any source distribution.
- --]]
- local table_concat, table_insert = table.concat, table.insert
- local ipairs = ipairs
- local GLSL = {}
- GLSL.VERSION = { -- index using [target][gles]
- glsl1 = {[false]="#version 120", [true]="#version 100"},
- glsl3 = {[false]="#version 330 core", [true]="#version 300 es"},
- glsl4 = {[false]="#version 430 core", [true]="#version 310 es"},
- }
- GLSL.SYNTAX = [[
- #if !defined(GL_ES) && __VERSION__ < 140
- #define lowp
- #define mediump
- #define highp
- #endif
- #if defined(VERTEX) || __VERSION__ > 100 || defined(GL_FRAGMENT_PRECISION_HIGH)
- #define LOVE_HIGHP_OR_MEDIUMP highp
- #else
- #define LOVE_HIGHP_OR_MEDIUMP mediump
- #endif
- #if __VERSION__ >= 300
- #define LOVE_IO_LOCATION(x) layout (location = x)
- #else
- #define LOVE_IO_LOCATION(x)
- #endif
- #define number float
- #define Image sampler2D
- #define ArrayImage sampler2DArray
- #define CubeImage samplerCube
- #define VolumeImage sampler3D
- #if __VERSION__ >= 300 && !defined(LOVE_GLSL1_ON_GLSL3)
- #define DepthImage sampler2DShadow
- #define DepthArrayImage sampler2DArrayShadow
- #define DepthCubeImage samplerCubeShadow
- #endif
- #define extern uniform
- #ifdef GL_EXT_texture_array
- #extension GL_EXT_texture_array : enable
- #endif
- #ifdef GL_OES_texture_3D
- #extension GL_OES_texture_3D : enable
- #endif
- #ifdef GL_OES_standard_derivatives
- #extension GL_OES_standard_derivatives : enable
- #endif
- ]]
- -- Uniforms shared by the vertex and pixel shader stages.
- GLSL.UNIFORMS = [[
- // According to the GLSL ES 1.0 spec, uniform precision must match between stages,
- // but we can't guarantee that highp is always supported in fragment shaders...
- // We *really* don't want to use mediump for these in vertex shaders though.
- #ifdef LOVE_USE_UNIFORM_BUFFERS
- layout (std140) uniform love_UniformsPerDrawBuffer {
- highp vec4 love_UniformsPerDraw[13];
- };
- #else
- uniform LOVE_HIGHP_OR_MEDIUMP vec4 love_UniformsPerDraw[13];
- #endif
- // These are initialized in love_initializeBuiltinUniforms below. GLSL ES can't
- // do it as an initializer.
- LOVE_HIGHP_OR_MEDIUMP mat4 TransformMatrix;
- LOVE_HIGHP_OR_MEDIUMP mat4 ProjectionMatrix;
- LOVE_HIGHP_OR_MEDIUMP mat3 NormalMatrix;
- LOVE_HIGHP_OR_MEDIUMP vec4 love_ScreenSize;
- LOVE_HIGHP_OR_MEDIUMP vec4 ConstantColor;
- #define TransformProjectionMatrix (ProjectionMatrix * TransformMatrix)
- // Alternate names
- #define ViewSpaceFromLocal TransformMatrix
- #define ClipSpaceFromView ProjectionMatrix
- #define ClipSpaceFromLocal TransformProjectionMatrix
- #define ViewNormalFromLocal NormalMatrix
- void love_initializeBuiltinUniforms() {
- TransformMatrix = mat4(
- love_UniformsPerDraw[0],
- love_UniformsPerDraw[1],
- love_UniformsPerDraw[2],
- love_UniformsPerDraw[3]
- );
- ProjectionMatrix = mat4(
- love_UniformsPerDraw[4],
- love_UniformsPerDraw[5],
- love_UniformsPerDraw[6],
- love_UniformsPerDraw[7]
- );
- NormalMatrix = mat3(
- love_UniformsPerDraw[8].xyz,
- love_UniformsPerDraw[9].xyz,
- love_UniformsPerDraw[10].xyz
- );
- love_ScreenSize = love_UniformsPerDraw[11];
- ConstantColor = love_UniformsPerDraw[12];
- }
- ]]
- GLSL.FUNCTIONS = [[
- #ifdef GL_ES
- #if __VERSION__ >= 300 || defined(GL_EXT_texture_array)
- precision lowp sampler2DArray;
- #endif
- #if __VERSION__ >= 300 || defined(GL_OES_texture_3D)
- precision lowp sampler3D;
- #endif
- #if __VERSION__ >= 300
- precision lowp sampler2DShadow;
- precision lowp samplerCubeShadow;
- precision lowp sampler2DArrayShadow;
- #endif
- #endif
- #if __VERSION__ >= 130 && !defined(LOVE_GLSL1_ON_GLSL3)
- #define Texel texture
- #else
- #if __VERSION__ >= 130
- #define texture2D Texel
- #define texture3D Texel
- #define textureCube Texel
- #define texture2DArray Texel
- #define love_texture2D texture
- #define love_texture3D texture
- #define love_textureCube texture
- #define love_texture2DArray texture
- #else
- #define love_texture2D texture2D
- #define love_texture3D texture3D
- #define love_textureCube textureCube
- #define love_texture2DArray texture2DArray
- #endif
- vec4 Texel(sampler2D s, vec2 c) { return love_texture2D(s, c); }
- vec4 Texel(samplerCube s, vec3 c) { return love_textureCube(s, c); }
- #if __VERSION__ > 100 || defined(GL_OES_texture_3D)
- vec4 Texel(sampler3D s, vec3 c) { return love_texture3D(s, c); }
- #endif
- #if __VERSION__ >= 130 || defined(GL_EXT_texture_array)
- vec4 Texel(sampler2DArray s, vec3 c) { return love_texture2DArray(s, c); }
- #endif
- #ifdef PIXEL
- vec4 Texel(sampler2D s, vec2 c, float b) { return love_texture2D(s, c, b); }
- vec4 Texel(samplerCube s, vec3 c, float b) { return love_textureCube(s, c, b); }
- #if __VERSION__ > 100 || defined(GL_OES_texture_3D)
- vec4 Texel(sampler3D s, vec3 c, float b) { return love_texture3D(s, c, b); }
- #endif
- #if __VERSION__ >= 130 || defined(GL_EXT_texture_array)
- vec4 Texel(sampler2DArray s, vec3 c, float b) { return love_texture2DArray(s, c, b); }
- #endif
- #endif
- #define texture love_texture
- #endif
- float gammaToLinearPrecise(float c) {
- return c <= 0.04045 ? c / 12.92 : pow((c + 0.055) / 1.055, 2.4);
- }
- vec3 gammaToLinearPrecise(vec3 c) {
- bvec3 leq = lessThanEqual(c, vec3(0.04045));
- c.r = leq.r ? c.r / 12.92 : pow((c.r + 0.055) / 1.055, 2.4);
- c.g = leq.g ? c.g / 12.92 : pow((c.g + 0.055) / 1.055, 2.4);
- c.b = leq.b ? c.b / 12.92 : pow((c.b + 0.055) / 1.055, 2.4);
- return c;
- }
- vec4 gammaToLinearPrecise(vec4 c) { return vec4(gammaToLinearPrecise(c.rgb), c.a); }
- float linearToGammaPrecise(float c) {
- return c < 0.0031308 ? c * 12.92 : 1.055 * pow(c, 1.0 / 2.4) - 0.055;
- }
- vec3 linearToGammaPrecise(vec3 c) {
- bvec3 lt = lessThanEqual(c, vec3(0.0031308));
- c.r = lt.r ? c.r * 12.92 : 1.055 * pow(c.r, 1.0 / 2.4) - 0.055;
- c.g = lt.g ? c.g * 12.92 : 1.055 * pow(c.g, 1.0 / 2.4) - 0.055;
- c.b = lt.b ? c.b * 12.92 : 1.055 * pow(c.b, 1.0 / 2.4) - 0.055;
- return c;
- }
- vec4 linearToGammaPrecise(vec4 c) { return vec4(linearToGammaPrecise(c.rgb), c.a); }
- // http://chilliant.blogspot.com.au/2012/08/srgb-approximations-for-hlsl.html?m=1
- mediump float gammaToLinearFast(mediump float c) { return c * (c * (c * 0.305306011 + 0.682171111) + 0.012522878); }
- mediump vec3 gammaToLinearFast(mediump vec3 c) { return c * (c * (c * 0.305306011 + 0.682171111) + 0.012522878); }
- mediump vec4 gammaToLinearFast(mediump vec4 c) { return vec4(gammaToLinearFast(c.rgb), c.a); }
- mediump float linearToGammaFast(mediump float c) { return max(1.055 * pow(max(c, 0.0), 0.41666666) - 0.055, 0.0); }
- mediump vec3 linearToGammaFast(mediump vec3 c) { return max(1.055 * pow(max(c, vec3(0.0)), vec3(0.41666666)) - 0.055, vec3(0.0)); }
- mediump vec4 linearToGammaFast(mediump vec4 c) { return vec4(linearToGammaFast(c.rgb), c.a); }
- #define gammaToLinear gammaToLinearFast
- #define linearToGamma linearToGammaFast
- #ifdef LOVE_GAMMA_CORRECT
- #define gammaCorrectColor gammaToLinear
- #define unGammaCorrectColor linearToGamma
- #define gammaCorrectColorPrecise gammaToLinearPrecise
- #define unGammaCorrectColorPrecise linearToGammaPrecise
- #define gammaCorrectColorFast gammaToLinearFast
- #define unGammaCorrectColorFast linearToGammaFast
- #else
- #define gammaCorrectColor
- #define unGammaCorrectColor
- #define gammaCorrectColorPrecise
- #define unGammaCorrectColorPrecise
- #define gammaCorrectColorFast
- #define unGammaCorrectColorFast
- #endif]]
- GLSL.VERTEX = {
- HEADER = [[
- #define love_Position gl_Position
- #if __VERSION__ >= 130
- #define attribute in
- #define varying out
- #ifndef LOVE_GLSL1_ON_GLSL3
- #define love_VertexID gl_VertexID
- #define love_InstanceID gl_InstanceID
- #endif
- #endif
- #ifdef GL_ES
- uniform mediump float love_PointSize;
- #endif]],
- FUNCTIONS = [[
- void setPointSize() {
- #ifdef GL_ES
- gl_PointSize = love_PointSize;
- #endif
- }]],
- MAIN = [[
- LOVE_IO_LOCATION(0) attribute vec4 VertexPosition;
- LOVE_IO_LOCATION(1) attribute vec4 VertexTexCoord;
- LOVE_IO_LOCATION(2) attribute vec4 VertexColor;
- varying vec4 VaryingTexCoord;
- varying vec4 VaryingColor;
- vec4 position(mat4 clipSpaceFromLocal, vec4 localPosition);
- void main() {
- love_initializeBuiltinUniforms();
- VaryingTexCoord = VertexTexCoord;
- VaryingColor = gammaCorrectColor(VertexColor) * ConstantColor;
- setPointSize();
- love_Position = position(ClipSpaceFromLocal, VertexPosition);
- }]],
- }
- GLSL.PIXEL = {
- HEADER = [[
- #ifdef GL_ES
- precision mediump float;
- #endif
- #define love_MaxRenderTargets gl_MaxDrawBuffers
- #if __VERSION__ >= 130
- #define varying in
- // Some drivers seem to make the pixel shader do more work when multiple
- // pixel shader outputs are defined, even when only one is actually used.
- // TODO: We should use reflection or something instead of this, to determine
- // how many outputs are actually used in the shader code.
- #ifdef LOVE_MULTI_RENDER_TARGETS
- LOVE_IO_LOCATION(0) out vec4 love_RenderTargets[love_MaxRenderTargets];
- #define love_PixelColor love_RenderTargets[0]
- #else
- LOVE_IO_LOCATION(0) out vec4 love_PixelColor;
- #endif
- #else
- #ifdef LOVE_MULTI_RENDER_TARGETS
- #define love_RenderTargets gl_FragData
- #endif
- #define love_PixelColor gl_FragColor
- #endif
- // Legacy
- #define love_MaxCanvases love_MaxRenderTargets
- #define love_Canvases love_RenderTargets
- #ifdef LOVE_MULTI_RENDER_TARGETS
- #define LOVE_MULTI_CANVASES 1
- #endif
- // See Shader::updateScreenParams in Shader.cpp.
- #define love_PixelCoord (vec2(gl_FragCoord.x, (gl_FragCoord.y * love_ScreenSize.z) + love_ScreenSize.w))]],
- FUNCTIONS = [[
- uniform sampler2D love_VideoYChannel;
- uniform sampler2D love_VideoCbChannel;
- uniform sampler2D love_VideoCrChannel;
- vec4 VideoTexel(vec2 texcoords) {
- vec3 yuv;
- yuv[0] = Texel(love_VideoYChannel, texcoords).r;
- yuv[1] = Texel(love_VideoCbChannel, texcoords).r;
- yuv[2] = Texel(love_VideoCrChannel, texcoords).r;
- yuv += vec3(-0.0627451017, -0.501960814, -0.501960814);
- vec4 color;
- color.r = dot(yuv, vec3(1.164, 0.000, 1.596));
- color.g = dot(yuv, vec3(1.164, -0.391, -0.813));
- color.b = dot(yuv, vec3(1.164, 2.018, 0.000));
- color.a = 1.0;
- return gammaCorrectColor(color);
- }]],
- MAIN = [[
- uniform sampler2D MainTex;
- varying LOVE_HIGHP_OR_MEDIUMP vec4 VaryingTexCoord;
- varying mediump vec4 VaryingColor;
- vec4 effect(vec4 vcolor, Image tex, vec2 texcoord, vec2 pixcoord);
- void main() {
- love_initializeBuiltinUniforms();
- love_PixelColor = effect(VaryingColor, MainTex, VaryingTexCoord.st, love_PixelCoord);
- }]],
- MAIN_CUSTOM = [[
- varying LOVE_HIGHP_OR_MEDIUMP vec4 VaryingTexCoord;
- varying mediump vec4 VaryingColor;
- void effect();
- void main() {
- love_initializeBuiltinUniforms();
- effect();
- }]],
- }
- local function getLanguageTarget(code)
- if not code then return nil end
- return (code:match("^%s*#pragma language (%w+)")) or "glsl1"
- end
- local function createShaderStageCode(stage, code, lang, gles, glsl1on3, gammacorrect, custom, multirendertarget, useubo)
- stage = stage:upper()
- local lines = {
- GLSL.VERSION[lang][gles],
- "#define " ..stage .. " " .. stage,
- glsl1on3 and "#define LOVE_GLSL1_ON_GLSL3 1" or "",
- gammacorrect and "#define LOVE_GAMMA_CORRECT 1" or "",
- multirendertarget and "#define LOVE_MULTI_RENDER_TARGETS 1" or "",
- useubo and "#define LOVE_USE_UNIFORM_BUFFERS 1" or "",
- GLSL.SYNTAX,
- GLSL[stage].HEADER,
- GLSL.UNIFORMS,
- GLSL.FUNCTIONS,
- GLSL[stage].FUNCTIONS,
- custom and GLSL[stage].MAIN_CUSTOM or GLSL[stage].MAIN,
- ((lang == "glsl1" or glsl1on3) and not gles) and "#line 0" or "#line 1",
- code,
- }
- return table_concat(lines, "\n")
- end
- local function isVertexCode(code)
- return code:match("vec4%s+position%s*%(") ~= nil
- end
- local function isPixelCode(code)
- if code:match("vec4%s+effect%s*%(") then
- return true
- elseif code:match("void%s+effect%s*%(") then -- custom effect function
- local mrt = (code:match("love_RenderTargets") ~= nil) or (code:match("love_Canvases") ~= nil)
- return true, true, mrt
- else
- return false
- end
- end
- function love.graphics._shaderCodeToGLSL(gles, arg1, arg2)
- local vertexcode, pixelcode
- local is_custompixel = false -- whether pixel code has "effects" function instead of "effect"
- local is_multicanvas = false
- if arg1 then
- if isVertexCode(arg1) then
- vertexcode = arg1 -- first arg contains vertex shader code
- end
- local ispixel, isCustomPixel, isMultiCanvas = isPixelCode(arg1)
- if ispixel then
- pixelcode = arg1 -- first arg contains pixel shader code
- is_custompixel, is_multicanvas = isCustomPixel, isMultiCanvas
- end
- end
-
- if arg2 then
- if isVertexCode(arg2) then
- vertexcode = arg2 -- second arg contains vertex shader code
- end
- local ispixel, isCustomPixel, isMultiCanvas = isPixelCode(arg2)
- if ispixel then
- pixelcode = arg2 -- second arg contains pixel shader code
- is_custompixel, is_multicanvas = isCustomPixel, isMultiCanvas
- end
- end
- local graphicsfeatures = love.graphics.getSupported()
- local supportsGLSL3 = graphicsfeatures.glsl3
- local supportsGLSL4 = graphicsfeatures.glsl4
- local gammacorrect = love.graphics.isGammaCorrect()
- local renderer = love.graphics.getRenderer()
- local useubo = renderer == "Metal"
- local targetlang = getLanguageTarget(pixelcode or vertexcode)
- if getLanguageTarget(vertexcode or pixelcode) ~= targetlang then
- error("vertex and pixel shader languages must match", 2)
- end
- if targetlang == "glsl3" and not supportsGLSL3 then
- error("GLSL 3 shaders are not supported on this system.", 2)
- end
- if targetlang == "glsl4" and not supportsGLSL4 then
- error("GLSL 4 shaders are not supported on this system.", 2)
- end
- if targetlang ~= nil and not GLSL.VERSION[targetlang] then
- error("Invalid shader language: " .. targetlang, 2)
- end
- local lang = targetlang or "glsl1"
- local glsl1on3 = false
- if lang == "glsl1" and supportsGLSL3 then
- lang = "glsl3"
- glsl1on3 = true
- end
- if vertexcode then
- vertexcode = createShaderStageCode("VERTEX", vertexcode, lang, gles, glsl1on3, gammacorrect, false, false, useubo)
- end
- if pixelcode then
- pixelcode = createShaderStageCode("PIXEL", pixelcode, lang, gles, glsl1on3, gammacorrect, is_custompixel, is_multicanvas, useubo)
- end
- return vertexcode, pixelcode
- end
- local defaultcode = {
- vertex = [[
- vec4 position(mat4 clipSpaceFromLocal, vec4 localPosition) {
- return clipSpaceFromLocal * localPosition;
- }]],
- pixel = [[
- vec4 effect(vec4 vcolor, Image tex, vec2 texcoord, vec2 pixcoord) {
- return Texel(tex, texcoord) * vcolor;
- }]],
- videopixel = [[
- void effect() {
- love_PixelColor = VideoTexel(VaryingTexCoord.xy) * VaryingColor;
- }]],
- arraypixel = [[
- uniform ArrayImage MainTex;
- void effect() {
- love_PixelColor = Texel(MainTex, VaryingTexCoord.xyz) * VaryingColor;
- }]],
- }
- local defaults = {}
- local defaults_gammacorrect = {}
- local langs = {
- glsl1 = {target="glsl1", gles=false},
- essl1 = {target="glsl1", gles=true},
- glsl3 = {target="glsl3", gles=false},
- essl3 = {target="glsl3", gles=true},
- }
- -- FIXME: this is temporary until a glslang pull request is merged in.
- local useubo = true
- for lang, info in pairs(langs) do
- for _, gammacorrect in ipairs{false, true} do
- local t = gammacorrect and defaults_gammacorrect or defaults
- t[lang] = {
- vertex = createShaderStageCode("VERTEX", defaultcode.vertex, info.target, info.gles, false, gammacorrect, false, false, useubo),
- pixel = createShaderStageCode("PIXEL", defaultcode.pixel, info.target, info.gles, false, gammacorrect, false, false, useubo),
- videopixel = createShaderStageCode("PIXEL", defaultcode.videopixel, info.target, info.gles, false, gammacorrect, true, false, useubo),
- arraypixel = createShaderStageCode("PIXEL", defaultcode.arraypixel, info.target, info.gles, false, gammacorrect, true, false, useubo),
- }
- end
- end
- love.graphics._setDefaultShaderCode(defaults, defaults_gammacorrect)
- -- DO NOT REMOVE THE NEXT LINE. It is used to load this file as a C++ string.
- --)luastring"--"
|