DirectX11-Sample-Tutorial05-立方体的绘制和坐标系的变换

来源:互联网 发布:淘宝企业店铺入驻 编辑:程序博客网 时间:2024/06/03 22:44


本文实现的是立方体的绘制和坐标系变换。完整代码看这里。



Tutorial05.fx

//--------------------------------------------------------------------------------------// Constant Buffer Variables//--------------------------------------------------------------------------------------cbuffer CameraMatrix : register( b0 ){matrix world;matrix view;matrix projection;}//--------------------------------------------------------------------------------------struct VS_INPUT{    float4 Pos : POSITION;    float4 Color : COLOR;};struct PS_INPUT{    float4 Pos : SV_POSITION;    float4 Color : COLOR;};//--------------------------------------------------------------------------------------// Vertex Shader//--------------------------------------------------------------------------------------PS_INPUT VS( VS_INPUT input ){    PS_INPUT output = (PS_INPUT)0;    output.Pos = mul( input.Pos, world );    output.Pos = mul( output.Pos, view );    output.Pos = mul( output.Pos, projection );    output.Color = input.Color;        return output;}//--------------------------------------------------------------------------------------// Pixel Shader//--------------------------------------------------------------------------------------float4 PS( PS_INPUT input) : SV_Target{    return input.Color;}

main.cpp

