GLSL Error Handling
Moderator: Moderators
GLSL Error Handling
gl.CreateShader is causing Spring to crash, if the hardware cannot run shaders.
Why is it doing that? I can understand that callout not working, and returning a false result when it tries to compile, but it should attempt to run... and it's causing a crash, instead. Anybody know why?
Why is it doing that? I can understand that callout not working, and returning a false result when it tries to compile, but it should attempt to run... and it's causing a crash, instead. Anybody know why?
Re: GLSL Error Handling
You need to read error messages a little better:
attempt to call field 'CreateShader' (a nil value)
Code: Select all
if (gl.CreateShader == nil) then
Spring.Echo("oh snap")
gadgetHandler:RemoveGadget()
end
Re: GLSL Error Handling
But why is that field missing?
Re: GLSL Error Handling
Because the Lua OGL environment only makes the callout available (== non-nil) when
since otherwise

Code: Select all
haveGL20 && !!configHandler.Get("LuaShaders", 1)
would actually be true.glCreateShader is causing Spring to crash

Re: GLSL Error Handling
Okie doke. Seems like it would be better to have it run a function that does nothing, imo, instead of causing a crash. At least now I know what's going on.
Re: GLSL Error Handling
Silently failing is pretty bad; then you'd be wondering why your shader is empty.
Re: GLSL Error Handling
Well, since the crash doesn't happen on any of the hardware we're testing on... not knowing that this was occurring was a major problem.
You guys realize that this has ruined three releases now, for people with hardware that can't do GLSL?
You guys realize that this has ruined three releases now, for people with hardware that can't do GLSL?
Re: GLSL Error Handling
Ohh, so it is our fault that you didn't read the wiki?Argh wrote:You guys realize that this has ruined three releases now, for people with hardware that can't do GLSL?
- Attachments
-
- glslwiki.png
- (110.81 KiB) Downloaded 251 times
Re: GLSL Error Handling
1. Now you have something you need to add to your testing regimen. Run a game without modui or lua shaders. Those are rather obscure settings that can break many assumptions.
2. IIRC you can't make shaders during loading or init on GML spring, so if you make your code compatible there, loading this in a Draw* call the way you're supposed to, the error will simply output and stop that single gadget.
2. IIRC you can't make shaders during loading or init on GML spring, so if you make your code compatible there, loading this in a Draw* call the way you're supposed to, the error will simply output and stop that single gadget.
Re: GLSL Error Handling
Running the game without modui makes the game unplayable, at a practical level. I have to assume that if people can't run modui, they're below the hardware requirements.Now you have something you need to add to your testing regimen. Run a game without modui or lua shaders. Those are rather obscure settings that can break many assumptions.
I'll see if running without Lua shaders causes the same crash behavior over here. It'd be good to have some way to test for that particular trap.
Re: GLSL Error Handling
Where in the gadget is this code? Inside a function?
Re: GLSL Error Handling
It's in Initialize().
I'll move it, if I know where it should go. In a function called from Draw*, you said?
Meh. I really, really gtg now. I'll read this when I get back.
The lua's here:
I'll move it, if I know where it should go. In a function called from Draw*, you said?
Meh. I really, really gtg now. I'll read this when I get back.
The lua's here:
Code: Select all
function gadget:GetInfo()
return {
name = "GLSL Lighting",
desc = "The P.U.R.E. GLSL Realtime lighting implementation.",
author = "Argh",
date = "November 7, 2008",
license = "Public Domain, or the least-restrictive rights in your country of residence",
layer = 0,
enabled = true -- loaded by default?
}
end
if (gadgetHandler:IsSyncedCode()) then
----------------------------------------------------------------------------------------------------------SYNCED
local function CreateLightMe(u, ud, team, p, r, g, b, a)
p = Spring.GetUnitScriptPiece(u,p)
r = r / 255
g = g / 255
b = b / 255
a = a / 255
SendToUnsynced("CreateLight",u, ud, team, p, r, g, b, a)
end
local function DestroyLightMe(u, ud, team)
SendToUnsynced("DestroyLight",u, ud, team)
end
function gadget:Initialize()
gadgetHandler:RegisterGlobal("CreateLightMe", CreateLightMe)
gadgetHandler:RegisterGlobal("DestroyLightMe", DestroyLightMe)
end
function gadget:UnitDestroyed(u,ud,team)
SendToUnsynced("DestroyLight",u, ud, team)
end
----------------------------------------------------------------------------------------------------------END SYNCED
else
----------------------------------------------------------------------------------------------------------UNSYNCED
----------------------------------------------------------------------------------------------------------INITIALIZE SHADER
function gadget:Initialize()
if(gl.CreateShader == nil) then
Spring.Echo("GLSL Light Shader Failed")
gadgetHandler:RemoveGadget()
return false
end
GLSL_LIGHT_Shader = gl.CreateShader({
vertex = [[
varying vec4 diffuse;
void main()
{
gl_Position = ftransform();
vec3 normal = gl_NormalMatrix * gl_Normal;
vec3 lightVector = gl_LightSource[1].position.xyz - (gl_ModelViewMatrix * gl_Vertex);
float dist = length(lightVector);
float attenuation = 1.0 / (gl_LightSource[1].constantAttenuation +
gl_LightSource[1].linearAttenuation * dist +
gl_LightSource[1].quadraticAttenuation * dist * dist);
lightVector = normalize(lightVector);
float nxDir = max(0.0, dot(normal, lightVector));
diffuse = gl_FrontMaterial.diffuse * nxDir * attenuation;
}
]],
fragment = [[
varying vec4 diffuse;
void main()
{
gl_FragColor = (gl_LightSource[1].ambient + diffuse);
}
]],
})
if (GLSL_LIGHT_Shader == nil) then
Spring.Echo("GLSL Light Shader Failed"..gl.GetShaderLog())
gadgetHandler:RemoveGadget()
return false
else
Spring.Echo("GLSL Light Shader Succeeded")
UseShader = 1;
end
end
----------------------------------------------------------------------------------------------------------END INITIALIZE
----------------------------------------------------------------------------------------------------------LIGHT LIST HANDLER
local tinsert = table.insert
local tremove = table.remove
local LightList = {piece, red, green, blue, alpha}
local GetUnitPiecePosDir = Spring.GetUnitPiecePosDir
function gadget:RecvFromSynced(name, u, ud, team, p, r, g, b, a)
if name == "CreateLight" then
if LightList[u] ~= nil then
LightList[u] = nil
--Spring.Echo("table removed")
end
tinsert(LightList,u,{piece = p, red = r, green = g, blue = b, alpha = a})
end
if name == "DestroyLight" then
if LightList[u] ~= nil then
LightList[u] = nil
--Spring.Echo("table removed by Destroy")
end
end
end
----------------------------------------------------------------------------------------------------------END LIGHT LIST HANDLER
----------------------------------------------------------------------------------------------------------RENDERING
local x,y,z = 0,0,0
local glDepthTest = gl.DepthTest
local GL_LEQUAL = GL.LEQUAL
local glCulling = gl.Culling
local GL_BACK = GL.BACK
local glBlending = gl.Blending
local glLighting = gl.Lighting
local GetUnitPiecePosDir = Spring.GetUnitPiecePosDir
local glLight = gl.Light
local GL_POSITION = GL.POSITION
local glMaterial = gl.Material
local glUseShader = gl.UseShader
local glPolygonOffset = gl.PolygonOffset
local glUnit = gl.Unit
local glResetState = gl.ResetState
local GetVisibleUnits = Spring.GetVisibleUnits
local GetUnitLosState = Spring.GetUnitLosState
local myTeam = Spring.GetLocalAllyTeamID()
local myState
function gadget:DrawWorld()
if UseShader == 1 then
local myIDList = GetVisibleUnits(-1,3000,false)
if myIDList[1] ~= nil then
for _,myID in ipairs(myIDList) do
myState = GetUnitLosState(myID,myTeam)
if myState["los"] == true then
if LightList[myID] ~= nil then
glDepthTest(GL_LEQUAL)
glCulling(GL_BACK)
glBlending(true)
glLighting(true)
x,y,z = GetUnitPiecePosDir(myID,LightList[myID].piece)
glLight(1,GL_POSITION,x,y,z,1)
glMaterial ({
ambient = {0, 0, 0, 0},
diffuse = {LightList[myID].red,LightList[myID].green,LightList[myID].blue,LightList[myID].alpha},
ambidiff = {0, 0, 0, 0},
emission = {0, 0, 0, 0},
specular = {0, 0, 0, 0},
shininess = 10
})
glUseShader(GLSL_LIGHT_Shader)
glPolygonOffset(-3,-3)
glUnit(myID,true)
glLight(0,false)
glPolygonOffset(0,0)
glResetState()
glLighting(false)
end
end
end
end
end
end
----------------------------------------------------------------------------------------------------------END
end
Re: GLSL Error Handling
Or better yet:me wrote:i suggest:Code: Select all
local GLSL_LIGHTING_VP = [[ ...glsl code... ]]
Code: Select all
local GLSL_LIGHTING_VP = VFS.Include('../shaders/lighting.vp')
Last edited by SpliFF on 28 Mar 2009, 10:56, edited 1 time in total.
Re: GLSL Error Handling
referring to argh's point about how this has ruined 3 of his releases
if he properly tested on different machines (OS's and hardware)
and had a proper updating method most of these "problems" could be avoided
if he properly tested on different machines (OS's and hardware)
and had a proper updating method most of these "problems" could be avoided
Re: GLSL Error Handling
You don't need different machines, you can disable the shaders, which has the same effect as if it was running on an incapbable GPU.
- clericvash
- Posts: 1394
- Joined: 05 Oct 2004, 01:05
Re: GLSL Error Handling
+1, it would help to test things through and through before you release, i made many mistakes with my forum software.rattle wrote:You don't need different machines, you can disable the shaders, which has the same effect as if it was running on an incapbable GPU.
Re: GLSL Error Handling
Well, now that I know that, I can do that. Didn't know I could. Ah well.