DirectX 10/11禁止Alt Enter全屏的方法
DirectX 10/11的交换链有全屏功能,但是这个全屏并不是想象的那样,缓冲区大小不改变,画面会模糊,关掉的方法:
<code class="language-cpp">// 禁止Alt+Enter全屏 CComPtr<idxgifactory> dxgifac; (comexcept)g_swpch->GetParent(__uuidof(IDXGIFactory), (void**)&dxgifac); dxgifac->MakeWindowAssociation(g_hwnd, DXGI_MWA_NO_WINDOW_CHANGES | DXGI_MWA_NO_ALT_ENTER); dxgifac = NULL; </idxgifactory></code>
DXUT也有全屏切换,但实际上是重新建立了适合全屏的设备和交换链,不会模糊。
Win10中Debug Layer的安装
DirectX 9/10/11比较
DirectX 9.0用起来傻瓜化,直接用API就可以绘图,但是如果想实现高级特性的话,没有集成Shader编译器,需要先行编译或者使用D3DX库编译。
DirectX 10去掉了用API直接画图的功能,但是集成了Shader编译器,加入了Geometry Shader,同时分离了DXGI,用起来稍显复杂,初始化的复杂度增加了。
DirectX 11是基于DirectX 10小幅改进的版本,加上很多功能,包括Tessellation和DirectCompute以及CommandList。但同时,DirectX 11分离了编译器,必须安装运行库(2010或之前)或者附带dll(2012或之后)才能使用,剥离了Effects11必须自己编译。但同时2012又剥离了D3DX成为DirectXTK、DirectXTex、DirectXMesh等数个开源库,需要自己编译。
DirectX 9.0需要配合GDI+出图,DirectX 10/11可以用Direct2D和DirectWrite出图。
一个更理想的DirectX 10框架程序
实现了窗口大小变化,而且使用WndProc而不是C++类管理生命周期
<code class="language-cpp">// main.cpp - 主文件 #undef UNICODE #define UNICODE 1 #include <windows.h> #include <d3d10.h> #include <xnamath.h> // <directxmath.h> for VS2012+ #pragma comment(lib, "d3d10.lib") HINSTANCE hInst; HWND hMainWnd; #define WM_APPIDLE (WM_APP + 10) struct WndData { ID3D10Device *dev; D3D10_DRIVER_TYPE dt; IDXGISwapChain *swpch; ID3D10RenderTargetView *rtv; ID3D10Texture2D *dsbuf; ID3D10DepthStencilView *dsv; }; HRESULT CreateRTV(HWND hWnd, WndData *data) { HRESULT hr = S_OK; ID3D10Texture2D *backbuf = NULL; hr = data->swpch->GetBuffer(0, __uuidof(ID3D10Texture2D), (void**)&backbuf); if (FAILED(hr)) return hr; hr = data->dev->CreateRenderTargetView(backbuf, NULL, &data->rtv); backbuf->Release(); return hr; } HRESULT CreateDSBufAndDSV(HWND hWnd, WndData *data, int width, int height) { HRESULT hr = S_OK; D3D10_TEXTURE2D_DESC dsbufdesc = { width, height, 1, 1, DXGI_FORMAT_D32_FLOAT, { 1, 0 }, D3D10_USAGE_DEFAULT, D3D10_BIND_DEPTH_STENCIL, 0, 0 }; hr = data->dev->CreateTexture2D(&dsbufdesc, NULL, &data->dsbuf); if (FAILED(hr)) return hr; D3D10_DEPTH_STENCIL_VIEW_DESC dsvdesc = { DXGI_FORMAT_D32_FLOAT, D3D10_DSV_DIMENSION_TEXTURE2D }; dsvdesc.Texture2D.MipSlice = 0; hr = data->dev->CreateDepthStencilView(data->dsbuf, &dsvdesc, &data->dsv); return hr; } void SetViewport(HWND hWnd, WndData *data, int width, int height) { D3D10_VIEWPORT vp = { 0, 0, width, height, 0.0f, 1.0f }; data->dev->RSSetViewports(1, &vp); } LRESULT CALLBACK WndProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam) { WndData *data = (WndData *)GetWindowLongPtr(hWnd, 0); if (msg == WM_CREATE) { data = (WndData *)HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof (WndData)); if (data == NULL) DestroyWindow(hWnd); SetWindowLongPtr(hWnd, 0, (LONG_PTR)data); RECT rc = { 0 }; GetClientRect(hWnd, &rc); int width = rc.right - rc.left; int height = rc.bottom - rc.top; DXGI_MODE_DESC mode = { width, height, { 60, 1 }, DXGI_FORMAT_R8G8B8A8_UNORM, DXGI_MODE_SCANLINE_ORDER_UNSPECIFIED, DXGI_MODE_SCALING_UNSPECIFIED, }; DXGI_SWAP_CHAIN_DESC swpchdesc = { mode, { 1, 0 }, DXGI_USAGE_RENDER_TARGET_OUTPUT, 1, hWnd, TRUE, DXGI_SWAP_EFFECT_DISCARD, 0 }; D3D10_DRIVER_TYPE drvtype[] = { D3D10_DRIVER_TYPE_HARDWARE, D3D10_DRIVER_TYPE_WARP, D3D10_DRIVER_TYPE_REFERENCE }; HRESULT hr = S_OK; for (int i = 0; i < sizeof drvtype / sizeof drvtype[0]; i++) { data->dt = drvtype[i]; hr = D3D10CreateDeviceAndSwapChain(NULL, data->dt, NULL, 0, D3D10_SDK_VERSION, &swpchdesc, &data->swpch, &data->dev); if (SUCCEEDED(hr)) break; } if (FAILED(hr)) DestroyWindow(hWnd); hr = CreateRTV(hWnd, data); if (FAILED(hr)) DestroyWindow(hWnd); hr = CreateDSBufAndDSV(hWnd, data, width, height); if (FAILED(hr)) DestroyWindow(hWnd); data->dev->OMSetRenderTargets(1, &data->rtv, data->dsv); SetViewport(hWnd, data, width, height); // TODO - create objects return 0; } if (msg == WM_DESTROY) { if (data != NULL) { if (data->dev) data->dev->ClearState(); if (data->dsv) data->dsv->Release(); if (data->dsbuf) data->dsbuf->Release(); if (data->rtv) data->rtv->Release(); if (data->swpch) data->swpch->Release(); if (data->dev) data->dev->Release(); HeapFree(GetProcessHeap(), 0, data); } PostQuitMessage(0); return 0; } if (data == NULL) return DefWindowProc(hWnd, msg, wParam, lParam); // 下边的消息都是需要data的 if (msg == WM_SIZE) { int width = LOWORD(lParam); int height = HIWORD(lParam); char buf[1024] = ""; wsprintfA(buf, "%d %d\r\n", width, height); OutputDebugStringA(buf); data->dev->ClearState(); data->rtv->Release(); data->rtv = NULL; data->dsv->Release(); data->dsv = NULL; data->dsbuf->Release(); data->dsbuf = NULL; HRESULT hr = data->swpch->ResizeBuffers(1, width, height, DXGI_FORMAT_R8G8B8A8_UNORM, 0); if (FAILED(hr)) DestroyWindow(hWnd); hr = CreateRTV(hWnd, data); if (FAILED(hr)) DestroyWindow(hWnd); hr = CreateDSBufAndDSV(hWnd, data, width, height); if (FAILED(hr)) DestroyWindow(hWnd); data->dev->OMSetRenderTargets(1, &data->rtv, data->dsv); SetViewport(hWnd, data, width, height); return 0; } if (msg == WM_APPIDLE) { float backcolor[4] = { 0.0f, 0.5f, 0.5f, 1.0f }; data->dev->ClearRenderTargetView(data->rtv, backcolor); data->dev->ClearDepthStencilView(data->dsv, D3D10_CLEAR_DEPTH, 1.0f, 0); // TODO - draw frames data->swpch->Present(0, 0); return 0; } return DefWindowProc(hWnd, msg, wParam, lParam); } int WINAPI WinMain( __in HINSTANCE hInstance, __in_opt HINSTANCE hPrevInstance, __in_opt LPSTR lpCmdLine, __in int nShowCmd ) { hInst = hInstance; WNDCLASSEX wcex = { sizeof wcex, CS_VREDRAW|CS_HREDRAW, WndProc, 0, sizeof (WndData *), hInstance, LoadIcon(NULL, IDI_APPLICATION), LoadCursor(NULL, IDC_ARROW), (HBRUSH)GetStockObject(NULL_BRUSH), NULL, L"MainWndClass", LoadIcon(NULL, IDI_APPLICATION), }; RegisterClassEx(&wcex); RECT rc = { 0, 0, 640, 480 }; AdjustWindowRect(&rc, WS_OVERLAPPEDWINDOW, FALSE); hMainWnd = CreateWindow(L"MainWndClass", L"Main Window", WS_OVERLAPPEDWINDOW, CW_USEDEFAULT, CW_USEDEFAULT, rc.right - rc.left, rc.bottom - rc.top, NULL, NULL, hInstance, NULL); ShowWindow(hMainWnd, nShowCmd); UpdateWindow(hMainWnd); MSG msg = { 0 }; while (msg.message != WM_QUIT) { if (PeekMessage(&msg, NULL, 0, 0, PM_REMOVE)) { TranslateMessage(&msg); DispatchMessage(&msg); } else { SendMessage(hMainWnd, WM_APPIDLE, 0, 0); } } return 0; } </directxmath.h></xnamath.h></d3d10.h></windows.h></code>
时段 | 个数 |
---|---|
{{f.startingTime}}点 - {{f.endTime}}点 | {{f.fileCount}} |