Cleanup bindings and viewport

This commit is contained in:
2026-06-16 01:15:06 -07:00
parent 6a81522c29
commit 3c2242cc08
6 changed files with 98 additions and 61 deletions

View File

@ -1,6 +1,6 @@
/**
* Viewport Server Implementation - Shared Memory Framebuffer Export
*
*
*/
#include "viewport_server.h"
@ -12,7 +12,11 @@
#include <stdlib.h>
#include <math.h>
#ifdef KINC_WINDOWS
#ifdef KINC_OPENGL
#include <GL/glew.h>
#endif
#ifdef KINC_DIRECT3D11
#include <d3d11.h>
#include <dxgi.h>
@ -254,6 +258,8 @@ bool viewport_server_init(const char* shmem_name, int width, int height) {
uint8_t* pixel_dest = (uint8_t*)g_viewport_state.shmem_ptr + VIEWPORT_HEADER_SIZE;
memset(pixel_dest, 0, max_pixel_size);
#if !defined(KINC_DIRECT3D11) && !defined(KINC_OPENGL)
// Only create render target for platforms that need it (not Direct3D11 or OpenGL)
kinc_g4_render_target_t* rt = (kinc_g4_render_target_t*)malloc(sizeof(kinc_g4_render_target_t));
if (!rt) {
kinc_log(KINC_LOG_LEVEL_ERROR, "Failed to allocate render target");
@ -264,6 +270,7 @@ bool viewport_server_init(const char* shmem_name, int width, int height) {
kinc_g4_render_target_init(rt, width, height, KINC_G4_RENDER_TARGET_FORMAT_32BIT, 24, 0);
g_viewport_state.render_target = rt;
#endif
g_viewport_state.enabled = true;
g_viewport_state.initialized = true;
@ -275,7 +282,7 @@ bool viewport_server_init(const char* shmem_name, int width, int height) {
return true;
}
#ifdef KINC_WINDOWS
#ifdef KINC_DIRECT3D11
static ID3D11Texture2D* g_stagingTexture = NULL;
static int g_stagingWidth = 0, g_stagingHeight = 0;
#endif
@ -285,7 +292,7 @@ void viewport_server_shutdown(void) {
return;
}
#ifdef KINC_WINDOWS
#ifdef KINC_DIRECT3D11
if (g_stagingTexture) {
g_stagingTexture->Release();
g_stagingTexture = NULL;
@ -294,11 +301,13 @@ void viewport_server_shutdown(void) {
}
#endif
#if !defined(KINC_DIRECT3D11) && !defined(KINC_OPENGL)
if (g_viewport_state.render_target) {
kinc_g4_render_target_destroy((kinc_g4_render_target_t*)g_viewport_state.render_target);
free(g_viewport_state.render_target);
g_viewport_state.render_target = NULL;
}
#endif
if (g_viewport_state.pixel_buffer) {
free(g_viewport_state.pixel_buffer);
@ -346,7 +355,7 @@ void viewport_server_end_frame(void) {
uint8_t* pixels = g_viewport_state.pixel_buffer;
uint8_t* pixel_dest = (uint8_t*)g_viewport_state.shmem_ptr + VIEWPORT_HEADER_SIZE;
#ifdef KINC_WINDOWS
#ifdef KINC_DIRECT3D11
// Direct3D11 - read from backbuffer BEFORE swap_buffers
ID3D11DeviceContext* context = dx_ctx.context;
ID3D11Device* device = dx_ctx.device;
@ -417,20 +426,33 @@ void viewport_server_end_frame(void) {
memcpy(pixel_dest, pixels, pixel_size);
}
}
#elif defined(KINC_OPENGL)
// OpenGL - read from default framebuffer using glReadPixels
glReadPixels(0, 0, g_viewport_state.width, g_viewport_state.height, GL_RGBA, GL_UNSIGNED_BYTE, pixels);
// OpenGL returns pixels bottom-to-top, need to flip
size_t row_size = g_viewport_state.width * 4;
for (int y = 0; y < g_viewport_state.height / 2; ++y) {
uint8_t* row_top = pixels + y * row_size;
uint8_t* row_bottom = pixels + (g_viewport_state.height - 1 - y) * row_size;
for (size_t x = 0; x < row_size; ++x) {
uint8_t temp = row_top[x];
row_top[x] = row_bottom[x];
row_bottom[x] = temp;
}
}
memcpy(pixel_dest, pixels, pixel_size);
#else
// other platforms use render target
if (g_viewport_state.render_target) {
kinc_g4_render_target_t* rt = (kinc_g4_render_target_t*)g_viewport_state.render_target;
kinc_g4_render_target_get_pixels(rt, pixels);
memcpy(pixel_dest, pixels, pixel_size);
}
kinc_g4_render_target_t* rt = (kinc_g4_render_target_t*)g_viewport_state.render_target;
kinc_g4_render_target_get_pixels(rt, pixels);
memcpy(pixel_dest, pixels, pixel_size);
#endif
g_viewport_state.frame_count++;
header->frame_id = g_viewport_state.frame_count;
// NOTE: Camera sync from RunT to Blender is handled via viewport_server_set_camera()
// which is called explicitly when RunT's internal camera changes.
// NOTE: Camera sync from Krom to Blender is handled via viewport_server_set_camera()
// which is called explicitly when Krom's internal camera changes.
// We do NOT extract camera from view_matrix here as that would create a feedback loop
// (Blender sends view_matrix -> we extract camera -> Blender applies it -> repeat)
@ -478,19 +500,23 @@ bool viewport_server_resize(int new_width, int new_height) {
// resize the actual Kinc window so the D3D11 backbuffer is the correct size critical because viewport_server_end_frame captures from the backbuffer
kinc_window_resize(0, new_width, new_height);
#if !defined(KINC_DIRECT3D11) && !defined(KINC_OPENGL)
if (g_viewport_state.render_target) {
kinc_g4_render_target_destroy((kinc_g4_render_target_t*)g_viewport_state.render_target);
// dont free here we reuse the allocation
}
#endif
// update dimensions pre-allocated and reinitialize render target with new size using same memory
g_viewport_state.width = new_width;
g_viewport_state.height = new_height;
#if !defined(KINC_DIRECT3D11) && !defined(KINC_OPENGL)
kinc_g4_render_target_t* rt = (kinc_g4_render_target_t*)g_viewport_state.render_target;
if (rt) {
kinc_g4_render_target_init(rt, new_width, new_height, KINC_G4_RENDER_TARGET_FORMAT_32BIT, 24, 0);
}
#endif
SharedFramebufferHeader* header = (SharedFramebufferHeader*)g_viewport_state.shmem_ptr;
if (header) {
@ -537,16 +563,16 @@ void viewport_server_set_camera(float pos_x, float pos_y, float pos_z,
SharedFramebufferHeader* header = (SharedFramebufferHeader*)g_viewport_state.shmem_ptr;
if (!header) return;
header->runt_camera_pos[0] = pos_x;
header->runt_camera_pos[1] = pos_y;
header->runt_camera_pos[2] = pos_z;
header->krom_camera_pos[0] = pos_x;
header->krom_camera_pos[1] = pos_y;
header->krom_camera_pos[2] = pos_z;
header->runt_camera_rot[0] = rot_x;
header->runt_camera_rot[1] = rot_y;
header->runt_camera_rot[2] = rot_z;
header->runt_camera_rot[3] = rot_w;
header->krom_camera_rot[0] = rot_x;
header->krom_camera_rot[1] = rot_y;
header->krom_camera_rot[2] = rot_z;
header->krom_camera_rot[3] = rot_w;
header->runt_camera_dirty = 1;
header->krom_camera_dirty = 1;
}
bool viewport_server_read_input(InputEvent* event) {
@ -572,9 +598,9 @@ bool viewport_server_read_input(InputEvent* event) {
bool viewport_server_input_enabled(void) {
if (!viewport_server_is_enabled()) return false;
SharedFramebufferHeader* header = (SharedFramebufferHeader*)g_viewport_state.shmem_ptr;
if (!header) return false;
return header->input_enabled != 0;
}