Coder Social home page Coder Social logo

3d2d-imgui's Introduction

3D2D Immediate Mode GUI for Garry's Mod

3D2D panels made simple.

USE IMGUI INSTEAD

Development of this library has been stopped and you should use IMGUI library. It has a more flexible API and fixes many of the fundamental design issues this library has had from the beginning, especially related to heap memory usage. Here's a small comparison of equivalent code rendering 30 clickable buttons in each library:

tdui used 	24.4609375	 kbytes of heap memory
imgui used 	0.21484375	 kbytes of heap memory

Example

example

local tdui = include("tdui.lua") -- tdui.lua should be in same folder and AddCSLuaFile'd

local p
hook.Add("PostDrawTranslucentRenderables", "Paint3D2DUI", function(bDrawingSkybox, bDrawingDepth)
    -- This is required so that TDUI isn't drawn twice (which would break input)
    if bDrawingDepth then return end

    -- Create a 3D2D-IMGUI instance and cache it
    -- Note: if drawing TDUI inside a ENT:Draw(), you should cache the
    --       panel to the entity instance (self) instead of a local variable.
    --       That way there will be one panel per entity.
    p = p or tdui.Create()

    -- Draw a rectangle (x, y, w, h, [fill_color], [outline_color])
    p:Rect(-320, 0, 640, 600, _, Color(255, 255, 255))

    -- Draw a line of text (text, font, x, y, [color], [halign], [valign])
    -- Note: text is implicitly horizontally centered
    p:Text("Hello there!", "!Roboto@100", 0, 20)

    -- Draw a button (text, font, x, y, w, h, [color])
    -- Return value is boolean indicating whether left mouse or +use was pressed during this frame
    if p:Button("Say hi", "DermaLarge", -200, 160, 400, 100) then
        RunConsoleCommand("say", "hi!")
    end

    -- Draws a simple crosshair cursor at current mouse position
    p:Cursor()

    -- Renders all the queued draw commands at given 3D location (this one's near gm_construct wall)
    p:Render(Vector(980, -83, -79), Angle(0, 0, 0), 0.1)
end)

Installation

Copy tdui.lua into a folder in your addon and make sure it is AddCSLuaFiled.

Usage

Panel creation (should be called only once):

local p = tdui.Create()

Drawing components (should be called in a drawing hook, eg. ENT:Draw() or PostDrawTranslucentRenderables):

p:Rect(x, y, w, h, [fill_color], [outline_color])

p:Mat(material, x, y, w, h)

-- Same vertices layout as surface.DrawPoly
p:Polygon(vertices, color, material)

-- Note: horizontally aligned to center by default
p:Text(text, font, x, y, [color], [halign], [valign], [scissor_rect])

local isMouseOrUseDown = p:Button(text, font, x, y, w, h, [color])
if isMouseOrUseDown then
 	-- this is only called once per press
	print "Hello!"
end

-- Note: because TDUI attempts to be as stateless as possible, you need to pass
-- the current slider value to the slider function. The fraction returned by the
-- function is the new slider value.
-- Fraction is a numeric value between 0 and 1. TDUI Slider has no concept of "min" and "max"
-- values. You'll need to calculate those yourself.
local frac = p:Slider(gFrac, x, y, w, h)
if frac ~= gFrac then
	print "Slider value changed!"
	gFrac = frac
end

-- You can pass normal GMod fonts to the font parameter of p:Text and p:Button
-- but it also accepts some special formats that you can use:

p:Text("Hello world", "!Roboto@18", 0, 0)
-- This kind of syntax automatically creates and caches a font based on "Roboto"
-- typeface at size 18. The caching is pretty efficient so this can be used even
-- in finished projects, not just during development.

p:Cursor()

Configuration:

-- Draws and accepts input through walls
p:SetIgnoreZ(true)

-- Scales (multiplies) all UI elements by this value. This can be used during development
-- to test different UI scales or if you're lazy and don't want to scale values by hand.
-- This method also scales fonts that use the special !Typeface@Size format
p:SetUIScale(10)

-- Adds this tdui to list of tduis that are checked when the player presses +use bind
-- If said bind is pressed and user is hovering a TDUI on the list, the bind is blocked.
-- This is useful for eg. TDUIs inside cars, so that player doesn't leave car upon pressing +use
-- on tdui.
p:BlockUseBind()

Rendering (should be called in same drawing hook as drawing components):

p:Render(pos, angles, scale)

Tips

Code is mostly self-documenting. If there's a part you don't understand, feel free to post an issue.

Cache the panel. Use a local variable for hooks and self.Panel = self.Panel or tdui.CreatePanel() for ENT:Draw().

Make the scale parameter to p:Render as small as possible (eg. 0.1) and compensate by either scaling UI elements manually or by using p:SetUIScale. This makes the elements look sharper.

Don't be afraid to use the y-axis as the horizontal center point. 3D2D-IMGUI supports negative coordinates and the example uses them.

If you need to make eg. scrolling text, p:Text() accepts scissor_rect as the last parameter. It should be a table containing x, y, x2, y2.

3d2d-imgui's People

Contributors

velkon avatar wyozi avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar

3d2d-imgui's Issues

Performance/Usage improvements

  • Include DrawX code in X (ie check for are we rendering yet inside that function)
  • Add static API (ie API that does not require creating TDUI instance, but internally uses one)

installation link

the link you provide in the installation topic gives an 404 ๐Ÿ”ญ

Font helpers

To quickly create fonts or retrieve cached versions of them. Probably something like
ui:GetFont("Roboto", 180)

Running serverside code in a button

I want to make the button give the player ammo, or a weapon, I'm currently running the script in shared.lua and I tried making the button part serverside but it still doesn't work. No errors, but nothing happens when I press the button. ( The RunConsoleCommand works just fine tho). Sorry for bothering again but I've actually tried everything I could think of.

self.p = self.p or tdui.Create()
    
    local p = self.p
    local ply = LocalPlayer()

    -- Draw a button (text, font, x, y, w, h, [color])
    if p:Button("$500", "AmmoM", 65,9, 50, 50) then

      
if SERVER then

	ply:Give("weapon_smg1")
end         
          
    end
    p:Cursor()
    p:Render(posss + offset3, angss, 0.15)
    
end

3d2d button isn't pressing.

local posss = self:GetPos()
    local angss = self:GetAngles()
    local offset3 = angss:Up() + angss:Forward() * 22 + angss:Right() * 1.9;

    angss:RotateAroundAxis(self:GetAngles():Up(),180)
    angss:RotateAroundAxis(self:GetAngles():Right(),360)
    angss:RotateAroundAxis(self:GetAngles():Forward(),360)
    
    cam.Start3D2D(posss,angss,0.15)

     local p
hook.Add("PostDrawTranslucentRenderables", "Paint3D2DUI", function(bDrawingSkybox, bDrawingDepth)
    -- This is required so that TDUI isn't drawn twice (which would break input)
   if bDrawingDepth then return end

    -- Create a 3D2D-IMGUI instance and cache it
    -- Note: if drawing TDUI inside a ENT:Draw(), you should cache the
    --       panel to the entity instance (self) instead of a local variable.
    --       That way there will be one panel per entity.
    p = p or tdui.Create()
    -- Draw a button (text, font, x, y, w, h, [color])
    -- Return value is boolean indicating whether left mouse or +use was pressed during this frame
   if p:Button("$500", "AmmoM", 60,9.5, 50, 50) then
        RunConsoleCommand("say", "hi!")
    end
p:Render(posss+offset3 ,angss, 0.15)
end)    
   cam.End3D2D()

I'm trying to make a button but it doesn't work from when i changed the angles to match entity's model correct placement. If i change the angles to some weird positions it starts working again but only from one side if that makes sense.

http://imgur.com/a/BvSQG

Add performance debugging tools

Something like cl_showfps that shows

  • Amount of visible TDUIs
  • List of TDUIs (time to render each TDUI too?)
  • Highlight visible TDUIs

Performance

  • Cache the transformed angles (in UpdatePAS) if the original has not been changed
  • Localize all global accesses
  • Localize variables (LocalPlayer() in ComputeScreenmouse etc)

Does this not work anymore?

I'm doing it how I'm supposed to do and nothing happens but errors and every time its telling me

[ERROR] CG] Chikkenslayer:12: attempt to index upvalue 'tdui' (a nil value)

  1. fn - [STEAM_0:1:40778419][CG] Chikkenslayer:12
    1. unknown - addons/ulib/lua/ulib/shared/hook.lua:110

