Unity: копирование текстуры во внешнюю текстуру 2D

Мне нужно предоставить текстуру/Rendertexture Unity для некоторого собственного плагина, для которого требуется флаг «D3D11_RESOURCE_MISC_SHARED» на текстуре.

текстуры, созданные единством, не имеют этого флага, поэтому я создал его со стороны плагина, а затем создал эталонную текстуру в единстве, используя CreateExternalTexture, и скопировал содержимое в эту нативную текстуру, используя Graphics.CopyTexture.

2 текстуры имеют одинаковый размер, одинаковый размер, один и тот же формат и один и тот же mipCount (0)

проблема в том, что когда я показываю это в единстве (в целях отладки), я ничего не вижу и ошибок не возникает.

Кстати, если я копирую ReadPixel, возникает ошибка:

ReadPixels вызывается для неопределенного изображения 0 (допустимые значения: 0 - -1

если я создаю текстуру с помощью API Unity, CopyTexture преуспевает, и результат можно увидеть. но тогда я теряю флаг "D3D11_RESOURCE_MISC_SHARED".

Итак, может быть, текстура, которую я создал, недействительна? мой код:

    D3D11_TEXTURE2D_DESC desc = { 0 };
desc.Width = width;
desc.Height = height;
desc.MipLevels = 0;
desc.ArraySize = 1;
desc.Format = DXGI_FORMAT_R8G8B8A8_UNORM;//这里,格式能不能调整?比如,A8是需要的吗?
desc.SampleDesc.Count = 1;
desc.Usage = D3D11_USAGE_DEFAULT;
desc.BindFlags = D3D11_BIND_SHADER_RESOURCE;//普通资源
//desc.CPUAccessFlags = D3D11_CPU_ACCESS_READ;//应该不需要cpu访问的,不是read也不是write
desc.MiscFlags = D3D11_RESOURCE_MISC_SHARED;//for "OpenSharedHandle" d3d11 api

HRESULT hr = E_FAIL;
if (FAILED(hr = pDevice->CreateTexture2D(&desc, nullptr, &g_unityEquirectTexture)))
{
    Log(" Create Shared Texture Failed!");
    return NULL;
}
Log("CreateSharedTexture success");
//return g_unityEquirectTexture;

Код Unity CopyTexture:

        if (output == null)
    {
        Debug.Log($"limit = {QualitySettings.masterTextureLimit}");
        //output = new Texture2D(equirect.width, equirect.height, TextureFormat.RGBA32,false);//uncomment this line and then copyTexture below succeeds
        IntPtr externalTextureData = CGDKInterOp.cgdk_c_CreateExternalTexture(equirectLeft.GetNativeTexturePtr(), equirectLeft.width * 2, equirectLeft.height);
        if (externalTextureData != IntPtr.Zero)
        {
            output = Texture2D.CreateExternalTexture(equirectLeft.width * 2, equirectLeft.height, TextureFormat.RGBA32, false, true, externalTextureData);
        }
    }
    if (output == null)
    {
        Debug.LogError("create texture from external failed!");
        return;
    }

    //RenderTexture.active = equirect;
    //output.ReadPixels(new Rect(0, 0, equirect.width, equirect.height), 0, 0);
    //RenderTexture.active = null;
    Graphics.CopyTexture(equirect, output);
Стоит ли изучать PHP в 2023-2024 годах?
Стоит ли изучать PHP в 2023-2024 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
1
0
75
2
Перейти к ответу Данный вопрос помечен как решенный

Ответы 2

Для этого может быть лучшее решение, но в последний раз, когда мне нужно было скопировать данные текстуры с нативной стороны на управляемую (Unity), я сделал это путем сортировки данных.

По сути, вам просто нужно предоставить метод в нативном плагине, чтобы передать вам данные текстуры в виде массива, а затем иметь метод в коде C# для извлечения данных (путем вызова метода), освобождая указатель на нативную память, когда вы снова сделано. Вы можете найти информацию о сортировке и взаимодействии в документации Microsoft (например, https://docs.microsoft.com/en-us/dotnet/framework/interop/marshalling-other-types-of-arrays). Если ваша текстура всегда гарантированно будет одного размера и формата, это проще - но если вам нужно знать какие-то дополнительные параметры, чтобы вы знали, как Текстура должна быть представлена ​​в управляемом-земле, вы всегда можете передать себе дополнительные данные через тот же метод.

Ответ принят как подходящий

Хорошо, решил сам.

проблема в следующем: Miplevel == 0. Это приводит к тому, что d3d11 создает текстуру с выделено памяти 0B! изменение Miplevel на 1 решило проблему

примечание: В инспекторе единства мы можем видеть память, выделенную текстурами. Я обнаружил, что моя текстура имеет память 0B из инспектора, а затем я провел поиск, используя эту подсказку, и нашел решение.

Другие вопросы по теме