Huge surface.DrawPoly() bug, need help

Hello, I’m creating a gamemode to play with my friends. There’s going to be an ability system; to visualize the abilities’ cooldown timer, I decided to create a circular bar using a function I created:

function DrawRing( x, y, radius, thickness, maxSegments, segments, startAngle, totalAngle, direction, color )

local angleChange = ( math.min( totalAngle, 360 ) / maxSegments ) * ( math.pi / 180 )
local i = startAngle * ( math.pi / 180 )
local f = 0

local ax = x + ( math.cos(i) * radius )
local ay = y - ( math.sin(i) * radius )

local bx = x + ( math.cos(i) * ( radius + thickness ) )
local by = y - ( math.sin(i) * ( radius + thickness ) )

for k = 1, segments do
    i = i + direction * angleChange
    f = f + angleChange

    local cx = x + ( math.cos(i) * radius )
    local cy = y - ( math.sin(i) * radius )

    local dx = x + ( math.cos(i) * ( radius + thickness ) )
    local dy = y - ( math.sin(i) * ( radius + thickness ) )

    local triangle1 = {
        {x = ax, y = ay},
        {x = bx, y = by},
        {x = dx, y = dy}
    }
    local triangle2 = {
        {x = ax, y = ay},
        {x = cx, y = cy},
        {x = dx, y = dy}
    }
    local col = Color( 255, 255, 255 ) //gradient system
    if type(color) == "function" then col = color( k / segments, f / ( 0.017453292519943 * totalAngle ) ) else col = color end


    surface.SetDrawColor( col )
    //draw.NoTexture()
    surface.DrawPoly( triangle1 )
    surface.DrawPoly( triangle2 )

    ax = cx
    ay = cy

    bx = dx
    by = dy
end

end

Since a surface.SetMaterial() is used before this function to draw the ability’s icon and other stuff, a draw.NoTexture() is needed in order to reset the material, otherwise it won’t draw.
However, if I put the draw.NoTexture() inside the function (in the code above, commented), the circle results glitched.

I called the DrawRing() function in a HUDPaint hook on a client file for testing.

hook.Add( “HUDPaint”, “testing”, function()
local posX, posY, radius, radius2, thickness, size, sizeBack = 75, ScrH() - 195, 50, 60, 6, 85, 125

DrawRing( posX, posY, radius, thickness, 50, 50, 90, 360, 1, Color( 25, 25, 25, 125 ) )
DrawRing( posX, posY, radius, thickness, 50, 50, 90, ( LocalPlayer():Health() * 360 ) / LocalPlayer():GetMaxHealth(), 1, function(k, f) return Color( 255, f * 175, 25 - f * 25 ) end )

end )

This way, it creates a perfect circle, and it works fine.
However, if I put the same code inside the DrawAbilities() function (the code about to be shown is just a small part of the function), used to render all the ability icons and stuff on screen, it won’t give the desired result.

        --icon
        surface.SetMaterial(ABILITIES[v.id].Icon)
        surface.SetDrawColor( 255, 255, 255, 255 )
        surface.DrawTexturedRect( x, y, size, size, col )

        local posX, posY, radius, radius2, thickness, size, sizeBack = 75, ScrH() - 195, 50, 60, 6, 85, 125

        DrawRing( posX, posY, radius, thickness, 50, 50, 90, 360, 1, Color( 25, 25, 25, 125 ) )
        DrawRing( posX, posY, radius, thickness, 50, 50, 90, ( LocalPlayer():Health() * 360 ) / LocalPlayer():GetMaxHealth(), 1, function(k, f) return Color( 255, f * 175, 25 - f * 25 ) end )

And the result:

image

As you can see, it’s completely broken: one of the surface.DrawPoly() functions doesn’t work, creating this saw-like effect, also the color is completely broken. If I uncomment the draw.NoTexture() inside the DrawRing function, the color issue is fixed, but the ring is still broken.

So, to recap, if I draw the ring BEFORE any surface.SetMaterial() it works fine, if a material is set that way, the ring won’t show at all or show with a shape and color glitch, if I put a draw.NoTexture() the color works fine, but the shape is still broken; even if no surface.SetMaterial() is set before the DrawRing() function, putting a draw.NoTexture() creates the saw bug.
I couldn’t put more than one image in, because I’m a new user.
I’d really appreciate any help, I’m pretty sure that the material is causing this problem, but I have NO IDEA of how to fix it.

I recommend using GitHub - SneakySquid/Circles: Some circle thing because I'm tired of people using surface.DrawTexturedRect and surface.DrawLine. to do anything you need. Especially for this kind of geometrical shapes.

Thank you for the suggestion, however this function has been working very very fine, it’s just this bug that has been seriously bothering me in the past few days, and I wanted to find out some kind of way to fix it. Later I might try to do what you suggested me and see if it works better.

I tried it myself and it seems like the problem is in the basic texture itself.
draw.NoTexture() just sets the material to vgui/white.

Instead of using draw.NoTexture() I put this before the DrawRing function:

 surface.SetTexture(-1)

And it seemed to work.
Let me know if this fix works for you as well

1 Like

Tried it and it fixed the problem. I cannot explain you how thankful I am :smiley:

1 Like