Stupid OpenGL question - Page 2

Stupid OpenGL question

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

Moderator: Moderators

user
Posts: 452
Joined: 22 Jan 2008, 16:33

Re: Stupid OpenGL question

Post by user »

these 2 vertices, are drawn for every trail queue, think of 100 fighters with a 9000 frames trail, they fly there, and there, and they create lots of trail objects,

if there are 100 trails, it will be drawing it 10000 times.

yes, using one begin end to draw everything really makes it faster, but still there are 10000 lines being drawn.
User avatar
quantum
Posts: 590
Joined: 19 Sep 2006, 22:48

Re: Stupid OpenGL question

Post by quantum »

Here is how I'd do it:

Code: Select all

--------------------------------------------------------------------------------
--------------------------------------------------------------------------------

function widget:GetInfo()
  return {
    name      = "!Unit Trails",
    desc      = "Unit trails example, based on gui_mousetrail",
    author    = "quantum",
    date      = "Feb 22, 2007",
    license   = "GNU GPL, v2 or later",
    layer     = 0,
    enabled   = true  --  loaded by default?
  }
end

--------------------------------------------------------------------------------
--------------------------------------------------------------------------------

local gl            = gl --  use a local copy for faster access
local GL            = GL
local Spring        = Spring
local widgetHandler = widgetHandler
local math          = math

--------------------------------------------------------------------------------
--------------------------------------------------------------------------------

local lifeTime = 1.0


--------------------------------------------------------------------------------
--------------------------------------------------------------------------------

local units = {} 
local timer = 0

--------------------------------------------------------------------------------
--------------------------------------------------------------------------------

function widget:Initialize()
  local allUnits = Spring.GetAllUnits()
  for _, unitID in ipairs(allUnits) do
    units[unitID] = false
  end
end


function widget:UnitCreated(unitID) -- the last arguments can be omitted
  units[unitID] = false
end


function widget:DrawWorld()
  local toRemove = {}
  local timer = widgetHandler:GetHourTimer()
  for unitID, head in pairs(units) do
    
    local x, y, z = Spring.GetUnitPosition(unitID)
    
    if (not x) then -- if killed or out of LOS, discard unit
      toRemove[unitID] = nil
      break
    end
    
    local teamID = Spring.GetUnitTeam(unitID)
    local tcr, tcg, tcb = Spring.GetTeamColor(teamID)
    
     --  a linked list of timestamped vertices
    units[unitID] = { units[unitID], x, y, z, timer + lifeTime - 0.001 }
  
    -- collect the active vertices (and cull the old ones)  
    local elements = {}
    local h = units[unitID]
    while h do
      local timeLeft = math.mod((h[5] - timer) + 3600.0, 3600.0)
      if (timeLeft > lifeTime) then
        if (h == units[unitID]) then
          units[unitID] = nil
        end
        h[1] = nil
      else
        local a = (timeLeft / lifeTime)
        elements[#elements+1] = {
          v = { h[2], h[3], h[4] },
          c = { tcr, tcg, tcb, a }
        }
      end
      h = h[1]  -- next node
    end
    
    -- draw the lines
    gl.DepthTest(true)   
    gl.LineWidth(2.0)
    gl.Shape(GL.LINE_STRIP, elements)
    gl.LineWidth(1.0)
  end
  
  for unitID in pairs(toRemove) do
    units[unitID] = nil
  end
  
end


--------------------------------------------------------------------------------
--------------------------------------------------------------------------------
User avatar
rattle
Damned Developer
Posts: 8278
Joined: 01 Jun 2006, 13:15

Re: Stupid OpenGL question

Post by rattle »

What you want to have is like 5 vertices and move these when the unit moves, like a trail. They need to move with the model of course.

Better are a number of quads with a texture which stretch and relax as the unit changes speed, also move with the model and are attached to certain points. S44's propellers work that way.
I was thinking of exhaust trails now...

