@@ -11,15 +11,16 @@ input routing, configs and screenshots. An application links `sysLib` (premake p
1111| ` sys_window.cpp/.h ` | Window creation, SDL init, game loop (` sysHostInit ` , ` sysHostGameLoop ` , ` sysHostTerminate ` ) |
1212| ` sys_host.cpp/.h ` | ` g_pHost ` (` CGameHost ` ) — systems, frame, video modes, cursor, input events |
1313| ` sys_state.cpp/.h ` | ` CAppStateBase ` , ` eqAppStateMng ` — app states |
14- | ` sys_in_console.cpp/.h ` | ` g_consoleInput ` (` CEqConsoleInput ` ) — developer console, log, ImGui frame |
14+ | ` sys_viewport.cpp/.h ` | ` CHostViewport ` — state rendering inside an ImGui window |
15+ | ` sys_in_console.cpp/.h ` | ` g_consoleInput ` (` CEqConsoleInput ` ) — developer console, log |
1516| ` sys_in_joystick.cpp/.h ` | ` CEqGameControllerSDL ` — game controllers |
1617| ` cfgloader.cpp/.h ` | ` WriteCfgFile ` , ` writecfg ` |
1718| ` sys_version.cpp/.h ` | ` ENGINE_NAME ` , ` ENGINE_VERSION ` , ` COMPILE_* ` , ` GetEngineBuildNumber() ` |
18- | ` imgui/imgui_impl_sys.* ` | ImGui platform backend for SDL |
1919| ` scripting/ ` | Engine Lua state and bindings ([ scripting_esl_overview.md] ( scripting_esl_overview.md ) ) |
2020
2121` sysLib ` also compiles ` shared/input ` ([ input_overview.md] ( input_overview.md ) ) and uses
22- ` renderUtilLib ` , ` equiLib ` , ` movieLib ` , ` scriptLib ` , SDL2 and the ImGui backend.
22+ ` renderUtilLib ` , ` equiLib ` , ` movieLib ` , ` scriptLib ` , SDL2 and ` imguiBackendLib ` (` g_imGuiHost ` ,
23+ ` shared/imgui_backend ` , which also contains the ImGui platform backend for SDL).
2324
2425## Start-up and shutdown
2526
@@ -39,7 +40,8 @@ WinMain / main
3940 │ │ ├─ window (vid_mode, vid_fullscreen, vid_screen), command line (+cmd value)
4041 │ │ ├─ g_matSystem->Init() RHI on the SDL window
4142 │ │ ├─ g_fontCache, g_localizer (+GAME_VERSION, BUILD_NUMBER tokens),
42- │ │ │ debugoverlay, equi::Manager, g_inputCommandBinder, g_consoleInput (ImGui)
43+ │ │ │ debugoverlay, g_imGuiHost (ImGui on the SDL window), equi::Manager,
44+ │ │ │ g_inputCommandBinder, g_consoleInput
4345 │ │ └─ REGISTER_INTERNAL_SHADERS() material shaders compiled into the application
4446 │ └─ CEqGameControllerSDL::Init()
4547 ├─ sysHostGameLoop()
@@ -101,6 +103,7 @@ A state is one mode of the application (menu, game, editor). Derive from `CAppSt
101103| ` HandleKeyPress ` , ` HandleMouseClick ` , ` HandleMouseMove ` , ` HandleMouseWheel ` , ` HandleJoyAxis ` | Input not consumed by console / ImGui / EqUI |
102104| ` GetMouseCursorProperties(visible, centered) ` | Cursor visibility and relative (centered) mouse mode |
103105| ` GetTimescale() ` | Time scale for this state's ` dt ` |
106+ | ` GetViewport() ` | ` CHostViewport ` the state renders to, ` nullptr ` for the whole window (see [ Host viewport] ( #host-viewport--chostviewport ) ) |
104107
105108State management (` eqAppStateMng ` ):
106109
@@ -130,15 +133,19 @@ frame the loop sleeps `sys_sleep` ms (default 1).
1301331 . Measures time. With ` sys_maxfps ` set, the frame is skipped until enough time passed; the frame
131134 time is clamped to 0.001–0.1 s.
1321352 . ` g_onBeginFrame ` , controller button repeats, cursor state.
133- 3 . ` BeginScene ` : ` g_matSystem->BeginFrame ` , ` r_wireframe ` / ` r_overdraw ` , console / ImGui frame
134- start.
136+ 3 . ` BeginScene ` : ` g_matSystem->BeginFrame ` , console frame start, ImGui frame start
137+ (` g_imGuiHost->BeginFrame ` , debug menus while the console is open), ` r_wireframe ` /
138+ ` r_overdraw ` .
1351394 . ` eqAppStateMng::UpdateStates(dt × state timescale × sys_timescale) ` — the current state
136140 renders and queues its command buffers.
1371415 . EqUI render, full-screen edge AA, ` g_matSystem->SubmitQueuedCommandsAwaitable() ` .
1381426 . Debug overlay with engine statistics (FPS, draw / dispatch counts, GPU and system memory),
139- ` r_showFPS ` , ` r_showFPSGraph ` , input debug drawing.
140- 7 . ` EndScene ` : screenshot (without console / ImGui), console and ImGui drawing,
141- ` g_matSystem->EndFrame() ` .
143+ ` r_showFPS ` , ` r_showFPSGraph ` . Screenshot (without console / ImGui), then one render pass with
144+ the debug overlay, input debug drawing, console (` g_consoleInput->EndFrame ` ) and ImGui
145+ (` g_imGuiHost->EndFrame ` ). With a visible state viewport, EqUI, debug overlays, input debug
146+ drawing and the console go to the viewport target, ImGui is drawn in a separate backbuffer pass
147+ and the screenshot is taken after it (see [ Host viewport] ( #host-viewport--chostviewport ) ).
148+ 7 . ` EndScene ` : ` g_matSystem->EndFrame() ` .
1421498 . Pending fullscreen toggle, ` g_onEndFrame ` .
143150
144151` GetFrameTime() ` returns the current frame time; ` GetWindowSize() ` , ` GetDefaultFont() ` ,
@@ -165,29 +172,92 @@ dispatched by `CGameHost`:
165172
166173| Event | Order |
167174| ---| ---|
168- | Keyboard | console → EqUI → state ` HandleKeyPress ` |
169- | Mouse buttons | console / ImGui → EqUI → (touch emulation with ` m_clicks_to_touch ` ) → state ` HandleMouseClick ` |
175+ | Keyboard | console toggle key → ImGui → console → EqUI → state ` HandleKeyPress ` |
176+ | Mouse buttons | ImGui → console → EqUI → (touch emulation with ` m_clicks_to_touch ` ) → state ` HandleMouseClick ` |
170177| Mouse movement | console / ImGui position → EqUI → ` g_inputCommandBinder->OnVectorEvent(MOU_MOVE) ` → state ` HandleMouseMove ` |
171- | Mouse wheel | console → binder (` MOU_MOVE ` ) → state ` HandleMouseWheel ` |
178+ | Mouse wheel | ImGui → console → binder (` MOU_MOVE ` ) → state ` HandleMouseWheel ` |
172179| Controller buttons / axes | binder → state ` HandleKeyPress ` / ` HandleJoyAxis ` |
173180| Touch | binder touch zones |
174- | Text input | console |
181+ | Text input | ImGui → console |
182+
183+ With a visible state viewport (` GetViewport() ` ), the console, EqUI and the state receive mouse
184+ buttons, movement and wheel only over the viewport, in viewport coordinates. Keys and text go past
185+ the ImGui check while the viewport window is focused or the console is open, unless an ImGui text
186+ field is active. See [ Host viewport] ( #host-viewport--chostviewport ) .
175187
176188Keyboard keys and mouse buttons reach command bindings only if the state forwards them to
177189` g_inputCommandBinder->OnPressEvent ` (see [ input_overview.md] ( input_overview.md ) ). Input is ignored
178190for 0.25 s after the window regains focus.
179191
192+ ImGui (` g_imGuiHost->Input* ` ) receives keys, mouse buttons, wheel and text first. While an ImGui
193+ item is hovered, active or focused, or ImGui wants the mouse / keyboard
194+ (` g_imGuiHost->IsImGuiItemsInFocus() ` ), the event goes no further; key releases still reach the
195+ console so its modifier state does not stick.
196+
197+ ## Host viewport — ` CHostViewport `
198+
199+ A state can render into a render target shown in an ImGui window instead of the whole window
200+ (tools with panels around the scene). The state owns a ` CHostViewport ` and returns it from
201+ ` CAppStateBase::GetViewport() ` .
202+
203+ ``` cpp
204+ CHostViewport m_viewport{ "egfman2_scene" };
205+
206+ CHostViewport* GetViewport() override { return &m_viewport; }
207+
208+ // ImGui handler (runs in BeginScene, before Update)
209+ if (ImGui::Begin("Scene"))
210+ m_viewport.DrawImGui(); // fills the available content region
211+ ImGui::End ();
212+
213+ // Update
214+ const IVector2D viewSize = m_viewport.GetSize();
215+ projMat = perspectiveMatrixY(fov, viewSize.x, viewSize.y, zNear, zFar);
216+ g_renderAPI->BeginRenderPass(
217+ Builder<RenderPassDesc >()
218+ .ColorTarget(m_viewport.GetColorTarget(), true, clearColor)
219+ .DepthStencilTarget(m_viewport.GetDepthTarget())
220+ .DepthClear()
221+ .End());
222+ ```
223+
224+ - `DrawImGui(size)` resizes the color and depth targets (backbuffer formats, `ResizeRenderTarget`)
225+ to the drawn size and puts an invisible button with the image in the current ImGui window. The
226+ viewport is *visible* only in a frame where `DrawImGui` was called.
227+ - Viewports are disabled in `Retail` and `Profile` builds (`HOST_VIEWPORT_ENABLED` in
228+ `sys_viewport.h`): `DrawImGui` does nothing and the viewport is never visible.
229+ - When the viewport is not visible (ImGui window closed, `Retail` or `Profile` build),
230+ `GetColorTarget`, `GetDepthTarget` and `GetSize` return the backbuffer, the default depth buffer
231+ and the window size, and the host routes input as without a viewport.
232+ - Input: mouse coordinates passed to the state handlers are relative to the viewport. A button
233+ pressed over the viewport captures the mouse until all captured buttons are released, so drags
234+ continue outside the viewport. Mouse movement and wheel reach the state while the mouse is over
235+ the viewport or captured. Key releases always reach the state, so keys do not stick when focus
236+ moves away.
237+ - `CGameHost::SetCursorPosition` takes viewport coordinates, and a centered cursor
238+ (`GetMouseCursorProperties`) is warped to the viewport center.
239+ - `GetScreenRect`, `ToViewport`, `ToWindow` convert between window and viewport coordinates.
240+ - The state viewport is the main viewport: the host draws EqUI (`equi::Manager->Render(target)`,
241+ view frame of the viewport size), debug overlays (`debugoverlay->Draw` with the viewport targets),
242+ `r_showFPS`, input debug drawing and the console only into it. ImGui stays in the window
243+ backbuffer. Full-screen edge AA is skipped: its luma pass needs a storage source texture.
244+ - `screenshot` with a visible viewport saves the whole window with ImGui, since the viewport gets
245+ to the backbuffer only through ImGui.
246+
180247## Developer console — `g_consoleInput`
181248
182- - Opened by the ` +con_toggle ` command (bind it to a key, e.g. ` bind GRAVE +con_toggle ` in
183- ` cfg/config_default.cfg ` ), or ` con_show ` , ` con_show_full ` , ` con_hide ` ; ` clear ` , ` help ` .
249+ - Opened by the key bound to `toggleconsole` (`bind GRAVE toggleconsole` in
250+ `cfg/config_default.cfg`). `CGameHost::Key_Event` checks this key before any other input
251+ handling, so it works while ImGui has focus; with the console open, Shift + the key toggles the
252+ log view. Also `con_toggle` / `+con_toggle`, `con_show`, `con_show_full`, `con_hide`; `clear`,
253+ `help`.
184254- Executes console commands (see [framework_core.md](framework_core.md)) with autocompletion,
185255 variants, history and a log view. With the Lua state initialized, input that fails as a command
186256 is executed as Lua (`SetAlternateHandler`, see [scripting_esl_overview.md](scripting_esl_overview.md)).
187257- ConVars: `con_size`, `con_suggest`, `con_minicon`, `con_minicon_time`.
188- - The console owns the ImGui frame (` g_imGuiHost ` , ` shared/imgui_backend ` ): ImGui windows registered
189- with ` g_imGuiHost->AddDebugHandler ` are always drawn, and the debug menu bar with
190- ` AddDebugMenu(path, handler) ` entries is shown while the console is open.
258+ - ImGui is run by the host (`g_imGuiHost`, `shared/imgui_backend`), not the console: ImGui
259+ windows registered with `g_imGuiHost->AddDebugHandler` are always drawn, and the debug menu bar
260+ with `AddDebugMenu(path, handler)` entries is shown while the console is open.
191261- `CEqConsoleInput::SpewInit` captures engine log output for the console log from the start.
192262
193263## Configuration files
0 commit comments