/** * @file pipeline.hpp * @brief Render pipeline visualization state and interface */ #pragma once #include "math3d.hpp" #include struct GameContext; constexpr int NUM_CUBE_VERTS = 8; constexpr int NUM_CUBE_EDGES = 12; constexpr int NUM_TRI_VERTS = 3; constexpr int NUM_TRI_EDGES = 3; struct PipelineState { int current_stage = 0; // 0-5 int prev_stage = 0; float transition_t = 1.0f; // 0→1 animation progress (1 = complete) float fade_alpha = 1.0f; // for 3D↔2D mode transitions // Interpolated vertices for rendering during transitions Vec3 display_verts[NUM_CUBE_VERTS]; // Vertex selection int selected_vertex = -1; // -1 = none, 0-7 = selected vertex index bool pending_click = false; float click_x = 0, click_y = 0; // Object transform parameters (user-adjustable) float obj_rot_y = 0.0f; float obj_pos_x = 2.0f; float obj_pos_y = 1.0f; float obj_pos_z = -3.0f; float obj_scale = 1.0f; bool auto_rotate = false; // Display camera (orbit around scene for visualization) float cam_orbit_pitch = 25.0f; // degrees float cam_orbit_yaw = -30.0f; // degrees float cam_distance = 10.0f; // Pipeline camera (the one being visualized in the pipeline) float pipe_cam_x = 0.0f; float pipe_cam_y = 2.0f; float pipe_cam_z = 5.0f; float pipe_cam_fov = 1.0f; // radians (~57 degrees) float pipe_cam_near = 0.1f; float pipe_cam_far = 100.0f; // Mouse drag state bool mouse_down = false; float mouse_start_x = 0, mouse_start_y = 0; float orbit_start_pitch = 0, orbit_start_yaw = 0; // Slider drag state int dragging_slider = -1; // -1 = none, 0+ = slider index bool show_sliders = true; // First-person camera view (picture-in-picture) bool show_first_person = false; // Matrix color breakdown bool show_matrix_breakdown = false; // Vertex shader simulation bool shader_mode = false; float shader_amplitude = 0.3f; float shader_frequency = 2.0f; float shader_time = 0.0f; // Help overlay bool show_help = false; // Clipping visualizer bool show_clipping = false; struct ClippedFace { static constexpr int MAX_VERTS = 24; Vec4 verts[MAX_VERTS]; int count = 0; bool was_clipped = false; }; ClippedFace clipped_faces[6]; // Depth buffer / Z-fighting demo bool show_depth_viz = false; bool show_zfight_plane = false; float zfight_plane_z = -3.0f; static constexpr int NUM_PLANE_VERTS = 4; Vec4 plane_world[4]; Vec3 plane_screen[4]; Vec3 plane_display[4]; // Input flags (set per event, cleared after processing) bool key_left = false; bool key_right = false; bool key_space = false; bool key_r = false; bool key_num[6] = {}; // Computed transforms Mat4 model_matrix; Mat4 view_matrix; Mat4 proj_matrix; // Transformed vertices at each pipeline stage (cube) Vec4 verts_object[NUM_CUBE_VERTS]; Vec4 verts_world[NUM_CUBE_VERTS]; Vec4 verts_view[NUM_CUBE_VERTS]; Vec4 verts_clip[NUM_CUBE_VERTS]; Vec3 verts_ndc[NUM_CUBE_VERTS]; Vec3 verts_screen[NUM_CUBE_VERTS]; // Second shape: triangle bool show_triangle = false; Vec4 tri_object[NUM_TRI_VERTS]; Vec4 tri_world[NUM_TRI_VERTS]; Vec4 tri_view[NUM_TRI_VERTS]; Vec4 tri_clip[NUM_TRI_VERTS]; Vec3 tri_ndc[NUM_TRI_VERTS]; Vec3 tri_screen[NUM_TRI_VERTS]; Vec3 tri_display[NUM_TRI_VERTS]; }; void pipeline_handle_event(PipelineState& ps, const SDL_Event& event); void pipeline_update(PipelineState& ps, GameContext& ctx); void pipeline_render(PipelineState& ps, GameContext& ctx);