• Rotated Text on panels
    29 replies, posted
[lua] local mat = Matrix(); local matScale = Vector(1, 1, 0); local matAng = Angle(0,0,0); local vec = Vector(); mat:Scale(matScale); function dbg.DrawRotatedText(txt, posX, posY, ang) surface.SetTextPos(0, 0); matAng.y = ang; vec.x = posX; vec.y = posY; mat:SetAngles(matAng); mat:SetTranslation(vec); cam.PushModelMatrix(mat); surface.DrawText(txt); cam.PopModelMatrix(); end [/lua] I found Wizard of Ass's code on a thread from forever ago and it appears to work when not in a panel, but i need it to work in a panel... anyone have any ideas? [editline]7th July 2014[/editline] I think this may be a bug, can anyone confirm? [editline]7th July 2014[/editline] Here's a picture, [img]http://meep.gentoocorp.org/fp/drt.gif[/img]
Try swapping [code]vec.x = posX; vec.y = posY;[/code] for [code]vec.x = posY; vec.y = posX;[/code] Your gif looks to me like it's swapped X and Y. Most likely due to the fact that the text is rotated, and it's X is Y (and visa versa).
[QUOTE=jackwilsdon;45321461]Try swapping [code]vec.x = posX; vec.y = posY;[/code] for [code]vec.x = posY; vec.y = posX;[/code] Your gif looks to me like it's swapped X and Y. Most likely due to the fact that the text is rotated, and it's X is Y (and visa versa).[/QUOTE] I thought exactly that, so I tried it before and it didn't help anything. [img]http://meep.gentoocorp.org/fp/drt2.gif[/img]
Could you provide a gif of you just moving it on set axis? (as in, move it horizontally, stop, move it vertically, stop), as currently moving it in circles makes it difficult to see what's going on.
Can you make a gif of the OP code moving only left/right then only up/down, I can't tell exactly what's going on when you move in circles edit: poster above had the same thoughts but faster :P
sure, [img]http://meep.gentoocorp.org/fp/drt3.gif[/img]
Can you also post a gif doing the same thing with my suggestion? (x = y, y = x)
[img]http://meep.gentoocorp.org/fp/drt4.gif[/img] It's kind of hard since it is right at the edge of the screen, but I tried my best.
Rotated text did not show up for me when I drew it in a DPanel, I drew both RotatedText, and draw.DrawText and set them both to the same posistions, and only 1 showed up. It did work when hooking it in HUDPaint. here's a screenshot. [IMG]http://puu.sh/a1hMR/3700a658bd.jpg[/IMG]
[QUOTE=MeepDarknessM;45321573][img]http://meep.gentoocorp.org/fp/drt4.gif[/img] It's kind of hard since it is right at the edge of the screen, but I tried my best.[/QUOTE] This looks to be doing exactly as the previous gif you posted (non flipped X and Y). Weird.
[QUOTE=jackwilsdon;45321585]This looks to be doing exactly as the previous gif you posted (non flipped X and Y). Weird.[/QUOTE] Yeah, i know.
Have you tried the function posted on the wiki to draw rotated text? [code]function draw.TextRotated( text, x, y, color, font, ang ) render.PushFilterMag( TEXFILTER.ANISOTROPIC ) render.PushFilterMin( TEXFILTER.ANISOTROPIC ) surface.SetFont( font ) surface.SetTextColor( color ) surface.SetTextPos( 0, 0 ) local textWidth, textHeight = surface.GetTextSize( text ) local rad = -math.rad( ang ) local halvedPi = math.pi / 2 x = x - ( math.sin( rad + halvedPi ) * textWidth / 2 + math.sin( rad ) * textHeight / 2 ) y = y - ( math.cos( rad + halvedPi ) * textWidth / 2 + math.cos( rad ) * textHeight / 2 ) local m = Matrix() m:SetAngles( Angle( 0, ang, 0 ) ) m:SetTranslation( Vector( x, y, 0 ) ) cam.PushModelMatrix( m ) surface.DrawText( text ) cam.PopModelMatrix() render.PopFilterMag() render.PopFilterMin() end[/code]
[QUOTE=jackwilsdon;45321597]Have you tried the function posted on the wiki to draw rotated text? [code]function draw.TextRotated( text, x, y, color, font, ang ) render.PushFilterMag( TEXFILTER.ANISOTROPIC ) render.PushFilterMin( TEXFILTER.ANISOTROPIC ) surface.SetFont( font ) surface.SetTextColor( color ) surface.SetTextPos( 0, 0 ) local textWidth, textHeight = surface.GetTextSize( text ) local rad = -math.rad( ang ) local halvedPi = math.pi / 2 x = x - ( math.sin( rad + halvedPi ) * textWidth / 2 + math.sin( rad ) * textHeight / 2 ) y = y - ( math.cos( rad + halvedPi ) * textWidth / 2 + math.cos( rad ) * textHeight / 2 ) local m = Matrix() m:SetAngles( Angle( 0, ang, 0 ) ) m:SetTranslation( Vector( x, y, 0 ) ) cam.PushModelMatrix( m ) surface.DrawText( text ) cam.PopModelMatrix() render.PopFilterMag() render.PopFilterMin() end[/code][/QUOTE] It's the exact same code, just implemented in lua (and it still does the same thing)
The important bit seems to be [code]x = x - ( math.sin( rad + halvedPi ) * textWidth / 2 + math.sin( rad ) * textHeight / 2 ) y = y - ( math.cos( rad + halvedPi ) * textWidth / 2 + math.cos( rad ) * textHeight / 2 )[/code] here, which yours doesn't have. EDIT: Also, are you sure you're actually passing your function valid X/Y coords? Try a surface.DrawRect with your X and Y to make sure it doesn't do the same thing.
[lua] local mat = Matrix(); local matScale = Vector(1, 1, 0); local matAng = Angle(0,0,0); local vec = Vector(); mat:Scale(matScale); local function other(text, x, y, ang) surface.SetTextPos(0, 0) local textWidth, textHeight = surface.GetTextSize(text) local rad = -math.rad(ang) local halvedPi = math.pi / 2 x = x - (math.sin(rad + halvedPi) * textWidth / 2 + math.sin(rad) * textHeight / 2) y = y - (math.cos(rad + halvedPi) * textWidth / 2 + math.cos(rad) * textHeight / 2) matAng.y = ang; mat:SetAngles(matAng) vec.x = x; vec.y = y; mat:SetTranslation(vec) cam.PushModelMatrix(mat) surface.DrawText(text) cam.PopModelMatrix() end function dbg.DrawRotatedText(txt, posX, posY, ang) if(txt == "OnGamemodeLoaded") then surface.SetTextPos(posX - 100, posY); -- due to edge surface.DrawText(txt); surface.SetTextPos(0, 0); matAng.y = ang; vec.x = posY; vec.y = posX; mat:SetAngles(matAng); mat:SetTranslation(vec); cam.PushModelMatrix(mat); surface.DrawText("11"..txt); cam.PopModelMatrix(); other("22"..txt, posX, posY, ang); end end [/lua] [img]http://meep.gentoocorp.org/fp/drt6.gif[/img]
[QUOTE=jackwilsdon;45321643]Also, are you sure you're actually passing your function valid X/Y coords? Try a surface.DrawRect with your X and Y to make sure it doesn't do the same thing.[/QUOTE] What happens if you chuck a surface.DrawRect(x, y, 100, 100) after cam.PopModelMatrix() in your DrawRotatedText?
[img]http://puu.sh/a1jNx/5af12eaf22.png[/img] [lua] cam.PushModelMatrix(mat); surface.DrawText("11"..txt); surface.SetDrawColor(Color(0,0,0,255)); cam.PopModelMatrix(); surface.DrawRect(posX - 100, posY, 100, 100); [/lua]
[QUOTE=MeepDarknessM;45321797][img]http://puu.sh/a1jNx/5af12eaf22.png[/img] [lua] cam.PushModelMatrix(mat); surface.DrawText("11"..txt); surface.SetDrawColor(Color(0,0,0,255)); cam.PopModelMatrix(); surface.DrawRect(posX - 100, posY, 100, 100); [/lua][/QUOTE] I assume this stays there when moving too?
Yes, that's why i made it static.
I got this code working, adapted from something on the wiki; [code]local function DrawRotatedText(text, x, y, angle) local matrix = Matrix() local position = Vector(x, y) matrix:Translate(position) matrix:Rotate(Angle(0, angle, 0) ) matrix:Translate(-position) cam.PushModelMatrix(matrix) surface.SetTextPos(x, y) surface.DrawText(text) cam.PopModelMatrix() end[/code]
Nope, [img]http://meep.gentoocorp.org/fp/drt7.gif[/img]
It has to be the X and Y you are passing it, unless you are calling that method in some weird render hook.
[QUOTE=jackwilsdon;45322062]It has to be the X and Y you are passing it, unless you are calling that method in some weird render hook.[/QUOTE] add me if you want, i will send you files there [url]http://steamcommunity.com/id/MeepDarknessMeep[/url] [editline]8th July 2014[/editline] output from printing x,y [code] 463.97368421053 163.13618492807 472.56578947368 163.13593860546 481.15789473684 162.61944662257 489.75 162.61887734366 498.34210526316 162.61912092935 506.93421052632 130.04494292842 515.52631578947 191.15161840796 524.11842105263 162.67614735018 532.71052631579 163.63950686214 541.30263157895 191.45546281965 549.89473684211 191.20326131134 558.48684210526 163.67460783388 567.07894736842 163.13591671012 575.67105263158 163.63681920878 584.26315789474 163.1021212482 592.85526315789 191.41957635248 601.44736842105 191.4880376162 610.03947368421 163.0879576982 618.63157894737 93.682835009011 627.22368421053 162.98773176563 635.81578947368 191.19100813001 644.40789473684 162.67853120565 653 191.48799929935 [/code] lua for drawing [lua] do local linecol = Color(75,75,75,255); local barcol = Color(255,255,255,255); function dbg.MenuPaint(self) local hookscalled = dbg.hookscalled; local init = dbg.StartTime; local choice = self:GetParent().m_Choice:GetValue(); local w = self:GetWide(); local h = self:GetTall(); if(choice == opts[OPT_FHC]) then local seconds = 30; local pixelpersecond = h / seconds; local width = w / table.Count(hookscalled); local b = 0; for i = 0, h, pixelpersecond do surface.SetDrawColor(linecol); surface.DrawLine(0, i, w, i); end local x, y = self:GetPos(); for k,v in pairs(hookscalled) do surface.SetDrawColor(barcol); surface.DrawRect(b * width, h - (pixelpersecond * (v.first - init)), width, h); surface.SetDrawColor(linecol); surface.DrawOutlinedRect(b * width, h - (pixelpersecond * (v.first - init)), width, h); surface.SetFont("BudgetLabel"); surface.SetTextPos((b + 1) * width, h - (pixelpersecond * (v.first - init))); dbg.DrawRotatedText(k, (b + 1) * width, h - (pixelpersecond * (v.first - init)), 90, x, y); b = b + 1; end elseif(choice == opts[OPT_CPS]) then end end end [/lua] implemented... [lua] local pnl = vgui.Create("DFrame"); local mn = vgui.Create("EditablePanel", pnl); ---..... mn.Paint = dbg.MenuPaint; [/lua]
Try this [lua]local function DrawRotatedText(str, x, y, degrees) local m = Matrix() local s = Vector(1, 1, 0) local a = Angle(0, degrees, 0) local v = Vector(x, y, 0) m:Scale(s) m:SetAngles(a) m:SetTranslation(v) surface.SetTextColor(color_white) surface.SetTextPos(0, 0) cam.PushModelMatrix(m) surface.DrawText(str) cam.PopModelMatrix() end[/lua]
didn't change anything :(
You've gotta be plugging in the wrong x/y, or somehow overlooking something. Because this is me drawing it at the very center of my screen. [img]http://puu.sh/a1otl/251d855612.gif[/img]
[QUOTE=Walrus Viking;45322320]You've gotta be plugging in the wrong x/y, or somehow overlooking something. Because this is me drawing it at the very center of my screen. [img]http://puu.sh/a1otl/251d855612.gif[/img][/QUOTE] try it in a panel
Panels seem to break it, as my function worked in HUDPaint, but breaks in Panel.Draw. EDIT: This sounds like a bug to me with how the panel transforms it's contents. [editline]8th July 2014[/editline] I can get it drawing on a panel with this code [code]local function DrawRotatedText(text, x, y, angle) local matrix = Matrix() local position = Vector(x, y) matrix:Translate(position) matrix:Rotate(Angle(0, angle, 0) ) matrix:Translate(-position) cam.PushModelMatrix(matrix) --surface.SetTextPos(x, y) surface.DrawText(text) cam.PopModelMatrix() end concommand.Add("open_rotated_frame", function() local frame = vgui.Create("DFrame") frame:SetSize(256, 256) frame:Center() frame:MakePopup() local inner = vgui.Create("DPanel", frame) inner:SetSize(128, 128) inner:SetPos(44, 66) inner:SetPaintBorderEnabled(true) function inner:Paint(width, height) local fx, fy = frame:GetPos() local ix, iy = 0, 0 local x, y = fx + ix, fy + iy self:DrawFilledRect() DrawRotatedText("I love rotated text!", x, y, 90) end end)[/code] But it draws about 100 pixels to the left of the window, well outside the Panel's boundaries.
This is just a guess, but I think this happens because it rotates all of the positions (even the panel's positions) [editline]8th July 2014[/editline] [lua] function dbg.DrawRotatedText(str, x, y, degrees, panel) local y = 32; local posx, posy = x, y; local pnl = panel; local last = panel; if(IsValid(panel)) then while(IsValid(pnl) and pnl:GetName() ~= "GModBase") do last = pnl; pnl = pnl:GetParent(); end end posx, posy = last:GetPos() pnl = last; matAng.y = degrees; local rx, ry = x, y; vec.x = posx; vec.y = posy; vec:Rotate(-matAng); vec.x = vec.x + x; vec.y = vec.y + y; print(vec.x, vec.y, posx, posy); mat:SetAngles(matAng) mat:SetTranslation(vec); surface.SetTextPos(0, 0) cam.PushModelMatrix(mat) surface.DrawText(str) cam.PopModelMatrix() end [/lua] I got it to stick to one place on the screen, if someone wants to jump in here just tell me [editline]8th July 2014[/editline] I win, [lua] local mat = Matrix(); local matAng = Angle(0,0,0); local vec = Vector(); function dbg.DrawRotatedText(str, x, y, degrees, panel) local posx, posy = x, y; local pnl = panel; local last = panel; if(IsValid(panel)) then while(IsValid(pnl) and pnl:GetName() ~= "GModBase") do last = pnl; pnl = pnl:GetParent(); end end posx, posy = last:GetPos() pnl = last; matAng.y = degrees; local rx, ry = x, y; vec.x = posx; vec.y = posy; vec:Rotate(-matAng); vec.x = vec.x + x + posx; vec.y = vec.y + y + posy; print(vec.x, vec.y, posx, posy); mat:SetAngles(matAng) mat:SetTranslation(vec); surface.SetTextPos(0, 0) cam.PushModelMatrix(mat) surface.DrawText(str) cam.PopModelMatrix() end [/lua]
Last update, [lua] local mat = Matrix(); local matAng = Angle(0,0,0); local vec = Vector(); function dbg.DrawRotatedText(str, x, y, degrees, panel, th) -- targetheight local posx, posy = 0, 0; local pnl = panel; local last = panel; if(IsValid(panel)) then while(IsValid(pnl) and pnl:GetName() ~= "GModBase") do local a, b = pnl:GetPos(); posx = posx + a; posy = posy + b; last = pnl; pnl = pnl:GetParent(); end end pnl = last; matAng.y = degrees; local rx, ry = x, y; vec.x = posx; vec.y = posy; vec:Rotate(-matAng); vec.x = vec.x + x + posx; vec.y = vec.y + y + posy; mat:SetAngles(matAng); mat:SetTranslation(vec); surface.SetTextPos(0, 0); cam.PushModelMatrix(mat); surface.DrawText(str); cam.PopModelMatrix(); end [/lua] Will someone post on github for this bug to get fixed?
Sorry, you need to Log In to post a reply to this thread.