#ifndef DXD3D #define DXD3D #include #include #include #include "dxGeometry.h" #include //Macros for releasing objects safely #define SAFE_DELETE(p) { if (p) { delete (p); (p)=NULL; } } #define SAFE_DELETE_SHUTDOWN(p) { if (p) { (p)->shutDown(); delete(p); (p)=NULL; } } #define RETURN_FALSE_OBJECT(p) { if (!p) { return false; } } /************************************************************************************** * dxD3D * Simon GL Jordan * Description: * Initialises DirectX10 and resources * Stands as the bare minimum for a project to work, can be expanded or manipulated to * meet the projects needs * * Note: * I tried to retain structure of the frame work of DirectX10 which is defined in dxSystem::initialise() * Create device -> Input assembly stage -> Rasterizer stage setup -> Output merger stage * * Use: * Begin() and End() are called in the render() function inside dxSystem to start and stop * rendering of data * * Future Implementations: * 1.A shader loader could be extracted from loadShadersAndCreateInputLayouts() * 2.Implement the camera to set up matrices and render scene * ***************************************************************************************/ class dxD3D { private: HWND* hWnd; IDXGISwapChain* m_swapChain; ID3D10Device* m_pD3DDevice; ID3D10RenderTargetView* m_renderTargetView; ID3D10Texture2D* m_depthStencilBuffer; ID3D10DepthStencilState* m_depthStencilState; ID3D10DepthStencilView* m_depthStencilView; ID3D10RasterizerState* m_rasterState; ID3D10Texture2D* pBackBuffer; D3D10_TEXTURE2D_DESC descDepth; D3D10_DEPTH_STENCIL_VIEW_DESC descDSV; D3D10_DEPTH_STENCIL_DESC depthStencilDesc; ID3D10EffectMatrixVariable* pViewMatrixEffectVariable; ID3D10EffectMatrixVariable* pProjectionMatrixEffectVariable; ID3D10EffectMatrixVariable* pWorldMatrixEffectVariable; ID3D10InputLayout* pVertexLayout; ID3D10Effect* pBasicEffect; ID3D10EffectTechnique* pBasicTechnique; D3D10_RASTERIZER_DESC rasterDesc; ID3D10RasterizerState* pRS; DXGI_SWAP_CHAIN_DESC swapChainDesc; D3D10_TECHNIQUE_DESC techDesc; public: dxD3D(); dxD3D(const dxD3D&); ~dxD3D(); bool createSwapChainAndDevice( UINT width, UINT height); bool loadShadersAndCreateInputLayouts(); void createViewports( UINT width, UINT height ); bool initRasterizerState(){ bool result; // Setup the raster description which will determine how and what polygons will be drawn. rasterDesc.AntialiasedLineEnable = false; rasterDesc.CullMode = D3D10_CULL_BACK; rasterDesc.DepthBias = 0; rasterDesc.DepthBiasClamp = 0.0f; rasterDesc.DepthClipEnable = true; rasterDesc.FillMode = D3D10_FILL_SOLID; rasterDesc.FrontCounterClockwise = false; rasterDesc.MultisampleEnable = false; rasterDesc.ScissorEnable = false; rasterDesc.SlopeScaledDepthBias = 0.0f; // Create the rasterizer state from the description we just filled out. result = m_pD3DDevice->CreateRasterizerState( &rasterDesc, &pRS); if(FAILED(result)) { MessageBox(NULL, L"Failed to create razterizer state", NULL, NULL); return false; } m_pD3DDevice->RSSetState(pRS); return true; }//Inline for greater speed bool createRenderTargetsAndDepthBuffer( UINT width, UINT height ); void beginScene(float red, float green, float blue, float alpha){ float colour[4]; // Setup the color to clear the buffer to. colour[0] = red; colour[1] = green; colour[2] = blue; colour[3] = alpha; // Clear the back buffer. m_pD3DDevice->ClearRenderTargetView(m_renderTargetView, colour); // Clear the depth buffer. m_pD3DDevice->ClearDepthStencilView(m_depthStencilView, D3D10_CLEAR_DEPTH, 1.0f, 0); } void endScene(){ // Present as fast as possible. m_swapChain->Present(0, 0); } void shutDown(); }; dxD3D::dxD3D(): m_pD3DDevice(NULL), m_swapChain(NULL), m_renderTargetView(NULL), m_depthStencilBuffer(0), m_depthStencilState(0), m_depthStencilView(0), m_rasterState(0) {} dxD3D::dxD3D(const dxD3D& other) {} dxD3D::~dxD3D() {} bool dxD3D::createSwapChainAndDevice( UINT width, UINT height ) { HRESULT result; //Set up DX swap chain //-------------------------------------------------------------- //set buffer dimensions and format // Initialize the swap chain description. ZeroMemory(&swapChainDesc, sizeof(swapChainDesc)); // Set to a single back buffer. swapChainDesc.BufferCount = 1; // Set the width and height of the back buffer. swapChainDesc.BufferDesc.Width = width; swapChainDesc.BufferDesc.Height = height; // Set regular 32-bit surface for the back buffer. swapChainDesc.BufferDesc.Format = DXGI_FORMAT_R8G8B8A8_UNORM; //set refresh rate swapChainDesc.BufferDesc.RefreshRate.Numerator = 60; swapChainDesc.BufferDesc.RefreshRate.Denominator = 1; // Set the usage of the back buffer. swapChainDesc.BufferUsage = DXGI_USAGE_RENDER_TARGET_OUTPUT; // Turn multisampling off. swapChainDesc.SampleDesc.Count = 1; swapChainDesc.SampleDesc.Quality = 0; // Set the handle for the window to render to. swapChainDesc.OutputWindow = *hWnd; // Set the scan line ordering and scaling to unspecified. swapChainDesc.BufferDesc.ScanlineOrdering = DXGI_MODE_SCANLINE_ORDER_UNSPECIFIED; swapChainDesc.BufferDesc.Scaling = DXGI_MODE_SCALING_UNSPECIFIED; // Discard the back buffer contents after presenting. swapChainDesc.SwapEffect = DXGI_SWAP_EFFECT_DISCARD; // Don't set the advanced flags. swapChainDesc.Flags = 0; if(FAILED(result)) { MessageBox(NULL, L"Failed", NULL, NULL); return false; } //Create the D3D device //-------------------------------------------------------------- result = D3D10CreateDeviceAndSwapChain(NULL, D3D10_DRIVER_TYPE_HARDWARE, NULL, 0, D3D10_SDK_VERSION, &swapChainDesc, &m_swapChain, &m_pD3DDevice); if(FAILED(result)) { MessageBox(NULL, L"Failed to create the D3D device", NULL, NULL); return false; } return true; } bool dxD3D::createRenderTargetsAndDepthBuffer(UINT width, UINT height) { HRESULT result; result = m_swapChain->GetBuffer(0, __uuidof(ID3D10Texture2D), (LPVOID*)&pBackBuffer); if(FAILED(result)) { MessageBox(NULL, L"Failed to get the buffer", NULL, NULL); return false; } // Create the render target view with the back buffer pointer. result = m_pD3DDevice->CreateRenderTargetView(pBackBuffer, NULL, &m_renderTargetView); if(FAILED(result)) { MessageBox(NULL, L"Failed to create the render target view", NULL, NULL); return false; } pBackBuffer->Release(); pBackBuffer = 0; descDepth.Width = width; descDepth.Height = height; descDepth.MipLevels = 1; descDepth.ArraySize = 1; descDepth.Format = DXGI_FORMAT_D32_FLOAT; descDepth.SampleDesc.Count = 1; descDepth.SampleDesc.Quality = 0; descDepth.Usage = D3D10_USAGE_DEFAULT; descDepth.BindFlags = D3D10_BIND_DEPTH_STENCIL; descDepth.CPUAccessFlags = 0; descDepth.MiscFlags = 0; // Create the texture for the depth buffer using the filled out description. result = m_pD3DDevice->CreateTexture2D(&descDepth, NULL, &m_depthStencilBuffer); if(FAILED(result)) { return false; MessageBox(NULL, L"Failed to create the texture for the depth buffer", NULL, NULL); } // Initialize the description of the stencil state. ZeroMemory(&depthStencilDesc, sizeof(depthStencilDesc)); // Set up the description of the stencil state. depthStencilDesc.DepthEnable = true; depthStencilDesc.DepthWriteMask = D3D10_DEPTH_WRITE_MASK_ALL; depthStencilDesc.DepthFunc = D3D10_COMPARISON_LESS; depthStencilDesc.StencilEnable = true; depthStencilDesc.StencilReadMask = 0xFF; depthStencilDesc.StencilWriteMask = 0xFF; // Stencil operations if pixel is front-facing. depthStencilDesc.FrontFace.StencilFailOp = D3D10_STENCIL_OP_KEEP; depthStencilDesc.FrontFace.StencilDepthFailOp = D3D10_STENCIL_OP_INCR; depthStencilDesc.FrontFace.StencilPassOp = D3D10_STENCIL_OP_KEEP; depthStencilDesc.FrontFace.StencilFunc = D3D10_COMPARISON_ALWAYS; // Stencil operations if pixel is back-facing. depthStencilDesc.BackFace.StencilFailOp = D3D10_STENCIL_OP_KEEP; depthStencilDesc.BackFace.StencilDepthFailOp = D3D10_STENCIL_OP_DECR; depthStencilDesc.BackFace.StencilPassOp = D3D10_STENCIL_OP_KEEP; depthStencilDesc.BackFace.StencilFunc = D3D10_COMPARISON_ALWAYS; // Create the depth stencil state. result = m_pD3DDevice->CreateDepthStencilState(&depthStencilDesc, &m_depthStencilState); if(FAILED(result)) { MessageBox(NULL, L"Failed to create the depth stencil state", NULL, NULL); return false; } // Initialise the depth stencil view. ZeroMemory(&descDepth, sizeof(descDepth)); // Set up the depth stencil view description. descDSV.Format = descDepth.Format; descDSV.ViewDimension = D3D10_DSV_DIMENSION_TEXTURE2D; descDSV.Texture2D.MipSlice = 0; // Create the depth stencil view. result = m_pD3DDevice->CreateDepthStencilView(m_depthStencilBuffer, &descDSV, &m_depthStencilView); if(FAILED(result)) { MessageBox(NULL, L"Failed to create the depth stencil view", NULL, NULL); return false; } // Bind the render target view and depth stencil buffer to the output render pipeline. m_pD3DDevice->OMSetRenderTargets(1, &m_renderTargetView, m_depthStencilView); return true; } bool dxD3D::loadShadersAndCreateInputLayouts() { //technique HRESULT result; result = D3DX10CreateEffectFromFile(L"./basicEffect.fx", NULL, NULL, "fx_4_0", D3D10_SHADER_ENABLE_STRICTNESS, 0, m_pD3DDevice, NULL, NULL, &pBasicEffect, NULL, NULL ); if(!result) { MessageBox(NULL, L"Failed to load effect file", NULL, NULL); return false; } pBasicTechnique = pBasicEffect->GetTechniqueByName("render"); if(!pBasicTechnique) { MessageBox(NULL, L"Failed to retrieve technique", NULL, NULL); return false; } //create matrix effect pointers pViewMatrixEffectVariable = pBasicEffect->GetVariableByName( "View" )->AsMatrix(); pProjectionMatrixEffectVariable = pBasicEffect->GetVariableByName( "Projection" )->AsMatrix(); pWorldMatrixEffectVariable = pBasicEffect->GetVariableByName( "World" )->AsMatrix(); //create input layout D3D10_PASS_DESC PassDesc; pBasicTechnique->GetPassByIndex( 0 )->GetDesc( &PassDesc ); // Create the input layout. result = m_pD3DDevice->CreateInputLayout( vertexInputLayout, 2, PassDesc.pIAInputSignature, PassDesc.IAInputSignatureSize, &pVertexLayout ); if(FAILED(result)) { MessageBox(NULL, L"Failed to create the input layout", NULL, NULL); return false; } // Set the input layout m_pD3DDevice->IASetInputLayout( pVertexLayout ); //get technique description pBasicTechnique->GetDesc( &techDesc ); return true; } void dxD3D::shutDown() { // Before shutting down set to windowed mode or when you release the swap chain it will throw an exception. if(m_swapChain) { m_swapChain->SetFullscreenState(false, NULL); } if(m_rasterState) { m_rasterState->Release(); m_rasterState = 0; } if(m_depthStencilView) { m_depthStencilView->Release(); m_depthStencilView = 0; } if(m_depthStencilState) { m_depthStencilState->Release(); m_depthStencilState = 0; } if(m_depthStencilBuffer) { m_depthStencilBuffer->Release(); m_depthStencilBuffer = 0; } if(m_renderTargetView) { m_renderTargetView->Release(); m_renderTargetView = 0; } if(m_swapChain) { m_swapChain->Release(); m_swapChain = 0; } if(m_pD3DDevice) { m_pD3DDevice->Release(); m_pD3DDevice = 0; } } #endif