Stupid OpenGL question
Moderator: Moderators
Stupid OpenGL question
Um... if I have vertexes at positions XYZ (1,1,1), (-1,1,1), (1,1,-1), (-1,1,-1) and I want to draw a line strip between them, how do I do that? The few examples I've seen are using functions, but I don't want to call a function, I just want to give it vertex locations. How do I feed it some raw numbers? Sorry in advance, if this seems stupid or whatever, but the LUA OpenGL stuff doesn't look at all like the OpenGL reference materials I could find.
To put this into perspective, the reference I found for drawing lines with C++ was written like this:
glBegin(GL_LINE_STRIP);
glVertex3f(-1.0f, 1.0f, 0.0f);
glVertex3f(-0.5f, 0.5f, 0.0f);
glVertex3f(-0.7f, 0.5f, 0.0f);
glEnd();
However, the LUA OpenGL API requires that it be written like this:
gl.BeginEnd( number GLType, function [, arg1,... ] ) -> nil
... which I'm finding totally confusing. Why does it require a function?
What I want, basically, is to do some lines from positions XYZ --> XYZ, then do another set of lines, but with a different alpha value, and so on.
To put this into perspective, the reference I found for drawing lines with C++ was written like this:
glBegin(GL_LINE_STRIP);
glVertex3f(-1.0f, 1.0f, 0.0f);
glVertex3f(-0.5f, 0.5f, 0.0f);
glVertex3f(-0.7f, 0.5f, 0.0f);
glEnd();
However, the LUA OpenGL API requires that it be written like this:
gl.BeginEnd( number GLType, function [, arg1,... ] ) -> nil
... which I'm finding totally confusing. Why does it require a function?
What I want, basically, is to do some lines from positions XYZ --> XYZ, then do another set of lines, but with a different alpha value, and so on.
Re: Stupid OpenGL question
it should be like this:
gl.BeginEnd(GL.LINE_STRIP,function()
gl.Vertex(-1.0, 1.0, 0.0)
gl.Vertex(-0.5, 0.5, 0.0)
gl.Vertex(-0.7, 0.5, 0.0)
End)
gl.BeginEnd(GL.LINE_STRIP,function()
gl.Vertex(-1.0, 1.0, 0.0)
gl.Vertex(-0.5, 0.5, 0.0)
gl.Vertex(-0.7, 0.5, 0.0)
End)
Re: Stupid OpenGL question
i recommend using a display list, it is much faster.
to use a list, make a "global" variable, then do this at initialize:
<variable name> = gl.CreateList(function()
<drawing functions here>
end)
then to call it use gl.Translate, to move it to where you want, then use
gl.CallList(<list name>)
to use a list, make a "global" variable, then do this at initialize:
<variable name> = gl.CreateList(function()
<drawing functions here>
end)
then to call it use gl.Translate, to move it to where you want, then use
gl.CallList(<list name>)
Re: Stupid OpenGL question
Hmm.
Ok, first off, here's what I've got, minus the information supply and COB-side stuff (that stuff works):
So, COB calls that, and supplies the arguments for all of the positions. That stuff is working.
Next, because I apparently cannot just draw without going to unsync, I send it over:
And then it fails, saying that I'm not supplying nil values for gl.Vertex. So... what's missing?
Ok, first off, here's what I've got, minus the information supply and COB-side stuff (that stuff works):
Code: Select all
SYNC, CALLED FROM COB
--////////////////////////////////////////////////////////////////////
function DrawLinePrimitive(PosX,PosY,PosZ,OldPosX,OldPosY,OldPosZ)
SendToUnsynced("onFire",PosX,PosY,PosZ,OldPosX,OldPosY,OldPosZ)
end
gadgetHandler:RegisterGlobal("DrawLinePrimitive", DrawLinePrimitive)
--////////////////////////////////////////////////////////////////////
Next, because I apparently cannot just draw without going to unsync, I send it over:
Code: Select all
--////////////////////////////////////////////////////////////////////
function RecvFromSynced(...)
if (arg[2] == 'onFire') then DrawWorld(arg[8])
end
end
--////////////////////////////////////////////////////////////////////
--////////////////////////////////////////////////////////////////////
function gadget:DrawWorld()
if (aircraftAlive) then
gl.Color(0,0.3,1,0.5)
gl.LineWidth(1.0)
gl.BeginEnd(GL.LINE_STRIP,function()
gl.Vertex(PosX, PosY, PosZ)
gl.Vertex(OldPosX, OldPosY, OldPosZ)
gl.Vertex(-0.7, 0.5, 0.0)
end)
end
end
--////////////////////////////////////////////////////////////////////
Re: Stupid OpenGL question
Ok, what's missing is that the values for the gl.Vertex aren't working. Put those in, everything draws, yay.
Re: Stupid OpenGL question
not sure what is the problem, probably the variables dont get sent when it is called.
try using this:
this is the best way i can think of making this.
this will make it get get drawn at the border of the map, you should change it.
try using this:
Code: Select all
local posx,posy,posz,oldposx,oldposy,oldposz = 0
local draw = 0
--////////////////////////////////////////////////////////////////////
function RecvFromSynced(...)
if (arg[2] == 'onFire') then
<set the values to the globals>
draw = 1
end
end
--////////////////////////////////////////////////////////////////////
--////////////////////////////////////////////////////////////////////
function gadget:DrawWorld()
if (aircraftAlive) then
if (draw==1)
gl.Color(0,0.3,1,0.5)
gl.LineWidth(1.0)
gl.BeginEnd(GL.LINE_STRIP,function()
gl.Vertex(PosX, PosY, PosZ)
gl.Vertex(OldPosX, OldPosY, OldPosZ)
gl.Vertex(-0.7, 0.5, 0.0)
end)
draw = 0
<set the variables values to 0>
end
end
end
--////////////////////////////////////////////////////////////////////
Code: Select all
gl.Vertex(-0.7, 0.5, 0.0)
Re: Stupid OpenGL question
Basically, what I'm trying to write here is a nice, simple ribbon-trail FX for everybody who wants to make trails for stuff. I figured it was something people wanted, and meh, it was about time for me to start digging into OpenGL for Spring.
This started out with a lot of very messy COB --> LUA. That turned out to be a fairly bad idea, since almost all of the data I actually need is over on the LUA side anyhow (with the rather important exception of not being able to get a worldspace coordinate for a particular Piece, but meh, I can probably get around that, by calculating some offsets, once the basic code works).
I'm a little closer to a solution, but once again, the issue of tables is stumping me.
After much fighting with the code, I belatedly realized that the only way to make this work is if I store a list of all points, new and old, to use as the source of my vertexes. That part's not working, and I can't seem to get it to work, either. What I need is a table, "PosTable", which stores, in pairs, unitIDs and a sub-table of PosX, PosY, PosZ, etc., etc.
I can't seem to figure out how to make this part, which is probably the easiest bit. If I had that, I could get back to working on the trig side, and see if I can do anything nicer than from the Unit's centroid...
This started out with a lot of very messy COB --> LUA. That turned out to be a fairly bad idea, since almost all of the data I actually need is over on the LUA side anyhow (with the rather important exception of not being able to get a worldspace coordinate for a particular Piece, but meh, I can probably get around that, by calculating some offsets, once the basic code works).
I'm a little closer to a solution, but once again, the issue of tables is stumping me.
Code: Select all
PosTable = {}
AirCraft = {
[UnitDefNames.scoutcraft.id] = "scoutcraft",
}
--////////////////////////////////////////////////////////////////////
function gadget:GameFrame(f)
for _,u in ipairs(Spring.GetAllUnits()) do
if AirCraft[Spring.GetUnitDefID(u)] then
Spring.Echo(PostTable[1])
PosTable.OldPosX = PosTable.PosX
PosTable.OldPosY = PosTable.PosY
PosTable.OldPosZ = PosTable.PosZ
local x,y,z = Spring.GetUnitPosition(u)
PosTable.PosX = x
PosTable.PosY = y
PosTable.PosZ = z
end
end
end
--////////////////////////////////////////////////////////////////////
--/////////////////////////////////////////////////////////////////////////////////////////////////////////////
--////////////////////////////////////////////////////////////////////////////////////////END OF SYNC FUNCTIONS
--/////////////////////////////////////////////////////////////////////////////////////////////////////////////
else
--////////////////////////////////////////////////////////////////////
function gadget:DrawWorld(u)
for _,u in ipairs(Spring.GetAllUnits()) do
if AirCraft[Spring.GetUnitDefID(u)] then
gl.Color(0,0.3,1,0.5)
gl.LineWidth(1.0)
Spring.Echo(PosTable[1])
gl.BeginEnd(GL.LINE,function()
--gl.Vertex(u.PosX,u.PosY,u.PosZ)
--gl.Vertex(u.OldPosX,u.OldPosY,u.OldPosZ)
end)
end
end
end
--////////////////////////////////////////////////////////////////////
I can't seem to figure out how to make this part, which is probably the easiest bit. If I had that, I could get back to working on the trig side, and see if I can do anything nicer than from the Unit's centroid...
Re: Stupid OpenGL question
make it a 2d array, that should be like this:
<name>[<number>][10]
then make a function to check for units created, and then add them to
<table name>[<unitid>][0].
then on a update function:
then on draw, just use the values.
<name>[<number>][10]
then make a function to check for units created, and then add them to
<table name>[<unitid>][0].
then on a update function:
Code: Select all
function gadget:update()
if (Spring.GetGameFrame() % 90 == 0) then
<then do a loop for every table variable>
<set the current values to the old values table,>
<set the new values to the new value table>
end
end
then on draw, just use the values.
Re: Stupid OpenGL question
Ok, so I (almost) have everything working. I finally sorted out how to build a table and stuff. Now I just need to figure out how to get the packed coordinates from COB over to LUA.
The only trouble remaining is that this doesn't seem to work:
Spring.GetCOBUnitVar
( number unitID, integer varID [, boolean unpack = false ] )
-> nil | number value | number unpackedX, number unpackedY
Now, maybe I'm just mis-reading this, but if I set up my COB like this:
And I have a line like this, in LUA;
Where u == UnitID of the Unit, it returns a value of nil. What's up with that? The only other way I can do this is by manually unpacking the coordinates, and I don't know how to do that, either 
The only trouble remaining is that this doesn't seem to work:
Spring.GetCOBUnitVar
( number unitID, integer varID [, boolean unpack = false ] )
-> nil | number value | number unpackedX, number unpackedY
Now, maybe I'm just mis-reading this, but if I set up my COB like this:
Code: Select all
static-var X;
SomeScript()
{
X = 1;
}
Code: Select all
local x = Spring.GetCOBUnitVar(u,1)

