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

后端 未结 2 1051
一个人的身影
一个人的身影 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 
    #include 
    #include 
    #include 
    #include 
    #include 
    #include 
    #include 
    
    #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

提交回复
热议问题