Page 1 of 1

WxLua GUI 2d mapping question.

Posted: Sat Jul 28, 2018 10:11 pm
by A Hamburgler
Ok guys so I’m trying to make a 2d map (a literal map of my game) for my gui. When in game I exported the terrain data to an external lua file which looks like this Info = { [1] = { Color = “blue”, x = 0, y = 0 }, ect ect...} basically one big array. My gui reads this file and wxDrawcircle and place pixel size colored dots at the coordinates. This all works and creates a nice looking map but the problem is when I go to click or do anything it freezes and looks like the GUI can’t handle all those dots. It almost seems like when ever I click the GUI refreshes and re renders all those dots again. So my question is should I make a texture instead or is there a way my GUI can render the map once and not over and over again like it’s refreshing it’s self?

Re: WxLua GUI 2d mapping question.

Posted: Sun Jul 29, 2018 5:15 am
by A Hamburgler
My code is

Code: Select all

package.cpath = package.cpath..";./?.dll;./?.so;../lib/?.so;../lib/vc_dll/?.dll;../lib/bcc_dll/?.dll;../lib/mingw_dll/?.dll;"
require("wx")

frame = nil
canrun = true

Panle1_Send_It_Button = 100
Panle1_Static_Box_1 = 101
Panle1_Static_Box_2 = 102
Panle1_Static_Box_3 = 103
Panle1_TextCtrl_1 = 104
Panle1_TextCtrl_2 = 105

P1_SB1_Selected = -1
P1_SB2_Selected = -1
P1_SB3_Selected = -1

function HandleEvents(event)
   local name = event:GetEventObject():DynamicCast("wxWindow"):GetName()
    frame:SetStatusText(string.format("%s - You are on the %d '%s'", name, event:GetSelection(), event:GetString()), 0)
    --if event:GetSelection() == 3 then create() end
end


local _T = function(s) return s end
local wxT = function(s) return s end

function GetColor(IC,Type)
    if IC == "Green" or IC == "Black" then
            if Type == 0 then 
                Pix = wx.wxGREEN_BRUSH
            else
                Pix = wx.wxGREEN_PEN
            end
        else
            if IC == "Blue" then
                if Type == 0 then 
                    Pix = wx.wxCYAN_BRUSH
                else
                    Pix = wx.wxCYAN_PEN
                end
            else
               if Type == 0 then 
                    Pix = wx.wxGREY_BRUSH
               else
                    Pix = wx.wxGREY_PEN
                end
            end
        end
    return Pix
end

function OnPaint(T, event )
    local dc = wx.wxPaintDC(T)
    T:PrepareDC( dc )
    --dc:DrawBitmap( T.T1, 0, 0, true )
    Number = 1
    for i = 22,1,-1 do 
        local FileName = string.format("PixleData%s.lua",Number)
        dofile(FileName)
        for i, GroupF in ipairs(Info) do 
            local Data = Info[i]
            local Color = Data["Color"]
            local Xpos = Data["Xp"]
            local Ypos = Data["Yp"]
            local PixColor = GetColor(Color,0)
            local PenColor = GetColor(Color,1)
        
            local dc = wx.wxPaintDC(T)
            T:PrepareDC( dc )   
            local dc = wx.wxPaintDC(T)
            dc:SetPen( PenColor )
            dc:SetBrush( PixColor )
            --dc:DrawRectangle( Xpos, Ypos, 1, 1 )
            dc:DrawCircle( Xpos, Ypos, 1, 1 )
            dc:delete()
        end
        Number = Number+1
    end
    
end

function create()
   --local this = wx.wxScrolledWindow( panel4, wx.wxID_ANY, wx.wxDefaultPosition, wx.wxSize(1300,1300), wx.wxSUNKEN_BORDER )
    sw = wx.wxScrolledWindow( panel4, wx.wxID_ANY, wx.wxDefaultPosition, wx.wxSize(900, 600),wx.wxHSCROLL + wx.wxVSCROLL)
    sw:SetScrollbars(15, 15, 900, 600, 0, 0, false)

    sw.T1 = wx.wxNullBitmap
    sw.my_square = wx.wxNullBitmap
    sw.OnPaint = OnPaint
    sw.CreateAntiAliasedBitmap = CreateAntiAliasedBitmap
    sw:SetBackgroundColour(wx.wxWHITE)

    local bitmap = wx.wxBitmap( 100, 100 )
    local dc = wx.wxMemoryDC()
    dc:SelectObject( bitmap )
    dc:SetBrush( wx.wxWHITE_BRUSH )
    dc:delete()

    local image = bitmap:ConvertToImage()
    image:Destroy()
    
    --sw.T1 = image:LoadFile("TB.png" )
    sw.T1 = wx.wxBitmap("TB.png")
    image:Destroy()
    sw:Connect(wx.wxEVT_PAINT, function(event) sw:OnPaint(event) end)
end

