Загрузка сетки DirectX11 - ошибка из-за текстур (с использованием SDKmesh.h)? Местоположение чтения нарушения доступа 0x00000000

Я пытался загрузить сетку из файла в своем приложении DirectX 11. В качестве основы я взял свой собственный код (который теперь отображает некоторые примитивы), и я хотел добавить к нему код создания/рендеринга сетки из проекта «Basic HLSL» из образцов SDK DirectX 11 (который использует, например, SDKmesh.h и DXUT.h из образцов.

Код сетки:

class FeyModel : public Graphic::Model, public FeyGraphicElement{
protected:
    CDXUTSDKMesh mesh;
public:
    FeyModel(ID3D11Device * device, std::string filename, const Common::Point3D center){    
        mesh.Create( device,  L"tiny\\tiny.sdkmesh", false ); //for now tiny.sdkmesh
    }

    void render(FeyShader * shader, 
        FeyCamera * camera,
        ID3D11DeviceContext* context,
        float t
        ){

            UINT Strides[1];
            UINT Offsets[1];
            ID3D11Buffer* pVB[1];
            pVB[0] = mesh.GetVB11( 0, 0 );
            Strides[0] = ( UINT )mesh.GetVertexStride( 0, 0 );
            Offsets[0] = 0;
            context->IASetVertexBuffers( 0, 1, pVB, Strides, Offsets );
            context->IASetIndexBuffer( mesh.GetIB11( 0 ), mesh.GetIBFormat11( 0 ), 0 );


            SDKMESH_SUBSET* pSubset = NULL;
            D3D11_PRIMITIVE_TOPOLOGY PrimType;

            //!  context->PSSetSamplers( 0, 1, &samLinear );

            for( UINT subset = 0; subset < mesh.GetNumSubsets( 0 ); ++subset )
            {
                // Get the subset
                pSubset = mesh.GetSubset( 0, subset );

                PrimType = CDXUTSDKMesh::GetPrimitiveType11( ( SDKMESH_PRIMITIVE_TYPE )pSubset->PrimitiveType );
                context->IASetPrimitiveTopology( PrimType );


                // TODO: D3D11 - material loading

                ID3D11ShaderResourceView* pDiffuseRV = mesh.GetMaterial( pSubset->MaterialID )->pDiffuseRV11;

                context->PSSetShaderResources( 0, 1, &pDiffuseRV );

                context->DrawIndexed( ( UINT )pSubset->IndexCount, 0, ( UINT )pSubset->VertexStart );
            }
        }
};

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

...
const D3D11_INPUT_ELEMENT_DESC layout[] =
{
    { "POSITION",  0, DXGI_FORMAT_R32G32B32_FLOAT, 0, 0,  D3D11_INPUT_PER_VERTEX_DATA, 0 },
    { "NORMAL",    0, DXGI_FORMAT_R32G32B32_FLOAT, 0, 12, D3D11_INPUT_PER_VERTEX_DATA, 0 },
    { "TEXCOORD",  0, DXGI_FORMAT_R32G32_FLOAT,    0, 24, D3D11_INPUT_PER_VERTEX_DATA, 0 },
};

UINT numElements = ARRAYSIZE( layout );

// Create the input layout
hr = device->CreateInputLayout( layout, numElements, pVSBlob->GetBufferPointer(), pVSBlob->GetBufferSize(), &*vertexLayout );
pVSBlob->Release();

// Set the input layout
context->IASetInputLayout( *vertexLayout );
...

Сборка работает. Но при выполнении кода получаю ошибку:

Access violation reading location 0x00000000

В SDKmish.h рядом:

if (bSRGB) {
    // This is a workaround so that we can load linearly, but sample in SRGB.  Right now, we can't load
    // as linear since D3DX will try to do conversion on load.  Loading as TYPELESS doesn't work either, and
    // loading as typed _UNORM doesn't allow us to create an SRGB view.

    // on d3d11 featuer levels this is just a copy, but on 10L9 we must use a cpu side copy with 2 staging resources.
    ID3D11Texture2D* unormStaging = NULL;
    ID3D11Texture2D* srgbStaging = NULL;

    D3D11_TEXTURE2D_DESC CopyDesc;
    pRes->GetDesc( &CopyDesc );

    pLoadInfo->BindFlags = 0;
    pLoadInfo->CpuAccessFlags = D3D11_CPU_ACCESS_WRITE | D3D11_CPU_ACCESS_READ;
    pLoadInfo->Depth = 0;
    pLoadInfo->Filter = D3DX11_FILTER_LINEAR;
    pLoadInfo->FirstMipLevel = 0;
    pLoadInfo->Format = CopyDesc.Format;
    pLoadInfo->Height = CopyDesc.Height;
    pLoadInfo->MipFilter = D3DX11_FILTER_LINEAR;
    pLoadInfo->MiscFlags = CopyDesc.MiscFlags;
    pLoadInfo->Usage = D3D11_USAGE_STAGING;
    pLoadInfo->Width = CopyDesc.Width;

    CopyDesc.BindFlags = 0;
    CopyDesc.Usage = D3D11_USAGE_STAGING;
    CopyDesc.CPUAccessFlags = D3D11_CPU_ACCESS_WRITE | D3D11_CPU_ACCESS_READ;
    CopyDesc.Format = MAKE_SRGB(CopyDesc.Format);

    hr = D3DX11CreateTextureFromFile( pDevice, pSrcFile, pLoadInfo, pPump, ( ID3D11Resource** )&unormStaging, NULL );
    DXUT_SetDebugName( unormStaging, "CDXUTResourceCache" );

    hr = pDevice->CreateTexture2D(&CopyDesc, NULL, &srgbStaging);
    DXUT_SetDebugName( srgbStaging, "CDXUTResourceCache" );
    pContext->CopyResource( srgbStaging, unormStaging );
    ID3D11Texture2D* srgbGPU;

    pRes->GetDesc( &CopyDesc );
    CopyDesc.Format = MAKE_SRGB(CopyDesc.Format);
    hr = pDevice->CreateTexture2D(&CopyDesc, NULL, &srgbGPU);
    pContext->CopyResource( srgbGPU, srgbStaging );

    SAFE_RELEASE(pRes);
    SAFE_RELEASE(srgbStaging);
    SAFE_RELEASE(unormStaging);
    pRes = srgbGPU;
}

Именно в строке:

pContext->CopyResource( srgbStaging, unormStaging );

Когда я комментирую несколько строк этой функции и что-то в своем коде (сейчас не могу вспомнить, что это была за строка), я получаю меш в окне, но без текстур. Я так понимаю, что-то с текстурами? У меня есть крошечная модель и текстура в соответствующей папке, я также установил расположение вершин, как я написал выше.

Что еще мне следует сделать?


person PolGraphic    schedule 06.07.2012    source источник
comment
DX ваши вызовы успешно? (проверьте hr с помощью макросов SUCCEEDED и FAILED). что вам говорит отладочная информация DX? (создайте свое устройство с флагом отладки, используйте DgbView от sysinternals для получения сообщений).   -  person Necrolis    schedule 06.07.2012


Ответы (1)


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

D3DX11CreateTextureFromFile(...,pPump,...);

Таким образом, вы можете пытаться выполнять операции с нулевыми указателями, потому что текстура еще не загружена (и, следовательно, дескрипторы имеют значение NULL), см. документацию на D3DX11CreateTextureFromFile.

person Necrolis    schedule 06.07.2012