Обновление буфера вершин в Directx10 и 11

Я использую Directx10 в моей программе. Когда я пытаюсь изменить положение вершин, я получаю сообщение об ошибке:

Исключение выдается в 0x558CA083 (d3d10core.dll) в
NBodyProblemDebug.exe: 0xC0000005: расположение чтения нарушения доступа
0x00000000.

Это происходит во время выполнения следующего кода во время выполнения:

    D3D10_MAPPED_TEXTURE3D resourse;
ZeroMemory(&resourse, sizeof(D3D10_MAPPED_TEXTURE3D));
g_pVertexBuffer->Map(D3D10_MAP_WRITE_DISCARD, 0, &resourse.pData); //exception is thrown here
memcpy(resourse.pData, positions, 4 * n_bodies * sizeof(float));
g_pVertexBuffer->Unmap();

где буфер vektex инициализируется следующим образом:

    float * positions;
ID3D10Buffer*  g_pVertexBuffer = nullptr;
D3D10_BUFFER_DESC bd;
ZeroMemory( &bd, sizeof(bd) );
bd.Usage = D3D10_USAGE_DYNAMIC;
bd.ByteWidth = sizeof( SimpleVertex ) * bodies;
bd.BindFlags = D3D10_BIND_VERTEX_BUFFER;
bd.CPUAccessFlags = D3D10_CPU_ACCESS_WRITE;
D3D10_SUBRESOURCE_DATA InitData;
ZeroMemory( &InitData, sizeof(InitData) );
InitData.pSysMem = positions;
result = m_device->CreateBuffer( &bd, &InitData, &g_pVertexBuffer );

Что нужно сделать, чтобы это исправить? Является ли этот код подходящим эквивалентом тому, который используется в Directx11:

 D3D11_MAPPED_SUBRESOURCE resourse;
ZeroMemory(&resourse, sizeof(D3D11_MAPPED_SUBRESOURCE));
g_pImmediateContext->Map(g_pVertexBuffer, 0, D3D11_MAP_WRITE_DISCARD, 0, &resourse);
memcpy(resourse.pData, positions, 4 * bodies * sizeof(float));
g_pImmediateContext->Unmap(g_pVertexBuffer, 0);

0

Решение

Ваш код не выполняет проверку ошибок. Всякий раз, когда COM API возвращает HRESULT, вы должны проверить это на неудачу. Если было бы безопасно игнорировать возвращаемое значение, то оно вернуло бы void, Вы должны использовать SUCCEEDED или же FAILED макросы, чтобы проверить результаты или принять что-то вроде ThrowIfFailed.

D3D11_MAPPED_SUBRESOURCE resource = {};
if ( SUCCEEDED(
g_pImmediateContext->Map(g_pVertexBuffer, 0, D3D11_MAP_WRITE_DISCARD,
0, &resource) )
{
memcpy(resourse.pData, positions, 4 * bodies * sizeof(float));
g_pImmediateContext->Unmap(g_pVertexBuffer, 0);
}

Если, как вы заметили, исключение выдается на строку с Map, то скорее всего вы пропустили неудачный HRESULT ранее в программе, которая привела к g_pImmediateContext все еще будучи nullptr.

Обратите внимание, что ZeroMemory очень старая школа Это необходимо только в том случае, если вы используете версию Visual C ++ до VS 2013. С VS 2013 или более поздней версии единые правила инициализации C ++ 11 означают D3D11_MAPPED_SUBRESOURCE resource = {}; гарантированно заполняет структуру нулями.

Если однажды вы проверили все HRESULTs где это уместно, вторым шагом для отладки приложения DirectX является включение устройства DEBUG. Затем в окне вывода отладки появятся дополнительные сведения о любых сбоях, которые помогут вам точно определить причину сбоя в вашей программе. Увидеть Анатомия Direct3D 11 Создать устройство а также Трюки с отладочным слоем Direct3D SDK

Кстати, в зависимости от вашего стиля вы используете сырые указатели для ваших интерфейсов COM. Вы должны рассмотреть вопрос о принятии смарт-указатель, как ComPtr.

Нет никаких причин продолжать использовать DirectX 10. Все поддерживаемые платформы, которые могут работать с DirectX 10, могут работать с DirectX 11. DirectX 11 поддерживает больше оборудования, имеет лучшую поддержку библиотек утилит, лучшую поддержку инструментов и является текущей «основной» версией DirectX. Не используйте DirectX 10. Перенос с DirectX 10 на DirectX 11 очень прост. Увидеть MSDN, Жизнь без D3DX, а также Развертывание Direct3D 11 для разработчиков игр

2

Другие решения

Других решений пока нет …

По вопросам рекламы ammmcru@yandex.ru
Adblock
detector