1. 创建Direct实例
HRESULT InitDevice()
{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 _DEBUGcreateDeviceFlags |= D3D11_CREATE_DEVICE_DEBUG;
#endifD3D_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_0,D3D_FEATURE_LEVEL_10_1,D3D_FEATURE_LEVEL_10_0,};UINT numFeatureLevels = ARRAYSIZE( featureLevels );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;for( UINT driverTypeIndex = 0; driverTypeIndex < numDriverTypes; driverTypeIndex++ ){g_driverType = driverTypes[driverTypeIndex];hr = D3D11CreateDeviceAndSwapChain( NULL, g_driverType, NULL, createDeviceFlags, featureLevels, numFeatureLevels,D3D11_SDK_VERSION, &sd, &g_pSwapChain, &g_pd3dDevice, &g_featureLevel, &g_pImmediateContext );if( SUCCEEDED( hr ) )break;}if( FAILED( hr ) )return hr;// Create a render target viewID3D11Texture2D* pBackBuffer = NULL;hr = g_pSwapChain->GetBuffer( 0, __uuidof( ID3D11Texture2D ), ( LPVOID* )&pBackBuffer );if( FAILED( hr ) )return hr;hr = g_pd3dDevice->CreateRenderTargetView( pBackBuffer, NULL, &g_pRenderTargetView );pBackBuffer->Release();if( FAILED( hr ) )return hr;g_pImmediateContext->OMSetRenderTargets( 1, &g_pRenderTargetView, NULL );// Setup the viewportD3D11_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 );return S_OK;
}
首先看这段源码,调用D3D11CreateDeviceAndSwapChain获取g_pSwapChain和g_pd3dDevice两个实例对D3D初始化。
//--------------------------------------------------------------------------------------
// Render the frame
//--------------------------------------------------------------------------------------
void Render()
{// Just clear the backbufferfloat ClearColor[4] = { 0.0f, 0.125f, 0.3f, 1.0f }; //red,green,blue,alphag_pImmediateContext->ClearRenderTargetView( g_pRenderTargetView, ClearColor );g_pSwapChain->Present( 0, 0 );
}//--------------------------------------------------------------------------------------
// Clean up the objects we've created
//--------------------------------------------------------------------------------------
void CleanupDevice()
{if( g_pImmediateContext ) g_pImmediateContext->ClearState();if( g_pRenderTargetView ) g_pRenderTargetView->Release();if( g_pSwapChain ) g_pSwapChain->Release();if( g_pImmediateContext ) g_pImmediateContext->Release();if( g_pd3dDevice ) g_pd3dDevice->Release();
}
这两段分别进行释放内存和渲染操作。
2. 生成3D立方体
HRESULT InitDevice()
{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 _DEBUGcreateDeviceFlags |= D3D11_CREATE_DEVICE_DEBUG;
#endifD3D_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_0,D3D_FEATURE_LEVEL_10_1,D3D_FEATURE_LEVEL_10_0,};UINT numFeatureLevels = ARRAYSIZE( featureLevels );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;for( UINT driverTypeIndex = 0; driverTypeIndex < numDriverTypes; driverTypeIndex++ ){g_driverType = driverTypes[driverTypeIndex];hr = D3D11CreateDeviceAndSwapChain( NULL, g_driverType, NULL, createDeviceFlags, featureLevels, numFeatureLevels,D3D11_SDK_VERSION, &sd, &g_pSwapChain, &g_pd3dDevice, &g_featureLevel, &g_pImmediateContext );if( SUCCEEDED( hr ) )break;}if( FAILED( hr ) )return hr;// Create a render target viewID3D11Texture2D* pBackBuffer = NULL;hr = g_pSwapChain->GetBuffer( 0, __uuidof( ID3D11Texture2D ), ( LPVOID* )&pBackBuffer );if( FAILED( hr ) )return hr;hr = g_pd3dDevice->CreateRenderTargetView( pBackBuffer, NULL, &g_pRenderTargetView );pBackBuffer->Release();if( FAILED( hr ) )return hr;g_pImmediateContext->OMSetRenderTargets( 1, &g_pRenderTargetView, NULL );// Setup the viewportD3D11_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 );// Compile the vertex shaderID3DBlob* pVSBlob = NULL;hr = CompileShaderFromFile( L"Tutorial04.fx", "VS", "vs_4_0", &pVSBlob );if( FAILED( hr ) ){MessageBox( NULL,L"The FX file cannot be compiled. Please run this executable from the directory that contains the FX file.", L"Error", MB_OK );return hr;}// Create the vertex shaderhr = g_pd3dDevice->CreateVertexShader( pVSBlob->GetBufferPointer(), pVSBlob->GetBufferSize(), NULL, &g_pVertexShader );if( FAILED( hr ) ){ pVSBlob->Release();return hr;}// Define the input layoutD3D11_INPUT_ELEMENT_DESC layout[] ={{ "POSITION", 0, DXGI_FORMAT_R32G32B32_FLOAT, 0, 0, D3D11_INPUT_PER_VERTEX_DATA, 0 },{ "COLOR", 0, DXGI_FORMAT_R32G32B32A32_FLOAT, 0, 12, D3D11_INPUT_PER_VERTEX_DATA, 0 },};UINT numElements = ARRAYSIZE( layout );// Create the input layouthr = g_pd3dDevice->CreateInputLayout( layout, numElements, pVSBlob->GetBufferPointer(),pVSBlob->GetBufferSize(), &g_pVertexLayout );pVSBlob->Release();if( FAILED( hr ) )return hr;// Set the input layoutg_pImmediateContext->IASetInputLayout( g_pVertexLayout );// Compile the pixel shaderID3DBlob* pPSBlob = NULL;hr = CompileShaderFromFile( L"Tutorial04.fx", "PS", "ps_4_0", &pPSBlob );if( FAILED( hr ) ){MessageBox( NULL,L"The FX file cannot be compiled. Please run this executable from the directory that contains the FX file.", L"Error", MB_OK );return hr;}// Create the pixel shaderhr = g_pd3dDevice->CreatePixelShader( pPSBlob->GetBufferPointer(), pPSBlob->GetBufferSize(), NULL, &g_pPixelShader );pPSBlob->Release();if( FAILED( hr ) )return hr;// Create vertex bufferSimpleVertex vertices[] ={{ XMFLOAT3( -1.0f, 1.0f, -1.0f ), XMFLOAT4( 0.0f, 0.0f, 1.0f, 1.0f ) },{ XMFLOAT3( 1.0f, 1.0f, -1.0f ), XMFLOAT4( 0.0f, 1.0f, 0.0f, 1.0f ) },{ XMFLOAT3( 1.0f, 1.0f, 1.0f ), XMFLOAT4( 0.0f, 1.0f, 1.0f, 1.0f ) },{ XMFLOAT3( -1.0f, 1.0f, 1.0f ), XMFLOAT4( 1.0f, 0.0f, 0.0f, 1.0f ) },{ XMFLOAT3( -1.0f, -1.0f, -1.0f ), XMFLOAT4( 1.0f, 0.0f, 1.0f, 1.0f ) },{ XMFLOAT3( 1.0f, -1.0f, -1.0f ), XMFLOAT4( 1.0f, 1.0f, 0.0f, 1.0f ) },{ XMFLOAT3( 1.0f, -1.0f, 1.0f ), XMFLOAT4( 1.0f, 1.0f, 1.0f, 1.0f ) },{ XMFLOAT3( -1.0f, -1.0f, 1.0f ), XMFLOAT4( 0.0f, 0.0f, 0.0f, 1.0f ) },};D3D11_BUFFER_DESC bd;ZeroMemory( &bd, sizeof(bd) );bd.Usage = D3D11_USAGE_DEFAULT;bd.ByteWidth = sizeof( SimpleVertex ) * 8;bd.BindFlags = D3D11_BIND_VERTEX_BUFFER;bd.CPUAccessFlags = 0;D3D11_SUBRESOURCE_DATA InitData;ZeroMemory( &InitData, sizeof(InitData) );InitData.pSysMem = vertices;hr = g_pd3dDevice->CreateBuffer( &bd, &InitData, &g_pVertexBuffer );if( FAILED( hr ) )return hr;// Set vertex bufferUINT stride = sizeof( SimpleVertex );UINT offset = 0;g_pImmediateContext->IASetVertexBuffers( 0, 1, &g_pVertexBuffer, &stride, &offset );// Create index bufferWORD indices[] ={3,1,0,2,1,3,0,5,4,1,5,0,3,4,7,0,4,3,1,6,5,2,6,1,2,7,6,3,7,2,6,4,5,7,4,6,};bd.Usage = D3D11_USAGE_DEFAULT;bd.ByteWidth = sizeof( WORD ) * 36; // 36 vertices needed for 12 triangles in a triangle listbd.BindFlags = D3D11_BIND_INDEX_BUFFER;bd.CPUAccessFlags = 0;InitData.pSysMem = indices;hr = g_pd3dDevice->CreateBuffer( &bd, &InitData, &g_pIndexBuffer );if( FAILED( hr ) )return hr;// Set index bufferg_pImmediateContext->IASetIndexBuffer( g_pIndexBuffer, DXGI_FORMAT_R16_UINT, 0 );// Set primitive topologyg_pImmediateContext->IASetPrimitiveTopology( D3D11_PRIMITIVE_TOPOLOGY_TRIANGLELIST );// Create the constant bufferbd.Usage = D3D11_USAGE_DEFAULT;bd.ByteWidth = sizeof(ConstantBuffer);bd.BindFlags = D3D11_BIND_CONSTANT_BUFFER;bd.CPUAccessFlags = 0;hr = g_pd3dDevice->CreateBuffer( &bd, NULL, &g_pConstantBuffer );if( FAILED( hr ) )return hr;// Initialize the world matrixg_World = XMMatrixIdentity();// Initialize the view matrixXMVECTOR Eye = XMVectorSet( 0.0f, 1.0f, -5.0f, 0.0f );XMVECTOR At = XMVectorSet( 0.0f, 1.0f, 0.0f, 0.0f );XMVECTOR Up = XMVectorSet( 0.0f, 1.0f, 0.0f, 0.0f );g_View = XMMatrixLookAtLH( Eye, At, Up );// Initialize the projection matrixg_Projection = XMMatrixPerspectiveFovLH( XM_PIDIV2, width / (FLOAT)height, 0.01f, 100.0f );return S_OK;
}void Render()
{// Update our timestatic float t = 0.0f;if( g_driverType == D3D_DRIVER_TYPE_REFERENCE ){t += ( float )XM_PI * 0.0125f;}else{static DWORD dwTimeStart = 0;DWORD dwTimeCur = GetTickCount();if( dwTimeStart == 0 )dwTimeStart = dwTimeCur;t = ( dwTimeCur - dwTimeStart ) / 1000.0f;}//// Animate the cube//g_World = XMMatrixRotationY( t );//// Clear the back buffer//float ClearColor[4] = { 0.0f, 0.125f, 0.3f, 1.0f }; // red,green,blue,alphag_pImmediateContext->ClearRenderTargetView( g_pRenderTargetView, ClearColor );//// Update variables//ConstantBuffer cb;cb.mWorld = XMMatrixTranspose( g_World );cb.mView = XMMatrixTranspose( g_View );cb.mProjection = XMMatrixTranspose( g_Projection );g_pImmediateContext->UpdateSubresource( g_pConstantBuffer, 0, NULL, &cb, 0, 0 );//// Renders a triangle//g_pImmediateContext->VSSetShader( g_pVertexShader, NULL, 0 );g_pImmediateContext->VSSetConstantBuffers( 0, 1, &g_pConstantBuffer );g_pImmediateContext->PSSetShader( g_pPixelShader, NULL, 0 );g_pImmediateContext->DrawIndexed( 36, 0, 0 ); // 36 vertices needed for 12 triangles in a triangle list//// Present our back buffer to our front buffer//g_pSwapChain->Present( 0, 0 );
}
以上代码通过在Buffer中设置Triangle点,然后在Render函数中对Buffer的访问,生成12个triangles形成一个Cube。由于每个Vertex的位置不同形成了3D物体的效果。