From b8b27447d94a3f6877d896ef8422c991d2a4ec9c Mon Sep 17 00:00:00 2001 From: "CVC\\jbelon" Date: Tue, 10 Apr 2018 18:40:28 +0200 Subject: [PATCH] Fix #318 - Direct3D RHI textures resampled to maintain the width*height*bytes_per_pixels being sent to the client when dest_stride!=src_stride --- .../Carla/Sensor/SceneCaptureCamera.cpp | 40 +++++++++++++++---- 1 file changed, 32 insertions(+), 8 deletions(-) diff --git a/Unreal/CarlaUE4/Plugins/Carla/Source/Carla/Sensor/SceneCaptureCamera.cpp b/Unreal/CarlaUE4/Plugins/Carla/Source/Carla/Sensor/SceneCaptureCamera.cpp index ecd7fbe97..85d41d9f6 100644 --- a/Unreal/CarlaUE4/Plugins/Carla/Source/Carla/Sensor/SceneCaptureCamera.cpp +++ b/Unreal/CarlaUE4/Plugins/Carla/Source/Carla/Sensor/SceneCaptureCamera.cpp @@ -19,6 +19,9 @@ #include "Materials/Material.h" #include "Paths.h" #include "Kismet/KismetSystemLibrary.h" +#include "Image.h" +#include "ImageUtils.h" +#include static constexpr auto DEPTH_MAT_PATH = @@ -318,27 +321,48 @@ void ASceneCaptureCamera::WritePixels(float DeltaTime) const UE_LOG(LogCarla, Error, TEXT("SceneCaptureCamera: Missing render texture")); return ; } + const uint32 num_bytes_per_pixel = 4; // PF_R8G8B8A8 const uint32 width = texture->GetSizeX(); - uint32 height = texture->GetSizeY(); - uint32 stride; - uint8 *src = reinterpret_cast(RHILockTexture2D(texture, 0, RLM_ReadOnly, stride, false)); + const uint32 height = texture->GetSizeY(); + const uint32 dest_stride = width * height * num_bytes_per_pixel; + uint32 src_stride; + uint8 *src = reinterpret_cast(RHILockTexture2D(texture, 0, RLM_ReadOnly, src_stride, false)); struct { uint32 Width; uint32 Height; uint32 Type; float FOV; } ImageHeader = { - SizeX, - SizeY, + width, + height, PostProcessEffect::ToUInt(PostProcessEffect), CaptureComponent2D->FOVAngle }; - FSensorDataView DataView( + + std::unique_ptr dest = nullptr; + //Direct 3D uses additional rows in the buffer,so we need check the result stride from the lock: + if(IsD3DPlatform(GMaxRHIShaderPlatform,false) && (dest_stride!=src_stride)) + { + const uint32 copy_row_stride = width * num_bytes_per_pixel; + dest = std::make_unique(dest_stride); + // Copy per row + uint8* dest_row = dest.get(); + uint8* src_row = src; + for (uint32 Row = 0; Row < height; ++Row) + { + FMemory::Memcpy(dest_row, src_row, copy_row_stride); + dest_row += copy_row_stride; + src_row += src_stride; + } + src = dest.get(); + } + + const FSensorDataView DataView( GetId(), FReadOnlyBufferView{reinterpret_cast(&ImageHeader), sizeof(ImageHeader)}, - FReadOnlyBufferView{src,stride*height} + FReadOnlyBufferView{src,dest_stride} ); - + WriteSensorData(DataView); RHIUnlockTexture2D(texture, 0, false); }