Lines could probably be enough for wing ribbons... do they actually fade from one vertex color to another? Last vertex shouls be transparent then.
user
Posts: 452
Joined: 22 Jan 2008, 16:33

Re: Stupid OpenGL question

Post by user »

using '-' is way better than using '/', it looks better.

the line width, rgba color, and life timer should be read from the unit file, so it can easily be customized.
user
Posts: 452
Joined: 22 Jan 2008, 16:33

Re: Stupid OpenGL question

Post by user »

the trails look really good in game, but they dont get drawn when paused.
User avatar
jK
Spring Developer
Posts: 2299
Joined: 28 Jun 2007, 07:30

Re: Stupid OpenGL question

Post by jK »

you want something, like this
Image
but it is a very long way to that...
user
Posts: 452
Joined: 22 Jan 2008, 16:33

Re: Stupid OpenGL question

Post by user »

that is a fire texture that follows the unit, right?,

i dont think that ribbon effects need a texture, it already looks good without textures in game.

and seting the life time variable in that script to very high values and flying around is really fun, it draws very long lines.
user
Posts: 452
Joined: 22 Jan 2008, 16:33

Re: Stupid OpenGL question

Post by user »

i will draw some cool shapes using this, then post a screenshot.
User avatar
jK
Spring Developer
Posts: 2299
Joined: 28 Jun 2007, 07:30

Re: Stupid OpenGL question

Post by jK »

@user
smoth wrote:image
IN BEFORE SOME IDIOT SUGGESTS CEG EMIT DOES THIS!

I am not sure if anyone has the time or energy to add this as a patch to spring, but a ribbon effect would be fantastic. Some ideal tags would be:

Repeat // bool to say if ribbon texture should repeat
Stretch //bool, texture stretches ribbon length
Blendmode // option to specify: subtractive, additive or overlay
texture // texture for ribbon
length //how long in game units is it?
width //how wide is it
user
Posts: 452
Joined: 22 Jan 2008, 16:33

Re: Stupid OpenGL question

Post by user »

that is what i posted before, custom unit def values, used to determine life, rgba color, line width.

blend mode would be cool, and texture would need "quads" not lines.
User avatar
jK
Spring Developer
Posts: 2299
Joined: 28 Jun 2007, 07:30

Re: Stupid OpenGL question

Post by jK »

user wrote:i dont think that ribbon effects need a texture, it already looks good without textures in game.
Also quads are the only interesting challange for those effects, as long as you don't try to interpolate the vertices in the fragment shader (something you should really do!), the rest is API stuff.

And not to forget that you can't use GL_LINES for this (even argh did use those only for debuging reason i think) because they aren't in perspective space -> constant width -> huge like XBOXes if you zoom out and thin like hairs if you zoom in.
User avatar
quantum
Posts: 590
Joined: 19 Sep 2006, 22:48

Re: Stupid OpenGL question

Post by quantum »

You could set gl.LineWidth to something that depends on the unit-camera distance. It would still look odd if units went directly towards you or away from you, but that doesn't happen in the usual TA camera.
User avatar
rattle
Damned Developer
Posts: 8278
Joined: 01 Jun 2006, 13:15

Re: Stupid OpenGL question

Post by rattle »

jK wrote:@user
smoth wrote:image
IN BEFORE SOME IDIOT SUGGESTS CEG EMIT DOES THIS!

I am not sure if anyone has the time or energy to add this as a patch to spring, but a ribbon effect would be fantastic. Some ideal tags would be:

Repeat // bool to say if ribbon texture should repeat
Stretch //bool, texture stretches ribbon length
Blendmode // option to specify: subtractive, additive or overlay
texture // texture for ribbon
length //how long in game units is it?
width //how wide is it
Also overall opacity and maybe some more blendmode combinations.
User avatar
KDR_11k
Game Developer
Posts: 8293
Joined: 25 Jun 2006, 08:44

Re: Stupid OpenGL question

Post by KDR_11k »

I tried my luck at this but the transformations won't work right, all vertices end up in the top left corner of the map.

