/** * Viewport Server - Shared Memory Framebuffer Export for Blender Integration * * This module provides headless rendering with framebuffer export via shared memory * for integration with Blender's viewport as an external render engine. * * Protocol: * - RunT renders to offscreen render target * - Pixels are exported to shared memory each frame * - Blender Python addon reads shared memory and displays in viewport */ #ifndef VIEWPORT_SERVER_H #define VIEWPORT_SERVER_H #include #include #ifdef __cplusplus extern "C" { #endif #define INPUT_EVENT_NONE 0 #define INPUT_EVENT_MOUSE_MOVE 1 #define INPUT_EVENT_MOUSE_DOWN 2 #define INPUT_EVENT_MOUSE_UP 3 #define INPUT_EVENT_KEY_DOWN 4 #define INPUT_EVENT_KEY_UP 5 #define INPUT_EVENT_MOUSE_WHEEL 6 #define MOUSE_BUTTON_LEFT 0 #define MOUSE_BUTTON_RIGHT 1 #define MOUSE_BUTTON_MIDDLE 2 #define MAX_INPUT_EVENTS 32 #pragma pack(push, 1) typedef struct { uint8_t type; // INPUT_EVENT_* type uint8_t button; // mouse button or key code int16_t x; // mouse X position or delta int16_t y; // mouse Y position or delta int16_t delta; // scroll wheel delta uint32_t modifiers; // shift/ctrl/alt flags } InputEvent; #pragma pack(pop) // shared memory header structure must match Python end #pragma pack(push, 1) typedef struct { uint32_t magic; // 0x52554E54 = 'RUNT' uint32_t version; // protocol version (2) uint32_t width; // current frame width uint32_t height; // current frame height uint64_t frame_id; // incrementing frame counter uint32_t ready_flag; // 1 = new frame ready, 0 = consumed by blender uint32_t format; // 0 = RGBA8, 1 = BGRA8 uint32_t viewport_width; // requested viewport width from Blender uint32_t viewport_height; // requested viewport height from Blender uint32_t resize_request; // 1 = blender requests resize uint32_t shutdown_flag; // 1 = blender requests shutdown uint32_t input_enabled; // 1 = blender is capturing input for RunT float view_matrix[16]; // view matrix from blender column-major float proj_matrix[16]; // projection matrix from blender column-major // camera output from RunT to Blender bidirectional sync float runt_camera_pos[3]; // camera position from RunT (x, y, z) float runt_camera_rot[4]; // camera rotation from RunT quaternion: x, y, z, w uint32_t runt_camera_dirty; // 1 = RunT updated camera, 0 = consumed by blender // input event queue from blender to RunT uint32_t input_write_idx; // write index Blender increments uint32_t input_read_idx; // read index RunT increments InputEvent input_events[MAX_INPUT_EVENTS]; // ring buffer of input events // pixel data follows header width * height * 4 bytes for RGBA8 } SharedFramebufferHeader; #pragma pack(pop) #define VIEWPORT_MAGIC 0x52554E54 #define VIEWPORT_VERSION 2 #define VIEWPORT_HEADER_SIZE sizeof(SharedFramebufferHeader) // default shared memory name #define VIEWPORT_SHMEM_NAME "RUNT_VIEWPORT_FB" #define VIEWPORT_MAX_WIDTH 4096 #define VIEWPORT_MAX_HEIGHT 4096 // viewport server state typedef struct { bool enabled; bool initialized; int width; int height; char shmem_name[256]; uint64_t frame_count; void* render_target; // kinc_g4_render_target_t* uint8_t* pixel_buffer; // CPU-side pixel buffer void* shmem_handle; // platform-specific handle void* shmem_ptr; // mapped memory pointer size_t shmem_size; // total shared memory size } ViewportServerState; bool viewport_server_init(const char* shmem_name, int width, int height); void viewport_server_shutdown(void); bool viewport_server_is_enabled(void); void viewport_server_begin_frame(void); void viewport_server_end_frame(void); bool viewport_server_check_resize(int* new_width, int* new_height); bool viewport_server_resize(int new_width, int new_height); bool viewport_server_check_shutdown(void); bool viewport_server_get_view_matrix(float* matrix); bool viewport_server_get_proj_matrix(float* matrix); ViewportServerState* viewport_server_get_state(void); void viewport_server_set_camera(float pos_x, float pos_y, float pos_z, float rot_x, float rot_y, float rot_z, float rot_w); bool viewport_server_read_input(InputEvent* event); bool viewport_server_input_enabled(void); #ifdef __cplusplus } #endif #endif