Re: Stupid OpenGL question
Everything works, except for one thing: I can't seem to get the Unsync side to see the values stored in my table. Any ideas? It's the only part of this that isn't working now...
That call in DrawWorld() to iterate the values stored in TrailQueue does nothing- not even an error message. However, putting in a Spring.Echo to print the value "test" works just fine. Obviously that code is running. So, wtf is wrong, here? All I need is for DrawWorld() to see TrailQueue's values, and I'm in business...
Code: Select all
function gadget:GetInfo()
return {
name = "Trails.lua",
desc = "Draws trails behind fighters.",
author = "Argh",
date = "February 21st, 2007",
license = "Public Domain",
layer = 1,
enabled = true,
}
end
local TrailQueue = {}
if (gadgetHandler:IsSyncedCode()) then
--////////////////////////////////////////////////////////////////BEGIN SYNC
--////////////////////////////////////////////////////////////////////////////
function GetValues(u,ud,team)
local x,y,z = Spring.GetUnitPosition(u)
return x,y,z
end
gadgetHandler:RegisterGlobal("GetValues", GetValues)
--////////////////////////////////////////////////////////////////////////////
--////////////////////////////////////////////////////////////////////////////
function SendOverValues(u,ud,team,X1,Y1,Z1,X2,Y2,Z2)
table.insert(TrailQueue,{x1=X1,y1=Y1,z1=Z1,x2=X2,y2=Y2,z2=Z2})
--[[for _,u in ipairs(TrailQueue) do
Spring.Echo (u.x1,u.y1,u.z1) end]]
end
gadgetHandler:RegisterGlobal("SendOverValues", SendOverValues)
--////////////////////////////////////////////////////////////////////////////
--////////////////////////////////////////////////////////////////END SYNC
else
--////////////////////////////////////////////////////////////////BEGIN UNSYNC
--////////////////////////////////////////////////////////////////////////////
function gadget:DrawWorld()
for _,u in ipairs(TrailQueue) do
Spring.Echo (u.x1,u.y1,u.z1) end
gl.Color(0,0.3,1,0.5)
gl.LineWidth(1.0)
for _,t in ipairs(TrailQueue) do
gl.BeginEnd(GL.LINE_STRIP,function()
gl.Vertex(t.x1,t.y1,t.z1)
gl.Vertex(t.x2,t.y2,t.z2)
end)
end
end
--////////////////////////////////////////////////////////////////////////////
--////////////////////////////////////////////////////////////////END UNSYNC
end
Re: Stupid OpenGL question
try using unpack(<name of array>).
Re: Stupid OpenGL question
Ok, so... how do I make a display list? I've tested it with 300 fighters, and it's going to drag people's machines to a halt if I don't figure out a way to speed it up.
For those not following the haphazard progress of this attempt, in multiple threads...
COB:
LUA:
For those not following the haphazard progress of this attempt, in multiple threads...
COB:
Code: Select all
lua_GetValues(arg){return 0;}
lua_SendOverValues(arg){return 0;}
positionUpdate()
{
while(1)
{
call-script lua_GetValues();
X1 = GET LUA1;
Y1 = GET LUA2;
Z1 = GET LUA3;
call-script lua_SendOverValues(X1,Y1,Z1,X2,Y2,Z2);
sleep 1000;
X2 = X1;
Y2 = Y1;
Z2 = Z1;
}
}
Code: Select all
function gadget:GetInfo()
return {
name = "Trails.lua",
desc = "Draws trails behind fighters.",
author = "Argh",
date = "February 21st, 2007",
license = "Public Domain",
layer = 1,
enabled = true,
}
end
if (gadgetHandler:IsSyncedCode()) then
local TrailQueue = {}
--////////////////////////////////////////////////////////////////BEGIN SYNC
--////////////////////////////////////////////////////////////////////////////
function GetValues(u,ud,team)
local x,y,z = Spring.GetUnitPosition(u)
return x,y,z
end
gadgetHandler:RegisterGlobal("GetValues", GetValues)
--////////////////////////////////////////////////////////////////////////////
--////////////////////////////////////////////////////////////////////////////
function SendOverValues(u,ud,team,X1,Y1,Z1,X2,Y2,Z2)
table.insert(TrailQueue,{x1=X1,y1=Y1,z1=Z1,x2=X2,y2=Y2,z2=Z2})
end
gadgetHandler:RegisterGlobal("SendOverValues", SendOverValues)
--////////////////////////////////////////////////////////////////////////////
function gadget:Initialize()
gadgetHandler:RegisterGlobal("TrailQueue", TrailQueue)
end
--////////////////////////////////////////////////////////////////END SYNC
else
--////////////////////////////////////////////////////////////////BEGIN UNSYNC
--////////////////////////////////////////////////////////////////////////////
function gadget:DrawWorld()
gl.Color(0,0.3,1,0.5)
gl.LineWidth(1.0)
for _,t in spairs(SYNCED.TrailQueue) do
gl.BeginEnd(GL.LINE_STRIP,function()
gl.Vertex(t.x1,t.y1,t.z1)
gl.Vertex(t.x2,t.y2,t.z2)
end)
end
end
--////////////////////////////////////////////////////////////////////////////
--////////////////////////////////////////////////////////////////END UNSYNC
end
Re: Stupid OpenGL question
you need to activate the depth buffer here, or the trails will be draw in the front of anything.
to set up the list:
to call it, the hard part:
the default values for the list should be:
that will create a line from 0,0,0 map coordinate to 0,0,16.
to correctly draw it you need to translate and rotate it to the place, scale if you really need.
making this seems to be hard, and it is, it is harder than using begin end, but much faster, i allways use lists, even when using begin end is way easier.
here you should make some new values to the table:
(creation time, trail life time, line width, rgba color, <and whatever you want>)
and a very slow update function:
you should also make a custom unit def value that has color, line width data, and max trail life, so that it is more customizable.
the gl.LineWidth, and gl.Color functions should be called for every TrailQueue, and look at its custom values.
to make the values work, they should be read when setting up TrailQueue values.
you have there unitID,unitDefID and teamID on the function, use the unitDefID to read from the unit file.
i hope that this works, and that it helps.
Code: Select all
function gadget:DrawWorld()
gl.Color(0,0.3,1,0.5)
gl.LineWidth(1.0)
gl.DepthTest(true)
for _,t in spairs(SYNCED.TrailQueue) do
gl.BeginEnd(GL.LINE_STRIP,function()
gl.Vertex(t.x1,t.y1,t.z1)
gl.Vertex(t.x2,t.y2,t.z2)
end)
end
gl.DepthTest(false)
end
Code: Select all
local Trail
local DrawTrail = function(<whatever>)
gl.BeginEnd(GL.LINE_STRIP, function()
gl.Vertex(t.x1,t.y1,t.z1)
gl.Vertex(t.x2,t.y2,t.z2)
<or whatever you want>
end
end
function gadget:Initialize()
gadgetHandler:RegisterGlobal("TrailQueue", TrailQueue)
Trail = gl.CreateList(DrawTrail,<some default values>)
end
Code: Select all
function gadget:DrawWorld()
gl.Color(0,0.3,1,0.5)
gl.LineWidth(1.0)
gl.DepthTest(true)
for _,t in spairs(SYNCED.TrailQueue) do
gl.PushMatrix()
gl.Translate(<unit position>)
gl.Rotate(<the angle between the 2 points>)
gl.Scale(<whatever>)
gl.CallList(Trail)
gl.PopMatrix()
<maybe use gl.ResetMatrices()>
end
gl.DepthTest(false)
end
Code: Select all
function gadget:Initialize()
gadgetHandler:RegisterGlobal("TrailQueue", TrailQueue)
Trail = gl.CreateList(DrawTrail,0,0,0,0,0,16)
end
to correctly draw it you need to translate and rotate it to the place, scale if you really need.
making this seems to be hard, and it is, it is harder than using begin end, but much faster, i allways use lists, even when using begin end is way easier.
here you should make some new values to the table:
(creation time, trail life time, line width, rgba color, <and whatever you want>)
Code: Select all
function SendOverValues(u,ud,team,X1,Y1,Z1,X2,Y2,Z2)
table.insert(TrailQueue,{x1=X1,y1=Y1,z1=Z1,x2=X2,y2=Y2,z2=Z2,f=Spring.GetGameFrame(),m=<make a max trail life variable,l = <the line width>,r = <color>,g = <color>,b = <color>,a = <color>})
end
Code: Select all
function gadget:Update()
if (Spring.GetGameFrame() % 150 == 0) then <every 5 seconds>
for _,i in spairs(SYNCED.TrailQueue) do
if (i.f < Spring.GetGameFrame() - i.m) then
table.remove(i)
end
end
end
end
the gl.LineWidth, and gl.Color functions should be called for every TrailQueue, and look at its custom values.
to make the values work, they should be read when setting up TrailQueue values.
Code: Select all
function SendOverValues(u,ud,team,X1,Y1,Z1,X2,Y2,Z2)
i hope that this works, and that it helps.
Re: Stupid OpenGL question
@argh:
1. Why do you send the UnitPos from Lua to Cob and then back to Lua??? That doesn't make sense at all!
2.
3.So you don't need any COB-changes at all, you want:
4.
@user:
using a displaylist to render 2 stupid vertices and putting a math-monster around it???
push-/pop-matrix,translate,rotate,scale are time intensive functions! also they don't make it any easier to handle those vertex positions, 'cus you would have to calc those angles and scales first in slow lua code!
(and no gl.ResetMatrices() isn't the right one either ...)
1. Why do you send the UnitPos from Lua to Cob and then back to Lua??? That doesn't make sense at all!
2.
first, you picked the wrong function, you want GetUnitCOBValue() which is the cob-get function (Spring.GetCOBUnitVar() accesses trepan's new custom get-vars, but not local defined variables).Argh wrote:Spring.GetCOBUnitVar
( number unitID, integer varID [, boolean unpack = false ] )
-> nil | number value | number unpackedX, number unpackedY
3.So you don't need any COB-changes at all, you want:
Code: Select all
local PIECE_XZ = 7
local PIECE_Y = 8
local x,z = Spring.GetUnitCOBValue(unitID,true,PIECE_XZ,piece)
local y = Spring.GetUnitCOBValue(unitID,PIECE_Y,piece)/COBSCALE
why do you use GL_LINE_STRIP if you render only 1 line? it should be (for using GL_LINE_STRIP you would have to change your array format):Argh wrote: for _,t in spairs(SYNCED.TrailQueue) do
gl.BeginEnd(GL.LINE_STRIP,function()
gl.Vertex(t.x1,t.y1,t.z1)
gl.Vertex(t.x2,t.y2,t.z2)
end)
end
Code: Select all
gl.BeginEnd(GL.LINES,function()
for _,t in spairs(SYNCED.TrailQueue) do
gl.Vertex(t.x1,t.y1,t.z1)
gl.Vertex(t.x2,t.y2,t.z2)
end
end)
@user:
you don't really think that this is the right way to do so???user wrote:Code: Select all
function gadget:DrawWorld() gl.Color(0,0.3,1,0.5) gl.LineWidth(1.0) gl.DepthTest(true) for _,t in spairs(SYNCED.TrailQueue) do gl.PushMatrix() gl.Translate(<unit position>) gl.Rotate(<the angle between the 2 points>) gl.Scale(<whatever>) gl.CallList(Trail) gl.PopMatrix() <maybe use gl.ResetMatrices()> end gl.DepthTest(false) end
using a displaylist to render 2 stupid vertices and putting a math-monster around it???
push-/pop-matrix,translate,rotate,scale are time intensive functions! also they don't make it any easier to handle those vertex positions, 'cus you would have to calc those angles and scales first in slow lua code!
(and no gl.ResetMatrices() isn't the right one either ...)
Re: Stupid OpenGL question
Whew! That's a lot to digest, you two 
The COB-->LUA stuff was because I was using the wrong function, lemme see if that works like you said, if so, then I can just wipe out everything in the table, every few frames, and re-populate it with new data, delivered via COB. That'd save me a lot of trouble, especially if I can get exact Piece locations intact.
What is the value of COBSCALE?
The line-strip thing was because I was originally thinking that a line-strip was the way to go, however I'm not sure that's going to be a very good solution, for the final concept- people generally expect trails to visually get smaller and fade in alpha values, as a visual convention... so I was thinking I'd use a larger line for the first segment, with a "core" of alpha-value 1.0 using another line, then shrink it a bit, so forth and so on...

The COB-->LUA stuff was because I was using the wrong function, lemme see if that works like you said, if so, then I can just wipe out everything in the table, every few frames, and re-populate it with new data, delivered via COB. That'd save me a lot of trouble, especially if I can get exact Piece locations intact.
What is the value of COBSCALE?
The line-strip thing was because I was originally thinking that a line-strip was the way to go, however I'm not sure that's going to be a very good solution, for the final concept- people generally expect trails to visually get smaller and fade in alpha values, as a visual convention... so I was thinking I'd use a larger line for the first segment, with a "core" of alpha-value 1.0 using another line, then shrink it a bit, so forth and so on...
Re: Stupid OpenGL question
65536Argh wrote:What is the value of COBSCALE?
Re: Stupid OpenGL question
COBSCALE is a global var in LuaRules/LuaCob you don't need to define it
Re: Stupid OpenGL question
Ah, so it's the linear constant... gotcha. Same applies for radian conversions?
Re: Stupid OpenGL question
65536 COB rotation units = 360 degreesArgh wrote:Ah, so it's the linear constant... gotcha. Same applies for radian conversions?
<> = 182.0444
Re: Stupid OpenGL question
Cool. Not that I have a use for that, at the moment, but it'd be nice to know, when I do.