#include <Windows.h>#include <tchar.h>#include <d3d11.h>#include <D3DX11.h>#include <D3Dcompiler.h>#include <xnamath.h>//全局结构,定义空间点和像素,相机矩阵,用于导入GPU中struct SimpleVertex{XMFLOAT3 Pos;//( x, y, z )XMFLOAT4 Color;//( B, G, R, A )};struct CameraMatrix{XMMATRIX world;//世界坐标系XMMATRIX view;//视图坐标系XMMATRIX projection;//投影坐标系};//全局变量HINSTANCE g_hInstance=NULL;//进程实例HWND g_hWnd=NULL;//窗口句柄D3D_DRIVER_TYPE g_driverType=D3D_DRIVER_TYPE_HARDWARE;//驱动类型D3D_FEATURE_LEVEL g_featureLevel=D3D_FEATURE_LEVEL_11_0;//SDK版本//利用函数D3D11CreateDeviceAndSwapChain()获取,设备、设备上下文、交换链ID3D11Device* g_device=NULL;//设备,使用完要releaseID3D11DeviceContext* g_deviceContext=NULL;//设备上下文IDXGISwapChain* g_swapChain=NULL;//利用设备上下文获取渲染目标视图ID3D11RenderTargetView* g_renderTargetView=NULL;//引入深度缓存和深度模板,解决遮挡问题ID3D11Texture2D* g_depthBuffer=NULL;ID3D11DepthStencilView* g_depthStencilView=NULL;//编译顶点着色器文件,获取g_vertexShaderID3D11VertexShader* g_vertexShader=NULL;//编译像素着色器文件,获取g_pixeShaderID3D11PixelShader* g_pixelShader=NULL;//引入顶点和颜色模型,创建顶点缓存//创建顶点分布和缓存ID3D11InputLayout* g_inputLayout=NULL;ID3D11Buffer* g_vertexBuffer=NULL;//创建顶点标号缓存ID3D11Buffer* g_indexBuffer=NULL;//创建相机矩阵,以及对应的缓存ID3D11Buffer* g_cameraMatrixBuffer=NULL;XMMATRIX g_world1;//世界坐标系1XMMATRIX g_world2;//世界坐标系2XMMATRIX g_view;//视图坐标系XMMATRIX g_projection;//投影坐标系//全局函数声明//初始化窗口HRESULT InitWindow( HINSTANCE hInstance, int nCmdShow );//初始化设备HRESULT InitDevice();HRESULT CompileShaderFromFile( WCHAR* filename, LPCSTR entrypoint, LPCSTR shaderModel, ID3DBlob** ppBlob );//编译着色器文件//接收消息,渲染窗口LRESULT CALLBACK WndProc( HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam );//窗口过程函数看,用于接收输入设备的消息void Render();//渲染窗口//关闭设备void ShutdownDevice();int WINAPI wWinMain( HINSTANCE hInstance, HINSTANCE hPreInstance, LPWSTR nCmdLine, int nCmdShow ){g_hInstance=hInstance;//初始化窗口if ( FAILED( InitWindow( g_hInstance, nCmdShow ) ) ){return 0;}//初始化设备if ( FAILED( InitDevice() ) ){ShutdownDevice();return 0;}//接收消息MSG msg={ 0 };while ( msg.message != WM_QUIT ){if ( PeekMessage( &msg, g_hWnd, 0, 0, PM_REMOVE ) )//接收任何消息(空或非空),直接返回,返回消息可能为空;而GetMessage是当接收到具体消息后才返回,都则等待{TranslateMessage( &msg );//翻译DispatchMessage( &msg );//分配给系统处理}else{Render();//当没有消息响应时,绘制窗口}}//关闭窗口后,显示完成,关闭设备ShutdownDevice();return 0;}//初始化窗口,获取窗口句柄g_hWndHRESULT InitWindow( HINSTANCE hInstance, int nCmdShow ){//初始化窗口类WNDCLASSEX wcex;wcex.cbClsExtra=0;wcex.cbSize=sizeof( WNDCLASSEX );wcex.cbWndExtra=0;wcex.hbrBackground=( HBRUSH )GetStockObject( BLACK_BRUSH );wcex.hCursor=LoadCursor( NULL, IDC_CROSS );wcex.hIcon=LoadIcon( hInstance, IDI_WINLOGO );wcex.hIconSm=wcex.hIcon;wcex.hInstance=hInstance;wcex.lpfnWndProc=WndProc;wcex.lpszClassName=_T("Tutorial05-Class");wcex.lpszMenuName=NULL;wcex.style=CS_HREDRAW | CS_VREDRAW;//注册窗口类if ( !RegisterClassEx( &wcex ) ){return E_FAIL;}//创建窗口RECT rc = { 0, 0, 640, 480 };AdjustWindowRect( &rc, WS_OVERLAPPEDWINDOW, FALSE );g_hWnd=CreateWindow( _T("Tutorial05-Class"), _T("Tutorial05-Window"), WS_OVERLAPPEDWINDOW,  CW_USEDEFAULT, CW_USEDEFAULT, rc.right - rc.left, rc.bottom - rc.top, NULL, NULL, hInstance, NULL );if ( !g_hWnd ){return E_FAIL;}//显示窗口ShowWindow( g_hWnd, nCmdShow );return S_OK;}//初始化设备,获取渲染需要的设备、设备上下文、缓存等HRESULT InitDevice(){HRESULT hResult;//----------------------------------------------------------------------------------------//创建交换链DXGI_SWAP_CHAIN_DESC swapChainDesc;ZeroMemory( &swapChainDesc, sizeof( swapChainDesc ) );UINT nScreenWidth=640;UINT nScreenHeight=480;UINT createDeviceFlags=0;D3D_DRIVER_TYPE driverTypes[]={ D3D_DRIVER_TYPE_HARDWARE,  D3D_DRIVER_TYPE_WARP,  D3D_DRIVER_TYPE_REFERENCE };UINT nNumDriverTypes=ARRAYSIZE( driverTypes );D3D_FEATURE_LEVEL featureLevels[]={ D3D_FEATURE_LEVEL_11_0,  D3D_FEATURE_LEVEL_10_1,  D3D_FEATURE_LEVEL_10_0 };UINT nNumFeatureLevels=ARRAYSIZE( featureLevels );swapChainDesc.BufferCount=1;//创建一个后备缓存swapChainDesc.BufferDesc.Format=DXGI_FORMAT_B8G8R8A8_UNORM;//一个像素占4个字节,32位swapChainDesc.BufferDesc.Width=nScreenWidth;//视频或后缓存的宽高swapChainDesc.BufferDesc.Height=nScreenHeight;swapChainDesc.BufferDesc.RefreshRate.Numerator=60;//后备缓存刷新率为1/60sswapChainDesc.BufferDesc.RefreshRate.Denominator=1;swapChainDesc.BufferUsage=DXGI_USAGE_RENDER_TARGET_OUTPUT;//交换链用途为 渲染目标视图//swapChainDesc.Flags=createDeviceFlags;swapChainDesc.OutputWindow=g_hWnd;//输出窗口句柄swapChainDesc.SampleDesc.Count=1;//去掉多重采样swapChainDesc.SampleDesc.Quality=0;swapChainDesc.Windowed=true;//采用窗口模式,当取false时,为全屏模式//遍历所设置的驱动,选取合适的创建交换链for ( UINT i=0; i<nNumDriverTypes; i++ ){g_driverType=driverTypes[ i ];hResult=D3D11CreateDeviceAndSwapChain( NULL,   g_driverType,   NULL,   createDeviceFlags,   featureLevels,   nNumFeatureLevels,   D3D11_SDK_VERSION,   &swapChainDesc,/*Input*/   &g_swapChain,/*Output*/   &g_device,/*Output*/   &g_featureLevel,/*Output*/   &g_deviceContext );/*Output*/if ( SUCCEEDED( hResult ) ){break;}}if ( FAILED( hResult ) ){return hResult;}//利用交换链获取后备缓存ID3D11Texture2D* backBuffer;hResult=g_swapChain->GetBuffer( 0, __uuidof( ID3D11Texture2D ), ( LPVOID* )&backBuffer );if ( FAILED( hResult ) ){return hResult;}//创建渲染目标视图hResult=g_device->CreateRenderTargetView( backBuffer,  NULL,  &g_renderTargetView );if ( backBuffer ){backBuffer->Release();backBuffer=NULL;}if ( FAILED( hResult ) ){return hResult;}//---------------------------------------------------------------------------------------------------//创建深度模板缓存D3D11_TEXTURE2D_DESC depthBuffer;ZeroMemory( &depthBuffer, sizeof( depthBuffer ) );depthBuffer.Width=nScreenWidth;//宽高depthBuffer.Height=nScreenHeight;depthBuffer.ArraySize=1;depthBuffer.BindFlags=D3D11_BIND_DEPTH_STENCIL;depthBuffer.CPUAccessFlags=0;depthBuffer.Format=DXGI_FORMAT_D24_UNORM_S8_UINT;depthBuffer.MipLevels=1;depthBuffer.MiscFlags=0;depthBuffer.SampleDesc.Count=1;//去掉多重采样depthBuffer.SampleDesc.Quality=0;depthBuffer.Usage=D3D11_USAGE_DEFAULT;hResult=g_device->CreateTexture2D( &depthBuffer,/*Input*/   NULL,   &g_depthBuffer );/*Output*/if ( FAILED(hResult) ){return hResult;}//创建深度目标视图D3D11_DEPTH_STENCIL_VIEW_DESC depthStencilViewDesc;ZeroMemory( &depthStencilViewDesc, sizeof( depthStencilViewDesc ) );depthStencilViewDesc.Format=depthBuffer.Format;depthStencilViewDesc.ViewDimension=D3D11_DSV_DIMENSION_TEXTURE2D;depthStencilViewDesc.Texture2D.MipSlice=0;hResult=g_device->CreateDepthStencilView( g_depthBuffer,/*Input*/  &depthStencilViewDesc,/*Input*/  &g_depthStencilView );/*Output*/if ( FAILED( hResult ) ){return hResult;}g_deviceContext->OMSetRenderTargets( 1, &g_renderTargetView, g_depthStencilView );D3D11_VIEWPORT viewpoint;viewpoint.Width=(FLOAT)nScreenWidth;viewpoint.Height=(FLOAT)nScreenHeight;viewpoint.MinDepth=0.0f;viewpoint.MaxDepth=1.0f;viewpoint.TopLeftX=0;viewpoint.TopLeftY=0;g_deviceContext->RSSetViewports( 1, &viewpoint );//---------------------------------------------------------------------------------------------------//编译顶点着色器ID3DBlob* pVSBlob;hResult=CompileShaderFromFile( _T("Tutorial05.fx"),/*Input*/   "VS",/*Input*/   "vs_4_0",/*Input*/   &pVSBlob );/*Output*/if ( FAILED(hResult) ){return hResult;}//创建顶点着色器hResult=g_device->CreateVertexShader( pVSBlob->GetBufferPointer(),/*Input*/  pVSBlob->GetBufferSize(),/*Input*/  NULL,/*Input*/  &g_vertexShader );/*Output*/if ( FAILED(hResult) ){pVSBlob->Release();pVSBlob=NULL;return hResult;}//初始化布局D3D11_INPUT_ELEMENT_DESC inputLayoutDesc[]={{"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 nNumElements=ARRAYSIZE( inputLayoutDesc );//创建输入布局hResult=g_device->CreateInputLayout( inputLayoutDesc,/*Input*/ nNumElements,/*Input*/ pVSBlob->GetBufferPointer(),/*Input*/ pVSBlob->GetBufferSize(),/*Input*/ &g_inputLayout );/*Output*///先释放pVSBlobif ( pVSBlob ){pVSBlob->Release();pVSBlob=NULL;}if ( FAILED( hResult ) ){return hResult;}//设置布局g_deviceContext->IASetInputLayout( g_inputLayout );//编译像素着色器ID3DBlob* pPSBlob;hResult=CompileShaderFromFile( _T("Tutorial05.fx"),   "PS",   "ps_4_0",   &pPSBlob );if ( FAILED( hResult ) ){return hResult;}//创建像素着色器hResult=g_device->CreatePixelShader( pPSBlob->GetBufferPointer(), pPSBlob->GetBufferSize(), NULL, &g_pixelShader );//直接释放pPSBlobif ( pPSBlob ){pPSBlob->Release();pPSBlob=NULL;}if ( FAILED( hResult ) ){return hResult;}//-------------------------------------------------------------------------------------//创建顶点缓存(8个点,6个矩形面,12个三角面)SimpleVertex 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 backBufferDesc;ZeroMemory( &backBufferDesc, sizeof(backBufferDesc) );backBufferDesc.Usage=D3D11_USAGE_DEFAULT;backBufferDesc.ByteWidth=sizeof( SimpleVertex ) * 8;backBufferDesc.BindFlags=D3D11_BIND_VERTEX_BUFFER;backBufferDesc.CPUAccessFlags=0;D3D11_SUBRESOURCE_DATA initData;ZeroMemory( &initData, sizeof( initData ) );initData.pSysMem=vertices;//创建后备缓存hResult=g_device->CreateBuffer( &backBufferDesc,&initData,&g_vertexBuffer );/*Output*/if ( FAILED( hResult ) ){return hResult;}UINT stride=sizeof( SimpleVertex );UINT offset=0;g_deviceContext->IASetVertexBuffers( 0, 1, &g_vertexBuffer, &stride, &offset );//创建索引缓存WORD 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,};D3D11_BUFFER_DESC indicesBufferDesc;ZeroMemory( &indicesBufferDesc, sizeof(indicesBufferDesc) );indicesBufferDesc.Usage=D3D11_USAGE_DEFAULT;indicesBufferDesc.ByteWidth=sizeof( WORD ) * 36;/*12个三角面片,12*3个点*/indicesBufferDesc.BindFlags=D3D11_BIND_INDEX_BUFFER;indicesBufferDesc.CPUAccessFlags=0;initData.pSysMem=indices;hResult=g_device->CreateBuffer( &indicesBufferDesc,&initData,&g_indexBuffer );/*Output*/if ( FAILED( hResult ) ){return hResult;}//设置索引缓存g_deviceContext->IASetIndexBuffer( g_indexBuffer,   DXGI_FORMAT_R16_UINT,   0 );g_deviceContext->IASetPrimitiveTopology( D3D11_PRIMITIVE_TOPOLOGY_TRIANGLELIST );//初始化常缓存描述,用于存储于相机矩阵相关的数据D3D11_BUFFER_DESC constantBufferDesc;ZeroMemory( &constantBufferDesc, sizeof(constantBufferDesc) );constantBufferDesc.Usage=D3D11_USAGE_DEFAULT;constantBufferDesc.ByteWidth=sizeof( CameraMatrix );constantBufferDesc.BindFlags=D3D11_BIND_CONSTANT_BUFFER;constantBufferDesc.CPUAccessFlags=0;//创建常缓存hResult=g_device->CreateBuffer( &constantBufferDesc,NULL,&g_cameraMatrixBuffer );if ( FAILED( hResult ) ){return hResult;}//初始化相机矩阵g_world1=XMMatrixIdentity();g_world2=XMMatrixIdentity();XMVECTOR 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 );g_projection = XMMatrixPerspectiveFovLH( XM_PIDIV2, nScreenWidth / (FLOAT)nScreenHeight, 0.01f, 100.0f );return S_OK;}HRESULT CompileShaderFromFile( WCHAR* filename, LPCSTR entrypoint, LPCSTR shaderModel, ID3DBlob** ppBlob ){HRESULT hResult;ID3DBlob* pErrorBlob;hResult=D3DX11CompileFromFile( filename,   NULL,   NULL,   entrypoint,   shaderModel,   D3DCOMPILE_ENABLE_STRICTNESS,   0,   NULL,   ppBlob,/*Output*/   &pErrorBlob,/*Output*/   NULL );if ( FAILED(hResult) ){if ( pErrorBlob != NULL ){OutputDebugStringA( (char*)pErrorBlob->GetBufferPointer() );}else{pErrorBlob->Release();pErrorBlob=NULL;}return hResult;}if ( pErrorBlob ){pErrorBlob->Release();pErrorBlob=NULL;}return S_OK;}void ShutdownDevice(){if ( g_deviceContext ){g_deviceContext->ClearState();}if ( g_cameraMatrixBuffer ){g_cameraMatrixBuffer->Release();g_cameraMatrixBuffer=NULL;}if ( g_vertexBuffer ){g_vertexBuffer->Release();g_vertexBuffer=NULL;}if ( g_indexBuffer ){g_indexBuffer->Release();g_indexBuffer=NULL;}if ( g_inputLayout ){g_inputLayout->Release();g_inputLayout=NULL;}if ( g_vertexShader ){g_vertexShader->Release();g_vertexShader=NULL;}if ( g_pixelShader ){g_pixelShader->Release();g_pixelShader=NULL;}if ( g_depthBuffer ){g_depthBuffer->Release();g_depthBuffer=NULL;}if ( g_depthStencilView ){g_depthStencilView->Release();g_depthStencilView=NULL;}if ( g_renderTargetView ){g_renderTargetView->Release();g_renderTargetView=NULL;}if ( g_swapChain ){g_swapChain->Release();g_swapChain=NULL;}if ( g_deviceContext ){g_deviceContext->Release();g_deviceContext=NULL;}if ( g_device ){g_device->Release();g_device=NULL;}return ;}LRESULT CALLBACK WndProc( HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam ){PAINTSTRUCT ps;HDC hdc;switch( uMsg ){case WM_PAINT:hdc = BeginPaint( hWnd, &ps );EndPaint( hWnd, &ps );break;case WM_DESTROY:PostQuitMessage( 0 );break;default:return DefWindowProc( hWnd, uMsg, wParam, lParam );}return 0;}void Render(){//-----------------------------------------------------------------------------------------//清除背景颜色float ClearColor[4]={ 0.0f, 0.125f, 0.3f, 1.0f };g_deviceContext->ClearRenderTargetView( g_renderTargetView, ClearColor );g_deviceContext->ClearDepthStencilView( g_depthStencilView, D3D11_CLEAR_DEPTH, 1.0f, 0 );//----------------------------------------------------------------------------------------//设置变换矩阵//设定选择角度变换规则static 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;}g_world1=XMMatrixRotationY( t );//第一个模型,绕y轴旋转,角度间隔为tXMMATRIX mSpin = XMMatrixRotationZ( -t );XMMATRIX mOrbit = XMMatrixRotationY( -t * 2.0f );//绕原来的Y轴旋转,但是旋转速度加速,旋转方向为反向XMMATRIX mTranslate = XMMatrixTranslation( -4.0f, 0.0f, 0.0f );//平移XMMATRIX mScale = XMMatrixScaling( 0.3f, 0.3f, 0.3f );//尺度,缩小g_world2=mScale * mSpin * mTranslate * mOrbit;//第一个模型:填充相机矩阵CameraMatrix cm1;cm1.world=XMMatrixTranspose( g_world1 );cm1.view=XMMatrixTranspose( g_view );cm1.projection=XMMatrixTranspose( g_projection );g_deviceContext->UpdateSubresource( g_cameraMatrixBuffer,/*Output*/0,NULL,&cm1,0,0 );//渲染第一个模型g_deviceContext->VSSetShader( g_vertexShader, NULL, 0 );//顶点着色器关联g_deviceContext->VSSetConstantBuffers( 0, 1, &g_cameraMatrixBuffer );//顶点对应相机矩阵关联g_deviceContext->PSSetShader( g_pixelShader, NULL, 0 );//像素着色器关联。/*只需关联一次,后面可以通过UpdateSubresource改变参数*/g_deviceContext->DrawIndexed( 36, 0, 0 );//绘制36个顶点//第二个模型:填充相机矩阵CameraMatrix cm2;cm2.world=XMMatrixTranspose( g_world2 );cm2.view=XMMatrixTranspose( g_view );cm2.projection=XMMatrixTranspose( g_projection );g_deviceContext->UpdateSubresource( g_cameraMatrixBuffer,/*Output*/0,NULL,&cm2,0,0 );//渲染第二个模型g_deviceContext->DrawIndexed( 36, 0, 0 );//-------------------------------------------------------------g_swapChain->Present( 0, 0 );return ;}



0 0
原创粉丝点击