0
votes

I recently followed a tutorial on YouTube on how to install DirectX into Win32. When I ran it before, I got a white window. When I ran it after installing DirectX, I tried to change the colour with DirectX, but I still got a white window when it should be cyan.

#include <Windows.h>
#include <iostream>
#include "wtypes.h"
#include "wtypes.h"
#include <d3d11.h>
#include <d3dx11.h>
#include <DxErr.h>

void GetDesktopResolution(int& horizontal, int& vertical)
{
    RECT desktop;
    const HWND hDesktop = GetDesktopWindow();
    GetWindowRect(hDesktop, &desktop);
    horizontal = desktop.right;
    vertical = desktop.bottom;
}

using namespace std;

HWND windowHandle;

LRESULT CALLBACK WndProc(HWND hwnd, UINT fMsg, WPARAM wParam, LPARAM lParam)
{
    switch (fMsg)
    {
    case WM_CLOSE:
        DestroyWindow(hwnd);
        break;
    case WM_DESTROY:
        PostQuitMessage(0);
        break;
    case WM_CHAR:
    {
        if (wParam == VK_ESCAPE)
        SendMessage(hwnd, WM_CLOSE, 0, 0);
        return 0;
    }
    default:
        return DefWindowProc(hwnd, fMsg, wParam, lParam);
    }
}

