Explorar o código

Update 01_HelloWorld.lua and Add 02_HelloGUI.lua.

Aster Jian %!s(int64=12) %!d(string=hai) anos
pai
achega
5fe38d3246

+ 30 - 27
Bin/Data/LuaScripts/01_HelloWorld.lua

@@ -1,49 +1,52 @@
-require "LuaScripts/Utilities/Sample"
+-- This first example, maintaining tradition, prints a "Hello World" message.
+-- Furthermore it shows:
+--     - Using the Sample utility functions as a base for the application
+--     - Adding a Text element to the graphical user interface
+--     - Subscribing to and handling of update events
 
-HelloWorld = {}
+require "LuaScripts/Utilities/Sample"
 
-function HelloWorld:new()
-    local o = {}
-    self.__index = self
-    setmetatable(o, self)
-    setmetatable(self, {__index = Sample}) -- Set Sample as base class.
-    return o
+function Start()
+    -- Execute the common startup for samples
+    SampleStart()
+    
+    -- Create "Hello World" Text
+    CreateText()
+    
+    -- Finally, hook-up this HelloWorld instance to handle update events
+    SubscribeToEvents()
 end
 
-function HelloWorld:Start()
-    Sample:Start() -- Call Start function in Sample.
-    self:CreateText()
+function Stop()
 end
 
-function HelloWorld:CreateText()
+function CreateText()
+    -- Construct new Text object
     local context = GetContext()
     local helloText = Text:new(context)
 
+    -- Set String to display
     helloText:SetText("Hello World from Urho3D!");
 
+    -- Set font and text color
     local cache = GetCache()
     helloText:SetFont(cache:GetFont("Fonts/Anonymous Pro.ttf"), 30)
-    
     helloText.color = Color(0.0, 1.0, 0.0)
     
+    -- Align Text center-screen
     helloText.horizontalAlignment = HA_CENTER;
     helloText.verticalAlignment = VA_CENTER;
     
-    GetUI():GetRoot():AddChild(helloText)
+    -- Add Text instance to the UI root element
+    local ui = GetUI()
+    ui.root:AddChild(helloText)
 end
 
-local sample = nil
-
-function Start()
-    if sample == nil then
-        sample = HelloWorld:new()
-    end
-    sample:Start()
+function SubscribeToEvents()
+    -- Subscribe HandleUpdate() function for processing update events
+    SubscribeToEvent("Update", "HandleUpdate")
 end
 
-function Stop()
-    if sample ~= nil then
-        sample:Stop()
-    end
-    sample = nil
-end
+function HandleUpdate(eventType, eventData)
+    -- Do nothing for now, could be extended to eg. animate the display
+end

+ 140 - 0
Bin/Data/LuaScripts/02_HelloGUI.lua

