Advertisement
Guest User

DirectX 11 basics

a guest
Jan 7th, 2011
215
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 11.72 KB | None | 0 0
  1. #include <stdio.h>
  2. #include <stdlib.h>
  3. #include <windows.h>
  4. #include <d3d11.h>
  5. #include <d3dx11.h>
  6. #include <xnamath.h>
  7.  
  8. #define SAFE_RELEASE(p) {if(p) p->Release(); p = NULL;}
  9.  
  10. HINSTANCE g_hInstance = NULL;
  11. HWND g_hwnd = NULL;
  12. LPTSTR g_className = TEXT("ScratchDX11 Window Class");
  13. int g_width = 640, g_height = 480;
  14.  
  15. ID3D11Device * g_device = NULL;
  16. IDXGIFactory1 * g_factory = NULL;
  17. IDXGIAdapter1 * g_adapter = NULL;
  18. IDXGIOutput * g_output = NULL;
  19. IDXGISwapChain * g_swapChain = NULL;
  20. ID3D11DeviceContext * g_deviceContext = NULL;
  21. ID3D11RenderTargetView * g_rtv = NULL;
  22. ID3D11Buffer * g_vb = NULL;
  23. ID3D11Buffer * g_ib = NULL;
  24. ID3D11Buffer * g_vertexCb = NULL;
  25. ID3D11VertexShader * g_vs = NULL;
  26. ID3D11PixelShader * g_ps = NULL;
  27. ID3D11InputLayout* g_il = NULL;
  28.    
  29. HRESULT InitDevice();
  30. HRESULT InitGeometry();
  31. HRESULT InitShaders();
  32. void Render();
  33. void CleanUp();
  34. void ShowError(DWORD code);
  35. BOOL InitWindow();
  36. LRESULT CALLBACK MyWindowProc(HWND, UINT, WPARAM, LPARAM);
  37.  
  38. typedef struct
  39. {
  40.     XMFLOAT4 pos;
  41.     XMFLOAT4 col;
  42. } SIMPLE_VERTEX;
  43.  
  44. XMMATRIX g_mWorld;
  45. XMMATRIX g_mView;
  46. XMMATRIX g_mProjection;
  47.  
  48. typedef struct
  49. {
  50.     XMMATRIX world, view, projection;
  51.     XMFLOAT4 data;
  52. } VERTEX_CB;
  53.  
  54. HRESULT InitDevice()
  55. {
  56.     HRESULT hr = S_OK;
  57.  
  58.     hr = CreateDXGIFactory1(__uuidof(g_factory), (void**)&g_factory);
  59.     if(FAILED(hr))
  60.         return hr;
  61.  
  62.     hr = g_factory->EnumAdapters1(0, &g_adapter);
  63.     if(FAILED(hr))
  64.         return hr;
  65.    
  66.     hr = g_adapter->EnumOutputs(0, &g_output);
  67.     if(FAILED(hr))
  68.         return hr;
  69.  
  70. #ifdef DEBUG
  71.     D3D11_CREATE_DEVICE_FLAG createFlags = D3D11_CREATE_DEVICE_DEBUG;
  72. #else
  73.     D3D11_CREATE_DEVICE_FLAG createFlags = (D3D11_CREATE_DEVICE_FLAG)0;
  74. #endif
  75.  
  76.     hr = D3D11CreateDevice(
  77.             g_adapter,
  78.             D3D_DRIVER_TYPE_UNKNOWN,
  79.             NULL,
  80.             createFlags,
  81.             NULL,
  82.             0,
  83.             D3D11_SDK_VERSION,
  84.             &g_device,
  85.             NULL,
  86.             &g_deviceContext);
  87.     if(FAILED(hr))
  88.         return hr;
  89.  
  90.     DXGI_MODE_DESC md;
  91.     md.Format = DXGI_FORMAT_R8G8B8A8_UNORM;
  92.     md.Width = g_width;
  93.     md.Height = g_height;
  94.     md.RefreshRate.Numerator = 75;
  95.     md.RefreshRate.Denominator = 1;
  96.     md.Scaling = DXGI_MODE_SCALING_UNSPECIFIED;
  97.     md.ScanlineOrdering = DXGI_MODE_SCANLINE_ORDER_UNSPECIFIED;
  98.    
  99.     hr = g_output->FindClosestMatchingMode(&md, &md, g_device);
  100.     if(FAILED(hr))
  101.         return hr;
  102.    
  103.     DXGI_SWAP_CHAIN_DESC sd;
  104.     SecureZeroMemory(&sd, sizeof(sd)); 
  105.     sd.BufferCount=2;
  106.     sd.BufferDesc = md;
  107.     sd.BufferUsage = DXGI_USAGE_RENDER_TARGET_OUTPUT;
  108.     sd.OutputWindow = g_hwnd;
  109.     sd.SampleDesc.Count = 4;
  110.     sd.SampleDesc.Quality = D3D11_STANDARD_MULTISAMPLE_PATTERN;
  111.     sd.Windowed = TRUE;
  112.     sd.SwapEffect = DXGI_SWAP_EFFECT_DISCARD;
  113.  
  114.     hr = g_factory->CreateSwapChain(g_device, &sd, &g_swapChain);
  115.  
  116.     if(FAILED(hr))
  117.         return hr;
  118.  
  119.     g_swapChain->ResizeTarget(&md);
  120.  
  121.     ID3D11Texture2D * buffer;
  122.     hr = g_swapChain->GetBuffer(0, __uuidof(buffer), (void**)&buffer);
  123.     if(FAILED(hr))
  124.         return hr;
  125.  
  126.     hr = g_device->CreateRenderTargetView(buffer, NULL, &g_rtv);
  127.     if(FAILED(hr))
  128.     {
  129.         buffer->Release();
  130.         return hr;
  131.     }
  132.        
  133.     buffer->Release();
  134.  
  135.     g_deviceContext->OMSetRenderTargets(1, &g_rtv, NULL);
  136.        
  137.     D3D11_VIEWPORT vp;
  138.     vp.Height = (FLOAT)g_height;
  139.     vp.Width = (FLOAT)g_width;
  140.     vp.MinDepth = 0.0f;
  141.     vp.MaxDepth = 1.0f;
  142.     vp.TopLeftX = 0.0f;
  143.     vp.TopLeftY = 0.0f;
  144.  
  145.     g_deviceContext->RSSetViewports(1, &vp);
  146.  
  147.     return hr;
  148. }
  149.  
  150. HRESULT InitGeometry()
  151. {
  152.     HRESULT hr = S_OK;
  153.  
  154.     SIMPLE_VERTEX vertices[] =
  155.     {
  156.         { XMFLOAT4(-1.0f, -1.0f, -1.0f, 1.0f), XMFLOAT4(1.0f, 0.0f, 0.0f, 1.0f) },
  157.         { XMFLOAT4(-1.0f,  1.0f, -1.0f, 1.0f), XMFLOAT4(0.0f, 1.0f, 0.0f, 1.0f) },
  158.         { XMFLOAT4( 1.0f,  1.0f, -1.0f, 1.0f), XMFLOAT4(0.0f, 0.0f, 1.0f, 1.0f) },
  159.         { XMFLOAT4( 1.0f, -1.0f, -1.0f, 1.0f), XMFLOAT4(1.0f, 1.0f, 1.0f, 1.0f) },
  160.         { XMFLOAT4( 1.0f, -1.0f, 1.0f, 1.0f), XMFLOAT4(1.0f, 0.0f, 0.0f, 1.0f) },
  161.         { XMFLOAT4( 1.0f,  1.0f, 1.0f, 1.0f), XMFLOAT4(0.0f, 1.0f, 0.0f, 1.0f) },
  162.         { XMFLOAT4(-1.0f,  1.0f, 1.0f, 1.0f), XMFLOAT4(0.0f, 0.0f, 1.0f, 1.0f) },
  163.         { XMFLOAT4(-1.0f, -1.0f, 1.0f, 1.0f), XMFLOAT4(1.0f, 1.0f, 1.0f, 1.0f) },
  164.        
  165.     };
  166.  
  167.     D3D11_BUFFER_DESC bd;
  168.     SecureZeroMemory(&bd, sizeof(bd));
  169.     bd.BindFlags = D3D11_BIND_VERTEX_BUFFER;
  170.     bd.ByteWidth = sizeof(vertices);
  171.     bd.StructureByteStride = sizeof(SIMPLE_VERTEX);
  172.     bd.Usage = D3D11_USAGE_DEFAULT;
  173.  
  174.     D3D11_SUBRESOURCE_DATA sd;
  175.     SecureZeroMemory(&sd, sizeof(sd));
  176.     sd.pSysMem = vertices;
  177.  
  178.     hr = g_device->CreateBuffer(&bd, &sd, &g_vb);
  179.     if(FAILED(hr))
  180.         return hr;
  181.    
  182.     DWORD indices[] =
  183.     {
  184.         0,1,2,
  185.         2,3,0,
  186.  
  187.         4,5,6,
  188.         6,7,4,
  189.  
  190.         1,6,5,
  191.         5,2,1,
  192.  
  193.         3,4,7,
  194.         7,0,3,
  195.  
  196.         7,6,1,
  197.         1,0,7,
  198.  
  199.         3,2,5,
  200.         5,4,3,
  201.     };
  202.  
  203.     bd.BindFlags = D3D11_BIND_INDEX_BUFFER;
  204.     bd.ByteWidth = sizeof(indices);
  205.     bd.StructureByteStride = sizeof(DWORD);
  206.    
  207.     sd.pSysMem = indices;
  208.  
  209.     hr = g_device->CreateBuffer(&bd, &sd, &g_ib);
  210.     if(FAILED(hr))
  211.         return hr;
  212.    
  213.     bd.BindFlags = D3D11_BIND_CONSTANT_BUFFER;
  214.     bd.ByteWidth = sizeof(VERTEX_CB);
  215.    
  216.     hr = g_device->CreateBuffer(&bd, NULL, &g_vertexCb);
  217.     if(FAILED(hr))
  218.         return hr;
  219.  
  220.     return hr;
  221. }
  222.  
  223. HRESULT InitShaders()
  224. {
  225.     HRESULT hr = S_OK;
  226.     ID3D10Blob * bc = NULL;
  227.     ID3D10Blob * err = NULL;
  228.  
  229.     hr = D3DX11CompileFromFile(
  230.             TEXT("../ScratchDX11.fx"),
  231.             NULL,
  232.             NULL,
  233.             "VS",
  234.             "vs_5_0",
  235.             0,
  236.             0,
  237.             NULL,
  238.             &bc,
  239.             &err,
  240.             NULL);
  241.  
  242.     if(FAILED(hr))
  243.     {
  244.         if(err)
  245.         {
  246.             MessageBoxA(NULL, (LPSTR)err->GetBufferPointer(), "Error", MB_ICONERROR);
  247.             err->Release();
  248.         }
  249.         else
  250.             ShowError(hr);
  251.         return hr;
  252.     }
  253.    
  254.     hr = g_device->CreateVertexShader(bc->GetBufferPointer(), bc->GetBufferSize(), NULL, &g_vs);
  255.    
  256.     if(FAILED(hr))
  257.     {
  258.         ShowError(hr);
  259.         bc->Release();
  260.         return hr;
  261.     }
  262.  
  263.     D3D11_INPUT_ELEMENT_DESC layout[] =
  264.     {
  265.         {"POSITION", 0, DXGI_FORMAT_R32G32B32A32_FLOAT, 0, 0, D3D11_INPUT_PER_VERTEX_DATA, 0},
  266.         {"COLOR", 0, DXGI_FORMAT_R32G32B32A32_FLOAT, 0, sizeof(XMFLOAT4), D3D11_INPUT_PER_VERTEX_DATA, 0},
  267.     };
  268.        
  269.     hr = g_device->CreateInputLayout(
  270.                         layout,
  271.                         sizeof(layout)/sizeof(D3D11_INPUT_ELEMENT_DESC),
  272.                         bc->GetBufferPointer(),
  273.                         bc->GetBufferSize(),
  274.                         &g_il);
  275.    
  276.     bc->Release();
  277.  
  278.     if(FAILED(hr))
  279.     {
  280.         ShowError(hr);
  281.         return hr;
  282.     }
  283.    
  284.     hr = D3DX11CompileFromFile(
  285.             TEXT("../ScratchDX11.fx"),
  286.             NULL,
  287.             NULL,
  288.             "PS",
  289.             "ps_5_0",
  290.             0,
  291.             0,
  292.             NULL,
  293.             &bc,
  294.             &err,
  295.             NULL);
  296.  
  297.     if(FAILED(hr))
  298.     {
  299.         if(err)
  300.         {
  301.             MessageBoxA(NULL, (LPSTR)err->GetBufferPointer(), "Error", MB_ICONERROR);
  302.             err->Release();
  303.         }
  304.         else
  305.             ShowError(hr);
  306.         return hr;
  307.     }
  308.    
  309.     hr = g_device->CreatePixelShader(bc->GetBufferPointer(), bc->GetBufferSize(), NULL, &g_ps);
  310.    
  311.     bc->Release();
  312.  
  313.     if(FAILED(hr))
  314.     {
  315.         ShowError(hr);
  316.         return hr;
  317.     }
  318.    
  319.     return hr;
  320. }
  321.  
  322. void Render()
  323. {
  324.     static float clearColor[4] = {0.0f, 0.5f, 1.0f, 1.0f};
  325.     g_deviceContext->ClearRenderTargetView(g_rtv, clearColor);
  326.  
  327.     static FLOAT t = 0.0f;
  328.     static DWORD timeStart = 0;
  329.     DWORD timeCur = GetTickCount();
  330.     if(0 == timeStart)
  331.         timeStart = timeCur;
  332.     t = (timeCur - timeStart)/1000.0f;
  333.  
  334.     UINT vbStride = sizeof(SIMPLE_VERTEX), vbOffset = 0;
  335.     g_deviceContext->IASetVertexBuffers(0, 1, &g_vb, &vbStride, &vbOffset);
  336.  
  337.     g_deviceContext->IASetIndexBuffer(g_ib, DXGI_FORMAT_R32_UINT, 0);
  338.  
  339.     g_deviceContext->IASetPrimitiveTopology(D3D11_PRIMITIVE_TOPOLOGY_TRIANGLELIST);
  340.  
  341.     g_deviceContext->IASetInputLayout(g_il);
  342.        
  343.     g_mView = XMMatrixLookAtLH(XMVectorSet(0.0f, 1.0f, -5.0f, 0.0f),
  344.                                XMVectorSet(0.0f, 0.0f, 0.0f, 0.0f),
  345.                                XMVectorSet(0.0f, 1.0f, 0.0f, 0.0f));
  346.     g_mProjection = XMMatrixPerspectiveFovLH(XM_PIDIV4, g_width/((FLOAT)g_height), 0.01f, 100.0f);
  347.     g_mWorld = XMMatrixRotationRollPitchYaw(t, 0.0f, t/2);
  348.  
  349.     VERTEX_CB cb =
  350.     {
  351.         XMMatrixTranspose(g_mWorld),
  352.         XMMatrixTranspose(g_mView),
  353.         XMMatrixTranspose(g_mProjection),
  354.         XMFLOAT4(t/2,rand()/1.0f/0x7fff,t,t)
  355.     };
  356.  
  357.     g_deviceContext->UpdateSubresource(g_vertexCb, 0, NULL, &cb, 0, 0);
  358.  
  359.     g_deviceContext->VSSetConstantBuffers(0, 1, &g_vertexCb);
  360.  
  361.     g_deviceContext->VSSetShader(g_vs, NULL, 0);
  362.  
  363.     g_deviceContext->PSSetShader(g_ps, NULL, 0);
  364.  
  365.     g_deviceContext->DrawIndexed(36, 0, 0);
  366.  
  367.     g_swapChain->Present(0, 0);
  368. }
  369.  
  370. void CleanUp()
  371. {  
  372.     if(g_deviceContext)
  373.         g_deviceContext->ClearState(); 
  374.     SAFE_RELEASE(g_factory);
  375.     SAFE_RELEASE(g_adapter);
  376.     SAFE_RELEASE(g_output);
  377.     SAFE_RELEASE(g_vs);
  378.     SAFE_RELEASE(g_ps);
  379.     SAFE_RELEASE(g_vertexCb);
  380.     SAFE_RELEASE(g_il);
  381.     SAFE_RELEASE(g_vb);
  382.     SAFE_RELEASE(g_ib);
  383.     SAFE_RELEASE(g_rtv);
  384.     SAFE_RELEASE(g_device);
  385.     SAFE_RELEASE(g_swapChain);
  386.     SAFE_RELEASE(g_deviceContext);
  387. }
  388.  
  389. void ShowError(DWORD code)
  390. {
  391.     LPWSTR buffer = NULL;
  392.     if(!FormatMessageW(
  393.         FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS,
  394.         NULL,
  395.         code,
  396.         0,
  397.         (LPWSTR)&buffer,
  398.         0,
  399.         NULL) ||
  400.         !buffer)
  401.     {
  402.         buffer = (LPWSTR)LocalAlloc(0, 150*sizeof(WCHAR));
  403.         swprintf_s(buffer, 150, L"Unidentified error: %08X(%I32u)", code);
  404.     }
  405.     MessageBoxW(NULL, buffer, L"Error", MB_ICONERROR);
  406.     LocalFree(buffer); 
  407. }
  408.  
  409. int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpcmdline, int nCmdShow)
  410. {
  411.     g_hInstance = hInstance;
  412.     if(!InitWindow())
  413.     {
  414.         ShowError(GetLastError());
  415.         return 1;
  416.     }
  417.     ShowWindow(g_hwnd, nCmdShow);
  418.     UpdateWindow(g_hwnd);
  419.  
  420.     HRESULT hr;
  421.     if(FAILED(hr = InitDevice()))
  422.     {
  423.         ShowError(hr);
  424.         CleanUp();
  425.         return 1;
  426.     }
  427.  
  428.     if(FAILED(hr = InitGeometry()))
  429.     {
  430.         ShowError(hr);
  431.         CleanUp();
  432.         return 1;
  433.     }
  434.  
  435.     if(FAILED(hr = InitShaders()))
  436.     {
  437.         CleanUp();
  438.         return 1;
  439.     }
  440.  
  441.     MSG msg;
  442.     do
  443.     {
  444.         if(PeekMessage(&msg, NULL, 0, 0, PM_REMOVE))
  445.         {
  446.             TranslateMessage(&msg);
  447.             DispatchMessage(&msg);
  448.         }
  449.         else
  450.         {
  451.             Render();
  452.         }
  453.     } while(msg.message != WM_QUIT);
  454.     CleanUp();
  455.     return 0;
  456. }
  457.  
  458. BOOL InitWindow()
  459. {
  460.     WNDCLASSEX wc;
  461.     SecureZeroMemory(&wc, sizeof(wc));
  462.     wc.cbSize = sizeof(wc);
  463.     wc.hbrBackground = (HBRUSH)COLOR_WINDOW;
  464.     wc.hIcon = LoadIcon(NULL, IDI_APPLICATION);
  465.     wc.hCursor = LoadCursor(NULL, IDC_ARROW);
  466.     wc.hInstance = g_hInstance;
  467.     wc.lpfnWndProc = MyWindowProc;
  468.     wc.style = CS_HREDRAW | CS_VREDRAW;
  469.     wc.lpszClassName = g_className;
  470.  
  471.     if(INVALID_ATOM == RegisterClassEx(&wc))
  472.         return FALSE;
  473.  
  474.     if(!(g_hwnd = CreateWindow(
  475.                     g_className,
  476.                     TEXT("DX11"),
  477.                     WS_OVERLAPPEDWINDOW,
  478.                     CW_USEDEFAULT,
  479.                     CW_USEDEFAULT,
  480.                     g_width,
  481.                     g_height,
  482.                     NULL,
  483.                     NULL,
  484.                     g_hInstance,
  485.                     NULL)))
  486.         return FALSE;
  487.  
  488.     return TRUE;
  489. }
  490.  
  491. LRESULT CALLBACK MyWindowProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
  492. {
  493.     switch(msg)
  494.     {
  495.         case WM_SIZE:
  496.             {
  497.                 g_width = LOWORD(lParam);
  498.                 g_height = HIWORD(lParam);
  499.  
  500.                 if(!g_swapChain || !g_device || !g_rtv)
  501.                     break;
  502.  
  503.                 DXGI_SWAP_CHAIN_DESC sd;
  504.                 g_swapChain->GetDesc(&sd);
  505.                 sd.BufferDesc.Height = g_height;
  506.                 sd.BufferDesc.Width = g_width;
  507.  
  508.                 g_rtv->Release();
  509.                 g_deviceContext->ClearState();
  510.  
  511.                 g_swapChain->ResizeBuffers(sd.BufferCount, (UINT)g_width, (UINT)g_height, sd.BufferDesc.Format, sd.Flags);             
  512.  
  513.                 ID3D11Texture2D * buffer;
  514.                 g_swapChain->GetBuffer(0, __uuidof(buffer), (void**)&buffer);
  515.                 g_device->CreateRenderTargetView(buffer, NULL, &g_rtv);
  516.  
  517.                 buffer->Release();
  518.  
  519.                 g_deviceContext->OMSetRenderTargets(1, &g_rtv, NULL);
  520.  
  521.                 D3D11_VIEWPORT vp;
  522.                 vp.Height = (FLOAT)g_height;
  523.                 vp.Width = (FLOAT)g_width;
  524.                 vp.MinDepth = 0.0f;
  525.                 vp.MaxDepth = 1.0f;
  526.                 vp.TopLeftX = 0.0f;
  527.                 vp.TopLeftY = 0.0f;
  528.                
  529.                 g_deviceContext->RSSetViewports(1, &vp);
  530.             }
  531.             break;
  532.         case WM_PAINT:
  533.             {
  534.                 PAINTSTRUCT ps;
  535.                 BeginPaint(hwnd, &ps);
  536.                 EndPaint(hwnd, &ps);
  537.             }
  538.             break;
  539.         case WM_KEYDOWN:
  540.             switch(wParam)
  541.             {
  542.                 case VK_ESCAPE:
  543.                     PostQuitMessage(0);
  544.                     return 0;
  545.                 default:
  546.                     return DefWindowProc(hwnd, msg, wParam, lParam);
  547.             }
  548.         case WM_DESTROY:
  549.             PostQuitMessage(0);
  550.             break;
  551.         default:
  552.             return DefWindowProc(hwnd, msg, wParam, lParam);
  553.     }
  554.     return 0;
  555. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement