if i draw millions of polygons with texture, its about twice as fast as with just 1 plain color (with no texture).
But I'm drawing one quad, lol, not many triangles.
You obviously don't understand jack about OpenGL yet. Per fragment, the blend operation's the same thing- the texture's just providing the alpha component for the test. IOW, once the texture's loaded, it really isn't a lot slower. A little, yes, but the smaller amount of geometry makes up for it.
Mainly though, you're making all sorts of basic errors, in terms of CPU-side optimization. It doesn't matter if your OpenGL's optimized... you're wasting a lot of CPU cycles, and that's exactly what you need to avoid, with a Widget that's basically a visual aid. I mean... you're pointing at your loop, and saying, "where's the problem"...
Code: Select all
if ( not Spring.AreTeamsAllied(myTeamID, teamID) ) then
local radius = GetUnitDefRealRadius(spGetUnitDefID(unitID))
if (radius) then
glDrawListAtUnit(unitID, circlePolys, false, radius, 1.0, radius)
end
end
The problem is that GetUnitDefRealRadius():
Code: Select all
local function GetUnitDefRealRadius(udid)
local radius = realRadii[udid]
if (radius) then return radius end
local ud = UnitDefs[udid]
if (ud == nil) then return nil end
local dims = spGetUnitDefDimensions(udid)
if (dims == nil) then return nil end
local scale = ud.hitSphereScale -- missing in 0.76b1+
scale = ((scale == nil) or (scale == 0.0)) and 1.0 or scale
radius = dims.radius / scale
realRadii[udid] = radius*innersize
return radius
end
...is very poorly optimized.
You're making all sorts of noob errors there. For one thing, do
not create locals within that loop. Creating locals is expensive, and you're doing it for every non-Ally that's visible.
Moreover... this check's not necessary at all:
Code: Select all
local teamID = spGetUnitTeam(unitID)
if (teamID) then
if ( not Spring.AreTeamsAllied(myTeamID, teamID) ) then
...because you can store the LocalTeam ID in a local variable at game start, and if teamID ~= LocalTeam, then.
And that's just the really
obvious stuff that's wrong. Meh. I know you're new to this, and people are being dicks about it, but that doesn't mean they aren't right. You need to review some basics:
1. It's much cheaper to look up data that's stored in a table than to perform an expensive callout to Spring, which has to pass through Spring and back. Avoid using it whenever possible. That whole GetUnitDefRealRadius() is 100% not necessary- you should run that during Initialize() for every UnitDef, and store the results in a table of values, not re-do all that stuff every pass through the loop- after all, it's not like the Units have changed size since the last time you did the calculations. So that entire operation should be done ONCE, and stored in a table being used like an array.
So... your loop:
Code: Select all
if ( not Spring.AreTeamsAllied(myTeamID, teamID) ) then
local radius = GetUnitDefRealRadius(spGetUnitDefID(unitID))
if (radius) then
glDrawListAtUnit(unitID, circlePolys, false, radius, 1.0, radius)
end
end
Should be:
Code: Select all
function widget:DrawWorldPreUnit()
glDepthTest(true)
glPolygonOffset(-100, -2)
for _,unitID in ipairs(GetVisibleUnits()) do
teamID = spGetUnitTeam(unitID)
if teamID ~= LocalTeam then
radius = RadiusTable[spGetUnitDefID(unitID)]
glDrawListAtUnit(unitID, circlePolys, false, radius, 1.0, radius)
end
end
end
Which... hmm... doesn't have any of that evil word "local" in it, and assumes that you've built a proper lookup table. It's also shorter by an IF-->THEN, and assumes that LocalTeam == Spring.GetLocalTeamID().
Hell, just fixing your GetUnitDefRealRadius() to operate where it should, i.e. during Initialize, would get rid of a lot of the suck... but that's about what your final loop should actually look like.
The UnitDefID lookup is unavoidable, unless you want to do a UnitCreated() loop and store the radius this way table.insert(SomeTable,{unitID = unitID, radius = radius}) instead. The only reason I don't suggest that is that then that table will get really long, and I've found that looking up the UnitDefID is usually faster.
But there is zero reason at all to be building all that data more than one time.
2. Local variables within a loop should be avoided, unless the loop is
very infrequent. Instead, create your locals at the start of the Widget:
local blah, blah2, blah3
And then just change their value.