function main()
    -- create the hierarchy: frame -> notebook
    frame = wx.wxFrame(wx.NULL, wx.wxID_ANY, "DCS Support Tablet",wx.wxDefaultPosition, wx.wxSize(900, 600))
    frame:CreateStatusBar(1)
    frame:SetStatusText("", 0)
    T = frame
    

    local notebook = wx.wxNotebook(frame, wx.wxID_ANY,
                                   wx.wxDefaultPosition, wx.wxDefaultSize)
                                   --wx.wxNB_BOTTOM)

    -- create first panel in the notebook control
    local panel1 = wx.wxPanel(notebook, wx.wxID_ANY)
    local sizer1 = wx.wxBoxSizer(wx.wxVERTICAL)
    local choice = wx.wxChoice(panel1, Panle1_Static_Box_1,
                               wx.wxDefaultPosition, wx.wxDefaultSize,
                               {"Al Dhafra AB", "Al Maktoum Intl", "Sharjah Intl", "Fujairah Intl"})

    local choiceBoxStaticBox = wx.wxStaticBox( panel1, wx.wxID_ANY, "Deployment From")
    local choiceBoxStaticBoxSizer = wx.wxStaticBoxSizer( choiceBoxStaticBox, wx.wxVERTICAL );
    choiceBoxStaticBoxSizer:Add(choice, 0, wx.wxALL + wx.wxGROW + wx.wxCENTER, 5)

    local choice2 = wx.wxChoice(panel1, Panle1_Static_Box_2,
                               wx.wxDefaultPosition, wx.wxDefaultSize,
                               {"Carrier", "Al Dhafra AB", "Al Maktoum Intl", "Sharjah Intl", "Fujairah Intl", "Grid Cordinates (For FOBs Only)"})

    local choiceBoxStaticBox2 = wx.wxStaticBox( panel1, wx.wxID_ANY, "Attack Location")
    local choiceBoxStaticBoxSizer2 = wx.wxStaticBoxSizer( choiceBoxStaticBox2, wx.wxVERTICAL );
    choiceBoxStaticBoxSizer2:Add(choice2, 0, wx.wxALL + wx.wxGROW + wx.wxCENTER, 5)

    local choice3 = wx.wxChoice(panel1, Panle1_Static_Box_3,
                               wx.wxDefaultPosition, wx.wxDefaultSize,
                               {"A-10C","F/A-18C","M1A2 MBT"})

    local choiceBoxStaticBox3 = wx.wxStaticBox( panel1, wx.wxID_ANY, "Unit To Be Deployed")
    local choiceBoxStaticBoxSizer3 = wx.wxStaticBoxSizer( choiceBoxStaticBox3, wx.wxVERTICAL );
    choiceBoxStaticBoxSizer3:Add(choice3, 0, wx.wxALL + wx.wxGROW + wx.wxCENTER, 5)

    local staticText = wx.wxStaticText( panel1, wx.wxID_ANY, "North", wx.wxPoint(7,194))
    local textCtrl   = wx.wxTextCtrl( panel1, Panle1_TextCtrl_1, "000", wx.wxPoint(35,190), wx.wxDefaultSize, wx.wxTE_PROCESS_ENTER )
    local text_w, text_h = textCtrl:GetTextExtent("00000.00000")
    textCtrl:SetInitialSize(wx.wxSize(text_w, -1))

    local staticText2 = wx.wxStaticText( panel1, wx.wxID_ANY, "East", wx.wxPoint(105,194))
    local textCtrl2   = wx.wxTextCtrl( panel1, Panle1_TextCtrl_2, "000", wx.wxPoint(128,190), wx.wxDefaultSize, wx.wxTE_PROCESS_ENTER )
    local text_w2, text_h2 = textCtrl2:GetTextExtent("00000.00000")
    textCtrl2:SetInitialSize(wx.wxSize(text_w2, -1))

    local staticText3 = wx.wxStaticText( panel1, wx.wxID_ANY, "Available Resources At Selected Base - 500/", wx.wxPoint(200,194))
    local staticText4 = wx.wxStaticText( panel1, wx.wxID_ANY, "Selected Unit Cost - 100", wx.wxPoint(415,194))
    button = wx.wxButton( panel1, Panle1_Send_It_Button, "Confirm",wx.wxPoint(245,242),wx.wxSize(50, 20),0)

    sizer1:Add(choiceBoxStaticBoxSizer, 0, wx.wxALL + wx.wxGROW + wx.wxCENTER, 5)
    sizer1:Add(choiceBoxStaticBoxSizer2, 0, wx.wxALL + wx.wxGROW + wx.wxCENTER, 5)
    sizer1:Add(choiceBoxStaticBoxSizer3, 0, wx.wxALL + wx.wxGROW + wx.wxCENTER, 5)
    panel1:SetSizer(sizer1)
    sizer1:SetSizeHints(panel1)
    notebook:AddPage(panel1, "Deployment")

    -- create second panel in the notebook control
    local panel2 = wx.wxPanel(notebook, wx.wxID_ANY)
    local sizer2 = wx.wxBoxSizer(wx.wxVERTICAL)

    local choice = wx.wxChoice(panel2, wx.wxID_ANY,
                               wx.wxDefaultPosition, wx.wxDefaultSize,
                               {"Al Dhafra AB", "Al Maktoum Intl", "Sharjah Intl", "Fujairah Intl"})

    local choiceBoxStaticBox = wx.wxStaticBox( panel2, wx.wxID_ANY, "Deployment From")
    local choiceBoxStaticBoxSizer = wx.wxStaticBoxSizer( choiceBoxStaticBox, wx.wxVERTICAL );
    choiceBoxStaticBoxSizer:Add(choice, 0, wx.wxALL + wx.wxGROW + wx.wxCENTER, 5)

   local choice2 = wx.wxChoice(panel2, wx.wxID_ANY,
                               wx.wxDefaultPosition, wx.wxDefaultSize,
                               {"A-10C","F/A-18C","M1A2 MBT"})

    local choiceBoxStaticBox2 = wx.wxStaticBox( panel2, wx.wxID_ANY, "Unit To Be Deployed")
    local choiceBoxStaticBoxSizer2 = wx.wxStaticBoxSizer( choiceBoxStaticBox2, wx.wxVERTICAL );
    choiceBoxStaticBoxSizer2:Add(choice2, 0, wx.wxALL + wx.wxGROW + wx.wxCENTER, 5)

    sizer2:Add(choiceBoxStaticBoxSizer, 0, wx.wxALL + wx.wxGROW + wx.wxCENTER, 5)
    sizer2:Add(choiceBoxStaticBoxSizer2, 0, wx.wxALL + wx.wxGROW + wx.wxCENTER, 5)
    panel2:SetSizer(sizer2)
    sizer2:SetSizeHints(panel2)
    notebook:AddPage(panel2, "Defense")

    local panel3 = wx.wxPanel(notebook, wx.wxID_ANY)
    notebook:AddPage(panel3, "Main H.Q.")

    panel4 = wx.wxPanel(notebook, 664)
    notebook:AddPage(panel4, "Mission Information")
    
     frame:SetSizeHints(notebook:GetBestSize():GetWidth(),notebook:GetBestSize():GetHeight())

    -- typically you will give a control a specific window id and connect an
    -- event handler for that id, in this case respond to any id
    frame:Connect(wx.wxID_ANY, wx.wxEVT_COMMAND_NOTEBOOK_PAGE_CHANGED, HandleEvents)

    frame:Connect(wx.wxID_ANY, wx.wxEVT_COMMAND_RADIOBOX_SELECTED, HandleEvents)
    frame:Connect(wx.wxID_ANY, wx.wxEVT_COMMAND_LISTBOX_SELECTED, HandleEvents)

    frame:Connect(wx.wxID_ANY, wx.wxEVT_COMMAND_COMBOBOX_SELECTED, HandleEvents)
    frame:Connect(wx.wxID_ANY, wx.wxEVT_COMMAND_CHOICE_SELECTED, HandleEvents)
    frame:Connect(wx.wxID_ANY, wx.wxEVT_COMMAND_CHECKLISTBOX_TOGGLED, HandleEvents)

    frame:Connect(Panle1_Static_Box_1, wx.wxEVT_COMMAND_CHOICE_SELECTED, 
        function(event)
            P1_SB1_Selected = event:GetSelection()
    end)

    frame:Connect(Panle1_Static_Box_2, wx.wxEVT_COMMAND_CHOICE_SELECTED, 
        function(event)
            P1_SB2_Selected = event:GetSelection()
    end)

    frame:Connect(Panle1_Static_Box_3, wx.wxEVT_COMMAND_CHOICE_SELECTED, 
        function(event)
            P1_SB3_Selected = event:GetSelection()
    end)

    frame:Connect(Panle1_Send_It_Button, wx.wxEVT_COMMAND_BUTTON_CLICKED,
        function(event)
            if P1_SB1_Selected == -1 or P1_SB2_Selected == -1 or P1_SB3_Selected == -1 then
                wx.wxMessageBox("Missing Entry\n", "Try Agian Commander", wx.wxOK + wx.wxICON_INFORMATION, frame)
            else
                local MissionVariables = string.format( "STCost = %s STSpawnFrom = %s STAttackLocation = %s STUnitType = %s STCanSpawn = true", 100,P1_SB1_Selected,P1_SB2_Selected+1,P1_SB3_Selected )
                local DataFile = io.open("Data.lua", "w")
                DataFile:write(MissionVariables)
                DataFile:close()
            end
    end)
    
    create()
    frame:Show(true)
end

canrun = false
main()
wx.wxGetApp():MainLoop()

Re: WxLua GUI 2d mapping question.

Posted: Sun Jul 29, 2018 7:34 am
by doublemax
Using DrawCircle to draw a single point is the worst of all options. Try DrawPoint().

But drawing individual pixels is always very slow and the GetColor() method with string comparisons makes it even worse. And on top of it seems you're loading the textfiles each time, too.

You should pre-render the data into a bitmap when the program starts (or only when the underlying data changes).

Using wxMemoryDC you can draw into a bitmap like into any other wxDC, so you can re-use the drawing code.