C++ 和 directx11 深度测试 不适用于少数对象场景



我正在研究 c++ 和 directx11。我正确地启动了一切。但无论我做什么.DepthBuffer 未按预期工作。

在两个立方体

中,一个立方体从某个角度看起来是透明的。即使第二立方体很远。它总是看起来好像在前面。但是当它足够接近时,它会在第一个立方体上渲染......

我不知道我在这里做错了什么。我完全受够了:(

任何人都可以好心地帮助我...请

// include the basic windows header files and the Direct3D header files
#include <windows.h>
#include <windowsx.h>
#include <d3d11.h>
#include <d3dx11.h>
#include <d3dx10.h>
#include <d3dx9effect.h>
#include <xnamath.h>

#include

// define the screen resolution
#define SCREEN_WIDTH  800
#define SCREEN_HEIGHT 600

// global declarations
IDXGISwapChain *swapchain;             // the pointer to the swap chain interface
ID3D11Device *dev;                     // the pointer to our Direct3D device interface
ID3D11DeviceContext *devcon;           // the pointer to our Direct3D device context
ID3D11RenderTargetView *backbuffer; // the pointer to our back buffer
ID3D11DepthStencilView * DepthBuffer = 0; // Depth Bufferr Pointer
XMMATRIX g_World;
XMMATRIX g_View;
XMMATRIX g_Projection;
// removed buffers code 
int _Size = 0;

// a struct to define a single vertex
struct VERTEX{FLOAT X, Y, Z; D3DXCOLOR Color;};
struct CuxtomVertex{ 
    D3DXVECTOR3 pos;
    D3DXVECTOR3 normal;
    XMFLOAT2 Coord;
    //D3DXCOLOR color;
};
struct Light
{
    XMFLOAT3 Pos;
    XMFLOAT3 Dir;
    XMFLOAT4 Color;
};
// Constant buffer structure
struct ConstantBuffer
{
 XMMATRIX World;
 XMMATRIX View;
 XMMATRIX Project;
 XMFLOAT3 LighDirs[2];
 XMFLOAT4 LightColor[2];
};
// function prototypes
void InitD3D(HWND hWnd);    // sets up and initializes Direct3D
void RenderFrame(void);     // renders a single frame
void CleanD3D(void);        // closes Direct3D and releases memory
void InitGraphics(void);    // creates the shape to render
void InitPipeline(HWND);    // loads and prepares the shaders
void InitBoxGraphics(void);
// the WindowProc function prototype
LRESULT CALLBACK WindowProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam);

// the entry point for any Windows program
int WINAPI WinMain(HINSTANCE hInstance,
                   HINSTANCE hPrevInstance,
                   LPSTR lpCmdLine,
                   int nCmdShow)
{
    /// Irrelavant
    g_World = XMMatrixIdentity();
    g_View = XMMatrixLookAtLH(XMVectorSet(0,10,-10.0,0),XMVectorSet(0,0,0,0),XMVectorSet(0,1.0,0,0));
    g_Projection = XMMatrixPerspectiveFovLH(XM_PIDIV2 , SCREEN_WIDTH / (float)SCREEN_HEIGHT,1,1000);
        UINT stride = sizeof(CuxtomVertex);
    UINT offsets = 0;
    devcon->IASetVertexBuffers(0,1,&B2Vbuffer,&stride,&offsets);
    devcon->IASetIndexBuffer(B2IBuffer,DXGI_FORMAT_R16_UINT,0);
    while(TRUE)
    {
        if(PeekMessage(&msg, NULL, 0, 0, PM_REMOVE))
        {
            TranslateMessage(&msg);
            DispatchMessage(&msg);
            if(msg.message == WM_QUIT)
                break;
        }else{
        RenderFrame();
        }
    }
    // clean up DirectX and COM
    CleanD3D();
    return msg.wParam;
}

