roblox backend: render scale for high-DPI displays; make tiles Active while imgui wants the mouse so input doesn't reach the game

This commit is contained in:
4DBug
2026-10-08 08:21:54 -05:00
parent d7a2b8a4df
commit 4719eeedf3
4 changed files with 62 additions and 14 deletions
+1 -1
View File
@@ -1 +1 @@
[[12, "imgui.lua"], [13756, "imgui_demo.lua"], [14689, "imgui_demo_2.lua"], [17764, "imgui_demo_widgets.lua"], [19688, "imgui_docking.lua"], [22816, "imgui_dragdrop.lua"], [23108, "imgui_draw.lua"], [28114, "imgui_h.lua"], [30324, "imgui_impl_roblox.lua"], [31089, "imgui_impl_roblox_fonts.lua"], [31867, "imgui_internal.lua"], [35023, "imgui_tables.lua"], [39370, "imgui_tabs.lua"], [40537, "imgui_widgets.lua"], [49061, "imstb_rectpack.lua"], [49507, "imstb_textedit.lua"], [50748, "imstb_truetype.lua"], [53216, "imstd_minstdio.lua"]] [[12, "imgui.lua"], [13756, "imgui_demo.lua"], [14689, "imgui_demo_2.lua"], [17764, "imgui_demo_widgets.lua"], [19688, "imgui_docking.lua"], [22816, "imgui_dragdrop.lua"], [23108, "imgui_draw.lua"], [28114, "imgui_h.lua"], [30324, "imgui_impl_roblox.lua"], [31111, "imgui_impl_roblox_fonts.lua"], [31889, "imgui_internal.lua"], [35045, "imgui_tables.lua"], [39392, "imgui_tabs.lua"], [40559, "imgui_widgets.lua"], [49083, "imstb_rectpack.lua"], [49529, "imstb_textedit.lua"], [50770, "imstb_truetype.lua"], [53238, "imstd_minstdio.lua"]]
+29 -6
View File
@@ -30788,11 +30788,13 @@ local function GetTile(bd, index, tx, ty)
label.Name = "Tile" .. index label.Name = "Tile" .. index
label.BackgroundTransparency = 1 label.BackgroundTransparency = 1
label.BorderSizePixel = 0 label.BorderSizePixel = 0
label.Size = UDim2.fromOffset(TILE, TILE) local scale = bd.Scale
label.Position = UDim2.fromOffset(tx * TILE, ty * TILE) label.Size = UDim2.fromOffset(TILE / scale, TILE / scale)
label.Position = UDim2.fromOffset(tx * TILE / scale, ty * TILE / scale)
label.ResampleMode = Enum.ResamplerMode.Pixelated label.ResampleMode = Enum.ResamplerMode.Pixelated
label.ImageContent = Content.fromObject(img) label.ImageContent = Content.fromObject(img)
label.Visible = false label.Visible = false
label.Active = bd.TilesActive
label.Parent = bd.Gui label.Parent = bd.Gui
tile = { Image = img, Label = label, Buffer = buffer.create(TILE * TILE * 4), H1 = -1, H2 = -1, Visible = false } tile = { Image = img, Label = label, Buffer = buffer.create(TILE * TILE * 4), H1 = -1, H2 = -1, Visible = false }
bd.Tiles[index] = tile bd.Tiles[index] = tile
@@ -30965,7 +30967,10 @@ end
--------------------------------------------------------- ---------------------------------------------------------
--- @param parent Instance? # where the ScreenGui goes, defaults to the local player's PlayerGui --- @param parent Instance? # where the ScreenGui goes, defaults to the local player's PlayerGui
function ImGui_ImplRoblox_Init(parent) --- @param render_scale number? # imgui pixels per Roblox UI point (defaults to 1). Roblox UI points are scaled by the
--- # OS display scale, so on a 150% display pass 1.5 to render at physical resolution
--- # (imgui then looks the same size as a desktop imgui app). Change later with SetRenderScale().
function ImGui_ImplRoblox_Init(parent, render_scale)
local io = ImGui.GetIO() local io = ImGui.GetIO()
local gui = Instance.new("ScreenGui") local gui = Instance.new("ScreenGui")
@@ -30978,7 +30983,7 @@ function ImGui_ImplRoblox_Init(parent)
local bd = { local bd = {
Time = os.clock(), Gui = gui, Connections = {}, Time = os.clock(), Gui = gui, Connections = {},
Textures = {}, TextureCount = 0, MouseX = -1, MouseY = -1, Textures = {}, TextureCount = 0, MouseX = -1, MouseY = -1,
Tiles = {}, TileCols = 0, TileRows = 0, TH1 = {}, TH2 = {}, TN = {}, TL = {}, LastPrimCount = 0, ForceRedraw = true, Tiles = {}, TileCols = 0, TileRows = 0, Scale = render_scale or 1, TilesActive = false, TH1 = {}, TH2 = {}, TN = {}, TL = {}, LastPrimCount = 0, ForceRedraw = true,
} }
io.BackendPlatformUserData = bd io.BackendPlatformUserData = bd
@@ -31055,7 +31060,7 @@ function ImGui_ImplRoblox_NewFrame()
local bd = ImGui_ImplRoblox_GetBackendData() local bd = ImGui_ImplRoblox_GetBackendData()
local screen = bd.Gui.AbsoluteSize local screen = bd.Gui.AbsoluteSize
local w, h = floor(screen.X), floor(screen.Y) local w, h = floor(screen.X * bd.Scale), floor(screen.Y * bd.Scale)
if w ~= bd.ScreenW or h ~= bd.ScreenH then if w ~= bd.ScreenW or h ~= bd.ScreenH then
bd.ScreenW, bd.ScreenH = w, h bd.ScreenW, bd.ScreenH = w, h
ImGui_ImplRoblox_UpdateMonitors(w, h) ImGui_ImplRoblox_UpdateMonitors(w, h)
@@ -31070,8 +31075,24 @@ function ImGui_ImplRoblox_NewFrame()
if m.X ~= bd.MouseX or m.Y ~= bd.MouseY then if m.X ~= bd.MouseX or m.Y ~= bd.MouseY then
bd.MouseX, bd.MouseY = m.X, m.Y bd.MouseX, bd.MouseY = m.X, m.Y
io:AddMouseSourceEvent(ImGuiMouseSource.Mouse) io:AddMouseSourceEvent(ImGuiMouseSource.Mouse)
io:AddMousePosEvent(m.X, m.Y) io:AddMousePosEvent(m.X * bd.Scale, m.Y * bd.Scale)
end end
-- While the mouse is over imgui, make the tiles Active so Roblox stops passing clicks/wheel to the game (camera zoom etc.)
local want = io.WantCaptureMouse
if want ~= bd.TilesActive then
bd.TilesActive = want
for _, tile in pairs(bd.Tiles) do tile.Label.Active = want end
end
end
function ImGui_ImplRoblox_SetRenderScale(scale)
local bd = ImGui_ImplRoblox_GetBackendData()
if scale == bd.Scale then return end
bd.Scale = scale
DestroyTiles(bd)
bd.TileCols, bd.TileRows = 0, 0
bd.ForceRedraw = true
end end
ImGui_ImplRoblox = { ImGui_ImplRoblox = {
@@ -31080,6 +31101,7 @@ ImGui_ImplRoblox = {
NewFrame = ImGui_ImplRoblox_NewFrame, NewFrame = ImGui_ImplRoblox_NewFrame,
RenderDrawData = ImGui_ImplRoblox_RenderDrawData, RenderDrawData = ImGui_ImplRoblox_RenderDrawData,
AddFile = ImGui_ImplRoblox_AddFile, AddFile = ImGui_ImplRoblox_AddFile,
SetRenderScale = ImGui_ImplRoblox_SetRenderScale,
} }
return true -- [Roblox] ModuleScripts must return exactly one value return true -- [Roblox] ModuleScripts must return exactly one value
@@ -53813,6 +53835,7 @@ return {
ImGui_ImplRoblox_Init = ImGui_ImplRoblox_Init, ImGui_ImplRoblox_Init = ImGui_ImplRoblox_Init,
ImGui_ImplRoblox_NewFrame = ImGui_ImplRoblox_NewFrame, ImGui_ImplRoblox_NewFrame = ImGui_ImplRoblox_NewFrame,
ImGui_ImplRoblox_RenderDrawData = ImGui_ImplRoblox_RenderDrawData, ImGui_ImplRoblox_RenderDrawData = ImGui_ImplRoblox_RenderDrawData,
ImGui_ImplRoblox_SetRenderScale = ImGui_ImplRoblox_SetRenderScale,
ImGui_ImplRoblox_Shutdown = ImGui_ImplRoblox_Shutdown, ImGui_ImplRoblox_Shutdown = ImGui_ImplRoblox_Shutdown,
ImGui_ImplRoblox_UpdateTexture = ImGui_ImplRoblox_UpdateTexture, ImGui_ImplRoblox_UpdateTexture = ImGui_ImplRoblox_UpdateTexture,
ImHashData = ImHashData, ImHashData = ImHashData,
+28 -6
View File
@@ -465,11 +465,13 @@ local function GetTile(bd, index, tx, ty)
label.Name = "Tile" .. index label.Name = "Tile" .. index
label.BackgroundTransparency = 1 label.BackgroundTransparency = 1
label.BorderSizePixel = 0 label.BorderSizePixel = 0
label.Size = UDim2.fromOffset(TILE, TILE) local scale = bd.Scale
label.Position = UDim2.fromOffset(tx * TILE, ty * TILE) label.Size = UDim2.fromOffset(TILE / scale, TILE / scale)
label.Position = UDim2.fromOffset(tx * TILE / scale, ty * TILE / scale)
label.ResampleMode = Enum.ResamplerMode.Pixelated label.ResampleMode = Enum.ResamplerMode.Pixelated
label.ImageContent = Content.fromObject(img) label.ImageContent = Content.fromObject(img)
label.Visible = false label.Visible = false
label.Active = bd.TilesActive
label.Parent = bd.Gui label.Parent = bd.Gui
tile = { Image = img, Label = label, Buffer = buffer.create(TILE * TILE * 4), H1 = -1, H2 = -1, Visible = false } tile = { Image = img, Label = label, Buffer = buffer.create(TILE * TILE * 4), H1 = -1, H2 = -1, Visible = false }
bd.Tiles[index] = tile bd.Tiles[index] = tile
@@ -642,7 +644,10 @@ end
--------------------------------------------------------- ---------------------------------------------------------
--- @param parent Instance? # where the ScreenGui goes, defaults to the local player's PlayerGui --- @param parent Instance? # where the ScreenGui goes, defaults to the local player's PlayerGui
function ImGui_ImplRoblox_Init(parent) --- @param render_scale number? # imgui pixels per Roblox UI point (defaults to 1). Roblox UI points are scaled by the
--- # OS display scale, so on a 150% display pass 1.5 to render at physical resolution
--- # (imgui then looks the same size as a desktop imgui app). Change later with SetRenderScale().
function ImGui_ImplRoblox_Init(parent, render_scale)
local io = ImGui.GetIO() local io = ImGui.GetIO()
local gui = Instance.new("ScreenGui") local gui = Instance.new("ScreenGui")
@@ -655,7 +660,7 @@ function ImGui_ImplRoblox_Init(parent)
local bd = { local bd = {
Time = os.clock(), Gui = gui, Connections = {}, Time = os.clock(), Gui = gui, Connections = {},
Textures = {}, TextureCount = 0, MouseX = -1, MouseY = -1, Textures = {}, TextureCount = 0, MouseX = -1, MouseY = -1,
Tiles = {}, TileCols = 0, TileRows = 0, TH1 = {}, TH2 = {}, TN = {}, TL = {}, LastPrimCount = 0, ForceRedraw = true, Tiles = {}, TileCols = 0, TileRows = 0, Scale = render_scale or 1, TilesActive = false, TH1 = {}, TH2 = {}, TN = {}, TL = {}, LastPrimCount = 0, ForceRedraw = true,
} }
io.BackendPlatformUserData = bd io.BackendPlatformUserData = bd
@@ -732,7 +737,7 @@ function ImGui_ImplRoblox_NewFrame()
local bd = ImGui_ImplRoblox_GetBackendData() local bd = ImGui_ImplRoblox_GetBackendData()
local screen = bd.Gui.AbsoluteSize local screen = bd.Gui.AbsoluteSize
local w, h = floor(screen.X), floor(screen.Y) local w, h = floor(screen.X * bd.Scale), floor(screen.Y * bd.Scale)
if w ~= bd.ScreenW or h ~= bd.ScreenH then if w ~= bd.ScreenW or h ~= bd.ScreenH then
bd.ScreenW, bd.ScreenH = w, h bd.ScreenW, bd.ScreenH = w, h
ImGui_ImplRoblox_UpdateMonitors(w, h) ImGui_ImplRoblox_UpdateMonitors(w, h)
@@ -747,8 +752,24 @@ function ImGui_ImplRoblox_NewFrame()
if m.X ~= bd.MouseX or m.Y ~= bd.MouseY then if m.X ~= bd.MouseX or m.Y ~= bd.MouseY then
bd.MouseX, bd.MouseY = m.X, m.Y bd.MouseX, bd.MouseY = m.X, m.Y
io:AddMouseSourceEvent(ImGuiMouseSource.Mouse) io:AddMouseSourceEvent(ImGuiMouseSource.Mouse)
io:AddMousePosEvent(m.X, m.Y) io:AddMousePosEvent(m.X * bd.Scale, m.Y * bd.Scale)
end end
-- While the mouse is over imgui, make the tiles Active so Roblox stops passing clicks/wheel to the game (camera zoom etc.)
local want = io.WantCaptureMouse
if want ~= bd.TilesActive then
bd.TilesActive = want
for _, tile in pairs(bd.Tiles) do tile.Label.Active = want end
end
end
function ImGui_ImplRoblox_SetRenderScale(scale)
local bd = ImGui_ImplRoblox_GetBackendData()
if scale == bd.Scale then return end
bd.Scale = scale
DestroyTiles(bd)
bd.TileCols, bd.TileRows = 0, 0
bd.ForceRedraw = true
end end
ImGui_ImplRoblox = { ImGui_ImplRoblox = {
@@ -757,6 +778,7 @@ ImGui_ImplRoblox = {
NewFrame = ImGui_ImplRoblox_NewFrame, NewFrame = ImGui_ImplRoblox_NewFrame,
RenderDrawData = ImGui_ImplRoblox_RenderDrawData, RenderDrawData = ImGui_ImplRoblox_RenderDrawData,
AddFile = ImGui_ImplRoblox_AddFile, AddFile = ImGui_ImplRoblox_AddFile,
SetRenderScale = ImGui_ImplRoblox_SetRenderScale,
} }
return true -- [Roblox] ModuleScripts must return exactly one value return true -- [Roblox] ModuleScripts must return exactly one value
+4 -1
View File
@@ -8,6 +8,9 @@ local G = require(ReplicatedStorage:WaitForChild("ImGui"))
local ImGui, ImVec4, ImGuiConfigFlags, ImGui_ImplRoblox = G.ImGui, G.ImVec4, G.ImGuiConfigFlags, G.ImGui_ImplRoblox local ImGui, ImVec4, ImGuiConfigFlags, ImGui_ImplRoblox = G.ImGui, G.ImVec4, G.ImGuiConfigFlags, G.ImGui_ImplRoblox
local main_scale = 1.0 local main_scale = 1.0
-- Roblox UI points are multiplied by the OS display scale (e.g. 150%), which makes imgui look large.
-- Set this to your display scale to render imgui at physical-pixel resolution (same size as a desktop imgui app).
local render_scale = 1.0
local clear_color = ImVec4(0.45, 0.55, 0.60, 1.00) local clear_color = ImVec4(0.45, 0.55, 0.60, 1.00)
local show_demo_window = true local show_demo_window = true
local show_another_window = false local show_another_window = false
@@ -23,7 +26,7 @@ local style = ImGui.GetStyle()
style:ScaleAllSizes(main_scale) style:ScaleAllSizes(main_scale)
style.FontScaleDpi = main_scale style.FontScaleDpi = main_scale
ImGui_ImplRoblox.Init() ImGui_ImplRoblox.Init(nil, render_scale)
RunService.Stepped:Connect(function() RunService.Stepped:Connect(function()
ImGui_ImplRoblox.NewFrame() ImGui_ImplRoblox.NewFrame()