Page 1 of 2

Lua replacment for set ALPHA_THRESHOLD

Posted: 06 Mar 2009, 14:58
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.

Re: Lua replacment for set ALPHA_THRESHOLD

Posted: 06 Mar 2009, 15:05
by Kloot

Code: Select all

glPushAttrib(GL_COLOR_BUFFER_BIT);
glAlphaFunc(GL_GREATER, a); // AlphaTest() in LOGL
// ... draw ...
glPopAttrib();
Such hardship indeed.

Re: Lua replacment for set ALPHA_THRESHOLD

Posted: 06 Mar 2009, 16:47
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.

Re: Lua replacment for set ALPHA_THRESHOLD

Posted: 07 Mar 2009, 03:43
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:

Re: Lua replacment for set ALPHA_THRESHOLD

Posted: 09 Mar 2009, 01:37
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

Re: Lua replacment for set ALPHA_THRESHOLD

Posted: 09 Mar 2009, 02:06
by lurker
I think I read it backwards when looking at DrawBins calling DrawUnitWithLists, and thought that would get overwritten. Oops.

Re: Lua replacment for set ALPHA_THRESHOLD

Posted: 09 Mar 2009, 04:40
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?

Re: Lua replacment for set ALPHA_THRESHOLD

Posted: 09 Mar 2009, 04:42
by lurker
More or less the lod number is the current display setting of the unit.

Re: Lua replacment for set ALPHA_THRESHOLD

Posted: 09 Mar 2009, 07:38
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.

Re: Lua replacment for set ALPHA_THRESHOLD

Posted: 09 Mar 2009, 17:05
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.

Re: Lua replacment for set ALPHA_THRESHOLD

Posted: 09 Mar 2009, 17:33
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.

Re: Lua replacment for set ALPHA_THRESHOLD

Posted: 09 Mar 2009, 17:40
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

Re: Lua replacment for set ALPHA_THRESHOLD

Posted: 23 Apr 2009, 14:50
by Pxtl
This thread would be hilarious if it weren't so depressing.

Re: Lua replacment for set ALPHA_THRESHOLD

Posted: 27 Apr 2009, 11:23
by KDR_11k
So, did it see any results?

Re: Lua replacment for set ALPHA_THRESHOLD

Posted: 02 May 2009, 14:30
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.

Re: Lua replacment for set ALPHA_THRESHOLD

Posted: 14 Jun 2009, 19:42
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

Re: Lua replacment for set ALPHA_THRESHOLD

Posted: 14 Jun 2009, 19:49
by Kloot
Use gl.UnitRaw(unitID, true) (not gl.Unit(unitID, false)) and make DrawUnit return true.

Re: Lua replacment for set ALPHA_THRESHOLD

Posted: 14 Jun 2009, 20:05
by zwzsg
Works. What's the difference betweent the two?

Re: Lua replacment for set ALPHA_THRESHOLD

Posted: 14 Jun 2009, 20:12
by lurker
Just a guess here, but Raw does a raw draw of the model and doesn't invoke DrawUnit first. :P

Re: Lua replacment for set ALPHA_THRESHOLD

Posted: 14 Jun 2009, 22:08
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: