0

DirectX 11 アプリケーションでファイルからメッシュをロードしようとしていました。ベースとして、私は自分のコード(現在いくつかのプリミティブをレンダリングしています)を取り、DirectX 11 SDKサンプル(SDKmesh.hとDXUT.hなどを使用)の「基本的なHLSL」プロジェクトからメッシュを作成/レンダリングするコードをそれに追加したかったのです。サンプルから。

メッシュコードは次のとおりです。

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 );
            }
        }
};

また、サンプルでは異なる頂点レイアウトがあったことに気付きました。そのため、シェーダーのクラス コードを次のように変更しました (コードは、メッシュを作成する前に、シェーダーのクラス コンストラクターで 1 回実行されます)。

...
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 );

その関数の数行とコード内の何かにコメントすると (それが何行だったか思い出せません)、ウィンドウにメッシュが表示されますが、テクスチャは表示されません。それで、テクスチャのあるものだと思いますか?私は適切なフォルダに小さなモデルとテクスチャを持っています。また、上に投稿したように頂点レイアウトも設定しました。

他に何をすべきですか?

4

1 に答える 1

0

スレッドポンプを通過したことに気付きました。これは、テクスチャが非同期で読み込まれることを意味しますが、同期的に読み込まれたかのようにアクションを実行します(D3DX11CreateTextureFromFileポンプがある場合はブロックされません)。

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

したがって、テクスチャがまだロードされていないため(したがって、ハンドルがNULLであるため)、nullポインタに対して操作を実行しようとしている可能性があります。のドキュメントを参照してくださいD3DX11CreateTextureFromFile

于 2012-07-06T13:18:23.793 に答える