Created
March 28, 2020 16:46
-
-
Save lhog/e344dc006e4974809d38e2138ee18385 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
-- Spring OpenGL abstraction layer (GLAL). Abstracts away the difference between maintenance and develop engines | |
-- Author: ivand/LHoG | |
local isDevelop = (gl.CreateVertexArray ~= nil) | |
if isDevelop then | |
----------------------------------------------------------------- | |
-- Develop | |
----------------------------------------------------------------- | |
local orig = { | |
Vertex = gl.Vertex, | |
BeginEnd = gl.BeginEnd, | |
Color = gl.Color, | |
UseShader = gl.UseShader, | |
ActiveShader = gl.ActiveShader, | |
TexRect = gl.TexRect, | |
Rect = gl.Rect, | |
Texture = gl.Texture, | |
LoadFont = gl.LoadFont, | |
DeleteFont = gl.DeleteFont, | |
} | |
local inBeginEnd = false --TODO remove ? | |
----------------------------------------------------------------- | |
-- Misc functions | |
----------------------------------------------------------------- | |
----------------------------------------------------------------- | |
-- Display list functions | |
----------------------------------------------------------------- | |
gl.CreateList = function(functionName, ...) | |
return { | |
func = functionName, | |
args = {...}, | |
} | |
end | |
gl.CallList = function(dl) | |
dl.func(unpack(dl.args)) | |
end | |
gl.DeleteList = function(dl) | |
dl = nil | |
end | |
----------------------------------------------------------------- | |
-- Unit functions | |
----------------------------------------------------------------- | |
gl.DrawListAtUnit = function(unitID, listID, midPos, ...) | |
gl.DrawFuncAtUnit(unitID, listID, midPos) | |
end | |
----------------------------------------------------------------- | |
-- Line functions | |
----------------------------------------------------------------- | |
gl.LineStipple = function(arg1, arg2) | |
-- Not Implemented | |
end | |
gl.LineWidth = function(width) | |
-- Not Implemented | |
end | |
----------------------------------------------------------------- | |
-- State functions | |
----------------------------------------------------------------- | |
gl.Fog = function(width) | |
-- Not Implemented | |
end | |
gl.FogCoord = function(width) | |
-- Not Implemented | |
end | |
gl.PointSize = function(size) | |
-- Not Implemented | |
end | |
gl.AlphaTest = function(arg1, arg2) | |
-- Not Implemented | |
end | |
----------------------------------------------------------------- | |
-- FFP vertex functions | |
----------------------------------------------------------------- | |
local vertexCounter = 0 | |
gl.Vertex = function(arg1, arg2, arg3, arg4) | |
vertexCounter = vertexCounter + 1 | |
orig.Vertex(arg1, arg2, arg3, arg4) | |
end | |
local currentColor = {0, 0, 0, 0, 0, 0, 0} | |
gl.Color = function(r, g, b, a) | |
if type(r) == "table" then | |
local primColor = unpack(r) | |
currentColor[1] = primColor[1] | |
currentColor[2] = primColor[2] | |
currentColor[3] = primColor[3] | |
currentColor[4] = primColor[4] | |
else | |
currentColor[1] = r | |
currentColor[2] = g | |
currentColor[3] = b | |
currentColor[4] = a | |
end | |
orig.Color( | |
currentColor[1], | |
currentColor[2], | |
currentColor[3], | |
currentColor[4], | |
currentColor[5], | |
currentColor[6], | |
currentColor[7]) | |
end | |
gl.SecondaryColor = function(r, g, b) | |
currentColor[5] = r | |
currentColor[6] = g | |
currentColor[7] = b | |
end | |
----------------------------------------------------------------- | |
-- Shader functions | |
----------------------------------------------------------------- | |
local activeShader = 0 | |
gl.UseShader = function(shaderID) | |
if shaderID == 0 then | |
activeShader = 0 | |
else | |
--don't care if shader is wrong, it's only for bookkeeping purpose | |
activeShader = shaderID | |
end | |
orig.UseShader(shaderID) | |
end | |
gl.ActiveShader = function(shaderID, glFunc, ...) | |
if shaderID == 0 then | |
activeShader = 0 | |
return | |
end | |
activeShader = shaderID | |
orig.ActiveShader(shaderID, glFunc, ...) | |
activeShader = 0 | |
end | |
----------------------------------------------------------------- | |
-- Texture functions | |
----------------------------------------------------------------- | |
local boundTextures = {} | |
gl.Texture = function(arg1, arg2) | |
local tu | |
local tex | |
if arg2 == nil then | |
tu = 0 | |
tex = arg1 | |
else | |
tu = arg1 | |
tex = arg2 | |
end | |
boundTextures[tu] = tex | |
orig.Texture(tu, tex) | |
end | |
----------------------------------------------------------------- | |
-- Shape functions | |
----------------------------------------------------------------- | |
local lastDF = -1 | |
local vertIndices | |
local quadIndex = 0 | |
local function UpdateVertexIndicesForQuad() | |
local df = Spring.GetDrawFrame() | |
if lastDF ~= df then | |
lastDF = df | |
quadIndex = 0 | |
end | |
vertIndices = {} | |
local quadsCount = math.floor(vertexCounter / 4) | |
for quad = 0, quadsCount - 1 do | |
local q = quad + quadIndex | |
-- Upper triangle of QUAD | |
table.insert(vertIndices, 4 * q + 0) --tl | |
table.insert(vertIndices, 4 * q + 1) --tr | |
table.insert(vertIndices, 4 * q + 2) --br | |
-- Lower triangle of QUAD | |
table.insert(vertIndices, 4 * q + 2) --br | |
table.insert(vertIndices, 4 * q + 3) --bl | |
table.insert(vertIndices, 4 * q + 0) --tl | |
end | |
quadIndex = quadIndex + quadsCount | |
gl.VertexIndices(vertIndices) | |
end | |
--[[ | |
struct VA_TYPE_L { | |
float4 p; // Lua can freely set the w-component | |
float3 n; | |
float4 uv; // two channels for basic texturing | |
SColor c0; // primary | |
SColor c1; // secondary | |
}; | |
]]-- | |
local vaTypeLShaderSources = { | |
vs = | |
[[ | |
#version 410 core | |
#extension GL_ARB_explicit_attrib_location : enable | |
// defines | |
#define VA_TYPE VA_TYPE_L | |
// globals | |
// uniforms | |
uniform mat4 u_movi_mat; | |
uniform mat4 u_proj_mat; | |
// VS input attributes | |
layout(location = 0) in vec4 a_vertex_xyzw; | |
layout(location = 1) in vec3 a_normal_xyz; | |
layout(location = 2) in vec2 a_texcoor_stuv; | |
layout(location = 3) in vec4 a_color0_rgba; | |
layout(location = 4) in vec4 a_color1_rgba; | |
// VS output attributes | |
out vec4 v_vertex_xyzw; | |
out vec3 v_normal_xyz; | |
out vec2 v_texcoor_stuv; | |
out vec4 v_color0_rgba; | |
out vec4 v_color1_rgba; | |
void main() { | |
gl_Position = u_proj_mat * u_movi_mat * vec4(a_vertex_xyzw ); | |
v_vertex_xyzw = a_vertex_xyzw; | |
v_normal_xyz = a_normal_xyz; | |
v_texcoor_stuv = a_texcoor_stuv; | |
v_color0_rgba = a_color0_rgba; | |
v_color1_rgba = a_color1_rgba; | |
} | |
]], | |
fs = | |
[[ | |
#version 410 core | |
#extension GL_ARB_explicit_attrib_location : enable | |
// defines | |
#define VA_TYPE VA_TYPE_L | |
// globals | |
// uniforms | |
uniform sampler2D u_tex0; | |
uniform vec4 u_alpha_test_ctrl = vec4(0.0, 0.0, 0.0, 1.0); | |
uniform vec3 u_gamma_exponents = vec3(1.0, 1.0, 1.0); | |
uniform float u_tex_loaded = 0.0; | |
// FS input attributes | |
in vec4 v_vertex_xyzw; | |
in vec3 v_normal_xyz; | |
in vec2 v_texcoor_stuv; | |
in vec4 v_color0_rgba; | |
in vec4 v_color1_rgba; | |
// FS output attributes | |
layout(location = 0) out vec4 f_color_rgba; | |
void main() { | |
f_color_rgba = mix(vec4(1.0), texture(u_tex0, v_texcoor_stuv.st), u_tex_loaded); | |
f_color_rgba *= v_color0_rgba * (1.0 / 255.0); | |
float alpha_test_gt = float(f_color_rgba.a > u_alpha_test_ctrl.x) * u_alpha_test_ctrl.y; | |
float alpha_test_lt = float(f_color_rgba.a < u_alpha_test_ctrl.x) * u_alpha_test_ctrl.z; | |
if ((alpha_test_gt + alpha_test_lt + u_alpha_test_ctrl.w) == 0.0) | |
discard; | |
f_color_rgba.rgb = pow(f_color_rgba.rgb, u_gamma_exponents); | |
} | |
]] | |
} | |
local vertexTypes = { | |
["VA_TYPE_0"] = true, -- p | |
["VA_TYPE_C"] = true, -- p, c | |
["VA_TYPE_T"] = true, -- p, st | |
["VA_TYPE_T4"] = true, -- p, uvwz | |
["VA_TYPE_TN"] = true, -- p, st, n | |
["VA_TYPE_TC"] = true, -- p, st, c | |
["VA_TYPE_2D0"] = true, -- x, y | |
["VA_TYPE_2DT"] = true, -- x, y, st | |
["VA_TYPE_2DTC"] = true, -- x, y, st, c | |
["VA_TYPE_L"] = vaTypeLShaderSources, -- p, n, uvwz, c0, c1 | |
} | |
local defaultShaders = {} | |
local function CompileDefaultShader(shType) | |
if not vertexTypes[shType] then | |
return | |
end | |
local shaderSrc = vertexTypes[shType] | |
if not shaderSrc then | |
return | |
elseif type(shaderSrc) == "boolean" then | |
shaderSrc = gl.GetDefaultShaderSources(shType) | |
end | |
local shader = gl.CreateShader({ | |
vertex = shaderSrc.vs, | |
fragment = shaderSrc.fs, | |
}) | |
local shLog = gl.GetShaderLog() or "" | |
if not shader then | |
--self:ShowError(shLog) | |
Spring.Echo("CompileDefaultShader Error", shLog) | |
return false | |
elseif (shLog ~= "") then | |
--self:ShowWarning(shLog) | |
Spring.Echo("CompileDefaultShader Warning", shLog) | |
end | |
return shader | |
end | |
local DRAW_NONE = 0 | |
local DRAW_GENESIS = 1 | |
local DRAW_WORLD = 2 | |
local DRAW_WORLD_SHADOW = 3 | |
local DRAW_WORLD_REFLECTION = 4 | |
local DRAW_WORLD_REFRACTION = 5 | |
local DRAW_SCREEN = 6 | |
local DRAW_MINIMAP = 7 | |
local DRAW_MINIMAP_BACKGROUND = 8 | |
local worldDrawModes = { | |
[DRAW_GENESIS] = true, | |
[DRAW_WORLD] = true, | |
[DRAW_WORLD_REFLECTION] = true, --? | |
[DRAW_WORLD_REFRACTION] = true, --? | |
} | |
local mmDrawModes = { | |
[DRAW_MINIMAP] = true, | |
[DRAW_MINIMAP_BACKGROUND] = true, | |
} | |
local m1, m2, m3, m4, m5, m6, m7, m8, m9, m10, m11, m12, m13, m14, m15, m16 | |
local p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11, p12, p13, p14, p15, p16 | |
local function GetCallinMatrices() | |
local currDrawMode, prevDrawMode = gl.GetDrawMode() | |
if currDrawMode == prevDrawMode then | |
return true | |
end | |
local m1, m2, m3, m4, m5, m6, m7, m8, m9, m10, m11, m12, m13, m14, m15, m16 | |
local p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11, p12, p13, p14, p15, p16 | |
if worldDrawModes[currDrawMode] then | |
m1, m2, m3, m4, m5, m6, m7, m8, m9, m10, m11, m12, m13, m14, m15, m16 = gl.GetMatrixData("view") | |
p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11, p12, p13, p14, p15, p16 = gl.GetMatrixData("projection") | |
elseif mmDrawModes[currDrawMode] then | |
--skip for now | |
---- | |
---- | |
---- | |
---- | |
elseif currDrawMode == DRAW_SCREEN then | |
m1, m2, m3, m4, m5, m6, m7, m8, m9, m10, m11, m12, m13, m14, m15, m16 = gl.GetScreenViewMatrix() | |
p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11, p12, p13, p14, p15, p16 = gl.GetScreenProjMatrix() | |
elseif currDrawMode == DRAW_WORLD_SHADOW then | |
--skip for now | |
---- | |
---- | |
---- | |
---- | |
end | |
return false, | |
m1, m2, m3, m4, m5, m6, m7, m8, m9, m10, m11, m12, m13, m14, m15, m16, | |
p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11, p12, p13, p14, p15, p16 | |
end | |
local function CondEnableDisableDefaultShaders(shType, glCallFunc, ...) | |
if activeShader ~= 0 then --someone else activated non-default shader | |
glCallFunc(...) | |
return | |
end | |
if defaultShaders[shType] == nil then --can be false | |
defaultShaders[shType] = CompileDefaultShader(shType) | |
end | |
local useOld, _m1, _m2, _m3, _m4, _m5, _m6, _m7, _m8, _m9, _m10, _m11, _m12, _m13, _m14, _m15, _m16, | |
_p1, _p2, _p3, _p4, _p5, _p6, _p7, _p8, _p9, _p10, _p11, _p12, _p13, _p14, _p15, _p16 = GetCallinMatrices() | |
if not useOld then | |
m1, m2, m3, m4, m5, m6, m7, m8, m9, m10, m11, m12, m13, m14, m15, m16 = _m1, _m2, _m3, _m4, _m5, _m6, _m7, _m8, _m9, _m10, _m11, _m12, _m13, _m14, _m15, _m16 | |
p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11, p12, p13, p14, p15, p16 = _p1, _p2, _p3, _p4, _p5, _p6, _p7, _p8, _p9, _p10, _p11, _p12, _p13, _p14, _p15, _p16 | |
end | |
activeShader = defaultShaders[shType] | |
local viewMatLoc = gl.GetUniformLocation(activeShader, "u_movi_mat") | |
local projMatLoc = gl.GetUniformLocation(activeShader, "u_proj_mat") | |
local texLoadLoc = gl.GetUniformLocation(activeShader, "u_tex_loaded") | |
local tu0 = (boundTextures[0] and 1.0) or 0.0 | |
orig.UseShader(activeShader) | |
gl.UniformMatrix(viewMatLoc, m1, m2, m3, m4, m5, m6, m7, m8, m9, m10, m11, m12, m13, m14, m15, m16) | |
gl.UniformMatrix(projMatLoc, p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11, p12, p13, p14, p15, p16) | |
gl.Uniform(texLoadLoc, tu0) | |
glCallFunc(...) | |
orig.UseShader(0) | |
activeShader = 0 | |
end | |
local GL_QUADS = GL.QUADS | |
local GL_TRIANGLES = GL.TRIANGLES | |
gl.BeginEnd = function(glType, glFuncInput, ...) | |
inBeginEnd = true | |
vertexCounter = 0 | |
local glQuads = false | |
local glCallFunc | |
if glType == GL_QUADS then | |
glQuads = true | |
glType = GL_TRIANGLES | |
glCallFunc = function(...) | |
glFuncInput(...) | |
UpdateVertexIndicesForQuad() | |
end | |
else | |
glCallFunc = glFuncInput | |
end | |
CondEnableDisableDefaultShaders("VA_TYPE_L", orig.BeginEnd, glType, glCallFunc, ...) | |
vertexCounter = 0 | |
inBeginEnd = false | |
end | |
gl.TexRect = function(...) | |
CondEnableDisableDefaultShaders("VA_TYPE_TC", orig.TexRect, ...) | |
end | |
gl.Rect = function(...) | |
CondEnableDisableDefaultShaders("VA_TYPE_C", orig.Rect, ...) | |
end | |
gl.Shape = function(glType, shapeArray) | |
--Spring.Echo("gl.Shape") | |
end | |
----------------------------------------------------------------- | |
-- Font functions | |
----------------------------------------------------------------- | |
local CompatFont = setmetatable({}, { | |
__call = function(self, cf) return | |
setmetatable({ | |
sf = cf, | |
}, self) | |
end, | |
}) | |
CompatFont.__index = CompatFont | |
function CompatFont:SetTextColor(r, g, b, a) | |
self.sf:SetTextColor(r, g, b, a) | |
end | |
function CompatFont:SetOutlineColor(r, g, b, a) | |
self.sf:SetOutlineColor(r, g, b, a) | |
end | |
function CompatFont:SetAutoOutlineColor(enable) | |
self.sf:SetAutoOutlineColor(enable) | |
end | |
function CompatFont:GetTextWidth(text) | |
return self.sf:GetTextWidth(text) | |
end | |
function CompatFont:GetTextHeight(text) | |
return self.sf:GetTextHeight(text) | |
end | |
function CompatFont:WrapText(text, max_width, max_height, size) | |
return self.sf:WrapText(text, max_width, max_height, size) | |
end | |
function CompatFont:BindTexture(...) | |
return self.sf:BindTexture(...) | |
end | |
function CompatFont:Begin() | |
--self.sf:Begin() | |
end | |
function CompatFont:End() | |
self.sf:DrawBuffered() | |
--self.sf:End() | |
end | |
function CompatFont:Print(text, x, y, size, options) | |
local vsx, vsy, vx, vy = Spring.GetViewGeometry() | |
x, y = x / vsx, y / vsy --keep it simple for now (no vx/vy) | |
if options:find("n") then | |
options = options:gsub("n", "") | |
end | |
if not options:find("N") then | |
options = options.."N" | |
end | |
if not options:find("B") then | |
options = options.."B" | |
end | |
--options = options.."nN" --just in case | |
--size, options = 23.0, "ocvNB" | |
--Spring.Echo(self, self.sf, self.sf.Print, text, x, y, size, options) | |
self.sf:Print(text, x, y, size, options) | |
end | |
function CompatFont:DrawBuffered() | |
self.sf:DrawBuffered() | |
end | |
function CompatFont:WorldBegin() | |
--origFont | |
cfBeginEnd = true | |
self.sf:WorldBegin() | |
end | |
function CompatFont:WorldEnd() | |
self.sf:WorldEnd() | |
cfBeginEnd = false | |
end | |
function CompatFont:WorldPrint(...) | |
self.sf:WorldPrint(...) | |
end | |
--RenderDataBufferTC | |
loadedFonts = {} | |
gl.LoadFont = function(fn, sz, owi, owe) | |
local sf = orig.LoadFont(fn, sz, owi, owe) | |
--Spring.Echo("gl.LoadFont", fn, sz, owi, owe, sf, sf.Print) | |
if sf then | |
loadedFonts[sf] = true | |
return CompatFont(sf) | |
end | |
--return (sf and CompatFont(sf)) or nil | |
end | |
gl.DeleteFont = function(cf) | |
if cf then | |
if loadedFonts[cf.sf] then | |
orig.DeleteFont(cf.sf) | |
loadedFonts[cf.sf] = nil | |
end | |
cf = nil | |
end | |
end | |
----------------------------------------------------------------- | |
-- Scream Shutdown | |
----------------------------------------------------------------- | |
local glalScream = Script.CreateScream() | |
glalScream.func = function() | |
Spring.Echo("GLAL UNLOAD") | |
for k, v in pairs(defaultShaders) do | |
if v then | |
orig.DeleteShader(v) | |
end | |
end | |
-- somehow crashes the game | |
--[[ | |
for k, v in pairs(loadedFonts) do | |
if v then | |
orig.DeleteFont(k) | |
end | |
end | |
]]-- | |
end | |
----------------------------------------------------------------- | |
-- End of Develop | |
----------------------------------------------------------------- | |
end |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment