Invisible geometry in DX11

为君一笑 提交于 2019-12-12 02:56:32

问题


After struggling for many hours to understand and compensate for Microsoft's deprecation of D3DX in Windows 8, I've run into a problem that I can't shake off.

The first time I started my program, it became immortal because of an access violation. After having restarted my computer and recompiling and running the same code, it doesn't crash, but the cube I should be seeing just isn't there.

I'm also getting a warning that "object declared on the heap may not be aligned 16". AFAIK from my research, this usually occurs because of XNA Math. So, after finding this discussion I litteraly tried everything that was being suggested. Everything except for the XMFLOAT4X4 solution worked, but my cube is still invisible. Here's the part of the code I think is relevant:

class IEGame : public DX11InfernalEngineBase
{
public:
    //...
bool LoadContent()
{
    //...
    Vertex vertices[] =
    {
        { XMFLOAT3(-1.0f, 1.0f, -1.0f), XMFLOAT2(0.0f, 0.0f) },
        { XMFLOAT3(1.0f, 1.0f, -1.0f), XMFLOAT2(1.0f, 0.0f) },
        { XMFLOAT3(1.0f, 1.0f, 1.0f), XMFLOAT2(1.0f, 1.0f) },
        { XMFLOAT3(-1.0f, 1.0f, 1.0f), XMFLOAT2(0.0f, 1.0f) },

        { XMFLOAT3(-1.0f, -1.0f, -1.0f), XMFLOAT2(0.0f, 0.0f) },
        { XMFLOAT3(1.0f, -1.0f, -1.0f), XMFLOAT2(1.0f, 0.0f) },
        { XMFLOAT3(1.0f, -1.0f, 1.0f), XMFLOAT2(1.0f, 1.0f) },
        { XMFLOAT3(-1.0f, -1.0f, 1.0f), XMFLOAT2(0.0f, 1.0f) },

        { XMFLOAT3(-1.0f, -1.0f, 1.0f), XMFLOAT2(0.0f, 0.0f) },
        { XMFLOAT3(-1.0f, -1.0f, -1.0f), XMFLOAT2(1.0f, 0.0f) },
        { XMFLOAT3(-1.0f, 1.0f, -1.0f), XMFLOAT2(1.0f, 1.0f) },
        { XMFLOAT3(-1.0f, 1.0f, 1.0f), XMFLOAT2(0.0f, 1.0f) },

        { XMFLOAT3(1.0f, -1.0f, 1.0f), XMFLOAT2(0.0f, 0.0f) },
        { XMFLOAT3(1.0f, -1.0f, -1.0f), XMFLOAT2(1.0f, 0.0f) },
        { XMFLOAT3(1.0f, 1.0f, -1.0f), XMFLOAT2(1.0f, 1.0f) },
        { XMFLOAT3(1.0f, 1.0f, 1.0f), XMFLOAT2(0.0f, 1.0f) },

        { XMFLOAT3(-1.0f, -1.0f, -1.0f), XMFLOAT2(0.0f, 0.0f) },
        { XMFLOAT3(1.0f, -1.0f, -1.0f), XMFLOAT2(1.0f, 0.0f) },
        { XMFLOAT3(1.0f, 1.0f, -1.0f), XMFLOAT2(1.0f, 1.0f) },
        { XMFLOAT3(-1.0f, 1.0f, -1.0f), XMFLOAT2(0.0f, 1.0f) },

        { XMFLOAT3(-1.0f, -1.0f, 1.0f), XMFLOAT2(0.0f, 0.0f) },
        { XMFLOAT3(1.0f, -1.0f, 1.0f), XMFLOAT2(1.0f, 0.0f) },
        { XMFLOAT3(1.0f, 1.0f, 1.0f), XMFLOAT2(1.0f, 1.0f) },
        { XMFLOAT3(-1.0f, 1.0f, 1.0f), XMFLOAT2(0.0f, 1.0f) }
    };

    D3D11_BUFFER_DESC vertexDesc;
    ZeroMemory(&vertexDesc, sizeof(vertexDesc));
    vertexDesc.Usage = D3D11_USAGE_DEFAULT;
    vertexDesc.BindFlags = D3D11_BIND_VERTEX_BUFFER;
    vertexDesc.ByteWidth = sizeof(VertexPos)*24;

    D3D11_SUBRESOURCE_DATA resourceData;
    ZeroMemory(&resourceData, sizeof(resourceData));
    resourceData.pSysMem = vertices;

    try{
        d3dresult = d3dDevice_->CreateBuffer(&vertexDesc, &resourceData, &vertexBuffer_);
        if (FAILED(d3dresult))
        {
            throw _com_error(d3dresult);
        }
    }
    catch (_com_error & comEx){
        MessageBox(0, comEx.ErrorMessage(), "Error Creating Vertex Buffer", MB_OK);
        return false;
    }

    WORD indices[] = {
        3, 1, 0, 2, 1, 3,
        6, 4, 5, 7, 4, 6,
        11, 9, 8, 10, 9, 11,
        14, 12, 13, 15, 12, 14,
        19, 17, 16, 18, 17, 19,
        22, 20, 21, 23, 20, 22
    };

    D3D11_BUFFER_DESC indexDesc;
    ZeroMemory(&indexDesc, sizeof(indexDesc));
    indexDesc.Usage = D3D11_USAGE_DEFAULT;
    indexDesc.BindFlags = D3D11_BIND_INDEX_BUFFER;
    indexDesc.ByteWidth = sizeof(WORD)* 36;
    indexDesc.CPUAccessFlags = 0;
    resourceData.pSysMem = indices;

    try{
        d3dresult = d3dDevice_->CreateBuffer(&indexDesc, &resourceData, &indexBuffer_);
        if (FAILED(d3dresult))
        {
            throw _com_error(d3dresult);
        }
    }
    catch (_com_error & comEx){
        MessageBox(0, comEx.ErrorMessage(), "Error Creating Index Buffer", MB_OK);
        return false;
    }

    try{
        std::vector<byte> textureFile = LoadFile("C:\\Users\\Marcus\\documents\\visual studio 2013\\Projects\\infernalEngine\\Debug\\guide.png");
        d3dresult = CreateWICTextureFromMemory(d3dDevice_, d3dContext_, textureFile.data(), textureFile.size(), nullptr, &colorMapView_, 0);
        if (FAILED(d3dresult))
        {
            throw _com_error(d3dresult);
        }
    }
    catch (_com_error & comEx){
        MessageBox(0, comEx.ErrorMessage(), "Error Loading Texture", MB_OK);
        return false;
    }

    D3D11_SAMPLER_DESC colorMapDesc;
    ZeroMemory(&colorMapDesc, sizeof(colorMapDesc));
    colorMapDesc.AddressU = D3D11_TEXTURE_ADDRESS_WRAP;
    colorMapDesc.AddressV = D3D11_TEXTURE_ADDRESS_WRAP;
    colorMapDesc.AddressW = D3D11_TEXTURE_ADDRESS_WRAP;
    colorMapDesc.ComparisonFunc = D3D11_COMPARISON_NEVER;
    colorMapDesc.Filter = D3D11_FILTER_MIN_MAG_MIP_LINEAR;
    colorMapDesc.MaxLOD = D3D11_FLOAT32_MAX;

    try{
        d3dresult = d3dDevice_->CreateSamplerState(&colorMapDesc, &colorMapSampler_);
        if (FAILED(d3dresult))
        {
            throw _com_error(d3dresult);
        }
    }
    catch (_com_error & comEx){
        MessageBox(0, comEx.ErrorMessage(), "Error Creating Sampler State", MB_OK);
        return false;
    }

    D3D11_BUFFER_DESC constDesc;
    ZeroMemory(&constDesc, sizeof(constDesc));
    constDesc.BindFlags = D3D11_BIND_CONSTANT_BUFFER;
    constDesc.ByteWidth = sizeof(XMMATRIX);
    constDesc.Usage = D3D11_USAGE_DEFAULT;

    try{
        d3dresult = d3dDevice_->CreateBuffer(&constDesc, nullptr, &viewCB_);
        if (FAILED(d3dresult))
        {
            throw _com_error(d3dresult);
        }
    }
    catch (_com_error & comEx){
        MessageBox(0, comEx.ErrorMessage(), "Error Creating View Matrix", MB_OK);
        return false;
    }
    try{
        d3dresult = d3dDevice_->CreateBuffer(&constDesc, nullptr, &projCB_);
        if (FAILED(d3dresult))
        {
            throw _com_error(d3dresult);
        }
    }
    catch (_com_error & comEx){
        MessageBox(0, comEx.ErrorMessage(), "Error Creating Projection Matrix", MB_OK);
        return false;
    }
    try{
        d3dresult = d3dDevice_->CreateBuffer(&constDesc, nullptr, &worldCB_);
        if (FAILED(d3dresult))
        {
            throw _com_error(d3dresult);
        }
    }
    catch (_com_error & comEx){
        MessageBox(0, comEx.ErrorMessage(), "Error Creating World Matrix", MB_OK);
        return false;
    }

    viewMatrix_ = XMMatrixIdentity();
    projMatrix_ = XMMatrixPerspectiveFovLH(XM_PIDIV4, 800.0f / 600.0f, 0.01f, 100.0f);

    viewMatrix_ = XMMatrixTranspose(viewMatrix_);
    projMatrix_ = XMMatrixTranspose(projMatrix_);

    return true;
}

void UnloadContent()
{
    if (colorMapSampler_) colorMapSampler_->Release();
    if (colorMapView_) colorMapView_->Release();
    if (solidColorVS_) solidColorVS_->Release();
    if (solidColorPS_) solidColorPS_->Release();
    if (inputLayout_) inputLayout_->Release();
    if (vertexBuffer_) vertexBuffer_->Release();
    if (viewCB_) viewCB_->Release();
    if (projCB_) projCB_->Release();
    if (worldCB_) worldCB_->Release();

    colorMapSampler_ = 0;
    colorMapView_ = 0;
    solidColorVS_ = 0;
    solidColorPS_ = 0;
    inputLayout_ = 0;
    vertexBuffer_ = 0;
    viewCB_ = 0;
    projCB_ = 0;
    worldCB_ = 0;
}

void Render()
{
    if (d3dContext_ == 0)
        return;

    float clearColor[4] = { 0.0f, 0.0f, 0.25f, 1.0f };
    d3dContext_->ClearRenderTargetView(backBufferTarget_, clearColor);
    d3dContext_->ClearDepthStencilView(depthStencilView_, D3D11_CLEAR_DEPTH, 1.0f, 0);

    unsigned int nStride = sizeof(VertexPos);
    unsigned int nOffset = 0;

    d3dContext_->IASetInputLayout(inputLayout_);
    d3dContext_->IASetVertexBuffers(0, 1, &vertexBuffer_, &nStride, &nOffset);
    d3dContext_->IASetIndexBuffer(indexBuffer_, DXGI_FORMAT_R16_UINT, 0);
    d3dContext_->IASetPrimitiveTopology(D3D11_PRIMITIVE_TOPOLOGY_TRIANGLELIST);

    d3dContext_->VSSetShader(solidColorVS_, 0, 0);
    d3dContext_->PSSetShader(solidColorPS_, 0, 0);
    d3dContext_->PSSetShaderResources(0, 1, &colorMapView_);
    d3dContext_->PSSetSamplers(0, 1, &colorMapSampler_);

    XMMATRIX rotationMatrix;
    rotationMatrix = XMMatrixRotationRollPitchYaw(0.0f, 0.7f, 0.7f);
    XMMATRIX translationMatrix;
    translationMatrix = XMMatrixTranslation(0.0f, 0.0f, 0.6f);

    XMMATRIX worldMatrix;
    worldMatrix = rotationMatrix * translationMatrix;
    worldMatrix = XMMatrixTranspose(worldMatrix);

    d3dContext_->UpdateSubresource(worldCB_, 0, nullptr, &worldMatrix, 0, 0);
    d3dContext_->UpdateSubresource(viewCB_, 0, nullptr, &viewMatrix_, 0, 0);
    d3dContext_->UpdateSubresource(projCB_, 0, nullptr, &projMatrix_, 0, 0);

    d3dContext_->VSSetConstantBuffers(0, 1, &worldCB_);
    d3dContext_->VSSetConstantBuffers(1, 1, &viewCB_);
    d3dContext_->VSSetConstantBuffers(2, 1, &projCB_);

    d3dContext_->DrawIndexed(36, 0, 0);

    swapChain_->Present(0, 0);
}

private:
ID3D11VertexShader * solidColorVS_;
ID3D11PixelShader * solidColorPS_;

ID3D11InputLayout * inputLayout_;
ID3D11Buffer * vertexBuffer_;
ID3D11Buffer * indexBuffer_;

ID3D11ShaderResourceView * colorMapView_;
ID3D11SamplerState * colorMapSampler_;

ID3D11Buffer * viewCB_;
ID3D11Buffer * projCB_;
ID3D11Buffer * worldCB_;
XMMATRIX viewMatrix_;
XMMATRIX projMatrix_;
};

