Location
src/core/
viewport.c — Viewport lifecycle, scene, rendering, passes
viewport_internal.h — Internal struct definitions
light.c — Light management and light indicators
display.c — Display settings
overlay.c — Overlay system
overlay_builtin.c — Built-in overlay implementations
vertex_format.c — Flexible vertex format
subsystem.c — Subsystem vtable dispatch
Internal Structures
MopViewport
struct MopViewport {
const MopRhiBackend *rhi; /* Backend function table */
MopRhiDevice *device; /* Backend device instance */
MopRhiFramebuffer *framebuffer; /* Color+depth+ID targets */
MopBackendType backend_type; /* Active backend enum value */
int width, height; /* Framebuffer dimensions */
MopColor clear_color; /* Per-frame clear value */
MopRenderMode render_mode; /* Solid or wireframe */
MopShadingMode shading_mode; /* Flat or smooth */
/* Camera */
MopOrbitCamera camera; /* Orbit camera state */
MopVec3 cam_eye, cam_target, cam_up;
float cam_fov_radians, cam_near, cam_far;
MopMat4 view_matrix, projection_matrix;
/* Scene — flat array with active flags */
struct MopMesh meshes[MOP_MAX_MESHES];
uint32_t mesh_count;
/* Lights */
MopLight lights[MOP_MAX_LIGHTS]; /* Up to 8 lights */
uint32_t light_count;
MopMesh *light_indicators[MOP_MAX_LIGHTS]; /* Visual indicators */
/* Interaction */
MopGizmo *gizmo; /* TRS manipulation gizmo */
uint32_t selected_id; /* Currently selected object ID */
MopInteractState interact_state; /* State machine (idle, orbit..) */
MopGizmoAxis drag_axis; /* Active drag axis */
float click_start_x, click_start_y;
/* Event queue */
MopEvent events[MOP_MAX_EVENTS];
int event_head, event_tail;
/* Overlays */
MopOverlayEntry overlays[MOP_MAX_OVERLAYS];
uint32_t overlay_count;
/* Display settings */
MopDisplaySettings display;
/* Post-processing */
uint32_t post_effects; /* Bitmask of MopPostEffect */
/* Undo/redo stacks */
/* ... */
/* Subsystems (particles, water) */
/* ... */
/* Timing */
float time, last_time;
};
MopMesh (internal)
struct MopMesh {
MopRhiBuffer *vertex_buffer;
MopRhiBuffer *index_buffer;
uint32_t vertex_count, index_count;
uint32_t object_id;
MopMat4 transform;
MopVec3 position, rotation, scale_val;
bool use_trs;
MopColor base_color;
float opacity;
MopBlendMode blend_mode;
MopMaterial material;
bool has_material;
MopVertexFormat vertex_format;
MopMesh *parent;
bool active;
};
Scene Management
Meshes are stored in a flat array of MOP_MAX_MESHES (4096) entries. Adding a mesh scans for an inactive slot or appends. Removing a mesh marks it inactive and destroys its RHI buffers. The viewport destroy function walks the entire array.
Rendering Orchestration
mop_viewport_render orchestrates multiple passes:
- Frame begin — clear color, depth, and object ID buffers
- Light indicator update — create/destroy/reposition indicator meshes for active lights
- Gizmo update — recompute handle positions and screen-space scale
- Pass: scene — draw all active meshes with
object_id < 0xFFFE0000(depth test on, backface cull on) - Pass: gizmo + indicators — draw gizmo handles (
object_id >= 0xFFFF0000) and light indicators (object_id >= 0xFFFE0000) without depth test or backface cull - Pass: overlays — wireframe, normals, bounds, selection highlight, custom overlays
- Post-processing — gamma, tonemapping, vignette, fog
- Frame end — finalize and make framebuffer readable
Object ID Ranges
| Range | Usage |
|---|---|
0x00000001 – 0xFFFDFFFF | Scene meshes |
0xFFFE0000 – 0xFFFEFFFF | Light indicators (0xFFFE0000 + light_index) |
0xFFFF0000 – 0xFFFFFFFF | Gizmo handles |