GLSL Error Handling

GLSL Error Handling

Discuss the source code and development of Spring Engine in general from a technical point of view. Patches go here too.

Moderator: Moderators

Post Reply
User avatar
Argh
Posts: 10920
Joined: 21 Feb 2005, 03:38

GLSL Error Handling

Post by Argh »

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?
Kloot
Spring Developer
Posts: 1867
Joined: 08 Oct 2006, 16:58

Re: GLSL Error Handling

Post by Kloot »

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
User avatar
Argh
Posts: 10920
Joined: 21 Feb 2005, 03:38

Re: GLSL Error Handling

Post by Argh »

But why is that field missing?
Kloot
Spring Developer
Posts: 1867
Joined: 08 Oct 2006, 16:58

Re: GLSL Error Handling

Post by Kloot »

Because the Lua OGL environment only makes the callout available (== non-nil) when

Code: Select all

haveGL20 && !!configHandler.Get("LuaShaders", 1)
since otherwise
glCreateShader is causing Spring to crash
would actually be true. ;)
User avatar
Argh
Posts: 10920
Joined: 21 Feb 2005, 03:38

Re: GLSL Error Handling

Post by Argh »

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.
User avatar
lurker
Posts: 3842
Joined: 08 Jan 2007, 06:13

Re: GLSL Error Handling

Post by lurker »

Silently failing is pretty bad; then you'd be wondering why your shader is empty.
User avatar
Argh
Posts: 10920
Joined: 21 Feb 2005, 03:38

Re: GLSL Error Handling

Post by Argh »

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?
User avatar
jK
Spring Developer
Posts: 2299
Joined: 28 Jun 2007, 07:30

Re: GLSL Error Handling

Post by jK »

Argh wrote:You guys realize that this has ruined three releases now, for people with hardware that can't do GLSL?
Ohh, so it is our fault that you didn't read the wiki?
Image
Attachments
glslwiki.png
(110.81 KiB) Downloaded 251 times
User avatar
lurker
Posts: 3842
Joined: 08 Jan 2007, 06:13

Re: GLSL Error Handling

Post by lurker »

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.
User avatar
Argh
Posts: 10920
Joined: 21 Feb 2005, 03:38

Re: GLSL Error Handling

Post by Argh »

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.
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.

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.
User avatar
lurker
Posts: 3842
Joined: 08 Jan 2007, 06:13

Re: GLSL Error Handling

Post by lurker »

Where in the gadget is this code? Inside a function?
User avatar
Argh
Posts: 10920
Joined: 21 Feb 2005, 03:38

Re: GLSL Error Handling

Post by Argh »

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:

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
User avatar
SpliFF
Posts: 1224
Joined: 28 Jul 2008, 06:51

Re: GLSL Error Handling

Post by SpliFF »

me wrote:i suggest:

Code: Select all

local GLSL_LIGHTING_VP = [[
...glsl code...
]]
Or better yet:

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.
User avatar
Otherside
Posts: 2296
Joined: 21 Feb 2006, 14:09

Re: GLSL Error Handling

Post by Otherside »

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
User avatar
rattle
Damned Developer
Posts: 8278
Joined: 01 Jun 2006, 13:15

Re: GLSL Error Handling

Post by rattle »

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.
User avatar
clericvash
Posts: 1394
Joined: 05 Oct 2004, 01:05

Re: GLSL Error Handling

Post by clericvash »

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.
+1, it would help to test things through and through before you release, i made many mistakes with my forum software.
User avatar
Argh
Posts: 10920
Joined: 21 Feb 2005, 03:38

Re: GLSL Error Handling

Post by Argh »

Well, now that I know that, I can do that. Didn't know I could. Ah well.
Post Reply

Return to “Engine”