d7samurai

minimal d3d11 : render texture

Jan 20th, 2016
254
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 14.58 KB | None | 0 0
  1. // note: to keep things minimal, this example is using a "trick" to draw a textured quad without using a vertex buffer.
  2. // @d7samurai
  3.  
  4. #pragma once
  5. #pragma comment(lib, "d3d11")
  6.  
  7. #include <windows.h>
  8. #include <wrl.h>
  9. #include <d3d11_1.h>
  10.  
  11. ///////////////////////////////////////////////////////////////////////////////////////////////////
  12.  
  13. byte*                                               VertexShaderData;       // pointer to compiled vertex shader data
  14. int                                                 VertexShaderDataSize;   // size of compiled vertex shader data
  15.  
  16. byte*                                               PixelShaderData;        // pointer to compiled pixel shader data
  17. int                                                 PixelShaderDataSize;    // size of compiled pixel shader data
  18.  
  19. byte*                                               TextureData;            // pointer to bitmap data
  20. int                                                 TextureWidth;           // width of bitmap
  21. int                                                 TextureHeight;          // height of bitmap
  22.  
  23. ///////////////////////////////////////////////////////////////////////////////////////////////////
  24.  
  25. HWND                                                Window;
  26.  
  27. Microsoft::WRL::ComPtr<IDXGISwapChain1>             SwapChain;
  28.  
  29. Microsoft::WRL::ComPtr<ID3D11Device1>               Device;
  30. Microsoft::WRL::ComPtr<ID3D11DeviceContext1>        DeviceContext;
  31. Microsoft::WRL::ComPtr<ID3D11RenderTargetView>      RenderTargetView;
  32.  
  33. Microsoft::WRL::ComPtr<ID3D11VertexShader>          VertexShader;
  34. Microsoft::WRL::ComPtr<ID3D11PixelShader>           PixelShader;
  35.  
  36. Microsoft::WRL::ComPtr<ID3D11RasterizerState1>      RasterizerState;
  37. Microsoft::WRL::ComPtr<ID3D11BlendState1>           BlendState;
  38.  
  39. Microsoft::WRL::ComPtr<ID3D11ShaderResourceView>    Texture;
  40.  
  41. ///////////////////////////////////////////////////////////////////////////////////////////////////
  42.  
  43. LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam);
  44.  
  45. void InitializeD3D();
  46.  
  47. void ClearFrame(float r, float g, float b);
  48.  
  49. void DrawTexture(ID3D11ShaderResourceView** texture, int x, int y, int width, int height);
  50.  
  51. void Present();
  52.  
  53. void ResizeBackBuffer(UINT width, UINT height);
  54.  
  55. ///////////////////////////////////////////////////////////////////////////////////////////////////
  56.  
  57. int WINAPI wWinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPWSTR lpCmdLine, int nShowCmd)
  58. {
  59.     // todo:
  60.    
  61.     // load compiled vertex shader data and set VertexShaderData pointer
  62.     // set VertexShaderDataSize
  63.  
  64.     // load compiled pixel shader data and set PixelShaderData pointer
  65.     // set PixelShaderDataSize
  66.  
  67.     // load bitmp data (32 bpp BGRA) and set TextureData pointer
  68.     // set TextureWidth
  69.     // set TextureHeight
  70.  
  71.     ///////////////////////////////////////////////////////////////////////////////////////////////
  72.  
  73.     char* title = "Minimal D3D11";
  74.  
  75.     WNDCLASSEX wndClassEx = { sizeof(wndClassEx) };
  76.     wndClassEx.lpfnWndProc = WndProc;
  77.     wndClassEx.hCursor = LoadCursor(nullptr, IDC_ARROW);
  78.     wndClassEx.lpszClassName = title;
  79.  
  80.     RegisterClassEx(&wndClassEx);
  81.  
  82.     Window = CreateWindowEx(0, title, title, WS_OVERLAPPEDWINDOW, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, nullptr, nullptr, hInstance, nullptr);
  83.  
  84.     ///////////////////////////////////////////////////////////////////////////////////////////////
  85.  
  86.     InitializeD3D();
  87.  
  88.     ShowWindow(Window, SW_SHOWNORMAL);
  89.  
  90.     ///////////////////////////////////////////////////////////////////////////////////////////////
  91.  
  92.     bool run = true;
  93.  
  94.     while (run)
  95.     {
  96.         ClearFrame(0.25f, 0.125f, 0.0f);
  97.  
  98.         DrawTexture(Texture.GetAddressOf(), 100, 100, TextureWidth, TextureHeight);
  99.  
  100.         Present();
  101.  
  102.         MSG msg;
  103.  
  104.         while (PeekMessage(&msg, nullptr, 0, 0, PM_REMOVE) > 0)
  105.         {
  106.             if (msg.message != WM_QUIT)
  107.             {
  108.                 TranslateMessage(&msg);
  109.                 DispatchMessage(&msg);
  110.             }
  111.             else
  112.             {
  113.                 run = false;
  114.             }
  115.         }
  116.     }
  117.  
  118.     ///////////////////////////////////////////////////////////////////////////////////////////////
  119.  
  120.     return 0;
  121. }
  122.  
  123. ///////////////////////////////////////////////////////////////////////////////////////////////////
  124.  
  125. LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
  126. {
  127.     switch (message)
  128.     {
  129.     case WM_SIZE:
  130.     {
  131.         UINT width = static_cast<UINT>(lParam & 0xffff);
  132.         UINT height = static_cast<UINT>(lParam >> 16);
  133.  
  134.         ResizeBackBuffer(width, height);
  135.     }
  136.     return 0;
  137.  
  138.     case WM_DESTROY:
  139.     {
  140.         PostQuitMessage(0);
  141.     }
  142.     return 0;
  143.     }
  144.  
  145.     return DefWindowProc(hWnd, message, wParam, lParam);
  146. }
  147.  
  148. ///////////////////////////////////////////////////////////////////////////////////////////////////
  149.  
  150. void InitializeD3D()
  151. {
  152.     SwapChain.Reset();
  153.  
  154.     Device.Reset();
  155.     DeviceContext.Reset();
  156.     RenderTargetView.Reset();
  157.  
  158.     VertexShader.Reset();
  159.     PixelShader.Reset();
  160.  
  161.     RasterizerState.Reset();
  162.     BlendState.Reset();
  163.  
  164.     Texture.Reset();
  165.  
  166.     ///////////////////////////////////////////////////////////////////////////////////////////////
  167.  
  168.     D3D_FEATURE_LEVEL featureLevel[] =
  169.     {
  170.         D3D_FEATURE_LEVEL_11_1,
  171.         D3D_FEATURE_LEVEL_11_0,
  172.         D3D_FEATURE_LEVEL_10_1,
  173.         D3D_FEATURE_LEVEL_10_0 };
  174.  
  175.     Microsoft::WRL::ComPtr<ID3D11Device> device;
  176.     Microsoft::WRL::ComPtr<ID3D11DeviceContext> deviceContext;
  177.  
  178.     D3D11CreateDevice(nullptr, D3D_DRIVER_TYPE_HARDWARE, nullptr, 0, featureLevel, ARRAYSIZE(featureLevel), D3D11_SDK_VERSION, &device, nullptr, &deviceContext);
  179.  
  180.     ///////////////////////////////////////////////////////////////////////////////////////////////
  181.  
  182.     device.As(&Device);
  183.     deviceContext.As(&DeviceContext);
  184.  
  185.     Microsoft::WRL::ComPtr<IDXGIDevice1> dxgiDevice;
  186.     Device.As(&dxgiDevice);
  187.  
  188.     Microsoft::WRL::ComPtr<IDXGIAdapter> dxgiAdapter;
  189.     dxgiDevice->GetAdapter(&dxgiAdapter);
  190.  
  191.     Microsoft::WRL::ComPtr<IDXGIFactory2> dxgiFactory;
  192.     dxgiAdapter->GetParent(__uuidof(IDXGIFactory2), &dxgiFactory);
  193.  
  194.     ///////////////////////////////////////////////////////////////////////////////////////////////
  195.  
  196.     DXGI_SWAP_CHAIN_DESC1 swapChainDescription =
  197.     {
  198.         0,                                      // Width
  199.         0,                                      // Height
  200.         DXGI_FORMAT_B8G8R8A8_UNORM,             // Format
  201.         FALSE,{                                 // Stereo
  202.             1,                                  //      SampleDesc.Count
  203.             0 },                                //      SampleDesc.Quality
  204.         DXGI_USAGE_RENDER_TARGET_OUTPUT,        // BufferUsage
  205.         2,                                      // BufferCount
  206.         DXGI_SCALING_NONE,                      // Scaling (use DXGI_SCALING_STRETCH for Windows 7)
  207.         DXGI_SWAP_EFFECT_FLIP_SEQUENTIAL,       // SwapEffect (use DXGI_SWAP_EFFECT_DISCARD for Windows 7)
  208.         DXGI_ALPHA_MODE_UNSPECIFIED,            // AlphaMode
  209.         0 };                                    // Flags
  210.  
  211.     dxgiFactory->CreateSwapChainForHwnd(Device.Get(), Window, &swapChainDescription, nullptr, nullptr, &SwapChain);
  212.  
  213.     ///////////////////////////////////////////////////////////////////////////////////////////////
  214.  
  215.     Microsoft::WRL::ComPtr<ID3D11Texture2D> backBuffer;
  216.     SwapChain->GetBuffer(0, __uuidof(ID3D11Texture2D), &backBuffer);
  217.  
  218.     Device->CreateRenderTargetView(backBuffer.Get(), nullptr, &RenderTargetView);
  219.  
  220.     ///////////////////////////////////////////////////////////////////////////////////////////////
  221.  
  222.     Device->CreateVertexShader(VertexShaderData, VertexShaderDataSize, nullptr, &VertexShader);
  223.     Device->CreatePixelShader(PixelShaderData, PixelShaderDataSize, nullptr, &PixelShader);
  224.  
  225.     ///////////////////////////////////////////////////////////////////////////////////////////////
  226.  
  227.     D3D11_RASTERIZER_DESC1 rasterizerDescription =
  228.     {
  229.         D3D11_FILL_SOLID,                       // FillMode
  230.         D3D11_CULL_NONE,                        // CullMode
  231.         FALSE,                                  // FrontCounterClockwise
  232.         0,                                      // DepthBias
  233.         0.0f,                                   // DepthBiasClamp
  234.         0.0f,                                   // SlopeScaledDepthBias
  235.         FALSE,                                  // DepthClipEnable
  236.         FALSE,                                  // ScissorEnable
  237.         FALSE,                                  // MultisampleEnable
  238.         FALSE,                                  // AntialiasedLineEnable
  239.         0 };                                    // ForcedSampleCount    
  240.  
  241.     Device->CreateRasterizerState1(&rasterizerDescription, &RasterizerState);
  242.  
  243.     ///////////////////////////////////////////////////////////////////////////////////////////////
  244.  
  245.     D3D11_BLEND_DESC1 blendDescription =
  246.     {
  247.         FALSE,                                  // AlphaToCoverageEnable
  248.         FALSE, { {                              // IndependentBlendEnable
  249.             TRUE,                               //      RenderTarget[0].BlendEnable
  250.             FALSE,                              //      RenderTarget[0].LogicOpEnable
  251.             D3D11_BLEND_SRC_ALPHA,              //      RenderTarget[0].SrcBlend
  252.             D3D11_BLEND_INV_SRC_ALPHA,          //      RenderTarget[0].DestBlend
  253.             D3D11_BLEND_OP_ADD,                 //      RenderTarget[0].BlendOp
  254.             D3D11_BLEND_ONE,                    //      RenderTarget[0].SrcBlendAlpha
  255.             D3D11_BLEND_ONE,                    //      RenderTarget[0].DestBlendAlpha
  256.             D3D11_BLEND_OP_ADD,                 //      RenderTarget[0].BlendOpAlpha
  257.             D3D11_LOGIC_OP_CLEAR,               //      RenderTarget[0].LogicOp
  258.             D3D11_COLOR_WRITE_ENABLE_ALL } } }; //      RenderTarget[0].RenderTargetWriteMask
  259.  
  260.     Device->CreateBlendState1(&blendDescription, &BlendState);
  261.  
  262.     ///////////////////////////////////////////////////////////////////////////////////////////////
  263.  
  264.     D3D11_TEXTURE2D_DESC texture2dDescription =
  265.     {
  266.         static_cast<UINT>(TextureWidth),        // Width
  267.         static_cast<UINT>(TextureHeight),       // Height
  268.         1,                                      // MipLevels
  269.         1,                                      // ArraySize
  270.         DXGI_FORMAT_B8G8R8A8_UNORM, {           // Format      
  271.             1,                                  //      SampleDesc.Count
  272.             0 },                                //      SampleDesc.Quality
  273.         D3D11_USAGE_IMMUTABLE,                  // Usage
  274.         D3D11_BIND_SHADER_RESOURCE,             // BindFlags
  275.         0,                                      // CPUAccessFlags
  276.         0 };                                    // MiscFlags
  277.  
  278.     D3D11_SUBRESOURCE_DATA subresourceData =
  279.     {
  280.         TextureData,                            // pSysMem
  281.         static_cast<UINT>(TextureWidth * 4),    // SysMemPitch (4 bytes per pixel)
  282.         0 };                                    // SysMemSlicePitch
  283.  
  284.     Microsoft::WRL::ComPtr<ID3D11Texture2D> texture2d;
  285.     Device->CreateTexture2D(&texture2dDescription, &subresourceData, &texture2d);
  286.  
  287.     Device->CreateShaderResourceView(texture2d.Get(), nullptr, &Texture);
  288. }
  289.  
  290. ///////////////////////////////////////////////////////////////////////////////////////////////////
  291.  
  292. void ClearFrame(float r, float g, float b)
  293. {
  294.     FLOAT backgroundColor[] = { r, g, b, 1.0f };
  295.     DeviceContext->ClearRenderTargetView(RenderTargetView.Get(), backgroundColor);
  296. }
  297.  
  298. ///////////////////////////////////////////////////////////////////////////////////////////////////
  299.  
  300. void DrawTexture(ID3D11ShaderResourceView** texture, int x, int y, int width, int height)
  301. {
  302.     D3D11_VIEWPORT viewport = { static_cast<float>(x), static_cast<float>(y), static_cast<float>(x + width), static_cast<float>(y + height), 0.0f, 1.0f };
  303.  
  304.     DeviceContext->IASetPrimitiveTopology(D3D11_PRIMITIVE_TOPOLOGY_TRIANGLESTRIP);
  305.  
  306.     DeviceContext->VSSetShader(VertexShader.Get(), nullptr, 0);
  307.  
  308.     DeviceContext->RSSetViewports(1, &viewport);
  309.     DeviceContext->RSSetState(RasterizerState.Get());
  310.  
  311.     DeviceContext->PSSetShader(PixelShader.Get(), nullptr, 0);
  312.     DeviceContext->PSSetShaderResources(0, 1, texture);
  313.  
  314.     DeviceContext->OMSetBlendState(BlendState.Get(), nullptr, 0xffffffff);
  315.     DeviceContext->OMSetRenderTargets(1, RenderTargetView.GetAddressOf(), nullptr);
  316.  
  317.     DeviceContext->Draw(4, 0);
  318. }
  319.  
  320. ///////////////////////////////////////////////////////////////////////////////////////////////////
  321.  
  322. void Present()
  323. {
  324.     DXGI_PRESENT_PARAMETERS presentParameters = { 0, nullptr, nullptr, nullptr };
  325.  
  326.     HRESULT hr = SwapChain->Present1(1, 0, &presentParameters);
  327.  
  328.     if (hr != S_OK && hr != DXGI_STATUS_OCCLUDED)
  329.     {
  330.         InitializeD3D();
  331.     }
  332. }
  333.  
  334. ///////////////////////////////////////////////////////////////////////////////////////////////////
  335.  
  336. void ResizeBackBuffer(UINT width, UINT height)
  337. {
  338.     RenderTargetView.Reset();
  339.  
  340.     ///////////////////////////////////////////////////////////////////////////////////////////////
  341.  
  342.     HRESULT hr = SwapChain->ResizeBuffers(0, width, height, DXGI_FORMAT_UNKNOWN, 0);
  343.  
  344.     ///////////////////////////////////////////////////////////////////////////////////////////////
  345.  
  346.     Microsoft::WRL::ComPtr<ID3D11Texture2D> backBuffer;
  347.     SwapChain->GetBuffer(0, __uuidof(ID3D11Texture2D), &backBuffer);
  348.  
  349.     Device->CreateRenderTargetView(backBuffer.Get(), nullptr, &RenderTargetView);
  350. }
  351.  
  352. ///////////////////////////////////////////////////////////////////////////////////////////////////
  353. // vertex shader
  354.  
  355. static float2 xy[4] = { { -1.0f, -1.0f }, { -1.0f, 1.0f }, { 1.0f, -1.0f }, { 1.0f, 1.0f } };
  356. static float2 uv[4] = { {  0.0f,  1.0f }, {  0.0f, 0.0f }, { 1.0f,  1.0f }, { 1.0f, 0.0f } };
  357.  
  358. struct vs_out
  359. {
  360.     float4 position : SV_POSITION;
  361.     float2 texcoord : TEXCOORD;
  362. };
  363.  
  364. vs_out main(uint vertexId : SV_VERTEXID)
  365. {
  366.     vs_out output;
  367.  
  368.     output.position = float4(xy[vertexId], 0.0f, 1.0f);
  369.     output.texcoord = uv[vertexId];
  370.  
  371.     return output;
  372. }
  373.  
  374. ///////////////////////////////////////////////////////////////////////////////////////////////////
  375. // pixel shader
  376.  
  377. SamplerState state;
  378.  
  379. tbuffer tb0
  380. {
  381.     Texture2D texture2d;
  382. };
  383.  
  384. struct ps_in
  385. {
  386.     float4 position : SV_POSITION;
  387.     float2 texcoord : TEXCOORD;
  388. };
  389.  
  390. float4 main(ps_in input) : SV_TARGET
  391. {
  392.     return texture2d.Sample(state, input.texcoord);
  393. }
Add Comment
Please, Sign In to add comment