simvx.graphics.renderer.render_view

RenderView render-to-texture: the MAIN scene from a second camera (design D6).

A :class:~simvx.core.RenderView publishes an offscreen texture of the main scene tree rendered through the Camera3D its camera path points at: a security monitor, a rear-view mirror, a kill-cam. Where

class:

~.sub_viewport.SubViewportManager renders each SubViewport’s OWN subtree, this manager re-renders the MAIN tree with a camera override, reusing the proven :class:~.game_viewport.GameViewportRenderer offscreen target (begin_pass / render_scene_content / end_pass contract) as one scene-render unit (SRU) per view: an isolated transform-SSBO slice recorded into the same primary command buffer as the rest of the frame, exactly like the reflection-probe face captures.

Scheduling (D6/B1): RenderViews and SubViewports are ordered together by the shared :class:~simvx.core.scene_target_graph.SceneTargetGraph through

func:

render_offscreen_targets, the one pre-render entry point. A RenderView job consumes whatever the main tree samples (it renders the main scene), so a RenderView showing a SubViewport monitor renders after that SubViewport, and a SubViewport whose subtree samples a RenderView renders after the RenderView. Genuine cycles (two RenderViews each visible on the other’s monitor) degrade to a one-frame lag on the broken edge, never an error. A scene with no RenderView takes today’s exact SubViewportManager.render_all path.

The re-submit of the main tree happens with submit_2d=False: the 2D overlay submits are per-frame appends to shared renderer lists and already ran for the main pass, so a second run would double the main pass’s 2D content. A RenderView therefore captures the 3D world only (2D HUD content is a screen-space overlay, not part of the world a second camera would see).

Pipelined (P2) mode: RenderView capture is DEFERRED, exactly like reflection-probe capture (see render_packet.py, “State intentionally NOT snapshotted”): the manager is not invoked, the published slot stays valid but stale, and App._warn_pipelined_unpacketised logs a one-time warning. Immediate (synchronous) mode is the supported path.

Module Contents

Classes

RenderViewManager

Owns one :class:GameViewportRenderer per live RenderView node.

Functions

render_offscreen_targets

Record every offscreen scene target (SubViewports + RenderViews) into cmd.

Data

API

simvx.graphics.renderer.render_view.log

‘getLogger(…)’

simvx.graphics.renderer.render_view.__all__

[‘RenderViewManager’, ‘render_offscreen_targets’]

class simvx.graphics.renderer.render_view.RenderViewManager(engine: Any, adapter: Any)[source]

Owns one :class:GameViewportRenderer per live RenderView node.

Created once per :class:App run next to the SubViewportManager and driven from the engine pre_render callback via

Func:

render_offscreen_targets. Discovery is cached by the tree’s structure version (the live set only changes on add/remove), so a scene with no RenderView pays one integer compare per frame.

Initialization

collect_live(tree: Any) tuple[Any, ...][source]

Return the live RenderView nodes, cached by tree structure version.

prepare_all(tree: Any) list[tuple[Any, simvx.graphics.renderer.game_viewport.GameViewportRenderer, Any]][source]

Create/resize each live RenderView’s target; NO cmd recording.

Bindless descriptor updates (register on create, update on resize) happen here, before any offscreen draw is recorded into the shared primary cmd (same invariant as SubViewportManager.prepare_all). Honours render_target_update_mode and resolves each view’s camera; views without a resolvable camera are skipped with a one-time warning per node.

record_one(cmd: Any, tree: Any, entry: tuple[Any, simvx.graphics.renderer.game_viewport.GameViewportRenderer, Any]) None[source]

Record ONE prepared RenderView SRU: the MAIN tree, camera overridden.

Mirrors the reflection-probe face capture call shape: the live tree with a camera override and a stable sru_id (no screen_size override: the 3D viewport is sized from the target inside render_to_target, and 2D state is untouched because submit_2d=False).

destroy() None[source]

Tear down all targets (call on app shutdown).

simvx.graphics.renderer.render_view.render_offscreen_targets(cmd: Any, tree: Any, sub_viewports: Any, render_views: Any) None[source]

Record every offscreen scene target (SubViewports + RenderViews) into cmd.

The one pre-render entry point (synchronous path). With no live RenderView this is exactly sub_viewports.render_all(cmd, tree): the common path is unchanged (golden gate). With RenderViews present, both managers prepare (descriptor updates first), then one combined

Func:

~simvx.core._subviewport_order.order_subviewports compile over both kinds decides the recording order, so producers render before consumers across target kinds in the same frame.