# Render frame Кадр является последней стадией цикла, а не самостоятельной функцией renderer-а. До draw calls уже накоплен input, рассчитан tick, применены отложенные операции, выбрана камера и обновлён 3D sound listener. ## Frame skeleton ```text system messages and input -> simulation calculation -> deferred object operations -> animation and transforms -> camera and sound listener -> visibility and render queues -> materials and draw passes -> renderer completion -> end-of-render callbacks and UI ``` В `World3D::stdRenderGame` доказан крупный порядок: camera передаётся Terrain, настраиваются viewport/matrices, вызываются renderer boundary slots, устанавливается `in_render`, выполняется traversal мира, закрывается world/shade pass, вызывается renderer completion, снимается `in_render`, рассылается end-of-render. ## Draw item Подготовленный draw item содержит: - node world matrix; - batch flags and index range; - WEAR material handle; - MAT0 active phase and coefficients; - texture handle; - optional lightmap handle; - render phase and sorting key; - legacy pipeline state. Подготовленный item должен ссылаться на immutable данные кадра. Изменение phase или texture cache посреди прохода не должно менять уже собранную очередь. ## GOG camera dispatch evidence For the GOG `World3D.dll` baseline with SHA-256 `17e4a3089b2583a8cf2356c9db0390b1aba138356a09130d79b4e7e4791da61e`, the exported `stdRenderGame` is RVA `0x13BD0`. It first calls `Terrain::stdSetCurrentCamera2(camera)`, stores the camera pointer only for the frame, and clears it before return. `sendEndOfRender` is a separate export at RVA `0x13D90`. This is frame-order evidence only: the camera ABI, matrices and viewport values are not recovered by this call-order analysis. The implemented preview path below accepts selector-0 input produced through the [native frame capture workflow](../../tools/native-frame-capture/README.md). The capture workflow also records an observed mission path and, when its thread/generation and clock checks succeed, an `atmosphere_seconds` sample. For a fixed-camera preview, the renderer uses that optional absolute schedule phase when no `--atmosphere-seconds` override is supplied and keeps schedule sampling at that exact phase across readback frames. An explicit CLI value takes precedence. The phase sample is not full simulation time: weather, RNG, and other mission state remain unknown, so this evidence does not establish full-frame parity. Receiver-side GOG Terrain evidence refines this contract. `stdSetCurrentCamera2` (RVA `0x4FD40` in Terrain SHA-256 `af87d1b2e728a0be73c52be3b44cc196ab46da7799f25a15d40f8c9b0b425ead`) queries selector `18` on the supplied object and invokes slot `+12` on that result. It does not store the supplied pointer in `stdGetCurrentCamera2`; that getter returns a Terrain global populated by selector `8` during Terrain initialization. `Terrain.dll!LoadCamera` adds a separate factory-side contract. Its GOG entry at RVA `0x4EBE0` is `__stdcall` with four machine-word arguments, allocates `0x1A4` bytes, calls the constructor at RVA `0x4EC60`, and returns the interface at object offset `+0x134`. The constructor passes arguments 3 and 4 into base initialization at `this + 4`, writes argument 3 to `this + 0x138`, and calls a helper at RVA `0x4CEF0` with arguments 1, 2 and 4 plus `this`. Argument 1 is a mode string: only `REFLECTION` and `REFLECTION_SHIFTED` produce a non-zero mode value at `this + 0x1A0`. This is factory ABI evidence, not a recovered view or projection matrix contract. ## Legacy camera preview path `fparkan-game --legacy-camera-capture ` consumes the selector-0 transform, the native D3D7 viewport RECT `[left, top, right, bottom]`, near/far planes and field of view. It derives the D3D7 view and clip transform from those inputs, carries the resulting `clip_from_world` matrix into the preview camera, and keeps the view-matrix camera axes directly, so the captured basis, including roll, is not reduced to yaw/pitch. The RECT becomes a physical drawable extent of `right - left` by `bottom - top`. The preview window is fixed to that extent; startup and non-zero resize events reject a physical-size mismatch instead of stretching the captured view. Compare the result with the corresponding `[left, top, right, bottom]` crop of the original PNG. `FreeFlightCamera` is not created in this mode, but redraws still update environment and projected shadows from the captured camera. Before environment updates can emit sound events, the audio listener receives the captured position, forward and up axes; initial world draw sorting uses the same captured position. A phase capture may include an observed mission path and a verified `atmosphere_seconds` value; the latter is used only when no explicit CLI override is supplied. This value pins the atmosphere schedule sample during a fixed-camera comparison while FX still receives real frame time. `simulation_time_seconds`, weather, RNG and complete mission state remain unknown, and a camera/phase match alone does not establish visual parity with a native frame. ## Parity risks `VulkanStaticCamera::from_legacy_d3d7` keeps the D3D7 view and projection reconstruction in `fparkan-render`, then negates the vertical projection term once at the Vulkan adapter boundary. D3D7's top-down viewport places positive NDC Y at the top; the Vulkan swapchain uses a positive viewport height, so the adapter flips NDC Y while the shader preserves `gl_Position`. The generic `from_row_major_view_projection` path remains unchanged; its callers supply Vulkan-ready matrices, as the free-flight camera already does. - x87 precision and rounding; - scalar/SIMD `g_FastProc` differences; - object, batch and transparent primitive order; - depth, cull, alpha test and blend transitions; - mip-skip, palette and Page coordinates; - material fallback and phase selection; - RNG sequence for FX and atmosphere; - device capability fallback; - simulation time quantization. Для отладки нужен deterministic frame capture: camera state, visible object IDs, draw-item list, pipeline keys, matrices и hashes промежуточных buffers.