Рендеринг DirectX 11 Кадр BGRA32

Первый раз пытаюсь что-то отрендерить и у меня большие проблемы... Я использую библиотеку DirectN и класс SwapChainSurface из KlearTouch.MediaPlayer. Я пытаюсь визуализировать кадр BGRA32 с помощью D3D11Device.

Для этого я немного изменил OnNewSurfaceAvailable:

public void OnNewSurfaceAvailable2(Action<ID3D11Device, ID3D11DeviceContext> updateSurface)
{
    if (rendering)
    {
        return;
    }

    try
    {
        if (this.swapChain is null || swapChainComObject is null)
        {
            return;
        }

        swapChainComObject.GetDesc(out var swapChainDesc).ThrowOnError();

        if (swapChainDesc.BufferDesc.Width != PanelWidth || swapChainDesc.BufferDesc.Height != PanelHeight)
        {
            swapChainComObject.ResizeBuffers(2, PanelWidth, PanelHeight, DXGI_FORMAT.DXGI_FORMAT_UNKNOWN, 0).ThrowOnError();
        }

        var device = swapChain.Object.GetDevice1().Object.As<ID3D11Device>();

        device.GetImmediateContext(out var context);

        // context.ClearRenderTargetView(renderTargetView.Object, new []{0f, 1f, 1f, 1f});

        updateSurface(device, context);

        swapChainComObject.Present(1, 0).ThrowOnError();
    }
    catch (ObjectDisposedException)
    {
        Reinitialize();
    }
    catch (Exception ex)
    {
        System.Diagnostics.Debug.WriteLine("\nException: " + ex, nameof(SwapChainSurface) + '.' + nameof(OnNewSurfaceAvailable));
    }

    rendering = false;
}

OnSurfaceAvailable2 вызывается из:

void VideoFrameArrived(Bgra32VideoFrame frame)
    {
        DispatcherQueue.TryEnqueue(() =>
        {
            previewSurface.OnNewSurfaceAvailable2((device, context) =>
            {
                var size = frame.m_height * frame.m_height * 4;

                D3D11_TEXTURE2D_DESC td;
                td.ArraySize = 1;
                td.BindFlags = (uint) D3D11_BIND_FLAG.D3D11_BIND_SHADER_RESOURCE;
                td.Usage = D3D11_USAGE.D3D11_USAGE_DYNAMIC;
                td.CPUAccessFlags = (uint) D3D11_CPU_ACCESS_FLAG.D3D11_CPU_ACCESS_WRITE;
                td.Format = DXGI_FORMAT.DXGI_FORMAT_B8G8R8A8_UNORM;
                td.Height = (uint) frame.m_height;
                td.Width = (uint) frame.m_width;
                td.MipLevels = 1;
                td.MiscFlags = 0;
                td.SampleDesc.Count = 1;
                td.SampleDesc.Quality = 0;

                D3D11_SUBRESOURCE_DATA srd;
                srd.pSysMem = frame.m_pixelBuffer;
                srd.SysMemPitch = (uint) frame.m_height;
                srd.SysMemSlicePitch = 0;

                var texture = device.CreateTexture2D<ID3D11Texture2D>(td, new []{srd});

                var mappedResource = context.Map(texture.Object, 0, D3D11_MAP.D3D11_MAP_WRITE_DISCARD);

                var mappedData = mappedResource.pData;
                

                unsafe
                {
                    Buffer.MemoryCopy(frame.m_pixelBuffer.ToPointer(), mappedData.ToPointer(), size, size);
                }

                // Just for debug
                var pixelsInFrame = new byte[size];
                var pixelsInResource = new byte[size];

                Marshal.Copy(frame.m_pixelBuffer, pixelsInFrame, 0, size);
                Marshal.Copy(mappedResource.pData, pixelsInResource, 0, size);
                
                context.Unmap(texture.Object, 0);
            });
        });
    }

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

Обновление: Репозиторий проекта

Обновление 2:

