2016-06-01 2 views
1

Я пытаюсь прочитать данные пикселя из заполненного UTexture2D в проекте Unreal Engine C++. Прежде чем задать вопрос здесь, я попытался использовать метод, описанный в этой ссылке: https://answers.unrealengine.com/questions/25594/accessing-pixel-values-of-texture2d.html. Однако это не работает для меня. Все значения пикселей, которые я получил от текстуры, - это некоторые данные мусора.Как читать данные из UTexture2D в C++

Я просто хочу получить значения глубины из SceneCapture2D и материал для последующей обработки, содержащий узел SceneTexture: Depth. Мне нужны значения глубины, доступные на C++, чтобы я мог продолжить обработку с помощью OpenCV. В Directx11 текстура размещения может быть использована для чтения CPU, но в нереальном движке я не знаю, как создать «промежуточную текстуру», такую ​​как Dx11. Я не могу получить правильные значения пикселей из текущего метода, из-за чего я думаю, что могу попытаться получить доступ к текстуре, не читаемой процессором.

Вот мой экспериментальный код для чтения данных из RGB UTexture2D.

Инициализировать RGB Texture:

VideoTextureColor= UTexture2D::CreateTransient(640, 480, PF_B8G8R8A8); 
VideoTextureColor->UpdateResource(); 
VideoUpdateTextureRegionColor = new FUpdateTextureRegion2D(0, 0, 0, 0, 640, 480); 
ColorRegionData = new FUpdateTextureRegionsData; 

PixelDepthData.Init(FColor(0, 0, 0, 255), 640 * 480); 

// Populate the texture with blue color 
for (int i = 0; i < 640; i++) { 
    for (int j = 0; j < 480; j++) { 
     int idx = j * 640 + i; 
     PixelDepthData[idx].B = 255; 
     PixelDepthData[idx].G = 0; 
     PixelDepthData[idx].R = 0; 
     PixelDepthData[idx].A = 255; 
    } 
} 

UpdateTextureRegions(
    VideoTextureColor, 
    (int32)0, 
    (uint32)1, 
    VideoUpdateTextureRegionColor, 
    (uint32)(4 * 640), 
    (uint32)4, 
    (uint8*)PixelDepthData.GetData(), 
    false, 
    ColorRegionData 
); 

Затем, обновление прочитать его значение обратно к (типа TArray) массива PixelDepthData и обновлять эту текстуру со значениями хранения в PixelDepthData, что его старое значение.

UpdateTextureRegions(
    VideoTextureColor, 
    (int32)0, 
    (uint32)1, 
    VideoUpdateTextureRegionColor, 
    (uint32)(4 * 640), 
    (uint32)4, 
    (uint8*)PixelDepthData.GetData(), 
    false, 
    ColorRegionData 
); 

ENQUEUE_UNIQUE_RENDER_COMMAND_ONEPARAMETER(
    FRealSenseDelegator, 
    ARealSenseDelegator*, RealSenseDelegator, this, 
    { 
     FColor* tmpImageDataPtr = static_cast<FColor*>((RealSenseDelegator->VideoTextureColor)->PlatformData->Mips[0].BulkData.Lock(LOCK_READ_ONLY)); 
     for (uint32 j = 0; j < 480; j++) { 
      for (uint32 i = 0; i < 640; i++) { 
       uint32 idx = j * 640 + i; 
       RealSenseDelegator->PixelDepthData[idx] = tmpImageDataPtr[idx]; 
       RealSenseDelegator->PixelDepthData[idx].A = 255; 
      } 
     } 
     (RealSenseDelegator->VideoTextureColor)->PlatformData->Mips[0].BulkData.Unlock(); 
    } 
); 

Все, что я получил - это текстура белого цвета вместо синей цветовой текстуры на сцене визуализации.

Кто-нибудь знает, как читать данные объекта UTexture2D?

ответ

3

Я понял это. Сначала вам нужно получить ссылку на структуру RHI UTexture2D, а затем использовать RHILockTexture2D для чтения ее данных, и вам нужно сделать это в RenderThread. Следующий код только один пример:

FTexture2DResource* uTex2DRes = (FTexture2DResource*)(RealSenseDelegator->VideoTexturePixelDepth)->Resource; 
float* cpuDataPtr = (float*)RHILockTexture2D(
     uTex2DRes->GetTexture2DRHI(), 
     0, 
     RLM_ReadOnly, 
     destStride, 
     false); 

for (uint32 j = 0; j < 480; j++) { 
    for (uint32 i = 0; i < 640; i++) { 
     uint32 idx = j * 640 + i; 

     // TODO Read the pixel data right here 

    } 
} 
RHIUnlockTexture2D(uTex2DRes->GetTexture2DRHI(), 0, false); 

Чтобы сделать это в рендер тему, вы должны использовать макрос, такие как ENQUEUE_UNIQUE_RENDER_COMMAND_ONEPARAMETER // Если только один, чтобы передать один параметр в визуализации нить используйте эту. +

Смежные вопросы