2014-09-28 96 views
0

我最近在YouTube上關於如何將DirectX安裝到Win32中的教程。當我跑之前,我有一個白色的窗戶。當我在安裝DirectX後運行它時,我試圖用DirectX改變顏色,但當它應該是青色時,我仍然有一個白色窗口。DirectX SDK安裝顏色變化

#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; 

它明確規定:

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

      m_pD3D11Context->ClearRenderTargetView(m_pBackBufferTarget, clearColor); 

      m_pSwapChain->Present(0, 0); 

應該給一個青色的窗口,應該不是嗎?

在此先感謝!

回答

1

我試過這段代碼,它適用於我。我得到一個青色的窗戶。但是,由於您只呼叫Present一次,它不會保持(完全)青色。你的WndProc,通過調用DefWindowProc,將刪除窗口的部分窗口需要使用窗口的背景畫筆進行重新繪製,您將其設置爲(HBRUSH)(COLOR_WINDOW + 1)

要解決這個問題,你需要做兩件事。首先將fGame.hbrBackground設置爲0,這樣WndProc不再刪除該窗口。其次,改變你的消息循環所以它是像這樣(改編自一個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(); 
    } 
} 

你需要將你的代碼,使窗口,這是應該的部分,使其青色,到它在上面的例子中說Render()。具體來說,撥打電話ClearRenderTargetViewPresent。您可以用這兩個函數的調用替換Render(),或將它們移動到一個名爲Render的函數中。

也行if (success = GetDesktopResolution)不會做你顯然認爲它做的。它將指向success的函數指針指向GetDesktopResolution並始終評估爲true。根據GetDesktopWindowGetWindowRect是否失敗,您應該有GetDesktopResolution返回值(不是void),然後檢查該值是否失敗。