Better scale controls

Eg. make it possible to change 3d2d scale without having to resize all individual draw calls. Should this also affect fonts? #10

No cursor + Can't press

When I add a button the cursor doesn't show and I can't even press the button..

function ENT:Draw()
self:DrawModel()
local ang = self:GetAngles()
ang:RotateAroundAxis( self:GetUp(), 180 )
ang:RotateAroundAxis( self:GetRight(), 90 )

local p = tdui.Create() or p
p:Rect(0, 0, 475, 475, Color(58,58,58), _)
p:Text("Chambre 1", "!Coolvetica Rg@600", 237.5, 5)

p:Rect(125, 150, 200, 75, Color(150,58,58), _)
if p:Button("Sonner", "HVH_T600", 125, 150, 200, 75, Color(58,58,58)) then
    self:EmitSound("garrysmod/content_downloaded.wav")
end

p:Cursor()
p:SetUIScale(5)
p:Render(self:GetPos()+self:GetRight()*23.7+self:GetUp()*1.6+self:GetForward()*-23.7, ang, 0.02)

end

Multiple Buttons are Mixed

So i am using a button on a entity and when i have 2 entities the buttons mix themselves, so 1 controls 2 and 2 controls 1. If that could be fixed i would really apreciate! Thanks!

Buttons not registering?

Thanks for the update but i think you've just created a new bug. Sometimes the buttons just dont work D: Helep ples

Angle being set by something else

Trying to run this code:

local lposition = Vector(-13846, 570, 12880)
local lang = Angle(0,0,0)
local p
hook.Add("PostDrawTranslucentRenderables", "Paint3D2DUI", function()
    p = p or tdui.Create()

    p:Rect(-320, 0, 640, 600, Color(255,0,0, 50), Color(255,0,0,255))

    p:Text(game.GetMap(), "!Roboto@90", 0, 0)

    p:Cursor()

    p:Render(lposition, lang, 0.1)
    print(lang)

end)

lang constantly gets set between 3 Angles
90.000 90.000 0.000
-0.000 0.000 0.000
-0.000 -90.000 90.000
Doing the local var inside the hook, or putting the angle directly into the Render part works fine (I'm reading from a table however so cannot).

The position however is fine.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.