Lua replacment for set ALPHA_THRESHOLD

Lua replacment for set ALPHA_THRESHOLD

Discuss Lua based Spring scripts (LuaUI widgets, mission scripts, gaia scripts, mod-rules scripts, scripted keybindings, etc...)

Moderator: Moderators

User avatar
zwzsg
Kernel Panic Co-Developer
Posts: 7052
Joined: 16 Nov 2004, 13:08

Lua replacment for set ALPHA_THRESHOLD

Post by zwzsg »

I've been told the bos/cob command set ALPHA_THRESHOLD to a; will not be fixed since it "can be done easily with Lua".

So someone provides me with whatever I need to replace K.P.'s set ALPHA_THRESHOLD to a; statements with, plox.
Kloot
Spring Developer
Posts: 1867
Joined: 08 Oct 2006, 16:58

Re: Lua replacment for set ALPHA_THRESHOLD

Post by Kloot »

Code: Select all

glPushAttrib(GL_COLOR_BUFFER_BIT);
glAlphaFunc(GL_GREATER, a); // AlphaTest() in LOGL
// ... draw ...
glPopAttrib();
Such hardship indeed.
User avatar
zwzsg
Kernel Panic Co-Developer
Posts: 7052
Joined: 16 Nov 2004, 13:08

Re: Lua replacment for set ALPHA_THRESHOLD

Post by zwzsg »

Where do that bit of code go? What do I fill the ... with?

See, Lua might be as evident as mother tongue for some of you, but I have not yet reached that point. I've done great progress and learnt a ton on Spring's Lua, but there are still patches of dark in my knownledge.

As I understand, you posted how to make Lua drawn stuff use alpha. I agree that's most probably a bit of the solution, but far from enough.

Currently, the bos/cob set the alpha value, the engine then use that alpha for the unit. I don't draw the units myself. Units are s3o, of which one texture make use of an alpha channel, the script set alpha threshold, and the engine handle the rest. I now have to handle that rest in Lua.

Do I have to inhibit Spring unit drawing and rewrite my own graphical engine in Lua? Are there some "BeforeDrawingUnit(UnitID)" and "AfterDrawingUnit(UnitID)" Lua call-ins to let me change OpenGL setting for individual units rendering? I guess there might be something in here that I might need, but what and how? The one that mention "enables the DrawUnit callin" interest me, but I would need name of that callin and what to put in it. But maybe another one allows me to set some alpha threshold? Or maybe the whole page is a misleading wrong track.

I don't know how to proceed! And since two devs already told me it's easy, there's hopefully one evident clue I'm missing and then all will be clear. Or, it's not that trivial.
User avatar
lurker
Posts: 3842
Joined: 08 Jan 2007, 06:13

Re: Lua replacment for set ALPHA_THRESHOLD

Post by lurker »

If you change the alpha settings in a unit prelist or an aborted drawunit, it gets overwritten.

