#A ring library
1 messages · Page 1 of 1 (latest)
i am confusing it with Circles!
I understand the confusion. I, too, believed that Circles! was capable of a lot more
Rings!, Circles!, what's next?
I will be dropping my magnum opus, Ovals! soon
I mean technically I've also made Cubes!
Show us!
Squares!
Squares are 2D though
my screen is 2d
as long as they are not leaving my screen and come outside they are 2d for me 
https://sharex.imgonzo.dev/f/ZVsZFwxy.jpg
Good job my fellow pipi 
Sounds like a satisfied customer to me
@vagrant cloak Don't forget to update the Gist with the missing color
Did I forget the color again
Fixed
So
In many of the places that someone would want this kind of ring effect, they probably wouldn't actually want it to be sphere-based, but instead a cylinder
Yeah, in many cases you would probably want a cylinder instead
No built-in method for drawing those though
Plus it's gotta be somewhat expensive to generate a sphere mesh every frame with render.DrawSphere
I don't know the performance difference between render.DrawSphere and all of the stuff involved with manually creating an IMesh and drawing that instead
So really the way to do this is to generate IMeshes for the shapes and cache the most recent handful of them so they can be looked up easily
I just sent an email to Rubat about this exact thing
But I think we can safely say that NOT generating a mesh every frame is going to be more efficient than generating a mesh every frame
Oh look, found it
He says, before opening the file in question and seeing
void CRender::DrawSphere( const Vector &vCenter, int nRadius )
{
Assert(0);
}
I'm hoping Rubat will slide me the source for render.DrawSphere so I can convert it to lua and do some performance comparison testing
Well there is the source for DrawBox
void CRender::DrawBox( const Vector &vMins, const Vector &vMaxs, bool bFill)
{
Vector points[8];
PointsFromBox( vMins, vMaxs, points );
if ( bFill )
{
Assert(0);
}
else
{
// Draw the box bottom, top, and one corner edge.
meshBuilder.Begin( m_pMesh, MATERIAL_LINE_STRIP, 9 );
meshBuilder.Position3fv( &points[0].x );
meshBuilder.Color4ubv( (byte*)&m_DrawColor );
meshBuilder.AdvanceVertex();
meshBuilder.Position3fv( &points[1].x );
meshBuilder.Color4ubv( (byte*)&m_DrawColor );
meshBuilder.AdvanceVertex();
meshBuilder.Position3fv( &points[3].x );
meshBuilder.Color4ubv( (byte*)&m_DrawColor );
meshBuilder.AdvanceVertex();
meshBuilder.Position3fv( &points[2].x );
meshBuilder.Color4ubv( (byte*)&m_DrawColor );
meshBuilder.AdvanceVertex();
meshBuilder.Position3fv( &points[6].x );
meshBuilder.Color4ubv( (byte*)&m_DrawColor );
meshBuilder.AdvanceVertex();
meshBuilder.Position3fv( &points[7].x );
meshBuilder.Color4ubv( (byte*)&m_DrawColor );
meshBuilder.AdvanceVertex();
meshBuilder.Position3fv( &points[5].x );
meshBuilder.Color4ubv( (byte*)&m_DrawColor );
meshBuilder.AdvanceVertex();
meshBuilder.Position3fv( &points[4].x );
meshBuilder.Color4ubv( (byte*)&m_DrawColor );
meshBuilder.AdvanceVertex();
meshBuilder.Position3fv( &points[0].x );
meshBuilder.Color4ubv( (byte*)&m_DrawColor );
meshBuilder.AdvanceVertex();
meshBuilder.Position3fv( &points[2].x );
meshBuilder.Color4ubv( (byte*)&m_DrawColor );
meshBuilder.AdvanceVertex();
meshBuilder.End();
m_pMesh->Draw();
// Draw the three missing edges.
meshBuilder.Begin( m_pMesh, MATERIAL_LINES, 3 );
meshBuilder.Position3fv( &points[4].x );
meshBuilder.Color4ubv( (byte*)&m_DrawColor );
meshBuilder.AdvanceVertex();
meshBuilder.Position3fv( &points[6].x );
meshBuilder.Color4ubv( (byte*)&m_DrawColor );
meshBuilder.AdvanceVertex();
meshBuilder.Position3fv( &points[1].x );
meshBuilder.Color4ubv( (byte*)&m_DrawColor );
meshBuilder.AdvanceVertex();
meshBuilder.Position3fv( &points[5].x );
meshBuilder.Color4ubv( (byte*)&m_DrawColor );
meshBuilder.AdvanceVertex();
meshBuilder.Position3fv( &points[3].x );
meshBuilder.Color4ubv( (byte*)&m_DrawColor );
meshBuilder.AdvanceVertex();
meshBuilder.Position3fv( &points[7].x );
meshBuilder.Color4ubv( (byte*)&m_DrawColor );
meshBuilder.AdvanceVertex();
meshBuilder.End();
m_pMesh->Draw();
}
}
Assuming that it is just a direct binding
Where're you gettin' that from?
Places
sussy
Pretty sure people have uploaded the engine leaks to github yes they have: https://github.com/lua9520/source-engine-2018-hl2_src/blob/master/hammer/Render.cpp#L1222
Perchance
That's debug overlay stuff
I mean the other function was from hammer so shrug, good chance that Garry at some point made his own render funcs that took from the hammer funcs and added similar things for other primitives
I'm going to convert it to lua and compare it against render.drawsphere for the same inputs and see if the outputs are the same
Wait
No
It doesn't have the same signature, even
You can try the comparison with drawbox
Nah, see, boxes are a static runtime
No loops required
The loops are going to be important for determining how things scale when the polycount of the sphere increases
Either way I guess there's an idea for another library, something for generating IMesh primitives
mesh.Cylinder(material, height, radius, steps)
I think material is wrong
Feels like this should be an enum of some kind, not an IMaterial
I dunno man, seems like your library is bad and you should feel bad
(I'm testing some very low polycount spheres)
This is 3, 5, and 7, respectively. Seems like it maybe doesn't like low odd numbers?
4 is fine, for example
6
Huh, seems like it's any odd number actually
It's just less visible with high numbers
Yeah that's definitely something with DrawSphere then
20 vs 21
Go look at how 3 step drawsphere looks outside of the lib
Oh you know what @near phoenix it's a symmetry problem
Since the lib works by drawing the sphere multiple times, sometimes inside-out
Which means the positions of the uneven vertices are going to flip when it does
Yeah, I thought that kind of thing might come up
Hang on
You actually want to use this
This lets you control if the front faces or back faces are culled
I'll give it a go later
Also you should probably use render.OverrideColorWriteEnable to prevent drawing to the Color Channel while creating the mask, instead of relying on a transparent color
Makes it really easy to comment out and what's being drawn
Boom
Also fixed some stuff to do with the radii calculations so negative thickness works properly now
Though in this case it's 0 radius, 100 thickness
Also, with a bit of fuckery (frames permitting) you can get a soft edge going
How are you softening that edge?
I suppose you could draw to a render target and blur it?
Seems expensive
Just drawing 10 rings
Probably a decent example
Well that was interesting, hit save after changing some code and it just killed the renderer
Oh, turns out I was passing nil as the radius... how could that black out everything though, including the console?
... right
render.OverrideColorWriteEnable(true, false)
Anyways, gist is updated
gross
But you're at least drawing them with a lower polycount, right
...right
-- Draws a ring around the player with a softened edge
-- Note that this example isn't particularly performant, especially with higher step counts
hook.Add("PostDrawTranslucentRenderables", "Rings Example", function()
local pos = LocalPlayer():GetPos()
local radius = 100
local steps = 20
local color = Color(255, 0, 0, 10)
for i = 0, 10 do
render.DrawRing(pos, radius, -i, steps, color)
end
end)
sickening
20 < 50 though
20 do be less than 50
Oh interesting, the border issue is actually part of a stencil index I can't really fix
Index 1 where the actual ring is being drawn
Index 2 where the problem areas end up
Also turns out that the use case of using a radius of 0 and a thickness of whatever you want your radius to be won't work with multi-ring setups
Since it recreates the same issue, except the overlap area is everywhere
Current status:
Trying to verbalize what each of these spheres is doing is haaaarrdddd
Yep
this has to be the greatest addition to garrysmod since multiplayer 
Is this tool in a usable state atm/
Yes
It's probably got some bugs somewhere in there, but for the most part it should be fine for most usages
Part of getting someone to properly understand this as a wiki example is going to be understanding what inverting a model's faces does
I've been playing around with ways of visualizing that
Yeah it's usable, the things you saw above are more just edge cases that don't work quite right
Would you recommend I didn't permanently draw a ring under players depending on their team 😛
Should be fine as long as you understand that it's going to show those rings through walls and things like that (unless you draw them for LocalPlayer only)
Hmm. Was planning more for ease for knowing which team someone is on
for a JVS
it's fine i guess i'll just plug in a range check and call it a day
I'll probably avoid the softened edge one though if I'm gonna do that
Even though it looks nice 😦
JVS?
Oh shoot, I don't want to clutter up your thread for this tool, should we talk elsewhere?
jedi vs sith
I went on to the server I was developing to play for the first time and I ended up fragging some teammates just cos I didn't know who was my team lol
Moved the code over to https://github.com/TankNut/glua-extensions since I'm doing more stuff over there now
FYI I'm planning to add sphere generation to this library that matches render.DrawSphere
Couldn't find the source, so I'm just going to recreate it
Should be easy now that I've done some helper funcs for all the mesh stuff
Can you point them out to me? I’m looking at how you’ve implemented cylinder and using that as a sort of style guide
Oh, hadn't pushed that file yet it seems
local function addVertex(pos, normal, u, v, color)
mesh.Position(pos) mesh.Normal(normal)
mesh.TexCoord(0, u, v) mesh.Color(color:Unpack())
mesh.AdvanceVertex()
end
-- Bottom face
if radius1 != 0 then
addVertex(Vector(0, 0, 0), nDown, 0.5, 0, color)
addVertex(indices[1], nDown, 1, 1, color)
addVertex(indices[2], nDown, 0, 1, color)
end
I'm going to be including this in a pull request (Assuming I get this godforsaken sphere to generate) but I'll add it here for now
IsGeneratingMesh = false
hook.Add( "OnLuaError", "PrimitiveMeshCrashAvoidance", function()
if IsGeneratingMesh then
mesh.End()
print( "Prevented mesh-related crash!" )
end
end )
function Cylinder( iMesh, height, radius1, radius2, steps, color )
-- Code goes here
if iMesh then
mesh.Begin( iMesh, MATERIAL_TRIANGLES, primitiveCount )
else
mesh.Begin( nil, MATERIAL_TRIANGLES, primitiveCount )
end
IsGeneratingMesh = true
-- Mesh generation code goes here
IsGeneratingMesh = false
mesh.End()
end
That crashes for you?
On my end it just transitions into an error refusing to mesh.Begin until mesh.End is called
Oh @near phoenix are you trying to do a render.DrawSphere function atm or trying to get an IMesh first?
render.DrawSphere
Yeah try it with an IMesh instead, since cam.PushModelMatrix will brick your game much quickly if that goes wrong
Unless you're not using that at all in which case idk
I dunno
Whatever the case, that hook saves me from crashes and does nothing in other cases
I can't wait for Spheres!
And I can't wait until I can figure out what the fuck this sphere generation is!
I'm trying to reverse engineer their mesh generation by staring at it