Я решил свою проблему. У меня было слишком мало знаний о DX11, поэтому мне пришлось больше изучать, как там все работает. Обладая этими знаниями, я обновил репозиторий, который может отображать предварительный просмотр с карты дизайна черной магии. Это всего лишь пример со многими проблемами, поэтому будьте осторожны и не стесняйтесь искать там вдохновение.

У вас есть готовый проект по воспроизведению?

Simon Mourier 05.05.2022 21:41

Остальной код для DirectX 11 реализован точно так же, как и в KlearTouch.MediaPlayer. Приложение использует карту захвата BlackMagic и камеру. Я выложу весь проект на github и обновлю ответ.

Michal Zhradnk Nono3551 06.05.2022 09:39

Я создал общедоступный репозиторий со всем проектом и обновил вопрос.

Michal Zhradnk Nono3551 06.05.2022 12:37

Этот проект представляет собой целый проект, который не компилируется и не требует сторонних разработчиков. Вы должны опубликовать более простую вещь stackoverflow.com/help/минимально-воспроизводимый-пример

Simon Mourier 06.05.2022 15:30

Какую проблему производит buld? Я могу попытаться избавиться от ссылки на DeckLinkAPI, если это проблема, и других ненужных вещей.

Michal Zhradnk Nono3551 06.05.2022 15:37

Это как минимум одна проблема. Минимальный пример — это тот, который работает везде.

Simon Mourier 06.05.2022 16:49

Извините, что не ответил. Я уже решил свою проблему. Я обновил вопрос и репозиторий своим решением.

Michal Zhradnk Nono3551 12.05.2022 14:24
Стоит ли изучать PHP в 2026-2027 годах?
Стоит ли изучать PHP в 2026-2027 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
2
7
69
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

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

Здесь разное количество вопросов.

Первый кадр прибыл, у вас есть

var texture = device.CreateTexture2D<ID3D11Texture2D>(td, new []{srd});

Таким образом, вы создаете текстуру, но нигде ее не используете, ее нужно перенести в цепочку обмена (можно сделать CopyResource в контексте устройства или нарисовать полноэкранный треугольник/квадроцикл).

Обратите внимание, что CopyResource будет работать только в том случае, если ваша цепочка обмена имеет тот же размер, что и ваша входящая текстура, что довольно маловероятно, поэтому вам, скорее всего, придется рисовать блит с шейдером.

Также вы дважды копируете данные в текстуре:

 var texture = device.CreateTexture2D<ID3D11Texture2D>(td, new []{srd});

Поскольку вы предоставляете исходные данные, контент уже есть.

также неправильный шаг: srd.SysMemPitch = (uint)frame.m_height;

шаг - это длина (в байтах) строки, поэтому она должна быть:

srd.SysMemPitch = frame.GetRowBytes();

Также обратите внимание, что в случае непеределанной рамы Decklink, GetRowBytes может отличаться от width*4 (они могут выравнивать размер строки до кратного 16/32 или других значений).

Далее, в случае карты ресурсов неверно также следующее:

unsafe
{
    Buffer.MemoryCopy(frame.m_pixelBuffer.ToPointer(), mappedData.ToPointer(), size, size);
}

Вы не проверяете требования к шагу/шагу текстуры (которые также могут быть разными),

поэтому вам нужно сделать:

if (mappedResource.RowPitch == frame.GetRowBytes())
{
    //here you can use a direct copy as above
}
else
{
   //here you need to copy data line per line
}

Большое тебе спасибо. Ваш ответ совсем не помог мне, когда я впервые увидел его, потому что я слишком мало знал о DirectX 11 и рендеринге. Мне пришлось сделать большой шаг назад и сначала читать руководства, смотреть видео и пробовать простые вещи. Теперь это имеет гораздо больше смысла. Особенно первая и последняя часть намного понятнее и мне очень помогли. Спасибо.

Michal Zhradnk Nono3551 11.05.2022 15:27

Благодаря вашим советам я смог исправить свой код. Спасибо

Michal Zhradnk Nono3551 12.05.2022 14:20

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