2014-09-28 27 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),然后检查该值是否失败。