// this function initializes and prepares Direct3D for use
void InitD3D(HWND hWnd)
{
    // create a struct to hold information about the swap chain
    DXGI_SWAP_CHAIN_DESC scd;
    UINT MSAAQuality = 0;
    // clear out the struct for use
    ZeroMemory(&scd, sizeof(DXGI_SWAP_CHAIN_DESC));
    // fill the swap chain description struct
    scd.BufferCount = 1;                                   // one back buffer
    scd.BufferDesc.Format = DXGI_FORMAT_R8G8B8A8_UNORM;    // use 32-bit color
    scd.BufferDesc.Width = SCREEN_WIDTH;                   // set the back buffer width
    scd.BufferDesc.Height = SCREEN_HEIGHT;                 // set the back buffer height
    scd.BufferUsage = DXGI_USAGE_RENDER_TARGET_OUTPUT;     // how swap chain is to be used
    scd.OutputWindow = hWnd;                               // the window to be used
    scd.SampleDesc.Count = 4;                              // how many multisamples
    scd.Windowed = TRUE;                                   // windowed/full-screen mode
    scd.Flags = DXGI_SWAP_CHAIN_FLAG_ALLOW_MODE_SWITCH;    // allow full-screen switching
    // create a device, device context and swap chain using the information in the scd struct
    D3D11CreateDeviceAndSwapChain(NULL,
                                  D3D_DRIVER_TYPE_HARDWARE,
                                  NULL,
                                  NULL,
                                  NULL,
                                  NULL,
                                  D3D11_SDK_VERSION,
                                  &scd,
                                  &swapchain,
                                  &dev,
                                  NULL,
                                  &devcon);

    // get the address of the back buffer
    ID3D11Texture2D *pBackBuffer;
    swapchain->GetBuffer(0, __uuidof(ID3D11Texture2D), (LPVOID*)&pBackBuffer);
    // use the back buffer address to create the render target
    dev->CreateRenderTargetView(pBackBuffer, NULL, &backbuffer);
    pBackBuffer->Release();
    dev->CheckMultisampleQualityLevels(DXGI_FORMAT_R8G8B8A8_UNORM,4,&MSAAQuality);

    // Create Dpeth and Stencil buffrer
    D3D11_TEXTURE2D_DESC depthDesc;
    SecureZeroMemory(&depthDesc,sizeof(depthDesc));
    depthDesc.Width = SCREEN_WIDTH;
    depthDesc.Height = SCREEN_HEIGHT;
    depthDesc.ArraySize =1;
    depthDesc.Format = DXGI_FORMAT_D24_UNORM_S8_UINT;
    depthDesc.SampleDesc.Count = 2;
    depthDesc.SampleDesc.Quality = 0;
    depthDesc.BindFlags = D3D11_BIND_DEPTH_STENCIL;
    depthDesc.CPUAccessFlags = 0;
    depthDesc.MipLevels =1;
    depthDesc.Usage = D3D11_USAGE_DEFAULT;
    D3D11_DEPTH_STENCIL_VIEW_DESC dpethDesc2;
    SecureZeroMemory(&dpethDesc2,sizeof(dpethDesc2));
    dpethDesc2.Format = depthDesc.Format;
    dpethDesc2.ViewDimension = D3D11_DSV_DIMENSION_TEXTURE2D;
    dpethDesc2.Texture2D.MipSlice = 0;
    ID3D11Texture2D * depthBufferTEx = 0;
    dev->CreateTexture2D(&depthDesc,NULL,&depthBufferTEx);
    dev->CreateDepthStencilView(depthBufferTEx,&dpethDesc2,&DepthBuffer);
    // set the render target as the back buffer
    devcon->OMSetRenderTargets(1, &backbuffer,DepthBuffer);
    // Set the viewport
    D3D11_VIEWPORT viewport;
    ZeroMemory(&viewport, sizeof(D3D11_VIEWPORT));
    viewport.TopLeftX = 0;
    viewport.TopLeftY = 0;
    viewport.Width = SCREEN_WIDTH;
    viewport.Height = SCREEN_HEIGHT;
    viewport.MinDepth = 0;
    viewport.MaxDepth = 1;
    devcon->RSSetViewports(1, &viewport);

    TwInit(TW_DIRECT3D11,dev);
    TwWindowSize(300,800);
    InitPipeline(hWnd);
    InitGraphics();
    InitBoxGraphics();
    InitConstantBuffer();
    _Size = 52;
    InitPlane(_Size);
}
float LerpPos = 0;
// this is the function used to render a single frame
void RenderFrame(void)
{

    float LerpTime = 3;
    LerpPos += XM_PIDIV2 * 0.015;

    g_World = XMMatrixRotationY(LerpPos ) *   XMMatrixTranslation(1.0,1.0,1.0) ;
    #pragma region SetUPOLights
    Light lights[2]; SecureZeroMemory(&lights,sizeof(lights));
    lights[0].Dir = XMFLOAT3( -0.577f, 0.577f, -0.577f );
    lights[1].Dir = XMFLOAT3( 0.0f, 0.0f, -1.0f) ;

    //XMStoreFloat3(&lights[0].Dir,vec3);
    //lights[0].Dir = XMFLOAT3(1,1,1);
    lights[0].Color = XMFLOAT4(1,0,0,1);
    lights[1].Color = XMFLOAT4(1,1,1.0,1);
        //XMStoreFloat3(&lights[1].Pos, XMVectorSet(-40,40,-10,1));

#pragma endregion
    // clear the back buffer to a deep blue
    devcon->ClearRenderTargetView(backbuffer, D3DXCOLOR(0.0f, 0.2f, 0.4f, 1.0f));
    devcon->ClearDepthStencilView(DepthBuffer,D3D11_CLEAR_DEPTH,1.0f,0);
    #pragma region Draw Cube
    devcon->IASetPrimitiveTopology(D3D11_PRIMITIVE_TOPOLOGY::D3D10_PRIMITIVE_TOPOLOGY_TRIANGLELIST);
    devcon->IASetInputLayout(BInputLayout);

        UINT stride  = sizeof(CuxtomVertex);
    UINT offset = 0;
    devcon->IASetVertexBuffers(0,1,&BVBufer,&stride,&offset);
    devcon->IASetIndexBuffer(BIBufffer,DXGI_FORMAT_R16_UINT,0);

    ConstantBuffer cb;
    cb.World = XMMatrixTranspose(g_World);
    cb.View = XMMatrixTranspose(g_View);
    cb.Project = XMMatrixTranspose(g_Projection);
    cb.LighDirs[1] = lights[1].Dir;
    cb.LightColor[1] = lights[1].Color;
    cb.LightColor[0] = lights[0].Color;cb.LighDirs[0] = lights[0].Dir;
    cb.LightColor[0] = lights[0].Color;
    devcon->UpdateSubresource(g_ConstantBuffer,0,0,&cb,0,0);


    devcon->VSSetShader(BoxVShader,0,0);

    devcon->VSSetConstantBuffers(0,1,&g_ConstantBuffer);
    devcon->PSSetConstantBuffers(0,1,&g_ConstantBuffer);
    devcon->PSSetShaderResources(0,1,&BoxTex);
    devcon->PSSetSamplers(0,1,&samplerState);
    devcon->PSSetShader(BoxPixelShader,0,0);
    devcon->DrawIndexed(36,0,0);
#pragma endregion
    #pragma region Draw Box2
    g_World = XMMatrixRotationY(LerpPos ) *   XMMatrixTranslation(1.0,1.0 , 14.0) ;

    ConstantBuffer cb2;
    cb2.World = XMMatrixTranspose(g_World);
    cb2.View = XMMatrixTranspose(g_View);
    cb2.Project = XMMatrixTranspose(g_Projection);
    cb2.LighDirs[1] = lights[1].Dir;
    cb2.LightColor[1] = lights[1].Color;
    cb2.LighDirs[0] = lights[0].Dir;
    cb2.LightColor[0] = lights[0].Color;
    devcon->UpdateSubresource(g_ConstantBuffer,0,0,&cb2,0,0);
    devcon->VSSetConstantBuffers(0,1,&g_ConstantBuffer);
    devcon->PSSetConstantBuffers(0,1,&g_ConstantBuffer);
    devcon->DrawIndexed(36,0,0);  
    #pragma endregion
    devcon->IASetVertexBuffers(0,1,&PlaneBuffer,&stride,&offset);
    devcon->IASetIndexBuffer(PlaneIBuffer,DXGI_FORMAT_R16_UINT,0);
 *// Draw plane*
    g_World =  XMMatrixTranslation(_Size/2,-6,_Size/2);
    g_World *= XMMatrixRotationX(LerpPos * val)  ;

    devcon->UpdateSubresource(g_ConstantBuffer,0,0,&cb2,0,0);
    devcon->VSSetConstantBuffers(0,1,&g_ConstantBuffer);
    devcon->PSSetConstantBuffers(0,1,&g_ConstantBuffer);

    devcon->DrawIndexed( (_Size - 1) * (_Size - 1) ,0,0);
    // switch the back buffer and the front buffer

    swapchain->Present(0, 0);
}
// this function loads and prepares the shaders
void InitPipeline(HWND hwnd)
{
    ID3D10Blob * BVS = 0,*BPS  = 0;
    ID3D10Blob * BErrorVS,*BErrorPs;
    HRESULT hr1 = CompileShaderFromFile(L"Test.hlsl","Vs","vs_4_0",&BVS); 
    HRESULT hr =  CompileShaderFromFile(L"Test.hlsl","Ps","ps_4_0",&BPS); 
    dev->CreateVertexShader(BVS->GetBufferPointer(),BVS->GetBufferSize(),0,&BoxVShader);
    dev->CreatePixelShader(BPS->GetBufferPointer(),BPS->GetBufferSize(),0,&BoxPixelShader);

       // create the input layout object
    D3D11_INPUT_ELEMENT_DESC ied[] =
    {
        {"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},

    };
    //SecureZeroMemory(&Bin);
    dev->CreateInputLayout(ied,3,BVS->GetBufferPointer(),BVS->GetBufferSize(),&BInputLayout);
    devcon->VSSetShader(BoxVShader,0,0);
    devcon->PSSetShader(BoxPixelShader,0,0);
    devcon->IASetInputLayout(BInputLayout);
D3DX11CreateShaderResourceViewFromFile(dev,L"seafloor.dds",NULL,NULL,&BoxTex,NULL);
    D3D11_SAMPLER_DESC samplerdesc;
    SecureZeroMemory(&samplerdesc,sizeof(samplerdesc));
    samplerdesc.AddressU = D3D11_TEXTURE_ADDRESS_MODE::D3D11_TEXTURE_ADDRESS_WRAP;
    samplerdesc.AddressV =      D3D11_TEXTURE_ADDRESS_MODE::D3D11_TEXTURE_ADDRESS_WRAP;
        samplerdesc.AddressW =  D3D11_TEXTURE_ADDRESS_MODE::D3D11_TEXTURE_ADDRESS_WRAP;
        samplerdesc.Filter = D3D11_FILTER::D3D11_FILTER_COMPARISON_MIN_LINEAR_MAG_MIP_POINT;
        samplerdesc.ComparisonFunc = D3D11_COMPARISON_FUNC::D3D11_COMPARISON_NEVER;
        samplerdesc.MaxLOD = D3D11_FLOAT32_MAX;
        samplerdesc.MinLOD = 0;
        dev->CreateSamplerState(&samplerdesc,&samplerState);
}

图形调试可能非常具有挑战性,因为很多时候你会得到"没有绘制",并且可能有一百个错误中的任何一个。

使用 Direct3D,您应该:

  • 检查返回 HRESULT 的所有函数的 HRESULT(许多函数返回 void)。请务必使用SUCCEEDEDFAILED宏,而不是相等性测试。Windows 应用商店应用、Windows 手机应用和 Xbox One 应用的常见模式是使用 DX::ThrowIfFailed 帮助程序函数,该函数也是 Direct3D Win32 游戏模板的一部分。

  • 启用 Direct3D 调试设备并查找错误或警告。请参阅这篇文章,了解其他一些技巧和提示。

  • 使用传统的"注释并重试"样式调试来尽可能隔离问题。

  • 查看使用图形调试器,如VS 2013 Express for Windows,VS 2013 Community或VS 203 Pro+或视频IHV(AMD/ATI,NVIDIA,Intel)中的某些内容。

相关内容

  • 没有找到相关文章

最新更新