Direct3D 11 学习笔记(二)
2018-01-22 16:13
330 查看
Direct3D 11 学习笔记(二)
DXUT
DXUT 能够提供一个简单的接口来处理 window 的创建,D3D device 的创建。在不使用 DXUT 框架的时候,我们需要自己调用 windows 的 API 来创建窗口:
// Register class WNDCLASSEX wcex; wcex.cbSize = sizeof( WNDCLASSEX ); wcex.style = CS_HREDRAW | CS_VREDRAW; wcex.lpfnWndProc = WndProc; wcex.cbClsExtra = 0; wcex.cbWndExtra = 0; wcex.hInstance = hInstance; wcex.hIcon = LoadIcon( hInstance, ( LPCTSTR )IDI_TUTORIAL1 ); wcex.hCursor = LoadCursor( nullptr, IDC_ARROW ); wcex.hbrBackground = ( HBRUSH )( COLOR_WINDOW + 1 ); wcex.lpszMenuName = nullptr; wcex.lpszClassName = L"TutorialWindowClass"; wcex.hIconSm = LoadIcon( wcex.hInstance, ( LPCTSTR )IDI_TUTORIAL1 ); if( !RegisterClassEx( &wcex ) ) return E_FAIL; // Create window g_hInst = hInstance; RECT rc = { 0, 0, 800, 600 }; AdjustWindowRect( &rc, WS_OVERLAPPEDWINDOW, FALSE ); g_hWnd = CreateWindow( L"TutorialWindowClass", L"Direct3D 11 Tutorial 7", WS_OVERLAPPED | WS_CAPTION | WS_SYSMENU | WS_MINIMIZEBOX, CW_USEDEFAULT, CW_USEDEFAULT, rc.right - rc.left, rc.bottom - rc.top, nullptr, nullptr, hInstance, nullptr ); if( !g_hWnd ) return E_FAIL; ShowWindow( g_hWnd, nCmdShow ); return S_OK;
需要自己调用 D3D11CreateDeviceAndSwapChain 来创建 device 和 swap chain,代码如下:
HRESULT hr = S_OK; RECT rc; GetClientRect( g_hWnd, &rc ); UINT width = rc.right - rc.left; UINT height = rc.bottom - rc.top; UINT createDeviceFlags = 0; #ifdef _DEBUG createDeviceFlags |= D3D11_CREATE_DEVICE_DEBUG; #endif D3D_DRIVER_TYPE driverTypes[] = { D3D_DRIVER_TYPE_HARDWARE, D3D_DRIVER_TYPE_WARP, D3D_DRIVER_TYPE_REFERENCE, }; UINT numDriverTypes = ARRAYSIZE( driverTypes ); D3D_FEATURE_LEVEL featureLevels[] = { D3D_FEATURE_LEVEL_11_1, D3D_FEATURE_LEVEL_11_0, D3D_FEATURE_LEVEL_10_1, D3D_FEATURE_LEVEL_10_0, }; UINT numFeatureLevels = ARRAYSIZE( featureLevels ); for( UINT driverTypeIndex = 0; driverTypeIndex < numDriverTypes; driverTypeIndex++ ) { g_driverType = driverTypes[driverTypeIndex]; hr = D3D11CreateDevice( nullptr, g_driverType, nullptr, createDeviceFlags, featureLevels, numFeatureLevels, D3D11_SDK_VERSION, &g_pd3dDevice, &g_featureLevel, &g_pImmediateContext ); if ( hr == E_INVALIDARG ) { // DirectX 11.0 platforms will not recognize D3D_FEATURE_LEVEL_11_1 so we need to retry without it hr = D3D11CreateDevice( nullptr, g_driverType, nullptr, createDeviceFlags, &featureLevels[1], numFeatureLevels - 1, D3D11_SDK_VERSION, &g_pd3dDevice, &g_featureLevel, &g_pImmediateContext ); } if( SUCCEEDED( hr ) ) break; } if( FAILED( hr ) ) return hr; // Obtain DXGI factory from device (since we used nullptr for pAdapter above) IDXGIFactory1* dxgiFactory = nullptr; { IDXGIDevice* dxgiDevice = nullptr; hr = g_pd3dDevice->QueryInterface( __uuidof(IDXGIDevice), reinterpret_cast<void**>(&dxgiDevice) ); if (SUCCEEDED(hr)) { IDXGIAdapter* adapter = nullptr; hr = dxgiDevice->GetAdapter(&adapter); if (SUCCEEDED(hr)) { hr = adapter->GetParent( __uuidof(IDXGIFactory1), reinterpret_cast<void**>(&dxgiFactory) ); adapter->Release(); } dxgiDevice->Release(); } } if (FAILED(hr)) return hr; // Create swap chain IDXGIFactory2* dxgiFactory2 = nullptr; hr = dxgiFactory->QueryInterface( __uuidof(IDXGIFactory2), reinterpret_cast<void**>(&dxgiFactory2) ); if ( dxgiFactory2 ) { // DirectX 11.1 or later hr = g_pd3dDevice->QueryInterface( __uuidof(ID3D11Device1), reinterpret_cast<void**>(&g_pd3dDevice1) ); if (SUCCEEDED(hr)) { (void) g_pImmediateContext->QueryInterface( __uuidof(ID3D11DeviceContext1), reinterpret_cast<void**>(&g_pImmediateContext1) ); } DXGI_SWAP_CHAIN_DESC1 sd; ZeroMemory(&sd, sizeof(sd)); sd.Width = width; sd.Height = height; sd.Format = DXGI_FORMAT_R8G8B8A8_UNORM; sd.SampleDesc.Count = 1; sd.SampleDesc.Quality = 0; sd.BufferUsage = DXGI_USAGE_RENDER_TARGET_OUTPUT; sd.BufferCount = 1; hr = dxgiFactory2->CreateSwapChainForHwnd( g_pd3dDevice, g_hWnd, &sd, nullptr, nullptr, &g_pSwapChain1 ); if (SUCCEEDED(hr)) { hr = g_pSwapChain1->QueryInterface( __uuidof(IDXGISwapChain), reinterpret_cast<void**>(&g_pSwapChain) ); } dxgiFactory2->Release(); } else { // DirectX 11.0 systems DXGI_SWAP_CHAIN_DESC sd; ZeroMemory(&sd, sizeof(sd)); sd.BufferCount = 1; sd.BufferDesc.Width = width; sd.BufferDesc.Height = 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 = g_hWnd; sd.SampleDesc.Count = 1; sd.SampleDesc.Quality = 0; sd.Windowed = TRUE; hr = dxgiFactory->CreateSwapChain( g_pd3dDevice, &sd, &g_pSwapChain ); } // Note this tutorial doesn't handle full-screen swapchains so we block the ALT+ENTER shortcut dxgiFactory->MakeWindowAssociation( g_hWnd, DXGI_MWA_NO_ALT_ENTER ); dxgiFactory->Release(); if (FAILED(hr)) return hr; // Create a render target view ID3D11Texture2D* pBackBuffer = nullptr; hr = g_pSwapChain->GetBuffer( 0, __uuidof( ID3D11Texture2D ), reinterpret_cast<void**>( &pBackBuffer ) ); if( FAILED( hr ) ) return hr; hr = g_pd3dDevice->CreateRenderTargetView( pBackBuffer, nullptr, &g_pRenderTargetView ); pBackBuffer->Release(); if( FAILED( hr ) ) return hr; // Create depth stencil texture D3D11_TEXTURE2D_DESC descDepth; ZeroMemory( &descDepth, sizeof(descDepth) ); descDepth.Width = width; descDepth.Height = height; descDepth.MipLevels = 1; descDepth.ArraySize = 1; descDepth.Format = DXGI_FORMAT_D24_UNORM_S8_UINT; descDepth.SampleDesc.Count = 1; descDepth.SampleDesc.Quality = 0; descDepth.Usage = D3D11_USAGE_DEFAULT; descDepth.BindFlags = D3D11_BIND_DEPTH_STENCIL; descDepth.CPUAccessFlags = 0; descDepth.MiscFlags = 0; hr = g_pd3dDevice->CreateTexture2D( &descDepth, nullptr, &g_pDepthStencil ); if( FAILED( hr ) ) return hr; // Create the depth stencil view D3D11_DEPTH_STENCIL_VIEW_DESC descDSV; ZeroMemory( &descDSV, sizeof(descDSV) ); descDSV.Format = descDepth.Format; descDSV.ViewDimension = D3D11_DSV_DIMENSION_TEXTURE2D; descDSV.Texture2D.MipSlice = 0; hr = g_pd3dDevice->CreateDepthStencilView( g_pDepthStencil, &descDSV, &g_pDepthStencilView ); if( FAILED( hr ) ) return hr; g_pImmediateContext->OMSetRenderTargets( 1, &g_pRenderTargetView, g_pDepthStencilView ); // Setup the viewport D3D11_VIEWPORT vp; vp.Width = (FLOAT)width; vp.Height = (FLOAT)height; vp.MinDepth = 0.0f; vp.MaxDepth = 1.0f; vp.TopLeftX = 0; vp.TopLeftY = 0; g_pImmediateContext->RSSetViewports( 1, &vp );
我们使用 DXUT 框架之后,只需要使用如下代码就可以完成上述内容:
// Parse the command line, show msgboxes on error, no extra command line params DXUTInit( true, true, nullptr ); DXUTSetCursorSettings( true, true ); // Show the cursor and clip it when in full screen DXUTCreateWindow( L"Tutorial08" ); // Only require 10-level hardware or later DXUTCreateDevice( D3D_FEATURE_LEVEL_10_0, true, 800, 600 );
在上述代码完成后,我们直接使用 DXUTMainLoop() 就可以进入 DXUT 的循环,通过 DXUT 提供的回调函数来控制我们的渲染过程,回调函数如下:
// Set general DXUT callbacks DXUTSetCallbackFrameMove( OnFrameMove ); DXUTSetCallbackKeyboard( OnKeyboard ); DXUTSetCallbackMsgProc( MsgProc ); DXUTSetCallbackDeviceChanging( ModifyDeviceSettings ); DXUTSetCallbackDeviceRemoved( OnDeviceRemoved ); // Set the D3D11 DXUT callbacks. Remove these sets if the app doesn't need to support D3D11 DXUTSetCallbackD3D11DeviceAcceptable( IsD3D11DeviceAcceptable ); DXUTSetCallbackD3D11DeviceCreated( OnD3D11CreateDevice ); DXUTSetCallbackD3D11SwapChainResized( OnD3D11ResizedSwapChain ); DXUTSetCallbackD3D11FrameRender( OnD3D11FrameRender ); DXUTSetCallbackD3D11SwapChainReleasing( OnD3D11ReleasingSwapChain ); DXUTSetCallbackD3D11DeviceDestroyed( OnD3D11DestroyDevice );
上述代码来源于微软 D3D11 官方教程源码。
相关文章推荐
- Introduction to 3D Game Programming with DirectX 11学习笔记 6 Direct3D中的绘制(四)渲染状态
- Direct3D 11 学习笔记(一)
- DirectX 11游戏编程学习笔记之5: 第4章Direct3D Initialization(Direct3D初始化)
- Direct3D 9学习笔记(11)网格(Mesh)2
- Introduction to 3D Game Programming with DirectX 11学习笔记 4.2Direct3D进行初始化
- Introduction to 3D Game Programming with DirectX 11学习笔记 6 Direct3D中的绘制(二)顶点着色器
- 【DirectX 11 SDK 学习笔记】Direct3D 11 Basics
- DirectX 11游戏编程学习笔记之8: 第6章Drawing in Direct3D(在Direct3D中绘制)(习题解答)
- DirectX 11游戏编程学习笔记之7: 第6章Drawing in Direct3D(在Direct3D中绘制)(重点回顾+勘误)
- Introduction to 3D Game Programming with DirectX 11学习笔记 6 Direct3D中的绘制(一)
- Introduction to 3D Game Programming with DirectX 11学习笔记 6 Direct3D中的绘制(三)像素着色器
- DirectX 11游戏编程学习笔记之8: 第6章Drawing in Direct3D(在Direct3D中绘制)(习题解答)
- 黑马程序员_JAVA 学习笔记24 WEB篇11
- (Java学习笔记11) 快速查询
- ps学习笔记 11,12 路径,色彩调整
- ASP.Net学习笔记 11/5
- Opencv2系列学习笔记11(霍尔夫变换)
- 《Python 黑帽子》学习笔记 - SSH 远程登录 - Day 11
- PHP学习笔记11——文件处理
- TinyOS学习笔记11-节点与计算机利用串口通信2-BaseStation