Code: Select all

function gadget:GetInfo()
	return {
		name = "trails",
		desc = "hopes to implement trails",
		author = "KDR_11k (David Becker)",
		date = "2008-02-22",
		license = "Public Domain",
		layer = 1,
		enabled = true
	}
end

if (gadgetHandler:IsSyncedCode()) then

--SYNCED

local function AddTrail(u,ud,team,piece,width,ttl,rate)
	SendToUnsynced("Add",u,ud,team,piece,width,ttl,rate)
end

function gadget:UnitDestroyed(u,ud,team)
	Spring.SendToUnsynced("Destroy",u)
end

function gadget:Initialize()
	gadgetHandler:RegisterGlobal("AddTrail", AddTrail)
--	gadgetHandler:RegisterGlobal("RemoveTrail", RemoveTrail)
end

else

--UNSYNCED
local trailList = {}

local lastupdate = 0

local function AddTrail(u, ud, team, piece, width, ttl, rate)
	local p = Spring.GetUnitScriptPiece(u, piece)
	local t = {
		width = width,
		ttl = ttl,
		rate = rate,
		--texture = UnitDefs[ud].customParams.trailtex,
		R = UnitDefs[ud].customParams.trailr,
		G = UnitDefs[ud].customParams.trailg,
		B = UnitDefs[ud].customParams.trailb,
		A = UnitDefs[ud].customParams.trailalpha,
		phase = 1,
		maxPhase = math.ceil(ttl/rate),
	}
	if not trailList[u] then
		trailList[u]={}
	end
	trailList[u][p] = t
end

local function RemoveTrail(u, ud, team, piece)
	trailList[Spring.GetUnitScriptPiece(u, piece)]=nil
end

local function DrawTrail(vertexList, phase, maxPhase, unit, piece, width)
	local current = phase
	while (phase > 1 and current ~= phase - 1) or (phase == 1 and current ~= maxPhase) do
		gl.Vertex(vertexList[current * 2 - 1][1],vertexList[current * 2 - 1][2],vertexList[current * 2 - 1][3])
		gl.Vertex(vertexList[current * 2 - 0][1],vertexList[current * 2 - 0][2],vertexList[current * 2 - 0][3])
		current = current + 1
		if current > maxPhase then
			current = 1
		end
	end
end

function gadget:DrawWorld()
	gl.ResetMatrices()
	if lastupdate < Spring.GetGameFrame() then
		local f = Spring.GetGameFrame()
		lastupdate = f
		for u,ts in pairs(trailList) do
			for p,t in pairs(ts) do
				if f % t.rate < .1 and t.vertices then
					gl.PushMatrix()
					local x,y,z = Spring.GetUnitPosition(u)
					gl.Translate(x,y,z)
					gl.UnitMultMatrix(u)
					gl.UnitPieceMultMatrix(u,p)
					local pieceM1,pieceM2,pieceM3,pieceM4,pieceM5,_,_,pieceM8,pieceM9,_,_,pieceM12,pieceM13, pieceM14, pieceM15 = gl.GetMatrixData(GL.MODELVIEW)
					gl.PopMatrix()
					local width = t.width
					local phase = t.phase
					vertex0 = { width * .5 * pieceM1 + pieceM4, width * .5 * pieceM5 + pieceM8, width * .5 * pieceM9 + pieceM12}
					vertex1 = { -width * .5 * pieceM1 + pieceM4, -width * .5 * pieceM5 + pieceM8, -width * .5 * pieceM9 + pieceM12}
					t.vertices[phase * 2 - 1] = vertex0
					t.vertices[phase * 2 - 0] = vertex1
					t.phase = phase + 1
					if phase >= t.maxPhase then
						t.phase = 1
					end
				end
			end
		end
	end
	update = false
	local _,_,_,_,_,ateam = Spring.GetTeamInfo(Spring.GetLocalTeamID())
	local _,specView = Spring.GetSpectatingState()
	--gl.DepthTest(GL.LEQUAL)
	for u,ts in pairs(trailList) do
		x,y,z = Spring.GetUnitPosition(u)
		for p,t in pairs(ts) do
			if specView or Spring.GetPositionLosState(x,y,z,ateam) then
				if t.vertices then
					gl.Color(t.R,t.G,t.B,t.A)
					gl.BeginEnd(GL.TRIANGLE_STRIP,DrawTrail,t.vertices,t.phase,t.maxPhase,u,p,t.width)
				else
					local width = t.width
					gl.PushMatrix()
					local x,y,z = Spring.GetUnitPosition(u)
					gl.Translate(x,y,z)
					--gl.UnitMultMatrix(u)
					gl.UnitPieceMultMatrix(u,p)
					local pieceM1,_,_,pieceM4,pieceM5,_,_,pieceM8,pieceM9,_,_,pieceM12 = gl.GetMatrixData(GL.MODELVIEW)
					gl.PopMatrix()
					vertex0 = { width * .5 * pieceM1 + pieceM4, width * .5 * pieceM5 + pieceM8, width * .5 * pieceM9 + pieceM12}
					vertex1 = { -width * .5 * pieceM1 + pieceM4, -width * .5 * pieceM5 + pieceM8, -width * .5 * pieceM9 + pieceM12}
					local v = {}
					for i = 1 , t.maxPhase do
						v[2*i-1] = vertex0
						v[2*i-0] = vertex1
					end
					trailList[u][p].vertices = v
				end
			end
		end
	end
	gl.DepthTest(false)
	gl.Color(1,1,1,1)
