Files
love/src/scripts/graphics.lua
T
Alex Szpakowski 9313484fcc Cleaned up graphics.lua a bit
--HG--
branch : minor
2015-02-28 00:11:27 -04:00

249 lines
6.6 KiB
Lua

--[[
Copyright (c) 2006-2015 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.concat
-- SHADERS
local GLSL = {}
GLSL.VERSION = "#version 120"
GLSL.VERSION_ES = "#version 100"
GLSL.SYNTAX = [[
#ifndef GL_ES
#define lowp
#define mediump
#define highp
#endif
#define number float
#define Image sampler2D
#define extern uniform
#define Texel texture2D
#pragma optionNV(strict on)]]
-- Uniforms shared by the vertex and pixel shader stages.
GLSL.UNIFORMS = [[
#ifdef GL_ES
uniform mat4 TransformMatrix;
uniform mat4 ProjectionMatrix;
uniform mat4 TransformProjectionMatrix;
#else
#define TransformMatrix gl_ModelViewMatrix
#define ProjectionMatrix gl_ProjectionMatrix
#define TransformProjectionMatrix gl_ModelViewProjectionMatrix
#endif
uniform mediump vec4 love_ScreenSize;]]
GLSL.VERTEX = {
HEADER = [[
#define VERTEX
attribute vec4 VertexPosition;
attribute vec4 VertexTexCoord;
attribute vec4 VertexColor;
varying vec4 VaryingTexCoord;
varying vec4 VaryingColor;
#ifdef GL_ES
uniform mediump float love_PointSize;
#endif]],
FOOTER = [[
void main() {
VaryingTexCoord = VertexTexCoord;
VaryingColor = VertexColor;
#ifdef GL_ES
gl_PointSize = love_PointSize;
#endif
gl_Position = position(TransformProjectionMatrix, VertexPosition);
}]],
}
GLSL.PIXEL = {
HEADER = [[
#define PIXEL
#ifdef GL_ES
precision mediump float;
#endif
varying mediump vec4 VaryingTexCoord;
varying lowp vec4 VaryingColor;
#define love_Canvases gl_FragData
uniform sampler2D _tex0_;]],
FOOTER = [[
void main() {
// fix crashing issue in OSX when _tex0_ is unused within effect()
float dummy = Texel(_tex0_, vec2(.5)).r;
// See Shader::checkSetScreenParams in Shader.cpp.
vec2 pixelcoord = vec2(gl_FragCoord.x, (gl_FragCoord.y * love_ScreenSize.z) + love_ScreenSize.w);
gl_FragColor = effect(VaryingColor, _tex0_, VaryingTexCoord.st, pixelcoord);
}]],
FOOTER_MULTI_CANVAS = [[
void main() {
// fix crashing issue in OSX when _tex0_ is unused within effect()
float dummy = Texel(_tex0_, vec2(.5)).r;
// See Shader::checkSetScreenParams in Shader.cpp.
vec2 pixelcoord = vec2(gl_FragCoord.x, (gl_FragCoord.y * love_ScreenSize.z) + love_ScreenSize.w);
effects(VaryingColor, _tex0_, VaryingTexCoord.st, pixelcoord);
}]],
}
local function createVertexCode(vertexcode, lang)
local vertexcodes = {
lang == "glsles" and GLSL.VERSION_ES or GLSL.VERSION,
GLSL.SYNTAX, GLSL.VERTEX.HEADER, GLSL.UNIFORMS,
lang == "glsles" and "#line 1" or "#line 0",
vertexcode,
GLSL.VERTEX.FOOTER,
}
return table_concat(vertexcodes, "\n")
end
local function createPixelCode(pixelcode, is_multicanvas, lang)
local pixelcodes = {
lang == "glsles" and GLSL.VERSION_ES or GLSL.VERSION,
GLSL.SYNTAX, GLSL.PIXEL.HEADER, GLSL.UNIFORMS,
lang == "glsles" and "#line 1" or "#line 0",
pixelcode,
is_multicanvas and GLSL.PIXEL.FOOTER_MULTI_CANVAS or GLSL.PIXEL.FOOTER,
}
return table_concat(pixelcodes, "\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+effects%s*%(") then
-- function for rendering to multiple canvases simultaneously
return true, true
else
return false
end
end
function love.graphics._shaderCodeToGLSL(arg1, arg2)
local vertexcode, pixelcode
local is_multicanvas = false -- whether pixel code has "effects" function instead of "effect"
local lang = "glsl"
if (love.graphics.getRendererInfo()) == "OpenGL ES" then
lang = "glsles"
end
if arg1 then
if isVertexCode(arg1) then
vertexcode = arg1 -- first arg contains vertex shader code
end
local ispixel, isMultiCanvas = isPixelCode(arg1)
if ispixel then
pixelcode = arg1 -- first arg contains pixel shader code
is_multicanvas = isMultiCanvas
end
end
if arg2 then
if isVertexCode(arg2) then
vertexcode = arg2 -- second arg contains vertex shader code
end
local ispixel, isMultiCanvas = isPixelCode(arg2)
if ispixel then
pixelcode = arg2 -- second arg contains pixel shader code
is_multicanvas = isMultiCanvas
end
end
if vertexcode then
vertexcode = createVertexCode(vertexcode, lang)
end
if pixelcode then
pixelcode = createPixelCode(pixelcode, is_multicanvas, lang)
end
return vertexcode, pixelcode
end
function love.graphics._transformGLSLErrorMessages(message)
local shadertype = message:match("Cannot compile (%a+) shader code")
if not shadertype then return message end
local lines = {"Cannot compile "..shadertype.." shader code:"}
for l in message:gmatch("[^\n]+") do
-- nvidia compiler message:
-- 0(<linenumber>) : error/warning [NUMBER]: <error message>
local linenumber, what, message = l:match("^0%((%d+)%)%s*:%s*(%w+)[^:]+:%s*(.+)$")
if not linenumber then
-- ati compiler message:
-- ERROR 0:<linenumber>: error/warning(#[NUMBER]) [ERRORNAME]: <errormessage>
linenumber, what, message = l:match("^%w+: 0:(%d+):%s*(%w+)%([^%)]+%)%s*(.+)$")
if not linenumber then
-- OSX compiler message (?):
-- ERROR: 0:<linenumber>: <errormessage>
what, linenumber, message = l:match("^(%w+): %d+:(%d+): (.+)$")
end
end
if linenumber and what and message then
lines[#lines+1] = ("Line %d: %s: %s"):format(linenumber, what, message)
end
end
-- did not match any known error messages
if #lines == 1 then return message end
return table_concat(lines, "\n")
end
local defaultcode = {
vertex = [[
vec4 position(mat4 transform_proj, vec4 vertpos) {
return transform_proj * vertpos;
}]],
pixel = [[
vec4 effect(lowp vec4 vcolor, Image tex, vec2 texcoord, vec2 pixcoord) {
return Texel(tex, texcoord) * vcolor;
}]]
}
local defaults = {
opengl = {
createVertexCode(defaultcode.vertex, "glsl"),
createPixelCode(defaultcode.pixel, false, "glsl"),
},
opengles = {
createVertexCode(defaultcode.vertex, "glsles"),
createPixelCode(defaultcode.pixel, false, "glsles"),
},
}
love.graphics._setDefaultShaderCode(defaults)