@@ -0,0 +1,140 @@
+-- A simple 'HelloWorld' GUI created purely from code.
+-- This sample demonstrates:
+--     - Creation of controls and building a UI hierarchy
+--     - Loading UI style from XML and applying it to controls
+--     - Handling of global and per-control events
+
+require "LuaScripts/Utilities/Sample"
+
+local window = nil
+local windowTitle = nil
+
+function Start()
+    -- Execute the common startup for samples
+    SampleStart()
+
+    -- Enable OS cursor
+    local input = GetInput()
+    input.mouseVisible = true
+
+    -- Load XML file containing default UI style sheet
+    local cache = GetCache()
+    local style = cache:GetXMLFile("UI/DefaultStyle.xml")
+
+    -- Set the loaded style as default style
+    local ui = GetUI()
+    ui.root.defaultStyle = style
+
+    -- Initialize Window
+    InitWindow()
+
+    -- Create and add some controls to the Window
+    InitControls()
+
+    SubscribeToEvents()
+end
+
+function Stop()
+end
+
+function InitControls()
+    -- Create a CheckBox
+    local context = GetContext()
+    local checkBox = CheckBox:new(context)
+    checkBox:SetName("CheckBox")
+
+    -- Create a Button
+    local button = Button:new(context)
+    button:SetName("Button")
+    button.minHeight = 24
+
+    -- Create a LineEdit
+    local lineEdit = LineEdit:new(context)
+    lineEdit:SetName("LineEdit")
+    lineEdit.minHeight = 24
+
+    -- Add controls to Window
+    window:AddChild(checkBox)
+    window:AddChild(button)
+    window:AddChild(lineEdit)
+
+    -- Apply previously set default style
+    checkBox:SetStyleAuto()
+    button:SetStyleAuto()
+    lineEdit:SetStyleAuto()
+end
+
+function InitWindow()
+    -- Create the Window and add it to the UI's root node
+    local context = GetContext()
+    window = Window:new(context)
+    local ui = GetUI()
+    ui.root:AddChild(window)
+    
+    -- Set Window size and layout settings
+    window:SetMinSize(384, 192)
+    window:SetLayout(LM_VERTICAL, 6, IntRect(6, 6, 6, 6))
+    window:SetAlignment(HA_CENTER, VA_CENTER)
+    window:SetName("Window")
+    
+    -- Create Window 'titlebar' container
+    local titleBar = UIElement:new(context)
+    titleBar:SetMinSize(0, 24)
+    titleBar.verticalAlignment = VA_TOP
+    titleBar.layoutMode = LM_HORIZONTAL
+
+    -- Create the Window title Text
+    windowTitle = Text:new(context)
+    windowTitle:SetName("WindowTitle")
+    windowTitle:SetText("Hello GUI!")
+    
+    
+    -- Create the Window's close button
+    local buttonClose = Button:new(context)
+    buttonClose:SetName("CloseButton")
+
+    -- Add the controls to the title bar
+    titleBar:AddChild(windowTitle)
+    titleBar:AddChild(buttonClose)
+
+    -- Add the title bar to the Window
+    window:AddChild(titleBar)
+    
+    
+    -- Apply styles
+    window:SetStyleAuto()
+    windowTitle:SetStyleAuto()
+    buttonClose:SetStyle("CloseButton")
+    
+    -- Lastly, subscribe to buttonClose release (following a 'press') events
+    SubscribeToEvent(buttonClose, "Released", "HandleClosePressed")
+end
+
+function SubscribeToEvents()
+    -- Subscribe handler invoked whenever a mouse click event is dispatched
+    SubscribeToEvent("UIMouseClick", "HandleControlClicked")
+end
+
+function HandleClosePressed(eventType, eventData)
+    local engine = GetEngine()
+    engine:Exit()
+end
+
+function HandleControlClicked(eventType, eventData)
+    -- Get the Text control acting as the Window's title
+    --local windowTitle = window:GetChild("WindowTitle", true)
+    
+    -- Get control that was clicked
+    -- Note difference to C++: in C++ we would call GetPtr() and cast the function pointer to UIElement, here we must specify
+    -- what kind of object we are getting. Null will be returned on type mismatch
+    local clicked = eventData:GetUIElement("Element")
+
+    local name = "...?"
+    if clicked ~= nil then
+        -- Get the name of the control that was clicked
+        name = clicked:GetName():CString()
+    end
+
+    -- Update the Window's title text
+    windowTitle:SetText("Hello " .. name .. "!")
+end

+ 118 - 21
Bin/Data/LuaScripts/Utilities/Sample.lua

@@ -1,59 +1,86 @@
-Sample = {}
+-- Common sample initialization as a framework for all samples.
+--    - Create Urho3D logo at screen
+--    - Create Console and Debug HUD, and use F1 and F2 key to toggle them
+--    - Toggle rendering options from the keys 1-8
+--    - Handle Esc key down to hide Console or exit application
 
-function Sample:Start()
-    self.logoSprite = nil
-    self:CreateLogo()
-    self:CreateConsoleAndDebugHud()
+local logoSprite = nil
+
+function SampleStart()
+    -- Create logo
+    CreateLogo()
+    
+    -- Create console and debug HUD
+    CreateConsoleAndDebugHud()
+
+    -- Subscribe key down event
+    SubscribeToEvent("KeyDown", "HandleKeyDown")
 end
 
-function Sample:Stop()
-    self.logoSprite = nil
+function SetLogoVisible(enable)
+    if logoSprite ~= nil then
+        logoSprite.visible = enable
+    end
 end
 
-function Sample:CreateLogo()
+function CreateLogo()
+    -- Get logo texture
     local cache = GetCache()
     local logoTexture = cache:GetTexture2D("Textures/LogoLarge.png")
     if logoTexture == nil then
         return
     end
     
+    -- Create logo sprite and add to the UI layout
     local ui = GetUI()
-    self.logoSprite = ui.root:CreateSprite()
-    --self.logoSprite.texture = logoTexture
-    self.logoSprite:SetTexture(logoTexture)
+    logoSprite = ui.root:CreateSprite()
     
