DirectX::SpriteFont/SpriteBatch prevents 3D scene from drawing

后端 未结 2 1038
一个人的身影
一个人的身影 2021-01-27 03:45

I have a problem using DirectX::SpriteFont/DirectX::SpriteBatch (from DirectXTK; exactly the same problem as discussed here: Problems when drawing text

相关标签:
2条回答
  • 2021-01-27 04:06

    Here is the complete code:

    #include <Windows.h>
    #include <stdio.h>
    #include <Xinput.h>
    #include <DirectXMath.h>
    #include <d3d11.h>
    #include <d3dcompiler.h>
    #include <DirectXTex.h>
    #include <SpriteFont.h>
    
    #include "DDSTextureLoader.h"
    #include "WICTextureLoader.h"
    
    using namespace DirectX;
    
    #define CAMERA_ROTATION_SPEED (110.0f)
    #define CAMERA_TARGET_DISTANCE (3.0f)
    #define CAMERA_TARGET_VIEW_Y_START (-15.0f)
    #define CAMERA_TARGET_VIEW_XZ_START (0.0f)
    #define CAMERA_TARGET_START (XMVectorSet(0.0f, 0.0f, 0.0f, 0.0f))
    #define CAMERA_UP_START (XMVectorSet(0.0f, 1.0f, 0.0f, 0.0f))
    #define CAMERA_POS_START (XMVectorSet(0.0f, 0.0f, 3.0f, 0.0f))
    
    #define PLAYER_MOVEMENT_SPEED (5.0f)
    
    #define SAFE_DELETE(p) if (p) { delete (p); (p) = NULL; }
    #define SAFE_RELEASE(p) if (p) { (p)->Release(); (p) = NULL; }
    
    #ifdef _DEBUG
    #define ErrorBoxW(msg) MessageBox(NULL, (msg), L"Error", MB_OK | MB_ICONERROR)
    #else // _DEBUG
    #define ErrorBox(msg)
    #endif // _DEBUG
    
    #define NORMALIZE_ANGLE(ang) { while ((ang) > 360.0f) { (ang) -= 360.0f; } while ((ang) < -360.0f) { (ang) += 360.0f; } }
    #define LIMIT_ANGLE(ang, val) { if ((ang) > (val)) { (ang) = (val); } if ((ang) < -(val)) { (ang) = -(val); } }
    #define CHECK_CHANGE_F(curr, prev, flag) { (flag) = (curr) != (prev); }
    
    typedef struct _Camera
    {
        XMFLOAT3 _target;
        XMFLOAT3 _pos;
        XMFLOAT3 _up;
        float _viewRotXZ;
        float _viewRotY;
        XMFLOAT4X4 _cameraProjection;
    } Camera;
    
    typedef struct _FPS
    {
        _FPS(void)
            : _elapsedTime(0.0f), _frames(0), _fps(0.0f) {}
        void Calc(float timeDelta)
        {
            _elapsedTime += timeDelta;
            _frames++;
    
            if (_elapsedTime >= 1.0f)
            {
                _fps = (float)_frames / _elapsedTime;
    
                _elapsedTime = 0.0f;
                _frames = 0;
    
    #ifdef _DEBUG
                wchar_t buffer[32];
                swprintf_s(buffer, 32, L"FPS: %.2f\n", _fps);
                OutputDebugString(buffer);
    #endif // _DEBUG
            }
        }
    
        float _fps;
        float _elapsedTime;
        int _frames;
    } FPS;
    
    typedef struct _Player
    {
        _Player(void)
            : _moveX(0.0f), _moveY(0.0f), _moveZ(0.0f) {}
    
        float _moveX;
        float _moveY;
        float _moveZ;
    } Player;
    
    using namespace DirectX;
    
    typedef struct _SimpleVertex
    {
        _SimpleVertex() {}
        _SimpleVertex(float x, float y, float z, float cr, float cg, float cb, float ca, float cr2, float cg2, float cb2, float ca2, float u, float v)
            : _pos(x, y, z), _color0(cr, cg, cb, ca), _color1(cr2, cg2, cb2, ca2), _tex(u, v) {}
    
        XMFLOAT3 _pos;
        XMFLOAT4 _color0;
        XMFLOAT4 _color1;
        XMFLOAT2 _tex;
    } SimpleVertex;
    
    // sizeof(ConstantBufferPerObject) = 80; multiple of 16
    typedef struct _ConstantBufferPerObject
    {
        XMFLOAT4X4 _wvp; // sizeof(XMFLOAT4X4) = 64
        float _colorAdjust; // sizeof(float) = 4; 68
        int _mode; // sizeof(int) = 4; 72
        int _pad[2]; // 2 * sizeof(int) = 8; 80
    } ConstantBufferPerObject;
    
    LPWSTR const g_windowClassName = L"dx11demo";
    LPWSTR const g_windowTitle = L"DirectX11Demo";
    HWND g_hwnd = NULL;
    HINSTANCE g_hinstance = NULL;
    const int g_width = 800;
    const int g_height = 600;
    IDXGISwapChain *g_pSwapChain = NULL;
    ID3D11Device *g_pDevice = NULL;
    ID3D11DeviceContext *g_pDeviceContext = NULL;
    ID3D11RenderTargetView *g_pRenderTargetView = NULL;
    ID3D11Buffer *g_pTriangleVertexBuffer = NULL;
    ID3D11Buffer *g_pSquareIndexBuffer = NULL;
    ID3D11VertexShader *g_pVertexShader = NULL;
    ID3D11PixelShader *g_pPixelShader = NULL;
    ID3DBlob *g_pVertexShaderBuffer = NULL;
    ID3DBlob *g_pPixelShaderBuffer = NULL;
    ID3D11DepthStencilView *g_pDepthStencilView = NULL;
    ID3D11Buffer *g_pConstantBufferPerObject = NULL;
    ID3D11Texture2D *g_pDepthStencilBuffer = NULL;
    ID3D11InputLayout *g_pVertexLayout = NULL;
    ID3D11ShaderResourceView *g_pCageTexture = NULL;
    ID3D11ShaderResourceView *g_pBrickTexture = NULL;
    ID3D11SamplerState *g_pCubeTextureSamplerState = NULL;
    bool g_solid = true;
    float g_rotBox2 = 0.0f;
    ID3D11RasterizerState *g_pNoCullSolid = NULL;
    ID3D11RasterizerState *g_pNoCullWireframe = NULL;
    ID3D11RasterizerState *g_pCWCullSolid = NULL;
    ID3D11RasterizerState *g_pCCWCullSolid = NULL;
    ID3D11BlendState *g_pTransparency = NULL;
    SpriteBatch *g_pSpriteBatch = NULL;
    SpriteFont *g_pSpriteFont = NULL;
    D3D11_INPUT_ELEMENT_DESC g_layout_a[] =
    {
        { "POSITION", 0, DXGI_FORMAT_R32G32B32_FLOAT, 0, 0, D3D11_INPUT_PER_VERTEX_DATA, 0 },
        { "COLOR_ZERO", 0, DXGI_FORMAT_R32G32B32A32_FLOAT, 0, 12, D3D11_INPUT_PER_VERTEX_DATA, 0 },
        { "COLOR_ONE", 0, DXGI_FORMAT_R32G32B32A32_FLOAT, 0, 28, D3D11_INPUT_PER_VERTEX_DATA, 0 },
        { "TEXCOORD", 0, DXGI_FORMAT_R32G32_FLOAT, 0, 44, D3D11_INPUT_PER_VERTEX_DATA, 0 },
    };
    UINT g_numElements = ARRAYSIZE(g_layout_a);
    bool g_isMoving = true;
    ConstantBufferPerObject g_constantBufferPerObject;
    bool g_enableDraw = true;
    Player g_player;
    Camera g_camera;
    FPS g_fps;
    
    void CleanUp(void);
    LRESULT CALLBACK WndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam);
    int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nShowCmd);
    bool InitD3D11(void);
    bool InitScene(void);
    void DrawScene(void);
    void UpdateScene(float);
    
    void UpdateScene(float timeDelta)
    {
        g_rotBox2 += 20.0f * timeDelta;
        NORMALIZE_ANGLE(g_rotBox2);
    }
    
    void DrawScene(void)
    {
        HRESULT hr;
    
        float bgColor_a[4] = { 0.0f, 0.4f, 0.8f, 0.0f };
    
        g_pDeviceContext->ClearRenderTargetView(g_pRenderTargetView, bgColor_a);
        g_pDeviceContext->ClearDepthStencilView(g_pDepthStencilView, D3D11_CLEAR_DEPTH | D3D11_CLEAR_STENCIL, 1.0f, 0);
    
        XMMATRIX cameraProj = XMLoadFloat4x4(&g_camera._cameraProjection);
        XMVECTOR pos = XMLoadFloat3(&g_camera._pos);
        XMVECTOR target = XMLoadFloat3(&g_camera._target);
        XMVECTOR up = XMLoadFloat3(&g_camera._up);
        XMMATRIX cameraView = XMMatrixLookAtLH(pos, target, up);
        XMMATRIX worldBox2 = XMMatrixIdentity() * (XMMatrixTranslation(2.0f, 0.0f, 0.0f) * XMMatrixRotationY(XMConvertToRadians(g_rotBox2)));
        XMMATRIX wvp = worldBox2 * cameraView * cameraProj;
        XMMATRIX transposeWvp = XMMatrixTranspose(wvp);
        XMStoreFloat4x4(&g_constantBufferPerObject._wvp, transposeWvp);
        g_pDeviceContext->UpdateSubresource(g_pConstantBufferPerObject, 0, NULL, &g_constantBufferPerObject, 0, 0);
        g_pDeviceContext->VSSetConstantBuffers(0, 1, &g_pConstantBufferPerObject);
    
        g_pDeviceContext->PSSetShaderResources(0, 1, &g_pCageTexture);
        g_pDeviceContext->PSSetSamplers(0, 1, &g_pCubeTextureSamplerState);
    
        // box
        g_pDeviceContext->DrawIndexed(36, 0, 0);
    
        wchar_t buffer[32];
        swprintf_s(buffer, 32, L"%.2f", g_fps._fps);
    
        //g_pSpriteBatch->Begin();
        //g_pSpriteFont->DrawString(g_pSpriteBatch, buffer, XMFLOAT2(30, 30));
        //g_pSpriteBatch->End();
    
        // Present the backbuffer to the screen
        hr = g_pSwapChain->Present(0, 0);
        if (FAILED(hr))
        {
            ErrorBoxW(L"Cannot present without error.");
        }
    }
    
    bool InitScene(void)
    {
        HRESULT hr;
        ID3DBlob *pErrorBlob = NULL;
        UINT flags = D3DCOMPILE_ENABLE_STRICTNESS;
    #ifdef _DEBUG
        flags |= D3DCOMPILE_DEBUG;
    #endif // _DEBUG
    
        const D3D_SHADER_MACRO defines_a[] =
        {
            { NULL, NULL }
        };
    
        // Compile Shaders from shader file
        // https://msdn.microsoft.com/de-de/library/windows/desktop/hh968107(v=vs.85).aspx
        hr = D3DCompileFromFile(L"VertexShader.hlsl", defines_a, D3D_COMPILE_STANDARD_FILE_INCLUDE, "VS", "vs_5_0", flags, 0, &g_pVertexShaderBuffer, &pErrorBlob);
        if (FAILED(hr))
        {
            SAFE_RELEASE(pErrorBlob);
            ErrorBoxW(L"Cannot compile vertex shader VS vs_5_0.");
            return false;
        }
    
        hr = D3DCompileFromFile(L"PixelShader.hlsl", defines_a, D3D_COMPILE_STANDARD_FILE_INCLUDE, "PS", "ps_5_0", flags, 0, &g_pPixelShaderBuffer, &pErrorBlob);
        if (FAILED(hr))
        {
            SAFE_RELEASE(pErrorBlob);
            ErrorBoxW(L"Cannot compile pixel shader PS ps_5_0.");
            return false;
        }
    
        // Create the Shader Objects
        hr = g_pDevice->CreateVertexShader(g_pVertexShaderBuffer->GetBufferPointer(), g_pVertexShaderBuffer->GetBufferSize(), NULL, &g_pVertexShader);
        if (FAILED(hr))
        {
            ErrorBoxW(L"Cannot create vertex shader.");
            return false;
        }
    
        hr = g_pDevice->CreatePixelShader(g_pPixelShaderBuffer->GetBufferPointer(), g_pPixelShaderBuffer->GetBufferSize(), NULL, &g_pPixelShader);
        if (FAILED(hr))
        {
            ErrorBoxW(L"Cannot create pixel shader.");
            return false;
        }
    
        // Set Vertex and Pixel Shaders
        g_pDeviceContext->VSSetShader(g_pVertexShader, 0, 0);
        g_pDeviceContext->PSSetShader(g_pPixelShader, 0, 0);
    
        // Create the vertex buffer (vertices must be in clock-wise order)
        SimpleVertex vertices_a[] =
        {
            // Front Face
            /* 11 */ SimpleVertex(-1.0f, -1.0f, -1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 0.0f, 3.0f),
            /* 12 */ SimpleVertex(-1.0f,  1.0f, -1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 0.0f, 0.0f),
            /* 13 */ SimpleVertex(1.0f,  1.0f, -1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 3.0f, 0.0f),
            /* 14 */ SimpleVertex(1.0f, -1.0f, -1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 3.0f, 3.0f),
    
            // Back Face
            /* 15 */ SimpleVertex(-1.0f, -1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 3.0f, 3.0f),
            /* 16 */ SimpleVertex(1.0f, -1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 0.0f, 3.0f),
            /* 17 */ SimpleVertex(1.0f,  1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 0.0f, 0.0f),
            /* 18 */ SimpleVertex(-1.0f,  1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 3.0f, 0.0f),
    
            // Top Face
            /* 19 */ SimpleVertex(-1.0f, 1.0f, -1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 0.0f, 3.0f),
            /* 20 */ SimpleVertex(-1.0f, 1.0f,  1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 0.0f, 0.0f),
            /* 21 */ SimpleVertex(1.0f, 1.0f,  1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 3.0f, 0.0f),
            /* 22 */ SimpleVertex(1.0f, 1.0f, -1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 3.0f, 3.0f),
    
            // Bottom Face
            /* 23 */ SimpleVertex(-1.0f, -1.0f, -1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 3.0f, 3.0f),
            /* 24 */ SimpleVertex(1.0f, -1.0f, -1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 0.0f, 3.0f),
            /* 25 */ SimpleVertex(1.0f, -1.0f,  1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 0.0f, 0.0f),
            /* 26 */ SimpleVertex(-1.0f, -1.0f,  1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 3.0f, 0.0f),
    
            // Left Face
            /* 27 */ SimpleVertex(-1.0f, -1.0f,  1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 0.0f, 3.0f),
            /* 28 */ SimpleVertex(-1.0f,  1.0f,  1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 0.0f, 0.0f),
            /* 29 */ SimpleVertex(-1.0f,  1.0f, -1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 3.0f, 0.0f),
            /* 30 */ SimpleVertex(-1.0f, -1.0f, -1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 3.0f, 3.0f),
    
            // Right Face
            /* 31 */ SimpleVertex(1.0f, -1.0f, -1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 0.0f, 3.0f),
            /* 32 */ SimpleVertex(1.0f,  1.0f, -1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 0.0f, 0.0f),
            /* 33 */ SimpleVertex(1.0f,  1.0f,  1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 3.0f, 0.0f),
            /* 34 */ SimpleVertex(1.0f, -1.0f,  1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 3.0f, 3.0f),
        };
    
        D3D11_BUFFER_DESC vertexBufferDesc;
        ZeroMemory(&vertexBufferDesc, sizeof(vertexBufferDesc));
    
        vertexBufferDesc.Usage = D3D11_USAGE_DEFAULT;
        vertexBufferDesc.ByteWidth = sizeof(SimpleVertex) * 24;
        vertexBufferDesc.BindFlags = D3D11_BIND_VERTEX_BUFFER;
        vertexBufferDesc.CPUAccessFlags = 0;
        vertexBufferDesc.MiscFlags = 0;
    
        D3D11_SUBRESOURCE_DATA vertexBufferData;
        ZeroMemory(&vertexBufferData, sizeof(vertexBufferData));
        vertexBufferData.pSysMem = vertices_a;
        hr = g_pDevice->CreateBuffer(&vertexBufferDesc, &vertexBufferData, &g_pTriangleVertexBuffer);
        if (FAILED(hr))
        {
            ErrorBoxW(L"Cannot create triangle buffer.");
            return false;
        }
    
        // Set the vertex buffer
        UINT stride = sizeof(SimpleVertex);
        UINT offset = 0;
        g_pDeviceContext->IASetVertexBuffers(0, 1, &g_pTriangleVertexBuffer, &stride, &offset);
    
        DWORD indices_a[] =
        {
            // Front Face
            /*  5 */ 0,  1,  2,
            /*  6 */ 0,  2,  3,
    
            // Back Face
            /*  7 */ 4,  5,  6,
            /*  8 */ 4,  6,  7,
    
            // Top Face
            /*  9 */ 8,  9, 10,
            /* 10 */ 8, 10, 11,
    
            // Bottom Face
            /* 11 */ 12, 13, 14,
            /* 12 */ 12, 14, 15,
    
            // Left Face
            /* 13 */ 16, 17, 18,
            /* 14 */ 16, 18, 19,
    
            // Right Face
            /* 15 */ 20, 21, 22,
            /* 16 */ 20, 22, 23,
        };
    
        D3D11_BUFFER_DESC indexBufferDesc;
        ZeroMemory(&indexBufferDesc, sizeof(indexBufferDesc));
    
        indexBufferDesc.Usage = D3D11_USAGE_DEFAULT;
        indexBufferDesc.ByteWidth = sizeof(DWORD) * 12 * 3;
        indexBufferDesc.BindFlags = D3D11_BIND_INDEX_BUFFER;
        indexBufferDesc.CPUAccessFlags = 0;
        indexBufferDesc.MiscFlags = 0;
    
        D3D11_SUBRESOURCE_DATA iinitData;
        ZeroMemory(&iinitData, sizeof(D3D11_SUBRESOURCE_DATA));
        iinitData.pSysMem = indices_a;
        hr = g_pDevice->CreateBuffer(&indexBufferDesc, &iinitData, &g_pSquareIndexBuffer);
        if (FAILED(hr))
        {
            ErrorBoxW(L"Cannot create index buffer.");
            return false;
        }
    
        g_pDeviceContext->IASetIndexBuffer(g_pSquareIndexBuffer, DXGI_FORMAT_R32_UINT, 0);
    
        // Create the Input Layout
        hr = g_pDevice->CreateInputLayout(g_layout_a, g_numElements, g_pVertexShaderBuffer->GetBufferPointer(), g_pVertexShaderBuffer->GetBufferSize(), &g_pVertexLayout);
        if (FAILED(hr))
        {
            ErrorBoxW(L"Cannot create input layout.");
            return false;
        }
    
        // Set the Input Layout
        g_pDeviceContext->IASetInputLayout(g_pVertexLayout);
    
        // Set Primitive Topology
        g_pDeviceContext->IASetPrimitiveTopology(D3D11_PRIMITIVE_TOPOLOGY_TRIANGLELIST); // 3 vertices per triangle
        //g_pDeviceContext->IASetPrimitiveTopology(D3D11_PRIMITIVE_TOPOLOGY_POINTLIST); // 1 vertex per point
        //g_pDeviceContext->IASetPrimitiveTopology(D3D11_PRIMITIVE_TOPOLOGY_LINELIST); // 2 vertices per line
    
        // Create the Viewport
        D3D11_VIEWPORT viewport;
        ZeroMemory(&viewport, sizeof(D3D11_VIEWPORT));
    
        viewport.TopLeftX = 0;
        viewport.TopLeftY = 0;
        viewport.Width = g_width; // divide by 4 to only use 1/4 of client area (width)
        viewport.Height = g_height; // divide by 4 to only use 1/4 of client area (height)
        viewport.MinDepth = 0.0f;
        viewport.MaxDepth = 1.0f;
    
        //Set the Viewport
        g_pDeviceContext->RSSetViewports(1, &viewport);
    
        // Create the buffer to send to the cbuffer in effect file
        D3D11_BUFFER_DESC constantBufferDesc;
        ZeroMemory(&constantBufferDesc, sizeof(D3D11_BUFFER_DESC));
    
        constantBufferDesc.Usage = D3D11_USAGE_DEFAULT;
        constantBufferDesc.ByteWidth = sizeof(ConstantBufferPerObject);
        constantBufferDesc.BindFlags = D3D11_BIND_CONSTANT_BUFFER;
        constantBufferDesc.CPUAccessFlags = 0;
        constantBufferDesc.MiscFlags = 0;
    
        hr = g_pDevice->CreateBuffer(&constantBufferDesc, NULL, &g_pConstantBufferPerObject);
        if (FAILED(hr))
        {
            ErrorBoxW(L"Cannot create constant buffer.");
            return false;
        }
    
        D3D11_RASTERIZER_DESC rasterizerDesc;
        ZeroMemory(&rasterizerDesc, sizeof(D3D11_RASTERIZER_DESC));
    
        rasterizerDesc.FillMode = D3D11_FILL_SOLID;
        rasterizerDesc.CullMode = D3D11_CULL_NONE;
        rasterizerDesc.FrontCounterClockwise = true;
        hr = g_pDevice->CreateRasterizerState(&rasterizerDesc, &g_pNoCullSolid);
        if (FAILED(hr))
        {
            ErrorBoxW(L"Cannot create rasterizer state (no culling, solid).");
            return false;
        }
    
        rasterizerDesc.FillMode = D3D11_FILL_WIREFRAME;
        hr = g_pDevice->CreateRasterizerState(&rasterizerDesc, &g_pNoCullWireframe);
        if (FAILED(hr))
        {
            ErrorBoxW(L"Cannot create rasterizer state (no culling, wireframe).");
            return false;
        }
    
        g_pDeviceContext->RSSetState(g_pNoCullSolid);
    
        hr = CreateWICTextureFromFile(g_pDevice, L"tcage.png", NULL, &g_pCageTexture);
        if (FAILED(hr))
        {
            ErrorBoxW(L"Cannot create shader resource view (cage).");
            return false;
        }
    
        D3D11_SAMPLER_DESC sampDesc;
        ZeroMemory(&sampDesc, sizeof(sampDesc));
    
        sampDesc.Filter = D3D11_FILTER_MIN_MAG_MIP_LINEAR;
        sampDesc.AddressU = D3D11_TEXTURE_ADDRESS_WRAP;
        sampDesc.AddressV = D3D11_TEXTURE_ADDRESS_WRAP;
        sampDesc.AddressW = D3D11_TEXTURE_ADDRESS_WRAP;
        sampDesc.ComparisonFunc = D3D11_COMPARISON_NEVER;
        sampDesc.MinLOD = 0;
        sampDesc.MaxLOD = D3D11_FLOAT32_MAX;
    
        hr = g_pDevice->CreateSamplerState(&sampDesc, &g_pCubeTextureSamplerState);
        if (FAILED(hr))
        {
            ErrorBoxW(L"Cannot create sampler state.");
            return false;
        }
    
        D3D11_BLEND_DESC blendDesc; // Define the Blending Equation
        ZeroMemory(&blendDesc, sizeof(blendDesc));
    
        D3D11_RENDER_TARGET_BLEND_DESC rtbd;
        ZeroMemory(&rtbd, sizeof(rtbd));
    
        rtbd.BlendEnable = true;
        rtbd.SrcBlend = D3D11_BLEND_SRC_COLOR;
        rtbd.DestBlend = D3D11_BLEND_BLEND_FACTOR;
        rtbd.BlendOp = D3D11_BLEND_OP_ADD;
        rtbd.SrcBlendAlpha = D3D11_BLEND_ONE;
        rtbd.DestBlendAlpha = D3D11_BLEND_ZERO;
        rtbd.BlendOpAlpha = D3D11_BLEND_OP_ADD;
        rtbd.RenderTargetWriteMask = D3D11_COLOR_WRITE_ENABLE_ALL;
    
        blendDesc.AlphaToCoverageEnable = false;
        blendDesc.RenderTarget[0] = rtbd;
    
        hr = g_pDevice->CreateBlendState(&blendDesc, &g_pTransparency);
        if (FAILED(hr))
        {
            ErrorBoxW(L"Cannot create blend state.");
            return false;
        }
    
        // Create the Counter Clockwise and Clockwise Culling States
        D3D11_RASTERIZER_DESC cmdesc;
        ZeroMemory(&cmdesc, sizeof(D3D11_RASTERIZER_DESC));
    
        cmdesc.FillMode = D3D11_FILL_SOLID;
        cmdesc.CullMode = D3D11_CULL_BACK;
        cmdesc.FrontCounterClockwise = true;
        hr = g_pDevice->CreateRasterizerState(&cmdesc, &g_pCCWCullSolid);
        if (FAILED(hr))
        {
            ErrorBoxW(L"Cannot create ccw cull mode.");
            return false;
        }
    
        cmdesc.FrontCounterClockwise = false;
        hr = g_pDevice->CreateRasterizerState(&cmdesc, &g_pCWCullSolid);
        if (FAILED(hr))
        {
            ErrorBoxW(L"Cannot create cw cull mode.");
            return false;
        }
    
        g_pSpriteBatch = new SpriteBatch(g_pDeviceContext);
        if (!g_pSpriteBatch)
        {
            ErrorBoxW(L"Cannot create sprite batch.");
            return false;
        }
    
        g_pSpriteFont = new SpriteFont(g_pDevice, L"arial.font");
        if (!g_pSpriteFont)
        {
            ErrorBoxW(L"Cannot create sprite font.");
            return false;
        }
    
        XMStoreFloat3(&g_camera._target, CAMERA_TARGET_START);
        XMStoreFloat3(&g_camera._pos, CAMERA_POS_START);
        XMStoreFloat3(&g_camera._up, CAMERA_UP_START);
        g_camera._viewRotXZ = CAMERA_TARGET_VIEW_XZ_START;
        g_camera._viewRotY = CAMERA_TARGET_VIEW_Y_START;
    
        // Set the Projection matrix
        XMStoreFloat4x4(&g_camera._cameraProjection, XMMatrixPerspectiveFovLH(XMConvertToRadians(45.0f), (float)g_width / (float)g_height, 0.1f, 1000.0f));
    
        return true;
    }
    
    bool InitD3D11(void)
    {   
        HRESULT hr;
    
        DXGI_MODE_DESC bufferDesc; // Describe our Buffer
        ZeroMemory(&bufferDesc, sizeof(DXGI_MODE_DESC));
    
        bufferDesc.Width = g_width;
        bufferDesc.Height = g_height;
        bufferDesc.RefreshRate.Numerator = 60;
        bufferDesc.RefreshRate.Denominator = 1;
        bufferDesc.Format = DXGI_FORMAT_R8G8B8A8_UNORM;
        bufferDesc.ScanlineOrdering = DXGI_MODE_SCANLINE_ORDER_UNSPECIFIED;
        bufferDesc.Scaling = DXGI_MODE_SCALING_UNSPECIFIED;
    
        DXGI_SWAP_CHAIN_DESC swapChainDesc; // Describe our SwapChain
        ZeroMemory(&swapChainDesc, sizeof(DXGI_SWAP_CHAIN_DESC));
    
        swapChainDesc.BufferDesc = bufferDesc;
        swapChainDesc.SampleDesc.Count = 1;
        swapChainDesc.SampleDesc.Quality = 0;
        swapChainDesc.BufferUsage = DXGI_USAGE_RENDER_TARGET_OUTPUT;
        swapChainDesc.BufferCount = 1;
        swapChainDesc.OutputWindow = g_hwnd;
        swapChainDesc.Windowed = TRUE;
        swapChainDesc.SwapEffect = DXGI_SWAP_EFFECT_DISCARD;
    
        //Create our SwapChain
        hr = D3D11CreateDeviceAndSwapChain(
            NULL,
            D3D_DRIVER_TYPE_HARDWARE,
            NULL,
            D3D11_CREATE_DEVICE_DEBUG,
            NULL,
            NULL,
            D3D11_SDK_VERSION,
            &swapChainDesc,
            &g_pSwapChain,
            &g_pDevice,
            NULL,
            &g_pDeviceContext);
        if (FAILED(hr))
        {
            ErrorBoxW(L"Cannot create swap chain, device and device context.");
            return false;
        }
    
        ID3D11Texture2D* backBuffer; // Create our BackBuffer
        hr = g_pSwapChain->GetBuffer(0, __uuidof(ID3D11Texture2D), (void **)&backBuffer);
        if (FAILED(hr))
        {
            ErrorBoxW(L"Cannot create back buffer.");
            return false;
        }
    
        // Create our Render Target
        hr = g_pDevice->CreateRenderTargetView(backBuffer, NULL, &g_pRenderTargetView);
        SAFE_RELEASE(backBuffer); // release back buffer in any case
        if (FAILED(hr))
        {   
            ErrorBoxW(L"Cannot create render target view.");
            return false;
        }
    
        D3D11_TEXTURE2D_DESC depthStencilDesc; // Describe our Depth/Stencil Buffer
        ZeroMemory(&depthStencilDesc, sizeof(D3D11_TEXTURE2D_DESC));
    
        depthStencilDesc.Width = g_width;
        depthStencilDesc.Height = g_height;
        depthStencilDesc.MipLevels = 1;
        depthStencilDesc.ArraySize = 1;
        depthStencilDesc.Format = DXGI_FORMAT_D24_UNORM_S8_UINT;
        depthStencilDesc.SampleDesc.Count = 1;
        depthStencilDesc.SampleDesc.Quality = 0;
        depthStencilDesc.Usage = D3D11_USAGE_DEFAULT;
        depthStencilDesc.BindFlags = D3D11_BIND_DEPTH_STENCIL;
        depthStencilDesc.CPUAccessFlags = 0;
        depthStencilDesc.MiscFlags = 0;
    
        // Create the Depth/Stencil View
        hr = g_pDevice->CreateTexture2D(&depthStencilDesc, NULL, &g_pDepthStencilBuffer);
        if (FAILED(hr))
        {
            ErrorBoxW(L"Cannot create depth stencil buffer.");
            return false;
        }
    
        hr = g_pDevice->CreateDepthStencilView(g_pDepthStencilBuffer, NULL, &g_pDepthStencilView);
        if (FAILED(hr))
        {
            ErrorBoxW(L"Cannot create depth stencil view.");
            return false;
        }
    
        // Set our Render Target
        g_pDeviceContext->OMSetRenderTargets(1, &g_pRenderTargetView, g_pDepthStencilView);
    
        return true;
    }
    
    void CleanUp(void)
    {
        SAFE_RELEASE(g_pDevice);
        SAFE_RELEASE(g_pDeviceContext);
        SAFE_RELEASE(g_pPixelShader);
        SAFE_RELEASE(g_pPixelShaderBuffer);
        SAFE_RELEASE(g_pRenderTargetView);
        SAFE_RELEASE(g_pSwapChain);
        SAFE_RELEASE(g_pTriangleVertexBuffer);
        SAFE_RELEASE(g_pVertexLayout);
        SAFE_RELEASE(g_pVertexShader);
        SAFE_RELEASE(g_pVertexShaderBuffer);
        SAFE_RELEASE(g_pSquareIndexBuffer);
        SAFE_RELEASE(g_pDepthStencilBuffer);
        SAFE_RELEASE(g_pDepthStencilView);
        SAFE_RELEASE(g_pConstantBufferPerObject);
        SAFE_RELEASE(g_pNoCullSolid);
        SAFE_RELEASE(g_pNoCullWireframe);
        SAFE_RELEASE(g_pCageTexture);
        SAFE_RELEASE(g_pBrickTexture);
        SAFE_RELEASE(g_pCubeTextureSamplerState);
        SAFE_RELEASE(g_pTransparency);
        SAFE_RELEASE(g_pCWCullSolid);
        SAFE_RELEASE(g_pCCWCullSolid);
        SAFE_DELETE(g_pSpriteBatch);
        SAFE_DELETE(g_pSpriteFont);
    }
    
    LRESULT CALLBACK WndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
    {
        // Check message
        switch (msg)
        {
        case WM_KEYDOWN:
            // if escape key was pressed, display popup box         
            if (wParam == VK_ESCAPE)
            {
                if (MessageBox(0, L"Are you sure you want to exit?", L"Really?", MB_YESNO | MB_ICONQUESTION) == IDYES)
                {
                    // Release the windows allocated memory  
                    DestroyWindow(hwnd);
                }
            }
            return 0;
    
        case WM_DESTROY:
            // if x button in top right was pressed
            PostQuitMessage(0);
            return 0;
        }
    
        // return the message for windows to handle it
        return DefWindowProc(hwnd, msg, wParam, lParam);
    }
    
    int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nShowCmd)
    {
        UNREFERENCED_PARAMETER(lpCmdLine);
        UNREFERENCED_PARAMETER(hPrevInstance);
    
        g_hinstance = hInstance;
    
        WNDCLASSEX wc; // Create a new extended windows class
        ZeroMemory(&wc, sizeof(WNDCLASSEX));
    
        wc.cbSize = sizeof(WNDCLASSEX); // Size of our windows class
        wc.style = CS_HREDRAW | CS_VREDRAW; // class styles
        wc.lpfnWndProc = WndProc; // Default windows procedure function
        wc.cbClsExtra = NULL; // Extra bytes after our wc structure
        wc.cbWndExtra = NULL; // Extra bytes after our windows instance
        wc.hInstance = hInstance; // Instance to current application
        wc.hIcon = LoadIcon(NULL, IDI_WINLOGO); // Title bar Icon
        wc.hCursor = LoadCursor(NULL, IDC_ARROW); // Default mouse Icon
        wc.hbrBackground = (HBRUSH)(COLOR_WINDOW + 2); // Window bg color
        wc.lpszMenuName = NULL; // Name of the menu attached to our window
        wc.lpszClassName = g_windowClassName; // Name of our windows class
        wc.hIconSm = LoadIcon(NULL, IDI_WINLOGO); // Icon in your taskbar
    
        if (!RegisterClassEx(&wc)) // Register our windows class
        {
            ErrorBoxW(L"Error registering class");
            return 1;
        }
    
        // Create our Extended Window
        g_hwnd = CreateWindowEx(
            NULL, // Extended style
            g_windowClassName, // Name of our windows class
            g_windowTitle, // Name in the title bar of our window
            WS_OVERLAPPEDWINDOW ^ (WS_THICKFRAME | WS_MINIMIZEBOX | WS_MAXIMIZEBOX), // style of our window
            CW_USEDEFAULT, CW_USEDEFAULT, // Top left corner of window
            g_width, // Width of our window
            g_height, // Height of our window
            NULL, // Handle to parent window
            NULL, // Handle to a Menu
            hInstance, // Specifies instance of current program
            NULL // used for an MDI client window
            );
    
        // Make sure our window has been created
        if (!g_hwnd)
        {
            ErrorBoxW(L"Error creating window");
            return 1;
        }
    
        ShowWindow(g_hwnd, nShowCmd); // Shows our window
        UpdateWindow(g_hwnd); // Its good to update our window
    
        bool result;
        result = InitD3D11();
        if (result)
        {
            result = InitScene();
            if (result)
            {
                MSG msg; // Create a new message structure
                ZeroMemory(&msg, sizeof(MSG));
    
                DWORD timeLast = timeGetTime();
                DWORD timeCurr = timeLast;
                float timeDelta = 0.0f;
                bool run = true;
                //float elapsed = 0.0f;
                //float frameLimit = 1.0f / 60.0f;
    
                while (run)
                {
                    // if there was a windows message
                    while (PeekMessage(&msg, NULL, 0, 0, PM_REMOVE))
                    {
                        // if the message was WM_QUIT
                        if (msg.message == WM_QUIT)
                        {
                            run = false; // Exit the message loop
                        }
    
                        TranslateMessage(&msg); // Translate the message
                        DispatchMessage(&msg); // Send the message to default windows procedure
                    }
    
                    timeCurr = timeGetTime();
                    timeDelta = (float)(timeCurr - timeLast) / 1000.0f;
    
                    //elapsed += timeDelta;
                    //if (elapsed >= frameLimit)
                    //{
                    g_fps.Calc(timeDelta);
    
                    UpdateScene(timeDelta);
                    DrawScene();
    
                    //elapsed = 0.0f;
                    //}
    
                    timeLast = timeCurr;
                }
            }
        }
    
        CleanUp();
    
        return 0; // return the message
    }
    

    Scene without SpriteFont

    Scene with SpriteFont

    0 讨论(0)
  • 2021-01-27 04:31

    First, as you are using DirectXTK, you don't need DirectXTex. DirectXTex is intended for texture processing tools, while DirectXTK texture loaders are more suited to use in applications. See this blog post.

    Second, don't use the ancient timeGetTime function. You can use GetTickCount, although GetTickCount64 is better as it avoids overflow problems. For frame timing, however, these are not really precise enough. You should take a look at the StepTimer.h used in the DirectX Tool Kit tutorials.

    Third, you should look at using Microsoft::WRL::ComPtr rather than all the SAFE_RELEASE macro stuff. See this page for details.

    Your code was including xinput.h as well. You should take a look at using DirectX Tool Kit's GamePad instead which has a number of benefits. If nothing else, it uses XInput more robustly than you likely would.

    With all that said, your problem is quite simple: You set the render state up for your scene in InitScene, but drawing anything else changes the state which is exactly what SpriteBatch does. I document which render states each object in DirectX Toolkit manipulates on the wiki.

    You need to set all the state your Draw requires each frame, not assume it is set forever, if you do more than a single draw.

    void DrawScene(void)
    {
        HRESULT hr;
    
        float bgColor_a[4] = { 0.0f, 0.4f, 0.8f, 0.0f };
    
        g_pDeviceContext->ClearRenderTargetView(g_pRenderTargetView, bgColor_a);
        g_pDeviceContext->ClearDepthStencilView(g_pDepthStencilView, D3D11_CLEAR_DEPTH | D3D11_CLEAR_STENCIL, 1.0f, 0);
    
    //>>>> THESE WERE MOVED FROM INITSCENE ABOVE!
        // Set Vertex and Pixel Shaders
        g_pDeviceContext->VSSetShader(g_pVertexShader, 0, 0);
        g_pDeviceContext->PSSetShader(g_pPixelShader, 0, 0);
    
        // Set the vertex buffer
        UINT stride = sizeof(SimpleVertex);
        UINT offset = 0;
        g_pDeviceContext->IASetVertexBuffers(0, 1, &g_pTriangleVertexBuffer, &stride, &offset);
    
        g_pDeviceContext->IASetIndexBuffer(g_pSquareIndexBuffer, DXGI_FORMAT_R32_UINT, 0);
    
        // Set the Input Layout
        g_pDeviceContext->IASetInputLayout(g_pVertexLayout);
    
        // Set Primitive Topology
        g_pDeviceContext->IASetPrimitiveTopology(D3D11_PRIMITIVE_TOPOLOGY_TRIANGLELIST); // 3 vertices per triangle
                                                                                         //g_pDeviceContext->IASetPrimitiveTopology(D3D11_PRIMITIVE_TOPOLOGY_POINTLIST); // 1 vertex per point
                                                                                         //g_pDeviceContext->IASetPrimitiveTopology(D3D11_PRIMITIVE_TOPOLOGY_LINELIST); // 2 vertices per line
    
                                                                                         // Create the Viewport
    
        g_pDeviceContext->RSSetState(g_pNoCullSolid);
    //THESE WERE MOVED FROM INITSCENE ABOVE! <<<<
    
        XMMATRIX cameraProj = XMLoadFloat4x4(&g_camera._cameraProjection);
        XMVECTOR pos = XMLoadFloat3(&g_camera._pos);
        XMVECTOR target = XMLoadFloat3(&g_camera._target);
        XMVECTOR up = XMLoadFloat3(&g_camera._up);
        XMMATRIX cameraView = XMMatrixLookAtLH(pos, target, up);
        XMMATRIX worldBox2 = XMMatrixIdentity() * (XMMatrixTranslation(2.0f, 0.0f, 0.0f) * XMMatrixRotationY(XMConvertToRadians(g_rotBox2)));
        XMMATRIX wvp = worldBox2 * cameraView * cameraProj;
        XMMATRIX transposeWvp = XMMatrixTranspose(wvp);
        XMStoreFloat4x4(&g_constantBufferPerObject._wvp, transposeWvp);
        g_pDeviceContext->UpdateSubresource(g_pConstantBufferPerObject, 0, NULL, &g_constantBufferPerObject, 0, 0);
        g_pDeviceContext->VSSetConstantBuffers(0, 1, &g_pConstantBufferPerObject);
    
        g_pDeviceContext->PSSetShaderResources(0, 1, &g_pCageTexture);
        g_pDeviceContext->PSSetSamplers(0, 1, &g_pCubeTextureSamplerState);
    
        // box
        g_pDeviceContext->DrawIndexed(36, 0, 0);
    
        wchar_t buffer[32];
        swprintf_s(buffer, 32, L"%.2f", g_fps._fps);
    
        g_pSpriteBatch->Begin();
        g_pSpriteFont->DrawString(g_pSpriteBatch, buffer, XMFLOAT2(30, 30));
        g_pSpriteBatch->End();
    
        // Present the backbuffer to the screen
        hr = g_pSwapChain->Present(0, 0);
    //>>>> This behavior means the app crashes if you hit a DEVICE_REMOVED or DEVICE_RESET.
        if (FAILED(hr))
        {
            ErrorBoxW(L"Cannot present without error.");
        }
    }
    

    You can generally 'set it and forget it' for the viewport state RSSetViewports which also implicitly sets the scissors state, but a better usage is to set it at the start of each frame when you do your initial Clear. This is the pattern I use in the Direct3D Game Templates.

    0 讨论(0)
提交回复
热议问题