| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256 |
- -- Common sample initialization as a framework for all samples.
- -- - Create Urho3D logo at screen
- -- - Set custom window title and icon
- -- - Create Console and Debug HUD, and use F1 and F2 key to toggle them
- -- - Toggle rendering options from the keys 1-8
- -- - Take screenshots with key 9
- -- - Handle Esc key down to hide Console or exit application
- -- - Init touch input on mobile platform using screen joysticks (patched for each individual sample)
- local logoSprite = nil
- scene_ = nil -- Scene
- screenJoystickIndex = M_MAX_UNSIGNED -- Screen joystick index for navigational controls (mobile platforms only)
- screenJoystickSettingsIndex = M_MAX_UNSIGNED -- Screen joystick index for settings (mobile platforms only)
- touchEnabled = false -- Flag to indicate whether touch input has been enabled
- paused = false -- Pause flag
- drawDebug = false -- Draw debug geometry flag
- cameraNode = nil -- Camera scene node
- yaw = 0 -- Camera yaw angle
- pitch = 0 -- Camera pitch angle
- TOUCH_SENSITIVITY = 2
- function SampleStart()
- if GetPlatform() == "Android" or GetPlatform() == "iOS" or input.touchEmulation then
- -- On mobile platform, enable touch by adding a screen joystick
- InitTouchInput()
- elseif input:GetNumJoysticks() == 0 then
- -- On desktop platform, do not detect touch when we already got a joystick
- SubscribeToEvent("TouchBegin", "HandleTouchBegin")
- end
- -- Create logo
- CreateLogo()
- -- Set custom window Title & Icon
- SetWindowTitleAndIcon()
- -- Create console and debug HUD
- CreateConsoleAndDebugHud()
- -- Subscribe key down event
- SubscribeToEvent("KeyDown", "HandleKeyDown")
- -- Subscribe scene update event
- SubscribeToEvent("SceneUpdate", "HandleSceneUpdate")
- end
- function InitTouchInput()
- touchEnabled = true
- local layout = cache:GetResource("XMLFile", "UI/ScreenJoystick_Samples.xml")
- local patchString = GetScreenJoystickPatchString()
- if patchString ~= "" then
- -- Patch the screen joystick layout further on demand
- local patchFile = XMLFile()
- if patchFile:FromString(patchString) then layout:Patch(patchFile) end
- end
- screenJoystickIndex = input:AddScreenJoystick(layout, cache:GetResource("XMLFile", "UI/DefaultStyle.xml"))
- input:SetScreenJoystickVisible(screenJoystickSettingsIndex, true)
- end
- function SetLogoVisible(enable)
- if logoSprite ~= nil then
- logoSprite.visible = enable
- end
- end
- function CreateLogo()
- -- Get logo texture
- local logoTexture = cache:GetResource("Texture2D", "Textures/LogoLarge.png")
- if logoTexture == nil then
- return
- end
- -- Create logo sprite and add to the UI layout
- logoSprite = ui.root:CreateChild("Sprite")
- -- Set logo sprite texture
- logoSprite:SetTexture(logoTexture)
- local textureWidth = logoTexture.width
- local textureHeight = logoTexture.height
- -- 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)
- -- 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 SetWindowTitleAndIcon()
- local icon = cache:GetResource("Image", "Textures/UrhoIcon.png")
- graphics:SetWindowIcon(icon)
- graphics.windowTitle = "Urho3D Sample"
- end
- function CreateConsoleAndDebugHud()
- -- Get default style
- local uiStyle = cache:GetResource("XMLFile", "UI/DefaultStyle.xml")
- if uiStyle == nil then
- return
- end
- -- Create console
- engine:CreateConsole()
- console.defaultStyle = uiStyle
- console.background.opacity = 0.8
- -- Create debug HUD
- engine:CreateDebugHud()
- debugHud.defaultStyle = uiStyle
- end
- function HandleKeyDown(eventType, eventData)
- local key = eventData:GetInt("Key")
- -- Close console (if open) or exit when ESC is pressed
- if key == KEY_ESC then
- if not console:IsVisible() then
- engine:Exit()
- else
- console:SetVisible(false)
- end
- elseif key == KEY_F1 then
- console:Toggle()
- elseif key == KEY_F2 then
- debugHud:ToggleAll()
- end
- if ui.focusElement == nil then
- -- Preferences / Pause
- if key == KEY_SELECT and touchEnabled then
- paused = not paused
- if screenJoystickSettingsIndex == M_MAX_UNSIGNED then
- -- Lazy initialization
- screenJoystickSettingsIndex = input:AddScreenJoystick(cache:GetResource("XMLFile", "UI/ScreenJoystickSettings_Samples.xml"), cache:GetResource("XMLFile", "UI/DefaultStyle.xml"))
- else
- input:SetScreenJoystickVisible(screenJoystickSettingsIndex, paused)
- end
- -- Texture quality
- elseif key == KEY_1 then
- local quality = renderer.textureQuality
- quality = quality + 1
- if quality > QUALITY_HIGH then
- quality = QUALITY_LOW
- end
- renderer.textureQuality = quality
- -- Material quality
- elseif key == KEY_2 then
- local quality = renderer.materialQuality
- quality = quality + 1
- if quality > QUALITY_HIGH then
- quality = QUALITY_LOW
- end
- renderer.materialQuality = quality
- -- Specular lighting
- elseif key == KEY_3 then
- renderer.specularLighting = not renderer.specularLighting
- -- Shadow rendering
- elseif key == KEY_4 then
- renderer.drawShadows = not renderer.drawShadows
- -- Shadow map resolution
- elseif key == KEY_5 then
- local shadowMapSize = renderer.shadowMapSize
- shadowMapSize = shadowMapSize * 2
- if shadowMapSize > 2048 then
- shadowMapSize = 512
- end
- renderer.shadowMapSize = shadowMapSize
- -- Shadow depth and filtering quality
- elseif 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
- -- Occlusion culling
- elseif key == KEY_7 then
- local occlusion = renderer.maxOccluderTriangles > 0
- occlusion = not occlusion
- if occlusion then
- renderer.maxOccluderTriangles = 5000
- else
- renderer.maxOccluderTriangles = 0
- end
- -- Instancing
- elseif key == KEY_8 then
- renderer.dynamicInstancing = not renderer.dynamicInstancing
- -- Take screenshot
- elseif key == KEY_9 then
- local screenshot = Image()
- graphics:TakeScreenShot(screenshot)
- local timeStamp = Time:GetTimeStamp()
- timeStamp = string.gsub(timeStamp, "[:. ]", "_")
- -- Here we save in the Data folder with date and time appended
- screenshot:SavePNG(fileSystem:GetProgramDir() .. "Data/Screenshot_" .. timeStamp .. ".png")
- end
- end
- end
- function HandleSceneUpdate(eventType, eventData)
- -- Move the camera by touch, if the camera node is initialized by descendant sample class
- if touchEnabled and cameraNode then
- for i=0, input:GetNumTouches()-1 do
- local state = input:GetTouch(i)
- if not state.touchedElement then -- Touch on empty space
- if state.delta.x or state.delta.y then
- local camera = cameraNode:GetComponent("Camera")
- if not camera then return end
- yaw = yaw + TOUCH_SENSITIVITY * camera.fov / graphics.height * state.delta.x
- pitch = pitch + TOUCH_SENSITIVITY * camera.fov / graphics.height * state.delta.y
- -- Construct new orientation for the camera scene node from yaw and pitch; roll is fixed to zero
- cameraNode:SetRotation(Quaternion(pitch, yaw, 0))
- else
- -- Move the cursor to the touch position
- local cursor = ui:GetCursor()
- if cursor and cursor:IsVisible() then cursor:SetPosition(state.position) end
- end
- end
- end
- end
- end
- function HandleTouchBegin(eventType, eventData)
- -- On some platforms like Windows the presence of touch input can only be detected dynamically
- InitTouchInput()
- UnsubscribeFromEvent("TouchBegin")
- end
- -- Create empty XML patch instructions for screen joystick layout if none defined
- function GetScreenJoystickPatchString()
- return ""
- end
|