+    -- Set logo sprite texture
+    logoSprite:SetTexture(logoTexture)
     
     local textureWidth = logoTexture.width
     local textureHeight = logoTexture.height
     
-    self.logoSprite:SetScale(256 / textureWidth)
-    --self.logoSprite.size = IntVector2(textureWidth, textureHeight)
-    self.logoSprite:SetSize(textureWidth, textureHeight)
-    self.logoSprite.hotSpot = IntVector2(0, textureHeight)
+    -- Set logo sprite scale
+    logoSprite:SetScale(256 / textureWidth)
+    
+    -- Set logo sprite size
+    logoSprite:SetSize(textureWidth, textureHeight)
+    
+    -- Set logo sprite hot spot
+    logoSprite.hotSpot = IntVector2(0, textureHeight)
     
-    self.logoSprite:SetAlignment(HA_LEFT, VA_BOTTOM);
+    -- Set logo sprite alignment
+    logoSprite:SetAlignment(HA_LEFT, VA_BOTTOM);
+    
+    -- Make logo not fully opaque to show the scene underneath
+    logoSprite.opacity = 0.75
+    
+    -- Set a low priority for the logo so that other UI elements can be drawn on top
+    logoSprite.priority = -100
 end
 
-function Sample:CreateConsoleAndDebugHud()
+function CreateConsoleAndDebugHud()
+    -- Get default style
     local cache = GetCache()
     local uiStyle = cache:GetXMLFile("UI/DefaultStyle.xml")
     if uiStyle == nil then
         return
     end
     
+    -- Create console
     local engine = GetEngine()
     local console = engine:CreateConsole()
     console.defaultStyle = uiStyle
     
+    -- Create debug HUD
     local debugHud = engine:CreateDebugHud()
     debugHud.defaultStyle = uiStyle
-    
-    SubscribeToEvent("KeyDown", "Sample.HandleKeyDownEvent")
 end
 
-function Sample.HandleKeyDownEvent(eventType, eventData)
+function HandleKeyDown(eventType, eventData)
     local key = eventData:GetInt("Key")
-    
+    -- Close console (if open) or exit when ESC is pressed
     if key == KEY_ESC then
         local ui = GetUI()
         if ui:GetFocusElement() == nil then
@@ -74,4 +101,74 @@ function Sample.HandleKeyDownEvent(eventType, eventData)
         local debugHud = GetDebugHud()
         debugHud:ToggleAll()
     end
+    
+    local ui = GetUI()
+    if ui.focusElement == nil then
+        local renderer = GetRenderer()
+        -- Texture quality
+        if key == KEY_1 then
+            local quality = renderer.textureQuality
+            quality = quality + 1
+            if quality > QUALITY_HIGH then
+                quality = QUALITY_LOW
+            end
+            renderer.textureQuality = quality
+        end
+        
+        -- Material quality
+        if key == KEY_2 then
+            local quality = renderer.materialQuality
+            quality = quality + 1
+            if quality > QUALITY_HIGH then
+                quality = QUALITY_LOW
+            end
+            renderer.materialQuality = quality
+        end
+
+        -- Specular lighting
+        if key == KEY_3 then
+            renderer.specularLighting = not renderer.specularLighting
+        end
+        
+        -- Shadow rendering
+        if key == KEY_4 then
+            renderer.drawShadows = not renderer.drawShadows
+        end
+        
+        -- Shadow map resolution
+        if key == KEY_5 then
+            local shadowMapSize = renderer.shadowMapSize
+            shadowMapSize = shadowMapSize * 2
+            if shadowMapSize > 2048 then
+                shadowMapSize = 512
+            end
+            renderer.shadowMapSize = shadowMapSize
+        end
+        
+        -- Shadow depth and filtering quality
+        if key == KEY_6 then
+            local quality = renderer.shadowQuality
+            quality = quality + 1
+            if quality > SHADOWQUALITY_HIGH_24BIT then
+                quality = SHADOWQUALITY_LOW_16BIT
+            end
+            renderer.shadowQuality = quality
+        end
+        
+        -- Occlusion culling
+        if key == KEY_7 then
+            local occlusion = renderer.maxOccluderTriangles > 0
+            occlusion = not occlusion
+            if occlusion then
+                renderer.maxOccluderTriangles = 5000
+            else
+                renderer.maxOccluderTriangles = 0
+            end
+        end
+        
+        -- Instancing
+        if key == KEY_8 then
+            renderer.dynamicInstancing = not renderer.dynamicInstancing
+        end
+    end
 end