Need a little help here... I'm pretty useless when it comes to stencils. I'm looking to make an image-based progress bar.. So basically a png or texture (solid color) that fills up with a certain color over time. I'm guessing this involves a stencil, but have no idea how to implement that. Any pointers here?
surface.DrawTexturedRectUV
Set the rightmost UV coordinates to the width of the progress bar. Profit.
It depends on what sort of progress bar you're wanting. If you just want the normal rectangular progress bar you could just use render.SetScissorRect.
Thanks for the help, friends, but I think a stencil is probably the easiest/closest way to do this. Picture a 2d flask that fills up from the bottom to the top with a solid color. This is what I'm trying to do. Just need to use a stencil to "fill" the image with surface.DrawRect.
Trust me, I don't think a stencil is what you seek, if you are looking for the easiest/closest way to do this.
https://files.facepunch.com/forum/upload/377014/31fd5f5c-3fd3-4776-a1d9-08c01f941ad9/image.png
Alright, using SetScissorRect, how can I mask the icon in the middle with the black square?
https://steamuserimages-a.akamaihd.net/ugc/993513763552238194/87A6020671058506C953928E347F30E8AABB770E/
It depends on how the image on that display is being shown. Could you share some code with us which shows how the image is being "projected" onto the surface? The method that is used will change what you need to do.
surface.SetDrawColor(255, 255, 255, 255)
surface.SetMaterial(background)
surface.DrawTexturedRect(0, 0, w, h)
local sin = math.abs(math.sin(CurTime()))
render.ClearStencil()
render.SetStencilEnable(true)
render.SetStencilFailOperation(STENCILOPERATION_KEEP)
render.SetStencilZFailOperation(STENCILOPERATION_REPLACE)
render.SetStencilPassOperation(STENCILOPERATION_REPLACE)
render.SetStencilCompareFunction(STENCILCOMPARISONFUNCTION_ALWAYS)
render.SetStencilReferenceValue(1)
surface.SetDrawColor(Color(0, 0, 0, 255))
surface.DrawRect(w / 2 - 90, h / 2 - 110, 180, 180)
render.SetStencilCompareFunction(STENCILCOMPARISONFUNCTION_EQUAL)
render.SetStencilPassOperation(STENCILOPERATION_REPLACE)
render.SetStencilFailOperation(STENCILOPERATION_REPLACE)
render.SetStencilCompareFunction(STENCILCOMPARISONFUNCTION_ALWAYS)
if self:GetDrying() then
surface.SetDrawColor(50, 50 + sin * 100, 50, 200)
else
surface.SetDrawColor(50, 50, 50, 200)
end
surface.SetMaterial(weedMat)
surface.DrawTexturedRect(w / 2 - 90, h / 2 - 110, 180, 180)
render.SetStencilEnable(false)
This is all in a cam.Start3D2D render. I feel like I am very close with a stencil.
You can definitely use surface.DrawTexturedRectUV or render.SetScissorRect here!
How to do it with ScissorRect:
Get rid of all of your stencil functions
Before surface.DrawRect, do render.SetScissorRect(w/2 - 90, h/2 - 110, 180, 180*sin)
After surface.DrawRect, reset your scissorRect by doing render.SetScissorRect( 0, 0, 0, 0, false )
Done!
My bad, the black weed texture is not actually black. The black behind it was drawn with the surface lib in gmod. Here's how everything is:
The weed texture is a transparent background with a white icon.
I want to be able to draw a box that is any color behind (or in front of) the weed texture, but only have the part of the rectangle that's within the weed icon draw.
I have put together a demonstration in Photoshop. The red that masks with the weed icon is just a rectangle, but it is clipped by the weed texture.
https://i.gyazo.com/ff7c4b474dcc39dd63b53b1f335d22cd.mp4
surface.SetMaterial( "whatever material or color you want on the progress bar.png" )
surface.SetDrawColor( Color(r,g,b) )
surface.SetScissorRect(0,0,width,height*sin,true)
surface.DrawTexturedRect(0,0,width,height)
surface.SetScissorRect(0,0,0,0,false)
-- Draw the weed texture here
Yeah, I hear you. ScissorRect does not seem to be the answer for the method I had in mind, though. ScissorRect doesn't mask for an image like I'm using, it's good for rectangles and low-vertex polygons. I'm going to try and use another texture that is the same and ScissorRect it.
Please see my edited response. This is not necessary. If you render the bar, then render the mask, the bar shows up under the mask. There is no need to put the bar on top of the mask and painfully carve away every part of the bar that isn't inside the mask. Just put the bar under the mask by rendering the bar first.
It's like framing a picture, but the picture is the bar and the frame is the weed texture.
Represent your mask with a piece of paper with several holes in it.
Represent your progress bar with a piece of colored construction paper.
Slide the construction paper under the paper with several holes in it.
The mask covers the part of the bar that isn't "inside" of it.
I get what you mean. Here is my current attempt. The scissorrect doesn't appear it all. Should render.SetScissorRect work properly in 3d2d?
if self:GetDrying() then
surface.SetDrawColor(50, 50 + sin * 100, 50, 200)
else
surface.SetDrawColor(50, 50, 50, 200)
end
surface.SetMaterial(weedMat)
surface.DrawTexturedRect(w / 2 - 90, h / 2 - 110, 180, 180)
render.SetScissorRect(w / 2 - 90, h / 2 - 110, w / 2 + 90, h / 2 + 90, true)
surface.SetDrawColor(255, 255, 0, 255)
surface.SetMaterial(weedMat)
surface.DrawTexturedRect(w / 2 - 90, h / 2 - 110, 180, 180)
render.SetScissorRect(0, 0, 0, 0, false)
So far as I have looked in Google it seems like SetScissorRect doesn't work for some reason very well with 3D2D, and it seems like the solution is to use Stencils as you were going to do initially.
For now I can think of two ways of doing this:
Paint the black weed texture inside the mask of the stencil, and then inside of the stencil draw a red square that changes height depending on your needs,
or
you could draw a white square inside the stencils that has the needed height for the texture you want, and inside of it draw the red weed texture.
Sorry, you need to Log In to post a reply to this thread.