end

function gadget:RecvFromSynced(name, u, ud, team, piece, width, ttl, rate)
	if name == "Add" then
		AddTrail(u,ud,tean,piece,width,ttl,rate)
	elseif name == "Destroy" then
		trailList[u] = nil
	end
end

end
user
Posts: 452
Joined: 22 Jan 2008, 16:33

Re: Stupid OpenGL question

Post by user »

i made a few changes to the unit trails widget, and now it reads info from the unit file.
user
Posts: 452
Joined: 22 Jan 2008, 16:33

Re: Stupid OpenGL question

Post by user »

i did it!, made it read info from the unit file, and it works, screenshot in a second.

now we need to make it use quads instead of lines.

Image
right click to enlarge

the fighter has a red trail with 2.00 line width, the hawk has a blue trail with 3.00 width, and the thunder has a yellow line with 2.50 width.
Attachments
UnitTrails.jpg
(44.21 KiB) Downloaded 531 times
Kloot
Spring Developer
Posts: 1867
Joined: 08 Oct 2006, 16:58

Re: Stupid OpenGL question

Post by Kloot »

I wrote my own (bad) implementation of ribbons quite a while ago:

Image
user
Posts: 452
Joined: 22 Jan 2008, 16:33

Re: Stupid OpenGL question

Post by user »

yours looks good, in my opinion.

the current parameters for the trails are:

Code: Select all

[customParams] {       
        usetrail=<number>;
      	trailr=<number>;
      	trailg=<number>;
      	trailb=<number>;
      	trailwidth=<nmber>; 
        traillife=<number>;
}    
and here is an example:

Code: Select all

[customParams]
        {       
        usetrail=1;
      	trailr=1.00;
      	trailg=0.25;
      	trailb=0.50;
      	trailwidth=2.00; 
        traillife=5.00;
        }   
i will add the blending option.
user
Posts: 452
Joined: 22 Jan 2008, 16:33

Re: Stupid OpenGL question

Post by user »

there are currently 3 modes:

additive
overlay
subtractive

which gl.Blending blend mode should be used for subtractive?
User avatar
KDR_11k
Game Developer
Posts: 8293
Joined: 25 Jun 2006, 08:44

Re: Stupid OpenGL question

Post by KDR_11k »

Isn't multiply more useful?
Post Reply

Return to “Lua Scripts”