From 82aa233c27f223eacd7fc6045e9ab995690df057 Mon Sep 17 00:00:00 2001 From: ThinkWithPbody <51525460+ThinkWithPbody@users.noreply.github.com> Date: Mon, 10 Aug 2026 16:01:41 -0400 Subject: [PATCH 1/2] Fix Blender 5.2 texture readback layout --- fbs/ndi/NDIServer.py | 2 +- fbs/spout/SpoutServer.py | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/fbs/ndi/NDIServer.py b/fbs/ndi/NDIServer.py index 4e8f294..a750fa1 100644 --- a/fbs/ndi/NDIServer.py +++ b/fbs/ndi/NDIServer.py @@ -76,7 +76,7 @@ def send_texture(self, offscreen: gpu.types.GPUOffScreen, width: int, height: in texture_data = texture.read() # Convert texture data to numpy array and ensure correct format - flat_np = np.asarray(texture_data, dtype=np.uint8).transpose() + flat_np = np.asarray(texture_data, dtype=np.uint8) # If texture is flipped, flip it vertically while preserving RGBA channels if is_flipped: diff --git a/fbs/spout/SpoutServer.py b/fbs/spout/SpoutServer.py index e265425..dd4fb8d 100644 --- a/fbs/spout/SpoutServer.py +++ b/fbs/spout/SpoutServer.py @@ -44,9 +44,9 @@ def send_texture(self, offscreen: gpu.types.GPUOffScreen, width: int, height: in # Read texture data texture_data = texture.read() - # Convert texture data to numpy array and transpose + # Convert texture data to numpy array # This is the correct way to handle Blender's Buffer object - flat_np = np.asarray(texture_data, dtype=np.uint8).transpose() + flat_np = np.asarray(texture_data, dtype=np.uint8) # Reshape to image array (height, width, 4) image_array = flat_np.reshape(self.height, self.width, 4) From e7c03cc1918d3ff1376469010a0a5002f7a5d1d1 Mon Sep 17 00:00:00 2001 From: ThinkWithPbody <51525460+ThinkWithPbody@users.noreply.github.com> Date: Mon, 24 Aug 2026 17:47:33 -0400 Subject: [PATCH 2/2] Preserve legacy texture readback layout --- fbs/ndi/NDIServer.py | 5 +++-- fbs/spout/SpoutServer.py | 5 +++-- 2 files changed, 6 insertions(+), 4 deletions(-) diff --git a/fbs/ndi/NDIServer.py b/fbs/ndi/NDIServer.py index a750fa1..4d04c3e 100644 --- a/fbs/ndi/NDIServer.py +++ b/fbs/ndi/NDIServer.py @@ -75,8 +75,10 @@ def send_texture(self, offscreen: gpu.types.GPUOffScreen, width: int, height: in # Get texture data in 3d array texture_data = texture.read() - # Convert texture data to numpy array and ensure correct format + # Blender 5.2 corrected GPU buffer strides (89a0750); transpose legacy layouts only. flat_np = np.asarray(texture_data, dtype=np.uint8) + if flat_np.strides[-1] != flat_np.itemsize: + flat_np = flat_np.transpose() # If texture is flipped, flip it vertically while preserving RGBA channels if is_flipped: @@ -84,7 +86,6 @@ def send_texture(self, offscreen: gpu.types.GPUOffScreen, width: int, height: in flat_np = flat_np.reshape(self.height, self.width, 4) # Flip only the height dimension flat_np = np.flip(flat_np, axis=0) - # Flatten back to 1D array # Flatten the array from 3d to 1d flat_np = flat_np.flatten() diff --git a/fbs/spout/SpoutServer.py b/fbs/spout/SpoutServer.py index dd4fb8d..9fe2d08 100644 --- a/fbs/spout/SpoutServer.py +++ b/fbs/spout/SpoutServer.py @@ -44,9 +44,10 @@ def send_texture(self, offscreen: gpu.types.GPUOffScreen, width: int, height: in # Read texture data texture_data = texture.read() - # Convert texture data to numpy array - # This is the correct way to handle Blender's Buffer object + # Blender 5.2 corrected GPU buffer strides (89a0750); transpose legacy layouts only. flat_np = np.asarray(texture_data, dtype=np.uint8) + if flat_np.strides[-1] != flat_np.itemsize: + flat_np = flat_np.transpose() # Reshape to image array (height, width, 4) image_array = flat_np.reshape(self.height, self.width, 4)