If you gl.UnitShape (or Unit? what's the difference?), you get an unposed unit. Breaks on anything that moves.

Clearly you don't mean to draw an entire unit piece by piece, getting each position from calls and using gl.UnitPiece; that's far too much to be the trivially easy way.

I guess you could change the texture continuously but that's a big waste of video ram.

And that's all I can think of. :cry:
User avatar
jK
Spring Developer
Posts: 2299
Joined: 28 Jun 2007, 07:30

Re: Lua replacment for set ALPHA_THRESHOLD

Post by jK »

example:

Code: Select all

--my custom alpha threshold
local x = 0.35

--Unsafe way (but should work fine as long as the engine doesn't change)
local preDLUnsafe = gl.CreateList(gl.AlphaTest, GL.GREATER, x)
local postDLUnsafe = gl.CreateList(gl.AlphaTest, GL.GREATER, 0.5)

--Safe way
local GL_COLOR_BUFFER_BIT = 0x4000
local preDL = gl.CreateList(function() gl.PushAttrib(GL_COLOR_BUFFER_BIT); gl.AlphaTest(GL.GREATER, x) end)
local postDL = gl.CreateList(function() gl.PopAttrib(); end)

local SUR = Spring.UnitRendering

function gadget:UnitCreated(unitID)
  SUR.SetLODCount(unitID,1)
  SUR.SetMaterialDisplayLists(unitID, 1, "opaque", preDL, postDL)
  SUR.SetMaterialDisplayLists(unitID, 1, "alpha", preDL, postDL) -- is used when cloaked
  SUR.SetMaterialDisplayLists(unitID, 1, "shadow", preDL, postDL)
end

function gadget:UnitFinished(unitID)
  SUR.SetLODCount(unitID,0)
end

function gadget:Shutdown()
  gl.DeleteList( preDL )
  gl.DeleteList( postDL )
end
Last edited by jK on 09 Mar 2009, 04:43, edited 1 time in total.
User avatar
lurker
Posts: 3842
Joined: 08 Jan 2007, 06:13

Re: Lua replacment for set ALPHA_THRESHOLD

Post by lurker »

I think I read it backwards when looking at DrawBins calling DrawUnitWithLists, and thought that would get overwritten. Oops.
User avatar
zwzsg
Kernel Panic Co-Developer
Posts: 7052
Joined: 16 Nov 2004, 13:08

Re: Lua replacment for set ALPHA_THRESHOLD

Post by zwzsg »

The SetMaterialDisplayLists actually requires as a second argument an integer, lod. What should I fill it with? I tried with 0,1,2,3000, and my unit is always fully invisible.

And what's SetLODCount for?

The range of alpha in Lua, it's 0 (solid) to 1 (invisible), right?

That lua code, will it work without the AdvUnitShading, only with the AdvUnitShading, or both?
Last edited by zwzsg on 09 Mar 2009, 04:45, edited 3 times in total.
User avatar
lurker
Posts: 3842
Joined: 08 Jan 2007, 06:13

Re: Lua replacment for set ALPHA_THRESHOLD

Post by lurker »

More or less the lod number is the current display setting of the unit.
User avatar
zwzsg
Kernel Panic Co-Developer
Posts: 7052
Joined: 16 Nov 2004, 13:08

Re: Lua replacment for set ALPHA_THRESHOLD

Post by zwzsg »

Instead of:
\scripts\worm.bos

Code: Select all

set ALPHA_THRESHOLD to 20 + 2 * get BUILD_PERCENT_LEFT;



I now use:
\scripts\worm.bos

Code: Select all

lua_SetAlphaThreshold(alpha)
{
	return;
}
...
call-script lua_SetAlphaThreshold(20 + 2 * get BUILD_PERCENT_LEFT);
\LuaRules\Gadgets\LuaCOB.lua

Code: Select all

...
if (gadgetHandler:IsSyncedCode()) then
	...
	function SetAlphaThreshold(u,ud,team,alpha)
		if GG.Synced_Set_Alpha_Threshold then
			GG.Synced_Set_Alpha_Threshold(u,math.min(255,alpha)/255)
		end
	end
	...
	function gadget:Initialize()
		...
		gadgetHandler:RegisterGlobal("SetAlphaThreshold", SetAlphaThreshold)
	end
end
\LuaRules\Gadgets\set_alpha_threshold.lua

Code: Select all

function gadget:GetInfo()
		return {
				name = "set Alpha Threshold",
				desc = "A LUA replacement for the bos/cob command set ALPHA_THRESHOLD to alpha;",
				author = "jK & lurker & zwzsg",
				date = "9th March, 2009",
				license = "Public Domain",
				layer = 10,
				enabled = true
		}
end
 
GL_COLOR_BUFFER_BIT = 0x4000
 
if (gadgetHandler:IsSyncedCode()) then
 
		local function Synced_Set_Alpha_Threshold(UnitID,Alpha)
				SendToUnsynced("Unsynced_Set_Alpha_Threshold", UnitID, Alpha)
		end
		GG.Synced_Set_Alpha_Threshold = Synced_Set_Alpha_Threshold
		-- LuaCOB.lua wraps it into SetAlphaThreshold then registers it
 
else
 
		preDLs = {}
		postDL = gl.CreateList(function() gl.PopAttrib(); end)
 
		function gadget:UnitDestroyed(UnitID)
				Spring.UnitRendering.SetLODCount(UnitID,0)
				gl.DeleteList(preDL[index])
				gl.DeleteList(postDL[index])
				Alpha_List[UnitID]=nil;
				preDL[UnitID]=nil;
				postDL[UnitID]=nil;
		end
 
		function gadget:Shutdown()
				for _,DL in pairs(preDLs) do
					gl.DeleteList(DL)
				end
				gl.DeleteList(postDL[id])
		end
 
		local function Unsynced_Set_Alpha_Threshold(name,UnitID,Alpha)

				if not preDLs[Alpha] then
						preDLs[Alpha] = gl.CreateList(function() gl.PushAttrib(GL_COLOR_BUFFER_BIT); gl.AlphaTest(GL.GREATER, Alpha) end)
				end
 
				Spring.UnitRendering.SetLODCount(UnitID,1)
				for piece=1,#Spring.GetUnitPieceList(UnitID) do
						Spring.UnitRendering.SetPieceList(UnitID,1,piece,nil)
				end
 
				Spring.UnitRendering.SetMaterialDisplayLists(UnitID, 1, "opaque", preDLs[Alpha], postDL)
				Spring.UnitRendering.SetMaterialDisplayLists(UnitID, 1, "opaque_reflect", preDLs[Alpha], postDL)
				Spring.UnitRendering.SetMaterialDisplayLists(UnitID, 1, "alpha", preDLs[Alpha], postDL) -- is used when cloaked
				Spring.UnitRendering.SetMaterialDisplayLists(UnitID, 1, "alpha_reflect", preDLs[Alpha], postDL) -- is used when cloaked
				Spring.UnitRendering.SetMaterialDisplayLists(UnitID, 1, "shadow", preDLs[Alpha], postDL)
				Spring.Echo("alpha of ["..UnitID.."] set to "..Alpha)
				Spring.UnitRendering.Debug(UnitID)
		end
 
		function gadget:Initialize()
				gadgetHandler:AddSyncAction("Unsynced_Set_Alpha_Threshold",Unsynced_Set_Alpha_Threshold)
		end
 
end
And yet it does not work.

All the code gets loaded and executed without error, but the worm still looks the same (solid with Adv Shading Off, with a default fixed alpha threshold with Adv Shading On). I know it "does stuff" internally though, because before I added the bit about SetPieceList, then the worm was mode fully invisible (both with and without adv shading).

Infolog goes like:
[ 0] Player zwzsg connected with number 0 (client version 0.78.2.1 (0.78.2.1-0-g768a2af{@}-s))
[ 0] Player zwzsg finished loading and is now ingame
[ 0] GameID: 56b8b4493a1584373da063e616eb7d4d
[ 144]
[ 144] UnitID = 7498
[ 144] UnitDefID = 43
[ 144] UnitDefName = worm
[ 144] LodCount = 0
[ 144] CurrentLod = 0
[ 144]
[ 144] LUAMAT_ALPHA lastLOD = 0
[ 144] LUAMAT_OPAQUE lastLOD = 0
[ 144] LUAMAT_ALPHA_REFLECT lastLOD = 0
[ 144] LUAMAT_OPAQUE_REFLECT lastLOD = 0
[ 144] LUAMAT_SHADOW lastLOD = 0
[ 144] alpha of [7498] set to 0.86274510622025
[ 144]
[ 144] UnitID = 7498
[ 144] UnitDefID = 43
[ 144] UnitDefName = worm
[ 144] LodCount = 1
[ 144] CurrentLod = 0
[ 144]
[ 144] LUAMAT_ALPHA lastLOD = 0
[ 144] LUAMAT_OPAQUE lastLOD = 0
[ 144] LUAMAT_ALPHA_REFLECT lastLOD = 0
[ 144] LUAMAT_OPAQUE_REFLECT lastLOD = 0
[ 144] LUAMAT_SHADOW lastLOD = 0
[ 144] LOD 0:
[ 144] LodLength = -1.000000
[ 144] alpha of [7498] set to 0.85490196943283
[ 145]
[ 145] UnitID = 7498
[ 145] UnitDefID = 43
[ 145] UnitDefName = worm
[ 145] LodCount = 1
[ 145] CurrentLod = 0
[ 145]
[ 145] LUAMAT_ALPHA lastLOD = 0
[ 145] LUAMAT_OPAQUE lastLOD = 0
[ 145] LUAMAT_ALPHA_REFLECT lastLOD = 0
[ 145] LUAMAT_OPAQUE_REFLECT lastLOD = 0
[ 145] LUAMAT_SHADOW lastLOD = 0
[ 145] LOD 0:
[ 145] LodLength = -1.000000
[ 145] alpha of [7498] set to 0.85490196943283
I'm still confused by the lod thing, I mean, default lodcount is 0?


jK wrote:a feature what can be done easily with Lua
Kloot wrote:Such hardship indeed.
Are you honestly going to pretend that the 75 lines of code are as easy as the 1 line of code? And yet that isn't taking into account how the Lua code is making use of tons of undocumented unguessable weird stuff.
Kloot
Spring Developer
Posts: 1867
Joined: 08 Oct 2006, 16:58

Re: Lua replacment for set ALPHA_THRESHOLD

Post by Kloot »

zwzsg wrote:Are you honestly going to pretend that the 75 lines of code are as easy as the 1 line of code? And yet that isn't taking into account how the Lua code is making use of tons of undocumented unguessable weird stuff.
jK's example is one way of doing it. Another (more intuitive, but less complete) method is to use something like

Code: Select all

if (not gadgetHandler:IsSyncedCode()) then
  local at = 0.333
  local units = {}

  function gadget:RecvFromSynced(fun, unitID)
      if (fun == "MyUnitCreated") then MyUnitCreated(unitID) end
      if (fun == "MyUnitDestroyed") then MyUnitDestroyed(unitID) end
  end

  local funtion Draw(unitID)
      -- <setup lighting and texturing states, custom shaders, etc>

      gl.PushAttrib(GL_COLOR_BUFFER_BIT)
      gl.AlphaTest(GL_GREATER, at)
   
      gl.Unit(unitID, true)

      gl.PopAttrib()

      -- <undo state changes>
  end

  function gadget:DrawWorld()
      for unitID, alive in ipairs(units) do
          if (alive and Spring.IsUnitVisible(unitID)) then
              Draw(unitID)
          end
      end
  end

  local function MyUnitCreated(unitID) units[unitID] = true; end
  local function MyUnitDestroyed(unitID) units[unitID] = false; end
else
  function gadget:UnitCreated(unitID)
      Spring.SetUnitNoDraw(unitID)
      SendToUnsynced("MyUnitCreated", unitID)
  end

  function gadget:UnitDestroyed(unitID, atID)
      SendToUnsynced("MyUnitDestroyed", unitID)
  end
end
but in any case, what is "easy" or "guessable" depends on your level of comfort with graphics programming, for which the wiki is not and has never been a tutorial.
User avatar
zwzsg
Kernel Panic Co-Developer
Posts: 7052
Joined: 16 Nov 2004, 13:08

Re: Lua replacment for set ALPHA_THRESHOLD

Post by zwzsg »

I am not comfortable with OpenGL, which is why I call upon those who are.

My problem is fairly simple, new Spring version broke the mod I care for, I look for a fix. I would have been much happier if someone else provided me the fix, but jK and you considered it too evident to be worth posting.
User avatar
jK
Spring Developer
Posts: 2299
Joined: 28 Jun 2007, 07:30

Re: Lua replacment for set ALPHA_THRESHOLD

Post by jK »

using SetUnitNoDraw is the wrong way, many widgets (as healthbars) would misinterpret it.

Code: Select all

local GL_COLOR_BUFFER_BIT = 0x4000
local SUR = Spring.UnitRendering

function gadget:DrawUnit(unitID)
  local _,_,_,_,buildProgress = Spring.GetUnitHealth(unitID)

  gl.PushAttrib(GL_COLOR_BUFFER_BIT)
  gl.AlphaTest(GL.LOWER, buildProgress)

  gl.Unit(unitID,false)

  gl.PopAttrib()
end

function gadget:UnitCreated(unitID) --need to use SendToUnsynced
  SUR.SetUnitLuaDraw(unitID,true)
end

function gadget:UnitFinished(unitID) --see above
  SUR.SetUnitLuaDraw(unitID,false)
end
User avatar
Pxtl
Posts: 6112
Joined: 23 Oct 2004, 01:43

Re: Lua replacment for set ALPHA_THRESHOLD

Post by Pxtl »

This thread would be hilarious if it weren't so depressing.
User avatar
KDR_11k
Game Developer
Posts: 8293
Joined: 25 Jun 2006, 08:44

Re: Lua replacment for set ALPHA_THRESHOLD

Post by KDR_11k »

So, did it see any results?
User avatar
zwzsg
Kernel Panic Co-Developer
Posts: 7052
Joined: 16 Nov 2004, 13:08

Re: Lua replacment for set ALPHA_THRESHOLD

Post by zwzsg »

After spending a whole night on it and achieving nothing despite tons of help from lurker, I decided to drop it for the time and turn my attention to something else.

I still have to try jK lastest code. But feel free to have your own attempts at it.
User avatar
zwzsg
Kernel Panic Co-Developer
Posts: 7052
Joined: 16 Nov 2004, 13:08

Re: Lua replacment for set ALPHA_THRESHOLD

Post by zwzsg »

Tried jK code


jK wrote:--need to use SendToUnsynced
That means I had to type some untrivial lines of code.

GL.LOWER didn't exist. Using GL.GREATER for now.

Anyway, now using:

Code: Select all

function gadget:GetInfo()
	return {
		name = "set Alpha Threshold",
		desc = "A LUA replacement for the bos/cob command set ALPHA_THRESHOLD to alpha;",
		author = "jK & lurker & zwzsg",
		date = "9th March, 2009",
		license = "Public Domain",
		layer = 10,
		enabled = true
	}
end

GL_COLOR_BUFFER_BIT = 0x4000

if (gadgetHandler:IsSyncedCode()) then

	local function Synced_Set_Alpha_Threshold(UnitID,Alpha)
		--SendToUnsynced("Unsynced_Set_Alpha_Threshold", UnitID, Alpha)
	end
	GG.Synced_Set_Alpha_Threshold = Synced_Set_Alpha_Threshold
	-- LuaCOB.lua wraps it into SetAlphaThreshold then registers it

	function gadget:UnitCreated(UnitID)
		Spring.Echo("SendToUnsynced(\"Unsynced_UnitCreated\",UnitID)")
		SendToUnsynced("Unsynced_UnitCreated",UnitID)
	end

	function gadget:UnitFinished(UnitID)
		SendToUnsynced("Unsynced_UnitFinished",UnitID)
	end


else

	local GL_COLOR_BUFFER_BIT = 0x4000
	local SUR = Spring.UnitRendering

	function gadget:DrawUnit(UnitID)
		local _,_,_,_,buildProgress = Spring.GetUnitHealth(UnitID)
		gl.PushAttrib(GL_COLOR_BUFFER_BIT)
		Spring.Echo("DrawUnit("..UnitID..") with alpha "..buildProgress)
		gl.AlphaTest(GL.GREATER, buildProgress)
		gl.Unit(UnitID,false)
		gl.PopAttrib()
	end

	local function Unsynced_UnitCreated(name,UnitID) --need to use SendToUnsynced
		Spring.Echo("Unsynced_UnitCreated received!")
		SUR.SetUnitLuaDraw(UnitID,true)
	end

	local function Unsynced_UnitFinished(name,UnitID)
		SUR.SetUnitLuaDraw(UnitID,false)
	end
 
	function gadget:Initialize()
		gadgetHandler:AddSyncAction("Unsynced_Set_Alpha_Threshold",Unsynced_Set_Alpha_Threshold)
		gadgetHandler:AddSyncAction("Unsynced_UnitCreated",Unsynced_UnitCreated)
		gadgetHandler:AddSyncAction("Unsynced_UnitFinished",Unsynced_UnitFinished)
	end
 
end
The unit is now drawn way too big, black, and I have some:
LuaRules::RunCallIn: error = 2, DrawUnit, [string "LuaGadgets/gadgets.lua"]:1049: C stack overflow
Kloot
Spring Developer
Posts: 1867
Joined: 08 Oct 2006, 16:58

Re: Lua replacment for set ALPHA_THRESHOLD

Post by Kloot »

Use gl.UnitRaw(unitID, true) (not gl.Unit(unitID, false)) and make DrawUnit return true.
User avatar
zwzsg
Kernel Panic Co-Developer
Posts: 7052
Joined: 16 Nov 2004, 13:08

Re: Lua replacment for set ALPHA_THRESHOLD

Post by zwzsg »

Works. What's the difference betweent the two?
User avatar
lurker
Posts: 3842
Joined: 08 Jan 2007, 06:13

Re: Lua replacment for set ALPHA_THRESHOLD

Post by lurker »

Just a guess here, but Raw does a raw draw of the model and doesn't invoke DrawUnit first. :P
User avatar
zwzsg
Kernel Panic Co-Developer
Posts: 7052
Joined: 16 Nov 2004, 13:08

Re: Lua replacment for set ALPHA_THRESHOLD

Post by zwzsg »

Okay, so eventually, I got it working.


Instead of:
\scripts\trojan.bos

Code: Select all

set ALPHA_THRESHOLD to 20 + (23*get BUILD_PERCENT_LEFT) /10;



I now use:
\scripts\trojan.bos

Code: Select all

lua_SetAlphaThreshold(alpha) {
	return(0);
}
...
call-script lua_SetAlphaThreshold((get BUILD_PERCENT_LEFT)*13/10);
\LuaRules\Gadgets\LuaCOB.lua

Code: Select all

...
if (gadgetHandler:IsSyncedCode()) then
	...
	function SetAlphaThreshold(u,ud,team,alpha)
		if GG.Synced_Set_Alpha_Threshold then
			GG.Synced_Set_Alpha_Threshold(u,math.max(0,math.min(255,alpha)/255))
		end
	end
	...
	function gadget:Initialize()
		...
		gadgetHandler:RegisterGlobal("SetAlphaThreshold", SetAlphaThreshold)
	end
end
\LuaRules\Gadgets\set_alpha_threshold.lua

Code: Select all

function gadget:GetInfo()
	return {
		name = "set Alpha Threshold",
		desc = "A LUA replacement for the bos/cob command set ALPHA_THRESHOLD to alpha;",
		author = "jK & lurker & zwzsg",
		date = "9th March, 2009",
		license = "Public Domain",
		layer = 10,
		enabled = true
	}
end

GL_COLOR_BUFFER_BIT = 0x4000

if (gadgetHandler:IsSyncedCode()) then

	local function Synced_Set_Alpha_Threshold(UnitID,Alpha)
		SendToUnsynced("Unsynced_Set_Alpha_Threshold", UnitID, Alpha)
	end
	GG.Synced_Set_Alpha_Threshold = Synced_Set_Alpha_Threshold
	-- LuaCOB.lua wraps it into SetAlphaThreshold then registers it

	function gadget:UnitDestroyed(UnitID)
		SendToUnsynced("Unsynced_UnitDestroyed",UnitID)
	end

else

	local GL_COLOR_BUFFER_BIT = 0x4000

	local Alpha_List={}

	function gadget:DrawUnit(UnitID)
		if Alpha_List[UnitID] then
			gl.PushAttrib(GL_COLOR_BUFFER_BIT)
			gl.AlphaTest(GL.GREATER, Alpha_List[UnitID])
			gl.UnitRaw(UnitID,true)
			gl.PopAttrib()
		end
	end

	local function Unsynced_Set_Alpha_UnitDestroyed(name,UnitID)
		Spring.UnitRendering.SetUnitLuaDraw(UnitID,false)
		Alpha_List[UnitID]=nil;
	end

	local function Unsynced_Set_Alpha_Threshold(name,UnitID,Alpha)
		if Alpha==0 then
			Spring.UnitRendering.SetUnitLuaDraw(UnitID,false)
			Alpha_List[UnitID]=nil
		else
			Spring.UnitRendering.SetUnitLuaDraw(UnitID,true)
			Alpha_List[UnitID]=Alpha
		end
	end

	function gadget:Initialize()
		if(tonumber(Spring.GetConfigInt("AdvUnitShading"))==0) then
			gadgetHandler:RemoveGadget()
			return
		else
			gadgetHandler:AddSyncAction("Unsynced_Set_Alpha_Threshold",Unsynced_Set_Alpha_Threshold)
			gadgetHandler:AddSyncAction("Unsynced_Set_Alpha_UnitDestroyed",Unsynced_UnitDestroyed)
		end
	end
 
end
And it works.

The range of alpha somehow don't match, for instance I had to change the formula used during build anims and I can't get the hole build arm cubes to be fully transparent, but it mostly works.

I still says it was not trivial. :evil:
Post Reply

Return to “Lua Scripts”