C++ DirectX11 窗口颜色不变
Posted
技术标签:
【中文标题】C++ DirectX11 窗口颜色不变【英文标题】:C++ DirectX11 Window Color not changing 【发布时间】:2017-08-10 18:48:48 【问题描述】:我正在使用 DX11 开发游戏引擎。我正在关注http://www.rastertek.com/ 的教程。我已经完成了教程 2。问题是,当我尝试更改颜色值时,窗口仍然是黑色的。相关代码为:
Graphics.cpp
bool Graphics::Initialize(int screenWidth, int screenHeight, HWND hwnd)
bool result;
m_D3D = new D3DClass;
if (!m_D3D)
return false;
result = m_D3D->Initialize(screenWidth, screenHeight, hwnd, VSYNC_ENABLED, FULL_SCREEN, SCREEN_DEPTH, SCREEN_NEAR);
if (!result)
MessageBox(hwnd, "Could not initialize Direct3D", "Error", MB_OK);
return false;
return true;
bool Graphics::Render()
m_D3D->BeginScene(0.0f, 0.0f, 0.0f, 0.0f);
m_D3D->EndScene();
return true;
D3DClass.cpp
bool D3DClass::Initialize(int screenWidth, int screenHeight, HWND hwnd, bool vsync, bool fullscreen, float screenDepth, float screenNear)
HRESULT result;
IDXGIFactory* factory;
IDXGIAdapter* adapter;
IDXGIOutput* adapterOutput;
unsigned int numModes, i, numerator, denominator, stringLength;
DXGI_MODE_DESC* displayModeList;
DXGI_ADAPTER_DESC adapterDesc;
int error;
DXGI_SWAP_CHAIN_DESC swapChainDesc;
D3D_FEATURE_LEVEL featureLevel;
ID3D11Texture2D* backBufferPtr;
D3D11_TEXTURE2D_DESC depthBufferDesc;
D3D11_DEPTH_STENCIL_DESC depthStencilDesc;
D3D11_DEPTH_STENCIL_VIEW_DESC depthStencilViewDesc;
D3D11_RASTERIZER_DESC rasterDesc;
D3D11_VIEWPORT viewport;
float fieldOfView, screenAspect;
m_vsync_enabled = vsync;
result = CreateDXGIFactory(__uuidof(IDXGIFactory), (void**)&factory);
if (FAILED(result))
return false;
result = factory->EnumAdapters(0, &adapter);
if (FAILED(result))
return false;
result = adapter->EnumOutputs(0, &adapterOutput);
if (FAILED(result))
return false;
result = adapterOutput->GetDisplayModeList(DXGI_FORMAT_R8G8B8A8_UNORM, DXGI_ENUM_MODES_INTERLACED, &numModes, NULL);
if (FAILED(result))
return false;
displayModeList = new DXGI_MODE_DESC[numModes];
if (!displayModeList)
return false;
result = adapterOutput->GetDisplayModeList(DXGI_FORMAT_R8G8B8A8_UNORM, DXGI_ENUM_MODES_INTERLACED, &numModes, displayModeList);
if(FAILED(result))
return false;
for (int i = 0; i < numModes; i++)
if (displayModeList[i].Height == (unsigned int)screenHeight && displayModeList[i].Width == (unsigned int)screenWidth)
numerator = displayModeList[i].RefreshRate.Numerator;
denominator = displayModeList[i].RefreshRate.Denominator;
break;
result = adapter->GetDesc(&adapterDesc);
if (FAILED(result))
return false;
m_videoCardMemory = (int)(adapterDesc.DedicatedVideoMemory / 1048576); //MB
error = wcstombs_s(&stringLength, m_videoCardDescription, 128, adapterDesc.Description, 128);
if (error != 0)
return false;
delete[] displayModeList;
displayModeList = 0;
adapterOutput->Release();
adapterOutput = 0;
adapter->Release();
adapter = 0;
factory->Release();
factory = 0;
ZeroMemory(&swapChainDesc, sizeof(swapChainDesc));
swapChainDesc.BufferCount = 1;
swapChainDesc.BufferDesc.Width = screenWidth;
swapChainDesc.BufferDesc.Height = screenHeight;
swapChainDesc.BufferDesc.Format = DXGI_FORMAT_R8G8B8A8_UNORM;
if (m_vsync_enabled)
swapChainDesc.BufferDesc.RefreshRate.Numerator = numerator;
swapChainDesc.BufferDesc.RefreshRate.Denominator = denominator;
else
swapChainDesc.BufferDesc.RefreshRate.Numerator = 0;
swapChainDesc.BufferDesc.RefreshRate.Denominator = 1;
swapChainDesc.BufferUsage = DXGI_USAGE_RENDER_TARGET_OUTPUT;
swapChainDesc.OutputWindow = hwnd;
//MultiSampling Off
swapChainDesc.SampleDesc.Count = 1;
swapChainDesc.SampleDesc.Quality = 0;
swapChainDesc.Windowed = !fullscreen;
swapChainDesc.BufferDesc.ScanlineOrdering = DXGI_MODE_SCANLINE_ORDER_UNSPECIFIED;
swapChainDesc.BufferDesc.Scaling = DXGI_MODE_SCALING_UNSPECIFIED;
swapChainDesc.SwapEffect = DXGI_SWAP_EFFECT_DISCARD;
swapChainDesc.Flags = 0;
featureLevel = D3D_FEATURE_LEVEL_11_0;
result = D3D11CreateDeviceAndSwapChain(NULL, D3D_DRIVER_TYPE_HARDWARE, NULL, 0, &featureLevel, 1, D3D11_SDK_VERSION, &swapChainDesc, &m_swapChain, &m_device, NULL, &m_deviceContext);
if (FAILED(result))
return false;
result = m_swapChain->GetBuffer(0, __uuidof(ID3D11Texture2D), (LPVOID*)&backBufferPtr);
if (FAILED(result))
return false;
backBufferPtr->Release();
backBufferPtr = 0;
ZeroMemory(&depthBufferDesc, sizeof(depthBufferDesc));
depthBufferDesc.Width = screenWidth;
depthBufferDesc.Height = screenHeight;
depthBufferDesc.MipLevels = 1;
depthBufferDesc.ArraySize = 1;
depthBufferDesc.Format = DXGI_FORMAT_D24_UNORM_S8_UINT;
//Multisampling off
depthBufferDesc.SampleDesc.Count = 1;
depthBufferDesc.SampleDesc.Quality = 0;
depthBufferDesc.Usage = D3D11_USAGE_DEFAULT;
depthBufferDesc.BindFlags = D3D11_BIND_DEPTH_STENCIL;
depthBufferDesc.CPUAccessFlags = 0;
depthBufferDesc.MiscFlags = 0;
result = m_device->CreateTexture2D(&depthBufferDesc, NULL, &m_depthStencilBuffer);
if (FAILED(result))
return false;
ZeroMemory(&depthStencilDesc, sizeof(depthStencilDesc));
depthStencilDesc.DepthEnable = true;
depthStencilDesc.DepthWriteMask = D3D11_DEPTH_WRITE_MASK_ALL;
depthStencilDesc.DepthFunc = D3D11_COMPARISON_LESS;
depthStencilDesc.StencilEnable = true;
depthStencilDesc.StencilReadMask = 0xFF;
depthStencilDesc.StencilWriteMask = 0xFF;
depthStencilDesc.FrontFace.StencilFailOp = D3D11_STENCIL_OP_KEEP;
depthStencilDesc.FrontFace.StencilDepthFailOp = D3D11_STENCIL_OP_INCR;
depthStencilDesc.FrontFace.StencilPassOp = D3D11_STENCIL_OP_KEEP;
depthStencilDesc.FrontFace.StencilFunc = D3D11_COMPARISON_ALWAYS;
depthStencilDesc.BackFace.StencilFailOp = D3D11_STENCIL_OP_KEEP;
depthStencilDesc.BackFace.StencilDepthFailOp = D3D11_STENCIL_OP_DECR;
depthStencilDesc.BackFace.StencilPassOp = D3D11_STENCIL_OP_KEEP;
depthStencilDesc.BackFace.StencilFunc = D3D11_COMPARISON_ALWAYS;
result = m_device->CreateDepthStencilState(&depthStencilDesc, &m_depthStencilState);
if (FAILED(result))
return false;
m_deviceContext->OMSetDepthStencilState(m_depthStencilState, 1);
ZeroMemory(&depthStencilViewDesc, sizeof(depthStencilViewDesc));
depthStencilViewDesc.Format = DXGI_FORMAT_D24_UNORM_S8_UINT;
depthStencilViewDesc.ViewDimension = D3D11_DSV_DIMENSION_TEXTURE2D;
depthStencilViewDesc.Texture2D.MipSlice = 0;
result = m_device->CreateDepthStencilView(m_depthStencilBuffer, &depthStencilViewDesc, &m_depthStencilView);
if (FAILED(result))
return false;
m_deviceContext->OMSetRenderTargets(1, &m_renderTargetView, m_depthStencilView);
//TODO::CUSTOMIZE USER PRESETS
rasterDesc.AntialiasedLineEnable = false;
rasterDesc.CullMode = D3D11_CULL_BACK;
rasterDesc.DepthBias = 0;
rasterDesc.DepthBiasClamp = 0.0f;
rasterDesc.DepthClipEnable = true;
rasterDesc.FillMode = D3D11_FILL_SOLID;
rasterDesc.FrontCounterClockwise = false;
rasterDesc.MultisampleEnable = false;
rasterDesc.ScissorEnable = false;
rasterDesc.SlopeScaledDepthBias = 0.0f;
result = m_device->CreateRasterizerState(&rasterDesc, &m_rasterState);
if (FAILED(result))
return false;
m_deviceContext->RSSetState(m_rasterState);
viewport.Width = (float)screenWidth;
viewport.Height = (float)screenHeight;
viewport.MinDepth = 0.0f;
viewport.MaxDepth = 1.0f;
viewport.TopLeftX = 0.0f;
viewport.TopLeftY = 0.0f;
m_deviceContext->RSSetViewports(1, &viewport);
//TODO:: FOV SETTINGS
fieldOfView = (float)D3DX_PI / 4.0f;
screenAspect = (float)screenWidth / (float)screenHeight;
D3DXMatrixPerspectiveFovLH(&m_projectionMatrix, fieldOfView, screenAspect, screenNear, screenDepth);
D3DXMatrixIdentity(&m_worldMatrix);
D3DXMatrixOrthoLH(&m_orthoMatrix, (float)screenWidth, (float)screenHeight, screenNear, screenDepth);
return true;
void D3DClass::BeginScene(float red, float green, float blue, float alpha)
m_deviceContext->ClearRenderTargetView(m_renderTargetView, D3DXCOLOR(red, green, blue, alpha));
m_deviceContext->ClearDepthStencilView(m_depthStencilView, D3D11_CLEAR_DEPTH, 1.0f, 0);
return;
void D3DClass::EndScene()
if (m_vsync_enabled)
m_swapChain->Present(1, 0);
else
m_swapChain->Present(0, 0);
return;
Framework.cpp
void Framework::InitializeWindows(int& screenWidth, int& screenHeight)
WNDCLASSEX wc;
DEVMODE dmScreenSettings;
int posX, posY;
m_application = this;
m_hinstance = GetModuleHandle(NULL);
m_applicationName = "Racing Game";
wc.style = CS_HREDRAW | CS_VREDRAW | CS_OWNDC;
wc.lpfnWndProc = WndProc;
wc.cbClsExtra = 0;
wc.cbWndExtra = 0;
wc.hInstance = m_hinstance;
wc.hIcon = LoadIcon(NULL, IDI_WINLOGO);
wc.hIconSm = wc.hIcon;
wc.hCursor = LoadCursor(NULL, IDC_ARROW);
wc.hbrBackground = (HBRUSH)GetStockObject(BLACK_BRUSH);
wc.lpszMenuName = NULL;
wc.lpszClassName = m_applicationName;
wc.cbSize = sizeof(WNDCLASSEX);
RegisterClassEx(&wc);
screenWidth = GetSystemMetrics(SM_CXSCREEN);
screenHeight = GetSystemMetrics(SM_CYSCREEN);
if (FULL_SCREEN)
memset(&dmScreenSettings, 0, sizeof(dmScreenSettings));
dmScreenSettings.dmSize = sizeof(dmScreenSettings);
dmScreenSettings.dmPelsWidth = (unsigned long)screenWidth;
dmScreenSettings.dmPelsHeight = (unsigned long)screenHeight;
dmScreenSettings.dmBitsPerPel = 32;
dmScreenSettings.dmFields = DM_BITSPERPEL | DM_PELSWIDTH | DM_PELSHEIGHT;
ChangeDisplaySettings(&dmScreenSettings, CDS_FULLSCREEN);
posX = posY = 0;
else
screenWidth = 800;
screenHeight = 600;
posX = (GetSystemMetrics(SM_CXSCREEN) - screenWidth) / 2;
posY = (GetSystemMetrics(SM_CYSCREEN) - screenHeight) / 2;
m_hwnd = CreateWindowEx(WS_EX_APPWINDOW, m_applicationName, m_applicationName, WS_CLIPSIBLINGS | WS_CLIPCHILDREN | WS_POPUP, posX, posY, screenWidth, screenHeight, NULL, NULL, m_hinstance, NULL);
ShowWindow(m_hwnd, SW_SHOW);
SetForegroundWindow(m_hwnd);
SetFocus(m_hwnd);
ShowCursor(false);
return;
每次我更改BeginScene()
调用中的参数时,无论是什么(我尝试了红色范围为 1.0f 到 256.0f 的值),窗口始终为黑色并且没有窗口顶部三个按钮(关闭、最小化、展开)。我究竟做错了什么?任何帮助表示赞赏。
【问题讨论】:
Rastertek 教程仍然有效,但它们使用了很多遗留的东西,所以请记住这一点。你可能想看看DirectX Tool Kit的教程 【参考方案1】:我正在学习相同的教程,
0 到 1 之间的浮点数。
所以在你的情况下是红色的
bool Graphics::Render()
m_D3D->BeginScene(1.0f, 0.0f, 0.0f, 1.0f);
m_D3D->EndScene();
return true;
不要忘记将 opacity 设置为最后一个值 1.0。
祝下一个好运。
【讨论】:
以上是关于C++ DirectX11 窗口颜色不变的主要内容,如果未能解决你的问题,请参考以下文章
来自全窗口游戏的 C++ DirectX CreateDevice