1. #ifndef DXD3D
  2. #define DXD3D
  3.  
  4. #include <windows.h>
  5. #include <d3d10.h>
  6. #include <d3dx10.h>
  7.  
  8. #include "dxGeometry.h"
  9.  
  10. #include <vector>
  11.  
  12. //Macros for releasing objects safely
  13. #define SAFE_DELETE(p) { if (p) { delete (p); (p)=NULL; } }
  14. #define SAFE_DELETE_SHUTDOWN(p) { if (p) { (p)->shutDown(); delete(p); (p)=NULL; } }
  15. #define RETURN_FALSE_OBJECT(p) { if (!p) { return false; } }
  16.  
  17. /**************************************************************************************
  18. * dxD3D
  19. * Simon GL Jordan
  20.  
  21. * Description:
  22. *   Initialises DirectX10 and resources
  23. *   Stands as the bare minimum for a project to work, can be expanded or manipulated to
  24. *   meet the projects needs
  25. *  
  26. * Note:
  27. * I tried to retain structure of the frame work of DirectX10 which is defined in dxSystem::initialise()
  28. * Create device -> Input assembly stage -> Rasterizer stage setup -> Output merger stage
  29. *
  30. * Use:
  31. *   Begin() and End() are called in the render() function inside dxSystem to start and stop
  32. *   rendering of data
  33. *
  34. * Future Implementations:
  35. * 1.A shader loader could be extracted from loadShadersAndCreateInputLayouts()
  36. * 2.Implement the camera to set up matrices and render scene
  37. *
  38. ***************************************************************************************/
  39.  
  40. class dxD3D
  41. {
  42. private:
  43.     HWND*               hWnd;
  44.  
  45.     IDXGISwapChain*               m_swapChain;
  46.     ID3D10Device*                 m_pD3DDevice;
  47.     ID3D10RenderTargetView*       m_renderTargetView;
  48.     ID3D10Texture2D*              m_depthStencilBuffer;
  49.     ID3D10DepthStencilState*      m_depthStencilState;
  50.     ID3D10DepthStencilView*       m_depthStencilView;
  51.     ID3D10RasterizerState*        m_rasterState;
  52.  
  53.     ID3D10Texture2D*              pBackBuffer;
  54.     D3D10_TEXTURE2D_DESC          descDepth;
  55.     D3D10_DEPTH_STENCIL_VIEW_DESC descDSV;
  56.     D3D10_DEPTH_STENCIL_DESC      depthStencilDesc;
  57.  
  58.     ID3D10EffectMatrixVariable*   pViewMatrixEffectVariable;
  59.     ID3D10EffectMatrixVariable*   pProjectionMatrixEffectVariable;
  60.     ID3D10EffectMatrixVariable*   pWorldMatrixEffectVariable;
  61.    
  62.     ID3D10InputLayout*            pVertexLayout;
  63.     ID3D10Effect*                 pBasicEffect;
  64.     ID3D10EffectTechnique*        pBasicTechnique;
  65.  
  66.     D3D10_RASTERIZER_DESC rasterDesc;
  67.     ID3D10RasterizerState* pRS;
  68.  
  69.     DXGI_SWAP_CHAIN_DESC swapChainDesc;
  70.  
  71.     D3D10_TECHNIQUE_DESC        techDesc;
  72.  
  73. public:
  74.     dxD3D();
  75.     dxD3D(const dxD3D&);
  76.  
  77.     ~dxD3D();
  78.  
  79.     bool createSwapChainAndDevice( UINT width, UINT height);
  80.     bool loadShadersAndCreateInputLayouts();
  81.     void createViewports( UINT width, UINT height );
  82.     bool initRasterizerState(){
  83.         bool result;
  84.  
  85.         // Setup the raster description which will determine how and what polygons will be drawn.
  86.  
  87.         rasterDesc.AntialiasedLineEnable = false;
  88.         rasterDesc.CullMode = D3D10_CULL_BACK;
  89.         rasterDesc.DepthBias = 0;
  90.         rasterDesc.DepthBiasClamp = 0.0f;
  91.         rasterDesc.DepthClipEnable = true;
  92.         rasterDesc.FillMode = D3D10_FILL_SOLID;
  93.         rasterDesc.FrontCounterClockwise = false;
  94.         rasterDesc.MultisampleEnable = false;
  95.         rasterDesc.ScissorEnable = false;
  96.         rasterDesc.SlopeScaledDepthBias = 0.0f;
  97.  
  98.        
  99.         // Create the rasterizer state from the description we just filled out.
  100.         result = m_pD3DDevice->CreateRasterizerState( &rasterDesc, &pRS);
  101.         if(FAILED(result))
  102.         {
  103.             MessageBox(NULL, L"Failed to create razterizer state", NULL, NULL);
  104.             return false;
  105.         }
  106.  
  107.         m_pD3DDevice->RSSetState(pRS);
  108.  
  109.         return true;
  110.     }//Inline for greater speed
  111.  
  112.  
  113.     bool createRenderTargetsAndDepthBuffer( UINT width, UINT height );
  114.  
  115.     void beginScene(float red, float green, float blue, float alpha){
  116.         float colour[4];
  117.  
  118.  
  119.         // Setup the color to clear the buffer to.
  120.         colour[0] = red;
  121.         colour[1] = green;
  122.         colour[2] = blue;
  123.         colour[3] = alpha;
  124.  
  125.         // Clear the back buffer.
  126.         m_pD3DDevice->ClearRenderTargetView(m_renderTargetView, colour);
  127.  
  128.         // Clear the depth buffer.
  129.         m_pD3DDevice->ClearDepthStencilView(m_depthStencilView, D3D10_CLEAR_DEPTH, 1.0f, 0);
  130.     }
  131.     void endScene(){
  132.         // Present as fast as possible.
  133.         m_swapChain->Present(0, 0);
  134.     }
  135.  
  136.     void shutDown();
  137. };
  138.  
  139. dxD3D::dxD3D(): m_pD3DDevice(NULL),
  140.                 m_swapChain(NULL),
  141.                 m_renderTargetView(NULL),
  142.                 m_depthStencilBuffer(0),
  143.                 m_depthStencilState(0),
  144.                 m_depthStencilView(0),
  145.                 m_rasterState(0)
  146. {}
  147. dxD3D::dxD3D(const dxD3D& other)
  148. {}
  149.  
  150. dxD3D::~dxD3D()
  151. {}
  152.  
  153.  
  154.  
  155. bool dxD3D::createSwapChainAndDevice( UINT width, UINT height )
  156. {
  157.     HRESULT result;
  158.  
  159.     //Set up DX swap chain
  160.     //--------------------------------------------------------------
  161.  
  162.     //set buffer dimensions and format
  163.     // Initialize the swap chain description.
  164.     ZeroMemory(&swapChainDesc, sizeof(swapChainDesc));
  165.  
  166.     // Set to a single back buffer.
  167.     swapChainDesc.BufferCount = 1;
  168.  
  169.     // Set the width and height of the back buffer.
  170.     swapChainDesc.BufferDesc.Width = width;
  171.     swapChainDesc.BufferDesc.Height = height;
  172.  
  173.     // Set regular 32-bit surface for the back buffer.
  174.     swapChainDesc.BufferDesc.Format = DXGI_FORMAT_R8G8B8A8_UNORM;
  175.  
  176.     //set refresh rate
  177.     swapChainDesc.BufferDesc.RefreshRate.Numerator = 60;
  178.     swapChainDesc.BufferDesc.RefreshRate.Denominator = 1;
  179.  
  180.     // Set the usage of the back buffer.
  181.     swapChainDesc.BufferUsage = DXGI_USAGE_RENDER_TARGET_OUTPUT;
  182.  
  183.     // Turn multisampling off.
  184.     swapChainDesc.SampleDesc.Count = 1;
  185.     swapChainDesc.SampleDesc.Quality = 0;
  186.  
  187.     // Set the handle for the window to render to.
  188.     swapChainDesc.OutputWindow = *hWnd;
  189.  
  190.     // Set the scan line ordering and scaling to unspecified.
  191.     swapChainDesc.BufferDesc.ScanlineOrdering = DXGI_MODE_SCANLINE_ORDER_UNSPECIFIED;
  192.     swapChainDesc.BufferDesc.Scaling = DXGI_MODE_SCALING_UNSPECIFIED;
  193.  
  194.     // Discard the back buffer contents after presenting.
  195.     swapChainDesc.SwapEffect = DXGI_SWAP_EFFECT_DISCARD;
  196.  
  197.     // Don't set the advanced flags.
  198.     swapChainDesc.Flags = 0;
  199.     if(FAILED(result))
  200.     {
  201.         MessageBox(NULL, L"Failed", NULL, NULL);
  202.         return false;
  203.     }
  204.  
  205.     //Create the D3D device
  206.     //--------------------------------------------------------------
  207.     result = D3D10CreateDeviceAndSwapChain(NULL, D3D10_DRIVER_TYPE_HARDWARE, NULL, 0, D3D10_SDK_VERSION,
  208.         &swapChainDesc, &m_swapChain, &m_pD3DDevice);
  209.     if(FAILED(result))
  210.     {
  211.         MessageBox(NULL, L"Failed to create the D3D device", NULL, NULL);
  212.         return false;
  213.     }
  214.  
  215.     return true;
  216. }
  217.  
  218. bool dxD3D::createRenderTargetsAndDepthBuffer(UINT width, UINT height)
  219. {
  220.     HRESULT result;
  221.  
  222.     result = m_swapChain->GetBuffer(0, __uuidof(ID3D10Texture2D), (LPVOID*)&pBackBuffer);
  223.     if(FAILED(result))
  224.     {
  225.         MessageBox(NULL, L"Failed to get the buffer", NULL, NULL);
  226.         return false;
  227.     }
  228.  
  229.     // Create the render target view with the back buffer pointer.
  230.     result = m_pD3DDevice->CreateRenderTargetView(pBackBuffer, NULL, &m_renderTargetView);
  231.     if(FAILED(result))
  232.     {
  233.         MessageBox(NULL, L"Failed to create the render target view", NULL, NULL);
  234.         return false;
  235.     }
  236.  
  237.     pBackBuffer->Release();
  238.     pBackBuffer = 0;
  239.  
  240.     descDepth.Width = width;
  241.     descDepth.Height = height;
  242.     descDepth.MipLevels = 1;
  243.     descDepth.ArraySize = 1;
  244.     descDepth.Format = DXGI_FORMAT_D32_FLOAT;
  245.     descDepth.SampleDesc.Count = 1;
  246.     descDepth.SampleDesc.Quality = 0;
  247.     descDepth.Usage = D3D10_USAGE_DEFAULT;
  248.     descDepth.BindFlags = D3D10_BIND_DEPTH_STENCIL;
  249.     descDepth.CPUAccessFlags = 0;
  250.     descDepth.MiscFlags = 0;  
  251.    
  252.     // Create the texture for the depth buffer using the filled out description.
  253.     result = m_pD3DDevice->CreateTexture2D(&descDepth, NULL, &m_depthStencilBuffer);
  254.     if(FAILED(result))
  255.     {
  256.         return false;
  257.         MessageBox(NULL, L"Failed to create the texture for the depth buffer", NULL, NULL);
  258.     }
  259.  
  260.     // Initialize the description of the stencil state.
  261.     ZeroMemory(&depthStencilDesc, sizeof(depthStencilDesc));
  262.  
  263.     // Set up the description of the stencil state.
  264.     depthStencilDesc.DepthEnable = true;
  265.     depthStencilDesc.DepthWriteMask = D3D10_DEPTH_WRITE_MASK_ALL;
  266.     depthStencilDesc.DepthFunc = D3D10_COMPARISON_LESS;
  267.  
  268.     depthStencilDesc.StencilEnable = true;
  269.     depthStencilDesc.StencilReadMask = 0xFF;
  270.     depthStencilDesc.StencilWriteMask = 0xFF;
  271.  
  272.     // Stencil operations if pixel is front-facing.
  273.     depthStencilDesc.FrontFace.StencilFailOp = D3D10_STENCIL_OP_KEEP;
  274.     depthStencilDesc.FrontFace.StencilDepthFailOp = D3D10_STENCIL_OP_INCR;
  275.     depthStencilDesc.FrontFace.StencilPassOp = D3D10_STENCIL_OP_KEEP;
  276.     depthStencilDesc.FrontFace.StencilFunc = D3D10_COMPARISON_ALWAYS;
  277.  
  278.     // Stencil operations if pixel is back-facing.
  279.     depthStencilDesc.BackFace.StencilFailOp = D3D10_STENCIL_OP_KEEP;
  280.     depthStencilDesc.BackFace.StencilDepthFailOp = D3D10_STENCIL_OP_DECR;
  281.     depthStencilDesc.BackFace.StencilPassOp = D3D10_STENCIL_OP_KEEP;
  282.     depthStencilDesc.BackFace.StencilFunc = D3D10_COMPARISON_ALWAYS;
  283.  
  284.     // Create the depth stencil state.
  285.     result = m_pD3DDevice->CreateDepthStencilState(&depthStencilDesc, &m_depthStencilState);
  286.     if(FAILED(result))
  287.     {
  288.         MessageBox(NULL, L"Failed to create the depth stencil state", NULL, NULL);
  289.         return false;
  290.     }
  291.  
  292.     // Initialise the depth stencil view.
  293.     ZeroMemory(&descDepth, sizeof(descDepth));
  294.    
  295.     // Set up the depth stencil view description.
  296.     descDSV.Format = descDepth.Format;
  297.     descDSV.ViewDimension = D3D10_DSV_DIMENSION_TEXTURE2D;
  298.     descDSV.Texture2D.MipSlice = 0;
  299.  
  300.     // Create the depth stencil view.
  301.     result = m_pD3DDevice->CreateDepthStencilView(m_depthStencilBuffer, &descDSV, &m_depthStencilView);
  302.     if(FAILED(result))
  303.     {
  304.         MessageBox(NULL, L"Failed to create the depth stencil view", NULL, NULL);
  305.         return false;
  306.     }
  307.  
  308.     // Bind the render target view and depth stencil buffer to the output render pipeline.
  309.     m_pD3DDevice->OMSetRenderTargets(1, &m_renderTargetView, m_depthStencilView);
  310.  
  311.     return true;
  312. }
  313.  
  314. bool dxD3D::loadShadersAndCreateInputLayouts()
  315. {
  316.     //technique
  317.    
  318.  
  319.     HRESULT result;
  320.  
  321.     result = D3DX10CreateEffectFromFile(L"./basicEffect.fx",
  322.         NULL, NULL,
  323.         "fx_4_0",
  324.         D3D10_SHADER_ENABLE_STRICTNESS,
  325.         0,
  326.         m_pD3DDevice,
  327.         NULL,
  328.         NULL,
  329.         &pBasicEffect,
  330.         NULL,
  331.         NULL    );
  332.     if(!result)
  333.     {
  334.         MessageBox(NULL, L"Failed to load effect file", NULL, NULL);
  335.         return false;
  336.     }
  337.  
  338.     pBasicTechnique = pBasicEffect->GetTechniqueByName("render");
  339.     if(!pBasicTechnique)
  340.     {
  341.         MessageBox(NULL, L"Failed to retrieve technique", NULL, NULL);
  342.         return false;
  343.     }  
  344.  
  345.  
  346.     //create matrix effect pointers
  347.     pViewMatrixEffectVariable = pBasicEffect->GetVariableByName( "View" )->AsMatrix();
  348.     pProjectionMatrixEffectVariable = pBasicEffect->GetVariableByName( "Projection" )->AsMatrix();
  349.     pWorldMatrixEffectVariable = pBasicEffect->GetVariableByName( "World" )->AsMatrix();   
  350.  
  351.     //create input layout
  352.     D3D10_PASS_DESC PassDesc;
  353.     pBasicTechnique->GetPassByIndex( 0 )->GetDesc( &PassDesc );
  354.  
  355.  
  356.     // Create the input layout.
  357.     result = m_pD3DDevice->CreateInputLayout( vertexInputLayout,
  358.         2,
  359.         PassDesc.pIAInputSignature,
  360.         PassDesc.IAInputSignatureSize,
  361.         &pVertexLayout );
  362.     if(FAILED(result))
  363.     {
  364.         MessageBox(NULL, L"Failed to create the input layout", NULL, NULL);
  365.         return false;
  366.     }
  367.  
  368.     // Set the input layout
  369.     m_pD3DDevice->IASetInputLayout( pVertexLayout );
  370.  
  371.     //get technique description
  372.     pBasicTechnique->GetDesc( &techDesc );
  373.  
  374.     return true;
  375. }
  376.  
  377. void dxD3D::shutDown()
  378. {
  379.     // Before shutting down set to windowed mode or when you release the swap chain it will throw an exception.
  380.     if(m_swapChain)
  381.     {
  382.         m_swapChain->SetFullscreenState(false, NULL);
  383.     }
  384.  
  385.     if(m_rasterState)
  386.     {
  387.         m_rasterState->Release();
  388.         m_rasterState = 0;
  389.     }
  390.  
  391.     if(m_depthStencilView)
  392.     {
  393.         m_depthStencilView->Release();
  394.         m_depthStencilView = 0;
  395.     }
  396.  
  397.     if(m_depthStencilState)
  398.     {
  399.         m_depthStencilState->Release();
  400.         m_depthStencilState = 0;
  401.     }
  402.  
  403.     if(m_depthStencilBuffer)
  404.     {
  405.         m_depthStencilBuffer->Release();
  406.         m_depthStencilBuffer = 0;
  407.     }
  408.  
  409.     if(m_renderTargetView)
  410.     {
  411.         m_renderTargetView->Release();
  412.         m_renderTargetView = 0;
  413.     }
  414.  
  415.     if(m_swapChain)
  416.     {
  417.         m_swapChain->Release();
  418.         m_swapChain = 0;
  419.     }
  420.  
  421.     if(m_pD3DDevice)
  422.     {
  423.         m_pD3DDevice->Release();
  424.         m_pD3DDevice = 0;
  425.     }
  426.  
  427. }
  428.  
  429. #endif
  430.