UPDATE : So, after enabling the D3D Debug Device, I get this in the output. I really can't make sense of it.

D3D11 WARNING: Process is terminating. Using simple reporting. Please call ReportLiveObjects() at runtime for standard reporting.     [ STATE_CREATION WARNING #0: UNKNOWN]
D3D11 WARNING: Live Producer at 0x00F7F3F4, Refcount: 3. [ STATE_CREATION WARNING #0: UNKNOWN]
D3D11 WARNING:  Live Object at 0x00F80218, Refcount: 0. [ STATE_CREATION WARNING #0: UNKNOWN]
D3D11 WARNING:  Live Object at 0x0403A110, Refcount: 0. [ STATE_CREATION WARNING #0: UNKNOWN]
D3D11 WARNING:  Live Object at 0x0403801C, Refcount: 0. [ STATE_CREATION WARNING #0: UNKNOWN]
D3D11 WARNING:  Live Object at 0x04040304, Refcount: 0. [ STATE_CREATION WARNING #0: UNKNOWN]
D3D11 WARNING:  Live Object at 0x0404054C, Refcount: 0. [ STATE_CREATION WARNING #0: UNKNOWN]
D3D11 WARNING:  Live Object at 0x0404089C, Refcount: 0. [ STATE_CREATION WARNING #0: UNKNOWN]
D3D11 WARNING:  Live Object at 0x04040AAC, Refcount: 0. [ STATE_CREATION WARNING #0: UNKNOWN]
D3D11 WARNING:  Live Object at 0x04040CE0, Refcount: 0. [ STATE_CREATION WARNING #0: UNKNOWN]
D3D11 WARNING:  Live Object at 0x04041394, Refcount: 0. [ STATE_CREATION WARNING #0: UNKNOWN]
D3D11 WARNING:  Live Object at 0x040428E4, Refcount: 1. [ STATE_CREATION WARNING #0: UNKNOWN]
D3D11 WARNING:  Live Object at 0x04043534, Refcount: 0. [ STATE_CREATION WARNING #0: UNKNOWN]
D3D11 WARNING:  Live Object at 0x04043894, Refcount: 0. [ STATE_CREATION WARNING #0: UNKNOWN]
D3D11 WARNING:  Live Object at 0x0404490C, Refcount: 0. [ STATE_CREATION WARNING #0: UNKNOWN]
D3D11 WARNING:  Live Object at 0x0404F5CC, Refcount: 0. [ STATE_CREATION WARNING #0: UNKNOWN]
D3D11 WARNING:  Live Object at 0x0405C7EC, Refcount: 0. [ STATE_CREATION WARNING #0: UNKNOWN]
D3D11 WARNING:  Live Object at 0x0405B65C, Refcount: 0. [ STATE_CREATION WARNING #0: UNKNOWN]
D3D11 WARNING:  Live Object at 0x04069D0C, Refcount: 0. [ STATE_CREATION WARNING #0: UNKNOWN]
D3D11 WARNING:  Live Object at 0x0406701C, Refcount: 1. [ STATE_CREATION WARNING #0: UNKNOWN]
D3D11 WARNING:  Live Object at 0x040653AC, Refcount: 0. [ STATE_CREATION WARNING #0: UNKNOWN]
D3D11 WARNING:  Live Object at 0x0408243C, Refcount: 0. [ STATE_CREATION WARNING #0: UNKNOWN]
D3D11 WARNING:  Live Object at 0x04036FFC, Refcount: 0. [ STATE_CREATION WARNING #0: UNKNOWN]
D3D11 WARNING:  Live Object at 0x0403719C, Refcount: 0. [ STATE_CREATION WARNING #0: UNKNOWN]
D3D11 WARNING:  Live Object at 0x04085C04, Refcount: 0. [ STATE_CREATION WARNING #0: UNKNOWN]
D3D11 WARNING:  Live Object at 0x0408656C, Refcount: 0. [ STATE_CREATION WARNING #0: UNKNOWN]
D3D11 WARNING:  Live Object at 0x040618CC, Refcount: 0. [ STATE_CREATION WARNING #0: UNKNOWN]
D3D11 WARNING: Live                         Object :     25 [ STATE_CREATION WARNING #0: UNKNOWN]
DXGI WARNING: Live Producer at 0x00F4AE50, Refcount: 4. [ STATE_CREATION WARNING #0: ]
DXGI WARNING:   Live Object at 0x00F4D480, Refcount: 2. [ STATE_CREATION WARNING #0: ]
DXGI WARNING: Live                         Object :      1 [ STATE_CREATION WARNING #0: ]

UPDATE : My XMMATRIXs are now properly aligned. The cube is still invisible though. I also can't find the Visual Studio Graphics Debugger. I know where it it should be according to my research, it just isn't there.


回答1:


The key issue here is that you are using XMMATRIX which requires 16-byte alignment as a class member which is heap allocated, but new on x86 (32-bit) only provides 8-byte alignment by default.

This is exactly what XMFLOAT4X4, XMLoadFloat4x4, and XMStoreFloat4x4 exist to resolve.

XMMATRIX vm = XMMatrixIdentity();
XMMATRIX pm = XMMatrixPerspectiveFovLH(XM_PIDIV4, 800.0f / 600.0f, 0.01f, 100.0f);

XMStoreFloat4x4( &viewMatrix_, XMMatrixTranspose(vm) );
XMStoreFlaot4x4( &projMatrix_, XMMatrixTranspose(pm) );

XMFLOAT4X4 viewMatrix_;
XMFLOAT4X4 projMatrix_;

That or you can just switch to coding in x64 (64-bit) native which has 16-byte alignment by default and you can use XMMATRIX or XMVECTOR as a class member without any worry about alignment in most cases.

This is addressed on MSDN in the DirectXMath Programming Guide. See Getting Started, Type Usage Guidelines

You should also take a look at the SimpleMath wrapper in the DirectX Tool Kit. Those types handle this load/store behavior with C++ "magic":

#include <SimpleMath.h>

XMMATRIX vm = XMMatrixIdentity();
XMMATRIX pm = XMMatrixPerspectiveFovLH(XM_PIDIV4, 800.0f / 600.0f, 0.01f, 100.0f);

viewMatrix_ = XMMatrixTranspose(vm);
projMatrix_ = XMMatrixTranspose(pm); 

DirectX::SimpleMath::Matrix viewMatrix_;
DirectX::SimpleMath::Matrix projMatrix_;

If you haven't seen these yet, be sure to read:

  • Where is the DirectX SDK?
  • Living without D3DX
  • DirectX SDK Tools Catalog
  • DirectX SDK Samples Catalog
  • DirectX SDKs of a certain age
  • Direct3D Win32 Game Visual Studio template

EDIT For Windows desktop DirectX development, you should use Visual Studio 2013 Community Edition if you aren't already using VS 2013 Professional+. It includes the VS Graphics Debugger which VS 2013 Express for Windows Desktop does not.




回答2:


Well, I finally found the solution. As the VS Graphics Debugger gave no errors, I had to do some random things that actually worked.

I HAD to create a rasterizer state before anything became visible. It turned out that my cube was inside out too, so I set the FrontCounterClockWise field of D3D11_RASTERIZER_DESC to false. I also zoomed the camera out by setting the following line in Render():

 translationMatrix = XMMatrixTranslation(0.0f, 0.0f, 4.0f);

I also created a scissor rectangle; I don't know whether that had anything to do with the solution.

Here's where I found all the relevant stuff: This MSDN page.

Thanks for everybody's help, I cleared out the try-catch nonsense too with an inline function.



来源:https://stackoverflow.com/questions/30602602/invisible-geometry-in-dx11

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!