Skip to content

Commit 8df9833

Browse files
authored
Merge development work
- egfMan: model browser added - sys: console refactor, imgui platform backend moved to imgui_backend - sys: viewports implementation
2 parents cd90846 + c00460e commit 8df9833

29 files changed

Lines changed: 1039 additions & 297 deletions

‎core/materialsystem1/DefaultShader.cpp‎

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -56,7 +56,13 @@ BEGIN_SHADER_CLASS(
5656
bool SetupRenderPass(IShaderAPI* renderAPI, const PipelineInputParams& pipelineParams, ArrayCRef<RenderBufferInfo> uniformBuffers, const RenderPassContext& passContext, IMaterial* originalMaterial) override
5757
{
5858
const MatSysDefaultRenderPass* rendPassInfo = static_cast<const MatSysDefaultRenderPass*>(passContext.data);
59-
ASSERT_MSG(rendPassInfo, "Must specify MatSysDefaultRenderPass in userData when drawing with default material");
59+
if (!rendPassInfo)
60+
{
61+
ASSERT_FAIL("No render pass data specified");
62+
return false;
63+
}
64+
65+
ASSERT_MSG(rendPassInfo->type == RENDERPASS_DEFAULT, "Must specify MatSysDefaultRenderPass in userData when drawing with default material");
6066
const uint pipelineId = GenDefaultPipelineId(passContext.recorder->GetRenderTargetFormats(), passContext.recorder->GetDepthTargetFormat(), *rendPassInfo, pipelineParams.primitiveTopology);
6167

6268
auto it = m_renderPipelines.find(pipelineId);

‎docs/architecture.md‎

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ Related documents:
1010
| [codestyle.md](codestyle.md) | Code style for new files |
1111
| [framework_ds.md](framework_ds.md) | Containers, strings, smart pointers (`framework/ds`) |
1212
| [framework_math.md](framework_math.md) | Math library (`framework/math`) |
13-
| [framework_core.md](framework_core.md) | Console variables/commands, command line, profiler |
13+
| [framework_core.md](framework_core.md) | Console variables/commands, command line, console tool helpers (`cmdlib.h`), profiler |
1414
| [framework_platform.md](framework_platform.md) | Message boxes, timers |
1515
| [framework_multithreading.md](framework_multithreading.md) | Threads, locks, signals, TLS, atomics |
1616
| [framework_job_manager.md](framework_job_manager.md) | Job manager and `g_parallelJobs` |
@@ -87,12 +87,12 @@ Public interfaces are declared in `public/` and implemented in `core/` or `share
8787
| `shared/audio/` | Audio system on OpenAL, sound emitters/scripts/mixer; `source/` holds WAV/OGG sources |
8888
| `shared/physics/` | EqPhysics engine on top of Bullet collision — see [physics_overview.md](physics_overview.md) |
8989
| `shared/equi/` | EqUI interface library: manager, controls, scheme |
90-
| `shared/imgui_backend/` | ImGui host and material-system renderer backend |
90+
| `shared/imgui_backend/` | ImGui host (`g_imGuiHost`), SDL platform backend and material-system renderer backend |
9191
| `shared/scripting/` | ESL — Lua binding library |
9292
| `shared/movie/` | WebM movie player: AV1 video (dav1d), Vorbis audio, YUV to RGBA conversion on GPU (`MovieYUV` shader) |
9393
| `shared/network/` | UDP networking |
9494
| `shared/input/` | Input command binder |
95-
| `shared/sys/` | Application host: main loop, window, states, console, joystick, config loader; `sys/scripting/` exposes engine subsystems to ESL, `sys/imgui/` is the ImGui platform backend |
95+
| `shared/sys/` | Application host: main loop, window, states, console, joystick, config loader; `sys/scripting/` exposes engine subsystems to ESL |
9696
| `shared/components/`, `shared/entity/` | Component system and data tables (no engine project; compiled by consumers) |
9797
| `tools/` | Content tools (see below); `localization_tool/` is a separate C# project, `imp-exp blender/` is a Blender add-on |
9898
| `samples/` | Sample applications, each with its own workspace `premake5.lua` |
@@ -208,7 +208,7 @@ All are static libraries using `public` and `shared` include paths.
208208
| `studioLib` | `studio/**` | studioFileLib |
209209
| `animatingLib` | `animating/**` | studioLib |
210210
| `equiLib` | `equi/**` | fontLib (imgui) |
211-
| `imguiBackendLib` | `imgui_backend/**` | (imgui) |
211+
| `imguiBackendLib` | `imgui_backend/**` | (SDL2, imgui) |
212212
| `networkLib` | `network/**` except `NETThread.cpp` | (zlib) |
213213
| `soundSystemLib` | `audio/**` | (minivorbis, openal-soft, imgui) |
214214
| `physicsLib` | `physics/**` | (bullet2) |

‎docs/codestyle.md‎

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,9 @@ The reference shows the general layout; where it disagrees with this document, t
3535
4. the file's own header last.
3636
- Public interfaces live under `public/` (`I`-prefixed abstract classes); implementations live next
3737
to their module (`C`-prefixed classes).
38+
- In `.cpp` files, console variable and command declarations (`DECLARE_CVAR*`, `DECLARE_CMD*`,
39+
see `framework_core.md`) go at the top, after the includes and before function code: file-local
40+
helpers and other functions are placed below them.
3841
- Logical sections inside a file are separated with a dashed comment line:
3942

4043
```cpp

‎docs/framework_core.md‎

Lines changed: 20 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
# framework/core — console, command line, profiler
1+
# framework/core — console, command line, console tool helpers, profiler
22

33
This document covers the console variable/command system, the command line and the profiling
44
interface. Headers live in `framework/core/` (`coreLib`) and `public/core/`; implementations of
@@ -142,6 +142,25 @@ if (idx != -1)
142142
const char* value = g_cmdLine->GetArgumentsOf(g_cmdLine->Find("-game"));
143143
```
144144
145+
## Console tool helpers — `framework/core/cmdlib.h`
146+
147+
Included by `core/core_common.h`.
148+
149+
- `Install_SpewFunction()` — prints log messages to the process console with colors by message type
150+
(and `OutputDebugString` on Windows). Console tools (`egfca`, `animca`, ...) call it first in
151+
`main`.
152+
- `RunProcessToConsole(cmdLine, exitCode)` — runs a command, waits for it and prints its stdout and
153+
stderr line by line with `Msg`. On Windows the process gets no console window
154+
(`CreateProcess` + pipe), so it also works from windowed applications where `_popen` does not;
155+
elsewhere it uses `popen`. Returns `false` if the process could not be started. Child output
156+
that is block-buffered appears when the process flushes or exits.
157+
158+
```cpp
159+
int exitCode = 0;
160+
if (!RunProcessToConsole("egfca.exe models/box.esc", exitCode))
161+
MsgError("Failed to run egfca\n");
162+
```
163+
145164
## Profiler — `framework/core/profiler.h`
146165

147166
Profiling markers are compiled in all configurations except `Retail` (`PROFILE_ENABLE`); in

‎docs/sys_application_overview.md‎

Lines changed: 88 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -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

105108
State management (`eqAppStateMng`):
106109

@@ -130,15 +133,19 @@ frame the loop sleeps `sys_sleep` ms (default 1).
130133
1. 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.
132135
2. `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`.
135139
4. `eqAppStateMng::UpdateStates(dt × state timescale × sys_timescale)` — the current state
136140
renders and queues its command buffers.
137141
5. EqUI render, full-screen edge AA, `g_matSystem->SubmitQueuedCommandsAwaitable()`.
138142
6. 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()`.
142149
8. 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

176188
Keyboard 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
178190
for 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

‎docs/tools_overview.md‎

Lines changed: 13 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -55,14 +55,25 @@ skeleton, animations and sequences, physics objects. Built on `sysLib` with an I
5555
come from `nfd` (`src_dependency/nfd`).
5656

5757
- `-model <path>` opens a model on start.
58+
- The scene is rendered into a `CHostViewport` (see
59+
[sys_application_overview.md](sys_application_overview.md)) shown in the ImGui window between the
60+
model browser and the bottom panel; camera and drag input and hotkeys work while the mouse is over
61+
the scene or the scene window is focused.
62+
- Model browser on the left (View → Model browser) lists `.egf` files under `models/` of the `SP_MOD`
63+
search paths; clicking a file opens it. Directories are scanned when first expanded, Refresh
64+
rescans them. The filter field shows a flat list of files whose names contain the text (case
65+
insensitive); it scans all directories under `models/`.
66+
- File → Compile scripts... runs `egfca` (`.esc`) or `animca` (`.asc`) for the selected scripts and
67+
waits for them. Their stdout and stderr go to the engine console through a pipe (no console window
68+
is opened); a single compiled model is opened afterwards.
5869
- Camera: Shift + left / right / middle mouse button drag rotates, zooms and pans; the cursor wraps
59-
around the window edges while the camera moves. Left button drag pulls physics objects while
70+
around the scene viewport edges while the camera moves. Left button drag pulls physics objects while
6071
physics simulation runs.
6172
- Physics preview runs eqPhysics with a fixed 1/60 s step on a floor box at zero height. All
6273
surface params of the model fall back to one built-in `default` param. Ragdolls
6374
(`ragdoll/physics_ragdoll.*`) use point and angular limit constraints with the joint limits
6475
from the `.pod`; ragdoll parts collide only with the floor.
65-
- Hotkeys: Ctrl+O open, R reset view, P physics objects, B bones, W wireframe.
76+
- Hotkeys (scene window focused): Ctrl+O open, R reset view, P physics objects, B bones, W wireframe.
6677
- Writes its ConVars to `cfg/egfman2.cfg` instead of the game `cfg/user.cfg` unless `-user_cfg` is
6778
given.
6879

0 commit comments

Comments
 (0)