int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE prevIstance, PSTR cmdLine, int showCmd)
{
    int horizontal = 0;
    int vertical = 0;
    bool success;
    int hres = 0;
    int vres = 0;
    GetDesktopResolution(horizontal, vertical);

    if (success = GetDesktopResolution)
    {
        hres = horizontal - 800;
        vres = vertical - 600;
    }

    const int result = MessageBoxA(0, "Would you like to play in \nFull-Screen Mode?", "When the Sun Sets", MB_ICONEXCLAMATION | MB_YESNOCANCEL);

    switch (result)
    {
    case IDYES:

        if (result == IDYES)
        {
            // FIRST WINDOW

            WNDCLASSEX fGame;

            fGame.cbSize = sizeof(WNDCLASSEX);
            fGame.cbClsExtra = 0;
            fGame.cbWndExtra = 0;
            fGame.hIconSm = 0;

            fGame.hInstance = hInstance;
            fGame.lpfnWndProc = WndProc;
            fGame.style = CS_HREDRAW | CS_VREDRAW;
            fGame.lpszClassName = L"WTSS1";
            fGame.lpszMenuName = 0;
            fGame.hCursor = LoadCursor(0, IDC_ARROW);
            fGame.hIcon = LoadIcon(0, IDI_APPLICATION);
            fGame.hbrBackground = (HBRUSH)(COLOR_WINDOW + 1);

            RegisterClassEx(&fGame);

            windowHandle = CreateWindowEx(WS_MAXIMIZEBOX, L"WTSS1", L"When the Sun Sets", WS_OVERLAPPEDWINDOW | WS_VISIBLE, 0, 0, 800 + hres, 600 + vres, 0, 0, hInstance, 0);

            SetWindowLong(windowHandle, GWL_STYLE, 0);

            if (windowHandle == 0)
            {
                MessageBoxA(0, "Error: The window has been configured incorrectly.", "When the Sun Sets", 0);
                return -1;
            }

            ShowWindow(windowHandle, showCmd);

            UpdateWindow(windowHandle);

            HRESULT hResult = S_OK;

            ID3D11Device*           m_pD3D11Device = 0;
            IDXGISwapChain*         m_pSwapChain = 0;
            ID3D11DeviceContext*    m_pD3D11Context = 0;
            D3D_FEATURE_LEVEL       FeatureLevelsSupported;

            D3D_FEATURE_LEVEL FeatureLevelsRequested[] =
            {
                    D3D_FEATURE_LEVEL_11_0,
                    D3D_FEATURE_LEVEL_10_1,
                    D3D_FEATURE_LEVEL_10_0,
                    D3D_FEATURE_LEVEL_9_3,
                    D3D_FEATURE_LEVEL_9_2,
                    D3D_FEATURE_LEVEL_9_1,
            };

            RECT dimensions;
            GetClientRect(windowHandle, &dimensions);
            LONG width = dimensions.right - dimensions.left;
            LONG height = dimensions.bottom - dimensions.top;

            DXGI_SWAP_CHAIN_DESC sd;
            ZeroMemory(&sd, sizeof(sd));
            sd.BufferCount = 1;
            sd.BufferDesc.Width = static_cast<unsigned int>(width);
            sd.BufferDesc.Height = static_cast<unsigned int>(height);
            sd.BufferDesc.Format = DXGI_FORMAT_R8G8B8A8_UNORM;
            sd.BufferDesc.RefreshRate.Numerator = 60;
            sd.BufferDesc.RefreshRate.Denominator = 1;
            sd.BufferUsage = DXGI_USAGE_RENDER_TARGET_OUTPUT;
            sd.OutputWindow = windowHandle;
            sd.SampleDesc.Count = 1;
            sd.SampleDesc.Quality = 0;
            sd.Windowed = TRUE;

            hResult = D3D11CreateDeviceAndSwapChain(NULL,
                D3D_DRIVER_TYPE_HARDWARE,
                NULL,
                0,
                FeatureLevelsRequested,
                3,
                D3D11_SDK_VERSION,
                &sd,
                &m_pSwapChain,
                &m_pD3D11Device,
                &FeatureLevelsSupported,
                &m_pD3D11Context);

            if (FAILED(hResult))
            {
                MessageBoxA(windowHandle, "Error: The Direct3D device has been configured incorrectly.", "When the Sun Sets", 0);
                return -1;
            }

            ID3D11RenderTargetView* m_pBackBufferTarget = 0;

            ID3D11Texture2D* backBufferTexture;
            hResult = m_pSwapChain->GetBuffer(0, __uuidof(ID3D11Texture2D), (LPVOID*)&backBufferTexture);

            if (FAILED(hResult))
            {
                MessageBoxA(windowHandle, "Error: The Direct3D device has been configured incorrectly.", "When the Sun Sets", 0);
                return -1;
            }

            hResult = m_pD3D11Device->CreateRenderTargetView(backBufferTexture, 0, &m_pBackBufferTarget);

            if (backBufferTexture)
            {
                backBufferTexture->Release(); 
                backBufferTexture = 0;
            }

            if (FAILED(hResult))
            {
                MessageBoxA(windowHandle, "Error: The Direct3D device has been configured incorrectly.", "When the Sun Sets", 0);
                return -1;
            }

            m_pD3D11Context->OMSetRenderTargets(1, &m_pBackBufferTarget, 0);

            D3D11_VIEWPORT vp;
            vp.Width = static_cast<float>(width);
            vp.Height = static_cast<float>(height);
            vp.MinDepth = 0.0f;
            vp.MaxDepth = 1.0f;
            vp.TopLeftX = 0;
            vp.TopLeftY = 0;
            m_pD3D11Context->RSSetViewports(1, &vp);

            if (m_pD3D11Context == 0)
            {
                MessageBoxA(windowHandle, "Error: The Direct3D device has been configured incorrectly.", "When the Sun Sets", 0);
                return -1;
            }

            float clearColor[4] = { 0.0f, 135/225.0f, 189/225.0f, 1.0f };

            m_pD3D11Context->ClearRenderTargetView(m_pBackBufferTarget, clearColor);

            m_pSwapChain->Present( 0, 0 );

            MSG fMsg;

            SecureZeroMemory(&fMsg, sizeof(MSG));
            int fReturnValue = 0;

            while ((fReturnValue = GetMessage(&fMsg, 0, 0, 0)) != 0)
            {
                if (fReturnValue == -1)
                {
                    MessageBoxA(windowHandle, "Error: The window has been configured incorrectly.", "When the Sun Sets", 0);
                }

                TranslateMessage(&fMsg);
                DispatchMessage(&fMsg);
            }

            if (m_pBackBufferTarget)
            {
                m_pBackBufferTarget->Release();
                m_pBackBufferTarget = 0;
            }

            if (m_pSwapChain)
            {
                m_pSwapChain->Release();
                m_pSwapChain = 0;
            }

            if (m_pD3D11Context)
            {
                m_pD3D11Context->Release();
                m_pD3D11Context = 0;
            }

            if (m_pD3D11Device)
            {
                m_pD3D11Device->Release();
                m_pD3D11Device = 0;
            }
        }
        break;

It clearly states:

            float clearColor[4] = { 0.0f, 135/225.0f, 189/225.0f, 1.0f };

            m_pD3D11Context->ClearRenderTargetView(m_pBackBufferTarget, clearColor);

            m_pSwapChain->Present( 0, 0 );

Which should give a cyan window, should it not?

Thanks in advance!

1

1 Answers

1
votes

I tried the code and it works for me. I get a cyan window. However, since you only call Present once, it won't stay (completely) cyan. Your WndProc, by calling DefWindowProc, will erase parts of the window that need repainting with the window's background brush, which you set to be (HBRUSH)(COLOR_WINDOW + 1).

To fix this problem, you need to do two things. First set fGame.hbrBackground to 0, so WndProc no longer erases the window. Next, change your message loop so it's something like this (adapted from an MSDN example):

bool bGotMsg;
MSG  msg;
msg.message = WM_NULL;
PeekMessage(&msg, NULL, 0U, 0U, PM_NOREMOVE);

while (WM_QUIT != msg.message)
{
    // Process window events.
    // Use PeekMessage() so we can use idle time to render the scene. 
    bGotMsg = (PeekMessage(&msg, NULL, 0U, 0U, PM_REMOVE) != 0);

    if (bGotMsg)
    {
        // Translate and dispatch the message
        TranslateMessage(&msg);
        DispatchMessage(&msg);
    }
    else
    {
        Render();
    }
}

You'll need to move your code that renders the window, the part that's supposed to make it cyan, to where it says Render() in the above example. Specifically, the calls to ClearRenderTargetView and Present. You can either replace Render() with calls to these two functions, or move them to a a function called Render.

Also line if (success = GetDesktopResolution) doesn't do what you apparently think it does. It assigns to success a function pointer to GetDesktopResolution and always evaluates as true. You should have GetDesktopResolution return a value (not void) depending on whether GetDesktopWindow or GetWindowRect fails, and then check that value for failure.