bool D3D10Renderer::Initialize(int screenWidth, int screenHeight) { HRESULT result; IDXGIFactory* factory; IDXGIAdapter* adapter; IDXGIOutput* adapterOutput; unsigned int numModes, i, numerator, denominator; numModes = 0; i = 0; numerator = 0; denominator = 0; DXGI_MODE_DESC* displayModeList; DXGI_SWAP_CHAIN_DESC swapChainDesc; ID3D10Texture2D* backBufferPtr; D3D10_TEXTURE2D_DESC depthBufferDesc; D3D10_DEPTH_STENCIL_DESC depthStencilDesc; D3D10_DEPTH_STENCIL_VIEW_DESC depthStencilViewDesc; D3D10_VIEWPORT viewport; float fieldOfView, screenAspect; D3D10_RASTERIZER_DESC rasterDesc; m_vsync_enabled = true; result = CreateDXGIFactory(__uuidof(IDXGIFactory), (void**)&factory); if(FAILED(result)) { return false; } result = factory->EnumAdapters(0, &adapter); if(FAILED(result)) { return false; } result = adapter->EnumOutputs(0, &adapterOutput); if(FAILED(result)) { return false; } result = adapterOutput->GetDisplayModeList(DXGI_FORMAT_R8G8B8A8_UNORM, DXGI_ENUM_MODES_INTERLACED, &numModes, NULL); if(FAILED(result)) { return false; } displayModeList = new DXGI_MODE_DESC[numModes]; if(!displayModeList) { return false; } result = adapterOutput->GetDisplayModeList(DXGI_FORMAT_R8G8B8A8_UNORM, DXGI_ENUM_MODES_INTERLACED, &numModes, displayModeList); if(FAILED(result)) { return false; } for(i=0; i<numModes; i++) { if(displayModeList[i].Width == (unsigned int)screenWidth) { if(displayModeList[i].Height == (unsigned int)screenHeight) { numerator = displayModeList[i].RefreshRate.Numerator; denominator = displayModeList[i].RefreshRate.Denominator; } } } delete[] displayModeList; displayModeList = 0; adapterOutput->Release(); adapterOutput = 0; adapter->Release(); adapter = 0; factory->Release(); factory = 0; ZeroMemory(&swapChainDesc, sizeof(swapChainDesc)); swapChainDesc.BufferCount = 1; swapChainDesc.BufferDesc.Width = screenWidth; swapChainDesc.BufferDesc.Height = screenHeight; swapChainDesc.BufferDesc.Format = DXGI_FORMAT_R8G8B8A8_UNORM; if(m_vsync_enabled) { swapChainDesc.BufferDesc.RefreshRate.Numerator = numerator; swapChainDesc.BufferDesc.RefreshRate.Denominator = denominator; } else { swapChainDesc.BufferDesc.RefreshRate.Numerator = 0; swapChainDesc.BufferDesc.RefreshRate.Denominator = 1; } swapChainDesc.BufferUsage = DXGI_USAGE_RENDER_TARGET_OUTPUT; swapChainDesc.OutputWindow = m_hwnd; swapChainDesc.SampleDesc.Count = 1; swapChainDesc.SampleDesc.Quality = 0; swapChainDesc.Windowed = true; swapChainDesc.BufferDesc.ScanlineOrdering = DXGI_MODE_SCANLINE_ORDER_UNSPECIFIED; swapChainDesc.BufferDesc.Scaling = DXGI_MODE_SCALING_UNSPECIFIED; swapChainDesc.SwapEffect = DXGI_SWAP_EFFECT_DISCARD; swapChainDesc.Flags = 0; result = D3D10CreateDeviceAndSwapChain(NULL, D3D10_DRIVER_TYPE_HARDWARE, NULL, 0, D3D10_SDK_VERSION, &swapChainDesc, &m_swapChain, &m_device); if(FAILED(result)) { return false; } result = m_swapChain->GetBuffer(0, __uuidof(ID3D10Texture2D), (LPVOID*)&backBufferPtr); if(FAILED(result)) { return false; } result = m_device->CreateRenderTargetView(backBufferPtr, NULL, &m_renderTargetView); if(FAILED(result)) { return false; } backBufferPtr->Release(); backBufferPtr = 0; ZeroMemory(&depthBufferDesc, sizeof(depthBufferDesc)); depthBufferDesc.Width = screenWidth; depthBufferDesc.Height = screenHeight; depthBufferDesc.MipLevels = 1; depthBufferDesc.ArraySize = 1; depthBufferDesc.Format = DXGI_FORMAT_D24_UNORM_S8_UINT; depthBufferDesc.SampleDesc.Count = 1; depthBufferDesc.SampleDesc.Quality = 0; depthBufferDesc.Usage = D3D10_USAGE_DEFAULT; depthBufferDesc.BindFlags = D3D10_BIND_DEPTH_STENCIL; depthBufferDesc.CPUAccessFlags = 0; depthBufferDesc.MiscFlags = 0; result = m_device->CreateTexture2D(&depthBufferDesc, NULL, &m_depthStencilBuffer); if(FAILED(result)) { return false; } ZeroMemory(&depthStencilDesc, sizeof(depthStencilDesc)); depthStencilDesc.DepthEnable = true; depthStencilDesc.DepthWriteMask = D3D10_DEPTH_WRITE_MASK_ALL; depthStencilDesc.DepthFunc = D3D10_COMPARISON_LESS; depthStencilDesc.StencilEnable = true; depthStencilDesc.StencilReadMask = 0xFF; depthStencilDesc.StencilWriteMask = 0xFF; 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; 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; result = m_device->CreateDepthStencilState(&depthStencilDesc, &m_depthStencilState); if(FAILED(result)) { return false; } m_device->OMSetDepthStencilState(m_depthStencilState, 1); ZeroMemory(&depthStencilViewDesc, sizeof(depthStencilViewDesc)); depthStencilViewDesc.Format = DXGI_FORMAT_D24_UNORM_S8_UINT; depthStencilViewDesc.ViewDimension = D3D10_DSV_DIMENSION_TEXTURE2D; depthStencilViewDesc.Texture2D.MipSlice = 0; result = m_device->CreateDepthStencilView(m_depthStencilBuffer, &depthStencilViewDesc, &m_depthStencilView); if(FAILED(result)) { return false; } m_device->OMSetRenderTargets(1, &m_renderTargetView, m_depthStencilView); 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; result = m_device->CreateRasterizerState(&rasterDesc, &m_rasterState); if(FAILED(result)) { return false; } m_device->RSSetState(m_rasterState); viewport.Width = screenWidth; viewport.Height = screenHeight; viewport.MinDepth = 0.0f; viewport.MaxDepth = 1.0f; viewport.TopLeftX = 0; viewport.TopLeftY = 0; m_device->RSSetViewports(1, &viewport); fieldOfView = (float)D3DX_PI / 4.0f; screenAspect = (float)screenWidth / (float)screenHeight; D3DXMatrixPerspectiveFovLH(&m_projectionMatrix, fieldOfView, screenAspect, SCREEN_NEAR, SCREEN_DEPTH); D3DXMatrixIdentity(&m_worldMatrix); D3DXMatrixOrthoLH(&m_orthoMatrix, (float)screenWidth, (float)screenHeight, SCREEN_NEAR, SCREEN_DEPTH); m_camera = new DxCamera(); if(!m_camera) { return false; } m_camera->SetPosition(0.0f, 6.0f, -20.0f); //////LOAD THE SHADER InitializeShader(L"../Yarr_sharp_eyes/Resources/color.fx"); m_model = new DX10Model(); m_model->Initialize("../Game/Resources/Models/cube.txt", m_device, 0.5f, 1.0f, 0.0, 1.0); return true; }
void GetDisplayDevices(DeviceOutputs &deviceList) { HRESULT err; deviceList.ClearData(); #ifdef USE_DXGI1_2 REFIID iidVal = OSGetVersion() >= 8 ? __uuidof(IDXGIFactory2) : __uuidof(IDXGIFactory1); #else REFIIF iidVal = __uuidof(IDXGIFactory1); #endif IDXGIFactory1 *factory; if(SUCCEEDED(err = CreateDXGIFactory1(iidVal, (void**)&factory))) { UINT i=0; IDXGIAdapter1 *giAdapter; while(factory->EnumAdapters1(i++, &giAdapter) == S_OK) { //Log(TEXT("------------------------------------------")); DXGI_ADAPTER_DESC adapterDesc; if(SUCCEEDED(err = giAdapter->GetDesc(&adapterDesc))) { if (adapterDesc.DedicatedVideoMemory != 0) { DeviceOutputData &deviceData = *deviceList.devices.CreateNew(); deviceData.strDevice = adapterDesc.Description; UINT j=0; IDXGIOutput *giOutput; while(giAdapter->EnumOutputs(j++, &giOutput) == S_OK) { DXGI_OUTPUT_DESC outputDesc; if(SUCCEEDED(giOutput->GetDesc(&outputDesc))) { if(outputDesc.AttachedToDesktop) { deviceData.monitorNameList << outputDesc.DeviceName; MonitorInfo &monitorInfo = *deviceData.monitors.CreateNew(); monitorInfo.hMonitor = outputDesc.Monitor; mcpy(&monitorInfo.rect, &outputDesc.DesktopCoordinates, sizeof(RECT)); switch (outputDesc.Rotation) { case DXGI_MODE_ROTATION_ROTATE90: monitorInfo.rotationDegrees = 90.0f; break; case DXGI_MODE_ROTATION_ROTATE180: monitorInfo.rotationDegrees = 180.0f; break; case DXGI_MODE_ROTATION_ROTATE270: monitorInfo.rotationDegrees = 270.0f; } } } giOutput->Release(); } } } else AppWarning(TEXT("Could not query adapter %u"), i); giAdapter->Release(); } factory->Release(); } }
/// ///The screenWidth and screenHeight variables that are given to this function are the width and ///height of the window we created in the SystemClass. Direct3D will use these to initialize and ///use the same window dimensions. The hwnd variable is a handle to the window. Direct3D will ///need this handle to access the window previously created. The fullscreen variable is whether ///we are running in windowed mode or fullscreen. Direct3D needs this as well for creating the ///window with the correct settings. The screenDepth and screenNear variables are the depth ///settings for our 3D environment that will be rendered in the window. The vsync variable ///indicates if we want Direct3D to render according to the users monitor refresh rate or to ///just go as fast as possible. /// bool D3DClass::Initialize(int screenWidth, int screenHeight, bool vsync, HWND hwnd, bool fullscreen, float screenDepth, float screenNear) { HRESULT result; IDXGIFactory* factory; IDXGIAdapter* adapter; IDXGIOutput* adapterOutput; unsigned int numModes, i, numerator, denominator, stringLength; DXGI_MODE_DESC* displayModeList; DXGI_ADAPTER_DESC adapterDesc; int error; DXGI_SWAP_CHAIN_DESC swapChainDesc; D3D_FEATURE_LEVEL featureLevel; ID3D11Texture2D* backBufferPtr; D3D11_TEXTURE2D_DESC depthBufferDesc; D3D11_DEPTH_STENCIL_DESC depthStencilDesc; D3D11_DEPTH_STENCIL_VIEW_DESC depthStencilViewDesc; D3D11_RASTERIZER_DESC rasterDesc; D3D11_VIEWPORT viewport; float fieldOfView, screenAspect; // Store the vsync setting. m_vsync_enabled = vsync; /* Before we can initialize Direct3D we have to get the refresh rate from the video card/monitor. Each computer may be slightly different so we will need to query for that information. We query for the numerator and denominator values and then pass them to DirectX during the setup and it will calculate the proper refresh rate. If we don't do this and just set the refresh rate to a default value which may not exist on all computers then DirectX will respond by performing a blit instead of a buffer flip which will degrade performance and give us annoying errors in the debug output. */ // Create a DirectX graphics interface factory. result = CreateDXGIFactory(__uuidof(IDXGIFactory), (void**)&factory); if (FAILED(result)) { return false; } // Use the factory to create an adapter for the primary graphics interface (video card). result = factory->EnumAdapters(0, &adapter); if (FAILED(result)) { return false; } // Enumerate the primary adapter output (monitor). result = adapter->EnumOutputs(0, &adapterOutput); if (FAILED(result)) { return false; } // Get the number of modes that fit the DXGI_FORMAT_R8G8B8A8_UNORM display format for the adapter output (monitor). result = adapterOutput->GetDisplayModeList(DXGI_FORMAT_R8G8B8A8_UNORM, DXGI_ENUM_MODES_INTERLACED, &numModes, NULL); if (FAILED(result)) { return false; } // Create a list to hold all the possible display modes for this monitor/video card combination. displayModeList = new DXGI_MODE_DESC[numModes]; if (!displayModeList) { return false; } // Now fill the display mode list structures. result = adapterOutput->GetDisplayModeList(DXGI_FORMAT_R8G8B8A8_UNORM, DXGI_ENUM_MODES_INTERLACED, &numModes, displayModeList); if (FAILED(result)) { return false; } // Now go through all the display modes and find the one that matches the screen width and height. // When a match is found store the numerator and denominator of the refresh rate for that monitor. for (i = 0; i < numModes; i++) { if (displayModeList[i].Width == (unsigned int)screenWidth) { if (displayModeList[i].Height == (unsigned int)screenHeight) { numerator = displayModeList[i].RefreshRate.Numerator; denominator = displayModeList[i].RefreshRate.Denominator; } } } /* We now have the numerator and denominator for the refresh rate. The last thing we will retrieve using the adapter is the name of the video card and the amount of memory on the video card. */ // Get the adapter (video card) description. result = adapter->GetDesc(&adapterDesc); if (FAILED(result)) { return false; } // Store the dedicated video card memory in megabytes. m_videoCardMemory = (int)(adapterDesc.DedicatedVideoMemory / 1024 / 1024); // Convert the name of the video card to a character array and store it. error = wcstombs_s(&stringLength, m_videoCardDescription, 128, adapterDesc.Description, 128); if (error != 0) { return false; } /* Now that we have stored the numerator and denominator for the refresh rate and the video card information we can release the structures and interfaces used to get that information. */ // Release the display mode list. delete[] displayModeList; displayModeList = nullptr; // Release the adapter output. adapterOutput->Release(); adapterOutput = nullptr; // Release the adapter. adapter->Release(); adapter = nullptr; // Release the factory. factory->Release(); factory = nullptr; /* Now that we have the refresh rate from the system we can start the DirectX initialization. The first thing we'll do is fill out the description of the swap chain. The swap chain is the front and back buffer to which the graphics will be drawn. Generally you use a single back buffer, do all your drawing to it, and then swap it to the front buffer which then displays on the user's screen. That is why it is called a swap chain. */ // 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 = screenWidth; swapChainDesc.BufferDesc.Height = screenHeight; // Set regular 32-bit surface for the back buffer. swapChainDesc.BufferDesc.Format = DXGI_FORMAT_R8G8B8A8_UNORM; /* The next part of the description of the swap chain is the refresh rate. The refresh rate is how many times a second it draws the back buffer to the front buffer. If vsync is set to true in our graphicsclass.h header then this will lock the refresh rate to the system settings (for example 60hz). That means it will only draw the screen 60 times a second (or higher if the system refresh rate is more than 60). However if we set vsync to false then it will draw the screen as many times a second as it can, however this can cause some visual artifacts. */ // Set the refresh rate of the back buffer. if (m_vsync_enabled) { swapChainDesc.BufferDesc.RefreshRate.Numerator = numerator; swapChainDesc.BufferDesc.RefreshRate.Denominator = denominator; } else { swapChainDesc.BufferDesc.RefreshRate.Numerator = 0; swapChainDesc.BufferDesc.RefreshRate.Denominator = 1; } // Set the usage of the back buffer. swapChainDesc.BufferUsage = DXGI_USAGE_RENDER_TARGET_OUTPUT; // Set the handle for the window to render to. swapChainDesc.OutputWindow = hwnd; // Turn multisampling off. swapChainDesc.SampleDesc.Count = 1; swapChainDesc.SampleDesc.Quality = 0; // Set to full screen or windowed mode. swapChainDesc.Windowed = !fullscreen; // 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; /* After setting up the swap chain description we also need to setup one more variable called the feature level. This variable tells DirectX what version we plan to use. Here we set the feature level to 11.0 which is DirectX 11. You can set this to 10 or 9 to use a lower level version of DirectX if you plan on supporting multiple versions or running on lower end hardware. */ // Set the feature level to DirectX 11. featureLevel = D3D_FEATURE_LEVEL_11_0; /* Now that the swap chain description and feature level have been filled out we can create the swap chain, the Direct3D device, and the Direct3D device context. */ // Create the swap chain, Direct3D device, and Direct3D device context. result = D3D11CreateDeviceAndSwapChain(NULL, D3D_DRIVER_TYPE_HARDWARE, NULL, 0, &featureLevel, 1, D3D11_SDK_VERSION, &swapChainDesc, &m_swapChain, &m_device, NULL, &m_deviceContext); if (FAILED(result)) { return false; } /* Now that we have a swap chain we need to get a pointer to the back buffer and then attach it to the swap chain. We'll use the CreateRenderTargetView function to attach the back buffer to our swap chain. */ // Get the pointer to the back buffer. result = m_swapChain->GetBuffer(0, __uuidof(ID3D11Texture2D), (LPVOID*)&backBufferPtr); if (FAILED(result)) { return false; } // Create the render target view with the back buffer pointer. result = m_device->CreateRenderTargetView(backBufferPtr, NULL, &m_renderTargetView); if (FAILED(result)) { return false; } // Release pointer to the back buffer as we no longer need it. backBufferPtr->Release(); backBufferPtr = nullptr; /* We will also need to set up a depth buffer description.We'll use this to create a depth buffer so that our polygons can be rendered properly in 3D space. At the same time we will attach a stencil buffer to our depth buffer. The stencil buffer can be used to achieve effects such as motion blur, volumetric shadows, and other things. */ // Initialize the description of the depth buffer. ZeroMemory(&depthBufferDesc, sizeof(depthBufferDesc)); // Set up the description of the depth buffer. depthBufferDesc.Width = screenWidth; depthBufferDesc.Height = screenHeight; depthBufferDesc.MipLevels = 1; depthBufferDesc.ArraySize = 1; depthBufferDesc.Format = DXGI_FORMAT_D24_UNORM_S8_UINT; depthBufferDesc.SampleDesc.Count = 1; depthBufferDesc.SampleDesc.Quality = 0; depthBufferDesc.Usage = D3D11_USAGE_DEFAULT; depthBufferDesc.BindFlags = D3D11_BIND_DEPTH_STENCIL; depthBufferDesc.CPUAccessFlags = 0; depthBufferDesc.MiscFlags = 0; /* Now we create the depth/stencil buffer using that description. You will notice we use the CreateTexture2D function to make the buffers, hence the buffer is just a 2D texture. The reason for this is that once your polygons are sorted and then rasterized they just end up being colored pixels in this 2D buffer. Then this 2D buffer is drawn to the screen. */ // Create the texture for the depth buffer using the filled out description. result = m_device->CreateTexture2D(&depthBufferDesc, NULL, &m_depthStencilBuffer); if (FAILED(result)) { return false; } /* Now we need to setup the depth stencil description. This allows us to control what type of depth test Direct3D will do for each pixel. */ // Initialize the description of the stencil state. ZeroMemory(&depthStencilDesc, sizeof(depthStencilDesc)); // Set up the description of the stencil state. depthStencilDesc.DepthEnable = true; depthStencilDesc.DepthWriteMask = D3D11_DEPTH_WRITE_MASK_ALL; depthStencilDesc.DepthFunc = D3D11_COMPARISON_LESS; depthStencilDesc.StencilEnable = true; depthStencilDesc.StencilReadMask = 0xFF; depthStencilDesc.StencilWriteMask = 0xFF; // Stencil operations if pixel is front-facing. depthStencilDesc.FrontFace.StencilFailOp = D3D11_STENCIL_OP_KEEP; depthStencilDesc.FrontFace.StencilDepthFailOp = D3D11_STENCIL_OP_INCR; depthStencilDesc.FrontFace.StencilPassOp = D3D11_STENCIL_OP_KEEP; depthStencilDesc.FrontFace.StencilFunc = D3D11_COMPARISON_ALWAYS; // Stencil operations if pixel is back-facing. depthStencilDesc.BackFace.StencilFailOp = D3D11_STENCIL_OP_KEEP; depthStencilDesc.BackFace.StencilDepthFailOp = D3D11_STENCIL_OP_DECR; depthStencilDesc.BackFace.StencilPassOp = D3D11_STENCIL_OP_KEEP; depthStencilDesc.BackFace.StencilFunc = D3D11_COMPARISON_ALWAYS; /* With the description filled out we can now create a depth stencil state. */ // Create the depth stencil state. result = m_device->CreateDepthStencilState(&depthStencilDesc, &m_depthStencilState); if (FAILED(result)) { return false; } /* With the created depth stencil state we can now set it so that it takes effect. Notice we use the device context to set it. */ // Set the depth stencil state. m_deviceContext->OMSetDepthStencilState(m_depthStencilState, 1); /* The next thing we need to create is the description of the view of the depth stencil buffer. We do this so that Direct3D knows to use the depth buffer as a depth stencil texture. After filling out the description we then call the function CreateDepthStencilView to create it. */ // Initailze the depth stencil view. ZeroMemory(&depthStencilViewDesc, sizeof(depthStencilViewDesc)); // Set up the depth stencil view description. depthStencilViewDesc.Format = DXGI_FORMAT_D24_UNORM_S8_UINT; depthStencilViewDesc.ViewDimension = D3D11_DSV_DIMENSION_TEXTURE2D; depthStencilViewDesc.Texture2D.MipSlice = 0; // Create the depth stencil view. result = m_device->CreateDepthStencilView(m_depthStencilBuffer, &depthStencilViewDesc, &m_depthStencilView); if (FAILED(result)) { return false; } /* With that created we can now call OMSetRenderTargets. This will bind the render target view and the depth stencil buffer to the output render pipeline. This way the graphics that the pipeline renders will get drawn to our back buffer that we previously created. With the graphics written to the back buffer we can then swap it to the front and display our graphics on the user's screen. */ // Bind the render target view and depth stencil buffer to the output render pipeline. m_deviceContext->OMSetRenderTargets(1, &m_renderTargetView, m_depthStencilView); /* Now that the render targets are setup we can continue on to some extra functions that will give us more control over our scenes for future tutorials. First thing is we'll create is a rasterizer state. This will give us control over how polygons are rendered. We can do things like make our scenes render in wireframe mode or have DirectX draw both the front and back faces of polygons. By default DirectX already has a rasterizer state set up and working the exact same as the one below but you have no control to change it unless you set up one yourself. */ // Setup the raster description which will determine how and what polygons will be drawn. rasterDesc.AntialiasedLineEnable = false; rasterDesc.CullMode = D3D11_CULL_BACK; rasterDesc.DepthBias = 0; rasterDesc.DepthBiasClamp = 0.0f; rasterDesc.DepthClipEnable = true; rasterDesc.FillMode = D3D11_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_device->CreateRasterizerState(&rasterDesc, &m_rasterState); if (FAILED(result)) { return false; } // Now set the rasterizer state. m_deviceContext->RSSetState(m_rasterState); /* The viewport also needs to be setup so that Direct3D can map clip space coordinates to the render target space. Set this to be the entire size of the window. */ // Setup the viewport for rendering. viewport.Width = (float)screenWidth; viewport.Height = (float)screenHeight; viewport.MinDepth = 0.0f; viewport.MaxDepth = 1.0f; viewport.TopLeftX = 0.0f; viewport.TopLeftY = 0.0f; // Create the viewport. m_deviceContext->RSSetViewports(1, &viewport); /* Now we will create the projection matrix. The projection matrix is used to translate the 3D scene into the 2D viewport space that we previously created. We will need to keep a copy of this matrix so that we can pass it to our shaders that will be used to render our scenes. */ // Setup the projection matrix. fieldOfView = (float)XM_PI / 4.0f; screenAspect = (float)screenWidth / (float)screenHeight; // Create the projection matrix for 3D rendering. m_projectionMatrix = XMMatrixPerspectiveFovLH(fieldOfView, screenAspect, screenNear, screenDepth); /* We will also create another matrix called the world matrix. This matrix is used to convert the vertices of our objects into vertices in the 3D scene. This matrix will also be used to rotate, translate, and scale our objects in 3D space. From the start we will just initialize the matrix to the identity matrix and keep a copy of it in this object. The copy will be needed to be passed to the shaders for rendering also. */ // Initialize the world matrix to the identity matrix. m_worldMatrix = XMMatrixIdentity(); /* This is where you would generally create a view matrix. The view matrix is used to calculate the position of where we are looking at the scene from. You can think of it as a camera and you only view the scene through this camera. Because of its purpose I am going to create it in a camera class instead. */ /* And the final thing we will setup in the Initialize function is an orthographic projection matrix. This matrix is used for rendering 2D elements like user interfaces on the screen allowing us to skip the 3D rendering. */ // Create an orthographic projection matrix for 2D rendering. m_orthoMatrix = XMMatrixOrthographicLH((float)screenWidth, (float)screenHeight, screenNear, screenDepth); return true; }
bool D3DClass::Initialize(int screenWidth, int screenHeight, bool vsync, HWND hwnd, bool fullscreen, float screenDepth, float screenNear) { HRESULT result; IDXGIFactory* factory; IDXGIAdapter* adapter; IDXGIOutput* adapterOutput; unsigned int numModes, i, numerator, denominator, stringLength; DXGI_MODE_DESC* displayModeList; DXGI_ADAPTER_DESC adapterDesc; int error; DXGI_SWAP_CHAIN_DESC swapChainDesc; ID3D10Texture2D* backBufferPtr; D3D10_TEXTURE2D_DESC depthBufferDesc; D3D10_DEPTH_STENCIL_DESC depthStencilDesc; D3D10_DEPTH_STENCIL_VIEW_DESC depthStencilViewDesc; D3D10_VIEWPORT viewport; float fieldOfView, screenAspect; D3D10_RASTERIZER_DESC rasterDesc; // Store the vsync setting. m_vsync_enabled = vsync; //z 2015-07-28 15:23 Creates a DXGI 1.0 factory that you can use to generate other DXGI objects. // Create a DirectX graphics interface factory. result = CreateDXGIFactory(__uuidof(IDXGIFactory), (void**)&factory); if(FAILED(result)) { return false; } //z 2015-07-28 15:23 Enumerates the adapters (video cards). // Use the factory to create an adapter for the primary graphics interface (video card). /* When you create a factory, the factory enumerates the set of adapters that are available in the system. Therefore, if you change the adapters in a system, you must destroy and recreate the IDXGIFactory object. The number of adapters in a system changes when you add or remove a display card, or dock or undock a laptop. When the EnumAdapters method succeeds and fills the ppAdapter parameter with the address of the pointer to the adapter interface, EnumAdapters increments the adapter interface's reference count. When you finish using the adapter interface, call the Release method to decrement the reference count before you destroy the pointer. EnumAdapters first returns the adapter with the output on which the desktop primary is displayed. This adapter corresponds with an index of zero. EnumAdapters next returns other adapters with outputs. EnumAdapters finally returns adapters without outputs. */ //z 枚举 adapter 的例子 /* UINT i = 0; IDXGIAdapter * pAdapter; std::vector <IDXGIAdapter*> vAdapters; while(pFactory->EnumAdapters(i, &pAdapter) != DXGI_ERROR_NOT_FOUND) { vAdapters.push_back(pAdapter); ++i; }*/ result = factory->EnumAdapters(0, &adapter); if(FAILED(result)) { return false; } //z 2015-07-28 15:29 Enumerate adapter (video card) outputs. // Enumerating Outputs. Here is an example of how to use EnumOutputs to enumerate all the outputs on an adapter: /* //z UINT i = 0; IDXGIOutput * pOutput; std::vector<IDXGIOutput*> vOutputs; while(pAdapter->EnumOutputs(i, &pOutput) != DXGI_ERROR_NOT_FOUND) { vOutputs.push_back(pOutput); ++i; } */ // Enumerate the primary adapter output (monitor). result = adapter->EnumOutputs(0, &adapterOutput); if(FAILED(result)) { return false; } //z 2015-07-28 15:31 Gets the display modes that match the requested format and other input options. // Get the number of modes that fit the DXGI_FORMAT_R8G8B8A8_UNORM display format for the adapter output (monitor). /* pNumModes [in, out] Type: UINT* Set pDesc to NULL so that pNumModes returns the number of display modes that match the format and the options. Otherwise, pNumModes returns the number of display modes returned in pDesc. As shown, this API is designed to be called twice. First to get the number of modes available, and second to return a description of the modes. //z 2015-07-28 15:34 例子 UINT num = 0; DXGI_FORMAT format = DXGI_FORMAT_R32G32B32A32_FLOAT; UINT flags = DXGI_ENUM_MODES_INTERLACED; pOutput->GetDisplayModeList( format, flags, &num, 0); ... DXGI_MODE_DESC * pDescs = new DXGI_MODE_DESC[num]; pOutput->GetDisplayModeList( format, flags, &num, pDescs); */ result = adapterOutput->GetDisplayModeList(DXGI_FORMAT_R8G8B8A8_UNORM, DXGI_ENUM_MODES_INTERLACED, &numModes, NULL); if(FAILED(result)) { return false; } // Create a list to hold all the possible display modes for this monitor/video card combination. displayModeList = new DXGI_MODE_DESC[numModes]; if(!displayModeList) { return false; } // Now fill the display mode list structures. result = adapterOutput->GetDisplayModeList(DXGI_FORMAT_R8G8B8A8_UNORM, DXGI_ENUM_MODES_INTERLACED, &numModes, displayModeList); if(FAILED(result)) { return false; } // Now go through all the display modes and find the one that matches the screen width and height. // When a match is found store the numerator and denominator of the refresh rate for that monitor. for(i=0; i<numModes; i++) { if(displayModeList[i].Width == (unsigned int)screenWidth) { if(displayModeList[i].Height == (unsigned int)screenHeight) { //z 便利 display mode ,设置 numerator 以及 denominator 。 numerator = displayModeList[i].RefreshRate.Numerator; denominator = displayModeList[i].RefreshRate.Denominator; } } } //z 2015-07-28 15:39 Gets a DXGI 1.0 description of an adapter (or video card). /* Graphics driver model determination — Because DXGI is only available on systems with WDDM drivers, the app must first confirm the driver model by using the following API. //z 调用一次,将结果保存起来。 bool HasWDDMDriver() { LPDIRECT3DCREATE9EX pD3D9Create9Ex = NULL; HMODULE hD3D9 = NULL; hD3D9 = LoadLibrary( L"d3d9.dll" ); if ( NULL == hD3D9 ) { return false; } // // Try to create IDirect3D9Ex interface (also known as a DX9L interface). This interface can only be created if the driver is a WDDM driver. pD3D9Create9Ex = (LPDIRECT3DCREATE9EX) GetProcAddress( hD3D9, "Direct3DCreate9Ex" ); return pD3D9Create9Ex != NULL; } */ // Get the adapter (video card) description. result = adapter->GetDesc(&adapterDesc); if(FAILED(result)) { return false; } // Store the dedicated video card memory in megabytes. //z 记录下内存的数量 m_videoCardMemory = (int)(adapterDesc.DedicatedVideoMemory / 1024 / 1024); // Convert the name of the video card to a character array and store it. //z 记住 adapter 的 description error = wcstombs_s(&stringLength, m_videoCardDescription, 128, adapterDesc.Description, 128); if(error != 0) { return false; } // Release the display mode list. delete [] displayModeList; displayModeList = 0; // Release the adapter output. //z 释放与获取的顺序相反 adapterOutput->Release(); adapterOutput = 0; // Release the adapter. adapter->Release(); adapter = 0; // Release the factory. factory->Release(); factory = 0; // 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 = screenWidth; swapChainDesc.BufferDesc.Height = screenHeight; // Set regular 32-bit surface for the back buffer. swapChainDesc.BufferDesc.Format = DXGI_FORMAT_R8G8B8A8_UNORM; // Set the refresh rate of the back buffer. if(m_vsync_enabled) { swapChainDesc.BufferDesc.RefreshRate.Numerator = numerator; swapChainDesc.BufferDesc.RefreshRate.Denominator = denominator; } else { swapChainDesc.BufferDesc.RefreshRate.Numerator = 0; swapChainDesc.BufferDesc.RefreshRate.Denominator = 1; } // Set the usage of the back buffer. swapChainDesc.BufferUsage = DXGI_USAGE_RENDER_TARGET_OUTPUT; // Set the handle for the window to render to. swapChainDesc.OutputWindow = hwnd; // Turn multisampling off. swapChainDesc.SampleDesc.Count = 1; swapChainDesc.SampleDesc.Quality = 0; // Set to full screen or windowed mode. if(fullscreen) { swapChainDesc.Windowed = false; } else { swapChainDesc.Windowed = true; } // 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; //z 2015-07-28 16:02 同时创建 device 以及 swapchain 。 // Create the swap chain and the Direct3D device. result = D3D10CreateDeviceAndSwapChain(NULL, D3D10_DRIVER_TYPE_HARDWARE, NULL, 0, D3D10_SDK_VERSION, &swapChainDesc, &m_swapChain, &m_device); if(FAILED(result)) { return false; } // Get the pointer to the back buffer. result = m_swapChain->GetBuffer(0, __uuidof(ID3D10Texture2D), (LPVOID*)&backBufferPtr); if(FAILED(result)) { return false; } // Create the render target view with the back buffer pointer. //z 由 back buffer pointer 创建 render target view。 result = m_device->CreateRenderTargetView(backBufferPtr, NULL, &m_renderTargetView); if(FAILED(result)) { return false; } // Release pointer to the back buffer as we no longer need it. //z 不需要则 release。 backBufferPtr->Release(); backBufferPtr = 0; // Initialize the description of the depth buffer. ZeroMemory(&depthBufferDesc, sizeof(depthBufferDesc)); // Set up the description of the depth buffer. depthBufferDesc.Width = screenWidth; depthBufferDesc.Height = screenHeight; depthBufferDesc.MipLevels = 1; depthBufferDesc.ArraySize = 1; depthBufferDesc.Format = DXGI_FORMAT_D24_UNORM_S8_UINT; depthBufferDesc.SampleDesc.Count = 1; depthBufferDesc.SampleDesc.Quality = 0; depthBufferDesc.Usage = D3D10_USAGE_DEFAULT; depthBufferDesc.BindFlags = D3D10_BIND_DEPTH_STENCIL; depthBufferDesc.CPUAccessFlags = 0; depthBufferDesc.MiscFlags = 0; //z 创建一个 texture 2d 。 // Create the texture for the depth buffer using the filled out description. result = m_device->CreateTexture2D(&depthBufferDesc, NULL, &m_depthStencilBuffer); if(FAILED(result)) { return false; } // 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_device->CreateDepthStencilState(&depthStencilDesc, &m_depthStencilState); if(FAILED(result)) { return false; } // Set the depth stencil state on the D3D device. m_device->OMSetDepthStencilState(m_depthStencilState, 1); // Initailze the depth stencil view. ZeroMemory(&depthStencilViewDesc, sizeof(depthStencilViewDesc)); // Set up the depth stencil view description. depthStencilViewDesc.Format = DXGI_FORMAT_D24_UNORM_S8_UINT; depthStencilViewDesc.ViewDimension = D3D10_DSV_DIMENSION_TEXTURE2D; depthStencilViewDesc.Texture2D.MipSlice = 0; // Create the depth stencil view. result = m_device->CreateDepthStencilView(m_depthStencilBuffer, &depthStencilViewDesc, &m_depthStencilView); if(FAILED(result)) { return false; } // Bind the render target view and depth stencil buffer to the output render pipeline. m_device->OMSetRenderTargets(1, &m_renderTargetView, m_depthStencilView); // 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_device->CreateRasterizerState(&rasterDesc, &m_rasterState); if(FAILED(result)) { return false; } // Now set the rasterizer state. m_device->RSSetState(m_rasterState); // Setup the viewport for rendering. viewport.Width = screenWidth; viewport.Height = screenHeight; viewport.MinDepth = 0.0f; viewport.MaxDepth = 1.0f; viewport.TopLeftX = 0; viewport.TopLeftY = 0; // Create the viewport. m_device->RSSetViewports(1, &viewport); // Setup the projection matrix. fieldOfView = (float)D3DX_PI / 4.0f; screenAspect = (float)screenWidth / (float)screenHeight; // Create the projection matrix for 3D rendering. D3DXMatrixPerspectiveFovLH(&m_projectionMatrix, fieldOfView, screenAspect, screenNear, screenDepth); // Initialize the world matrix to the identity matrix. D3DXMatrixIdentity(&m_worldMatrix); // Create an orthographic projection matrix for 2D rendering. D3DXMatrixOrthoLH(&m_orthoMatrix, (float)screenWidth, (float)screenHeight, screenNear, screenDepth); return true; }
bool DX11Render::Initialize(int screenWidth, int screenHeight, bool fullscreen, HWND hwnd) { HRESULT result; IDXGIFactory* factory; IDXGIAdapter* adapter; IDXGIOutput* adapterOutput; unsigned int numModes, numerator, denominator, stringLength; DXGI_MODE_DESC* displayModeList; DXGI_ADAPTER_DESC adapterDesc; int error; DXGI_SWAP_CHAIN_DESC swapChainDesc; D3D_FEATURE_LEVEL featureLevel; ID3D11Texture2D* backBufferPtr; D3D11_TEXTURE2D_DESC depthBufferDesc; D3D11_DEPTH_STENCIL_DESC depthStencilDesc; D3D11_DEPTH_STENCIL_VIEW_DESC depthStencilViewDesc; D3D11_RASTERIZER_DESC rasterDesc; D3D11_VIEWPORT viewport; float fieldOfView, screenAspect; m_vsync_enabled = VSYNC_ENABLED; //Dx Graphics interface factory result = CreateDXGIFactory(__uuidof(IDXGIFactory), (void**)&factory); if(FAILED(result)) return false; //Factory is used to create adapter result = factory->EnumAdapters(0, &adapter); if(FAILED(result)) return false; //Enumerate the adapter output (monitor) result = adapter->EnumOutputs(0, &adapterOutput); if(FAILED(result)) return false; //Get # modes that fit format result = adapterOutput->GetDisplayModeList(DXGI_FORMAT_R8G8B8A8_UNORM, DXGI_ENUM_MODES_INTERLACED, &numModes, NULL); if(FAILED(result)) return false; //create list for display modes displayModeList = new DXGI_MODE_DESC[numModes]; if(!displayModeList) return false; //fill mode list result = adapterOutput->GetDisplayModeList(DXGI_FORMAT_R8G8B8A8_UNORM, DXGI_ENUM_MODES_INTERLACED, &numModes, displayModeList); if(FAILED(result)) return false; //go through list and find one that matches current monitor settings for(unsigned int i = 0; i < numModes; i++) { if(displayModeList[i].Width == (unsigned int)screenWidth) { if(displayModeList[i].Height == (unsigned int)screenHeight) { numerator = displayModeList[i].RefreshRate.Numerator; denominator = displayModeList[i].RefreshRate.Denominator; } } } //Get adapter desc. result = adapter->GetDesc(&adapterDesc); if(FAILED(result)) return false; //Get MB of video card m_videoCardMemory = (int)(adapterDesc.DedicatedVideoMemory / 1024 / 1024); //Convert Video Card desc to char array error = wcstombs_s(&stringLength, m_videoCardDescription, 128, adapterDesc.Description, 128); if(error != 0) return false; //release video card data delete [] displayModeList; displayModeList = 0; //Not needed, will go out of scope right after? adapterOutput->Release(); adapterOutput = 0; //Not needed, will go out of scope right after? adapter->Release(); adapter = 0; //Not needed, will go out of scope right after? factory->Release(); factory = 0; //Not needed, will go out of scope right after? //init swap chain ZeroMemory(&swapChainDesc, sizeof(swapChainDesc)); swapChainDesc.BufferCount = 1; swapChainDesc.BufferDesc.Width = screenWidth; swapChainDesc.BufferDesc.Height = screenHeight; swapChainDesc.BufferDesc.Format = DXGI_FORMAT_R8G8B8A8_UNORM; if(m_vsync_enabled) { swapChainDesc.BufferDesc.RefreshRate.Numerator = numerator; swapChainDesc.BufferDesc.RefreshRate.Denominator = denominator; } else { swapChainDesc.BufferDesc.RefreshRate.Numerator = 0; swapChainDesc.BufferDesc.RefreshRate.Denominator = 1; } //set scan line and scaling swapChainDesc.BufferDesc.ScanlineOrdering = DXGI_MODE_SCANLINE_ORDER_UNSPECIFIED; swapChainDesc.BufferDesc.Scaling = DXGI_MODE_SCALING_UNSPECIFIED; //set buffer usage swapChainDesc.BufferUsage = DXGI_USAGE_RENDER_TARGET_OUTPUT; //set handle swapChainDesc.OutputWindow = hwnd; //turn multisample off swapChainDesc.SampleDesc.Count = 1; swapChainDesc.SampleDesc.Quality = 0; //set fullscreen if(fullscreen) swapChainDesc.Windowed = false; else swapChainDesc.Windowed = true; //set swap effect swapChainDesc.SwapEffect = DXGI_SWAP_EFFECT_DISCARD; //dont set flags swapChainDesc.Flags = 0; //set dx level featureLevel = D3D_FEATURE_LEVEL_11_0; //Create the swap chain, d3d device and device context result = D3D11CreateDeviceAndSwapChain(NULL, D3D_DRIVER_TYPE_HARDWARE, NULL, 0, &featureLevel, 1, D3D11_SDK_VERSION, &swapChainDesc, &m_swapChain, &m_device, NULL, &m_deviceContext); if(FAILED(result)) return false; //get pointer to back buffer result = m_swapChain->GetBuffer(0, __uuidof(ID3D11Texture2D), (LPVOID*)&backBufferPtr); if(FAILED(result)) return false; //create render target result = m_device->CreateRenderTargetView(backBufferPtr, NULL, &m_renderTargetView); if(FAILED(result)) return false; //release pointer to back buffer backBufferPtr->Release(); backBufferPtr = 0; //Setup depth buffer desc. ZeroMemory(&depthBufferDesc, sizeof(depthBufferDesc)); depthBufferDesc.Width = screenWidth; depthBufferDesc.Height = screenHeight; depthBufferDesc.MipLevels = 1; depthBufferDesc.ArraySize = 1; depthBufferDesc.Format = DXGI_FORMAT_D24_UNORM_S8_UINT; depthBufferDesc.SampleDesc.Count = 1; depthBufferDesc.SampleDesc.Quality = 0; depthBufferDesc.Usage = D3D11_USAGE_DEFAULT; depthBufferDesc.BindFlags = D3D11_BIND_DEPTH_STENCIL; depthBufferDesc.CPUAccessFlags = 0; depthBufferDesc.MiscFlags = 0; //create depth buffer result = m_device->CreateTexture2D(&depthBufferDesc, NULL, &m_depthStencilBuffer); if(FAILED(result)) return false; //setup depth stencil desc. ZeroMemory(&depthStencilDesc, sizeof(depthStencilDesc)); depthStencilDesc.DepthEnable = true; depthStencilDesc.DepthWriteMask = D3D11_DEPTH_WRITE_MASK_ALL; depthStencilDesc.DepthFunc = D3D11_COMPARISON_LESS; depthStencilDesc.StencilEnable = true; depthStencilDesc.StencilReadMask = 0xFF; depthStencilDesc.StencilWriteMask = 0xFF; // Stencil operations if pixel is front-facing. depthStencilDesc.FrontFace.StencilFailOp = D3D11_STENCIL_OP_KEEP; depthStencilDesc.FrontFace.StencilDepthFailOp = D3D11_STENCIL_OP_INCR; depthStencilDesc.FrontFace.StencilPassOp = D3D11_STENCIL_OP_KEEP; depthStencilDesc.FrontFace.StencilFunc = D3D11_COMPARISON_ALWAYS; // Stencil operations if pixel is back-facing. depthStencilDesc.BackFace.StencilFailOp = D3D11_STENCIL_OP_KEEP; depthStencilDesc.BackFace.StencilDepthFailOp = D3D11_STENCIL_OP_DECR; depthStencilDesc.BackFace.StencilPassOp = D3D11_STENCIL_OP_KEEP; depthStencilDesc.BackFace.StencilFunc = D3D11_COMPARISON_ALWAYS; //create depth stencil result = m_device->CreateDepthStencilState(&depthStencilDesc, &m_depthStencilState); if(FAILED(result)) return false; //set the depth stencil state m_deviceContext->OMSetDepthStencilState(m_depthStencilState, 1); //create stencil view desc ZeroMemory(&depthStencilViewDesc, sizeof(depthStencilViewDesc)); depthStencilViewDesc.Format = DXGI_FORMAT_D24_UNORM_S8_UINT; depthStencilViewDesc.ViewDimension = D3D11_DSV_DIMENSION_TEXTURE2D; depthStencilViewDesc.Texture2D.MipSlice = 0; //create depth stencil view result = m_device->CreateDepthStencilView(m_depthStencilBuffer, &depthStencilViewDesc, &m_depthStencilView); if(FAILED(result)) return false; //bind render target view and depth stencil buffer to output m_deviceContext->OMSetRenderTargets(1, &m_renderTargetView, m_depthStencilView); //create raster control desc. rasterDesc.AntialiasedLineEnable = false; rasterDesc.CullMode = D3D11_CULL_BACK; rasterDesc.DepthBias = 0; rasterDesc.DepthBiasClamp = 0.0f; rasterDesc.DepthClipEnable = true; rasterDesc.FillMode = D3D11_FILL_SOLID; rasterDesc.FrontCounterClockwise = false; rasterDesc.MultisampleEnable = false; rasterDesc.ScissorEnable = false; rasterDesc.SlopeScaledDepthBias = 0.0f; //create raster state result = m_device->CreateRasterizerState(&rasterDesc, &m_rasterState); if(FAILED(result)) return false; //now set state m_deviceContext->RSSetState(m_rasterState); //setup viewport viewport.Width = (float)screenWidth; viewport.Height = (float)screenHeight; viewport.MinDepth = 0.0f; viewport.MaxDepth = 1.0f; viewport.TopLeftX = 0.0f; viewport.TopLeftY = 0.0f; //create viewport m_deviceContext->RSSetViewports(1, &viewport); //setup projetion matrix fieldOfView = (float)D3DX_PI / 4.0f; screenAspect = (float)screenWidth / (float)screenHeight; //create projection matrix D3DXMatrixPerspectiveFovLH(&m_projectionMatrix, fieldOfView, screenAspect, SCREEN_NEAR, SCREEN_DEPTH); //create world matrix D3DXMatrixIdentity(&m_worldMatrix); //create orthogonal projection matrix D3DXMatrixOrthoLH(&m_orthoMatrix, (float)screenWidth, (float)screenHeight, SCREEN_NEAR, SCREEN_DEPTH); //Tell someone we did well MessageManager::Instance()->NotifyHandlers(DEFAULT_MSG, "Default:\t DX11Renderer Init Complete."); return true; }
bool D3DClass::Initialize( int screenWidth, int screenHeight, bool vsync, HWND hwnd, bool fullscreen, float screenDepth, float screenNear ) { HRESULT result; IDXGIFactory* factory; IDXGIAdapter* adapter; IDXGIOutput* adapterOutput; unsigned int numModes, i, numerator, denominator, stringLength; DXGI_MODE_DESC* displayModeList; DXGI_ADAPTER_DESC adapterDesc; int error; DXGI_SWAP_CHAIN_DESC swapChainDesc; D3D_FEATURE_LEVEL featureLevel; ID3D11Texture2D* backBufferPtr; D3D11_TEXTURE2D_DESC depthBufferDesc; D3D11_DEPTH_STENCIL_DESC depthStencilDesc; D3D11_DEPTH_STENCIL_VIEW_DESC depthStencilViewDesc; D3D11_RASTERIZER_DESC rasterDesc; D3D11_VIEWPORT viewport; float fieldOfView, screenAspect; D3D11_BLEND_DESC blendStateDescription; m_vsync_enabled = vsync; //Store the vsync setting result = CreateDXGIFactory(__uuidof(IDXGIFactory), (void**)&factory); //creating a directx graphics interface factory, sends in the GUID of "IDXGIFactory" and a reference to our factory which is a pointer to an IDXGIFactory, but type casted as a pointer to a void pointer if(FAILED(result)) { return false; } result = factory->EnumAdapters(0, &adapter); //put an adapter for our video card into "adapter" if(FAILED(result)) { return false; } result = adapter->EnumOutputs(0, &adapterOutput); //enumerate the primary adapter output (monitor). if(FAILED(result)) { return false; } result = adapterOutput->GetDisplayModeList( //get the number of modes that fit this display format for the monitor DXGI_FORMAT_R8G8B8A8_UNORM, DXGI_ENUM_MODES_INTERLACED, &numModes, NULL ); if(FAILED(result)) { return false; } displayModeList = new DXGI_MODE_DESC[numModes]; //create an array of DXGI_MODE_DESC with the length of the number of compatible modes available if(!displayModeList) { return false; } result = adapterOutput->GetDisplayModeList( //now actually fill that displayModeList with all those display modes DXGI_FORMAT_R8G8B8A8_UNORM, DXGI_ENUM_MODES_INTERLACED, &numModes, displayModeList ); if(FAILED(result)) { return false; } //now go through all the display modes and find the one that matches the screen width and height. //when a match is found store the numerator and denominator of the refresh rate for that monitor. for(i = 0; i < numModes; i++) { if(displayModeList[i].Width == (unsigned int)screenWidth) { if(displayModeList[i].Height == (unsigned int)screenHeight) { numerator = displayModeList[i].RefreshRate.Numerator; denominator = displayModeList[i].RefreshRate.Denominator; } } } result = adapter->GetDesc(&adapterDesc); //get the video card description if(FAILED(result)) { return false; } m_videoCardMemory = (int)(adapterDesc.DedicatedVideoMemory / 1024 / 1024); //get the amount of video memory in bytes, devide by 1024 twice to get in megabytes error = wcstombs_s(&stringLength, m_videoCardDescription, 128, adapterDesc.Description, 128); //convert the name of the video card to a character array and store it if(error != 0) { return false; } //we will now release the structures and interfaces used to get the numerator and denominator for the refresh rate and video card information delete[] displayModeList; displayModeList = 0; adapterOutput->Release(); adapterOutput = 0; adapter->Release(); adapter = 0; factory->Release(); factory = 0; //now we will start the directx initialization, starting with the swap chain ZeroMemory(&swapChainDesc, sizeof(swapChainDesc)); //initialize swap chain description swapChainDesc.BufferCount = 1; //set the backbuffer count to 1 //set the size of the backbuffer to match the size of the client window swapChainDesc.BufferDesc.Width = screenWidth; swapChainDesc.BufferDesc.Height = screenHeight; swapChainDesc.BufferDesc.Format = DXGI_FORMAT_R8G8B8A8_UNORM; //set the format of the back buffer to 32bit //backbuffer refresh rate getting set if(m_vsync_enabled) //if vsync is on, set the refresh rate to the system refresh rate { swapChainDesc.BufferDesc.RefreshRate.Numerator = numerator; swapChainDesc.BufferDesc.RefreshRate.Denominator= denominator; } else //otherwise, set it to infinite { swapChainDesc.BufferDesc.RefreshRate.Numerator = 0; swapChainDesc.BufferDesc.RefreshRate.Denominator= 1; } swapChainDesc.BufferUsage = DXGI_USAGE_RENDER_TARGET_OUTPUT; //set the usage of the back buffer swapChainDesc.OutputWindow = hwnd; //give it our window handle that it shuold render to //turn MSAA off, multisampling anti-aliasing swapChainDesc.SampleDesc.Count = 1; swapChainDesc.SampleDesc.Quality = 0; //set fullscreen on or off if(fullscreen) { swapChainDesc.Windowed = false; } else { swapChainDesc.Windowed = true; } //set 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 avanced flags swapChainDesc.Flags = 0; featureLevel = D3D_FEATURE_LEVEL_11_0; //set feature level to dx11 result = D3D11CreateDeviceAndSwapChain( //create the swap chain, direct3d devide and direct3d device context NULL, D3D_DRIVER_TYPE_HARDWARE, //D3D_DRIVER_TYPE_REFERENCE, //uncomment this line and comment the above line to use software rendering NULL, 0, &featureLevel, 1, D3D11_SDK_VERSION, &swapChainDesc, &m_swapChain, &m_device, NULL, &m_deviceContext ); if(FAILED(result)) { return false; } result = m_swapChain->GetBuffer(0, __uuidof(ID3D11Texture2D), (LPVOID*)&backBufferPtr); //get the pointer to the back buffer if(FAILED(result)) { return false; } result = m_device->CreateRenderTargetView(backBufferPtr, NULL, &m_renderTargetView); //create the render target view with the back buffer pointer if(FAILED(result)) { return false; } //release the pointer to the back buffer backBufferPtr->Release(); backBufferPtr = 0; ZeroMemory(&depthBufferDesc, sizeof(depthBufferDesc)); //initialize the description of the depth buffer //set up the description of the depth buffer depthBufferDesc.Width = screenWidth; depthBufferDesc.Height = screenHeight; depthBufferDesc.MipLevels = 1; depthBufferDesc.ArraySize = 1; depthBufferDesc.Format = DXGI_FORMAT_D24_UNORM_S8_UINT; depthBufferDesc.SampleDesc.Count = 1; depthBufferDesc.SampleDesc.Quality = 0; depthBufferDesc.Usage = D3D11_USAGE_DEFAULT; depthBufferDesc.BindFlags = D3D11_BIND_DEPTH_STENCIL; depthBufferDesc.CPUAccessFlags = 0; depthBufferDesc.MiscFlags = 0; result = m_device->CreateTexture2D( //create the texture for the depth buffer using the filled out description &depthBufferDesc, NULL, &m_depthStencilBuffer ); if(FAILED(result)) { return false; } ZeroMemory(&depthStencilDesc, sizeof(depthStencilDesc)); //initialize the description of the stencil state //set up the description of the stencil state depthStencilDesc.DepthEnable = true; depthStencilDesc.DepthWriteMask = D3D11_DEPTH_WRITE_MASK_ALL; depthStencilDesc.DepthFunc = D3D11_COMPARISON_LESS; //compare what's there and take the lowest value? depthStencilDesc.StencilEnable = true; depthStencilDesc.StencilReadMask = 0xFF; depthStencilDesc.StencilWriteMask = 0xFF; //stencil operations if pixel is front-facing depthStencilDesc.FrontFace.StencilFailOp = D3D11_STENCIL_OP_KEEP; depthStencilDesc.FrontFace.StencilDepthFailOp = D3D11_STENCIL_OP_INCR; depthStencilDesc.FrontFace.StencilPassOp = D3D11_STENCIL_OP_KEEP; depthStencilDesc.FrontFace.StencilFunc = D3D11_COMPARISON_ALWAYS; //stencil operations if pixes is back-facing depthStencilDesc.BackFace.StencilFailOp = D3D11_STENCIL_OP_KEEP; depthStencilDesc.BackFace.StencilDepthFailOp = D3D11_STENCIL_OP_DECR; depthStencilDesc.BackFace.StencilPassOp = D3D11_STENCIL_OP_KEEP; depthStencilDesc.BackFace.StencilFunc = D3D11_COMPARISON_ALWAYS; result = m_device->CreateDepthStencilState(&depthStencilDesc, &m_depthStencilState); //create the depth stencil state if(FAILED(result)) { return false; } m_deviceContext->OMSetDepthStencilState(m_depthStencilState, 1); //we set the depth stencil state ZeroMemory(&depthStencilViewDesc, sizeof(depthStencilViewDesc)); //initialize the depth stencil view //set up the depth stencil view description depthStencilViewDesc.Format = DXGI_FORMAT_D24_UNORM_S8_UINT; depthStencilViewDesc.ViewDimension = D3D11_DSV_DIMENSION_TEXTURE2D; depthStencilViewDesc.Texture2D.MipSlice = 0; result = m_device->CreateDepthStencilView( //create the depsth stencil view m_depthStencilBuffer, &depthStencilViewDesc, &m_depthStencilView ); if(FAILED(result)) { return false; } m_deviceContext->OMSetRenderTargets(1, &m_renderTargetView, m_depthStencilView); //bind the render target view and depth stencil buffer to the output render pipeline //create a raster state to control how the polygons are rendered rasterDesc.AntialiasedLineEnable = false; //rasterDesc.CullMode = D3D11_CULL_BACK; rasterDesc.CullMode = D3D11_CULL_NONE; rasterDesc.DepthBias = 0; rasterDesc.DepthBiasClamp = 0.0f; rasterDesc.DepthClipEnable = true; rasterDesc.FillMode = D3D11_FILL_SOLID; rasterDesc.FrontCounterClockwise = false; rasterDesc.MultisampleEnable = false; rasterDesc.ScissorEnable = false; rasterDesc.SlopeScaledDepthBias = 0.0f; result = m_device->CreateRasterizerState(&rasterDesc, &m_rasterState);//create the rasterizer state from the description we just filled out if(FAILED(result)) { return false; } m_deviceContext->RSSetState(m_rasterState);//set the rasterizer state //setup the viewport for rendering m_viewport.Width = (float)screenWidth; m_viewport.Height = (float)screenHeight; m_viewport.MinDepth = 0.0f; m_viewport.MaxDepth = 1.0f; m_viewport.TopLeftX = 0.0f; m_viewport.TopLeftY = 0.0f; m_deviceContext->RSSetViewports(1, &viewport);//create the viewport //setup projection matrix fieldOfView = (float)D3DX_PI / 4.0f; screenAspect = (float)screenWidth / (float)screenHeight; //create the projection matrix D3DXMatrixPerspectiveFovLH(&m_projectionMatrix, fieldOfView, screenAspect, screenNear, screenDepth); D3DXMatrixIdentity(&m_worldMatrix);//initialize the world matrix to the identity matrix D3DXMatrixOrthoLH(&m_orthoMatrix, (float)screenWidth, (float)screenHeight, screenNear, screenDepth);//create a orthographic projection matrix for 2D rendering ZeroMemory(&blendStateDescription, sizeof(D3D11_BLEND_DESC)); blendStateDescription.RenderTarget[0].BlendEnable = TRUE; blendStateDescription.RenderTarget[0].SrcBlend = D3D11_BLEND_ONE; blendStateDescription.RenderTarget[0].DestBlend = D3D11_BLEND_ONE; blendStateDescription.RenderTarget[0].BlendOp = D3D11_BLEND_OP_ADD; blendStateDescription.RenderTarget[0].SrcBlendAlpha = D3D11_BLEND_ONE; blendStateDescription.RenderTarget[0].DestBlendAlpha = D3D11_BLEND_ZERO; blendStateDescription.RenderTarget[0].BlendOpAlpha = D3D11_BLEND_OP_ADD; blendStateDescription.RenderTarget[0].RenderTargetWriteMask = 0x0f; //create the blend state using the description result = m_device->CreateBlendState(&blendStateDescription, &m_alphaEnableBlendingState); if(FAILED(result)) { return false; } //modify the description to create an alpha disabled blend state description blendStateDescription.RenderTarget[0].BlendEnable = FALSE; //create the blend state using the description result = m_device->CreateBlendState(&blendStateDescription, &m_alphaDisableBlendingState); if(FAILED(result)) { return false; } return true; }
bool D3DClass::Initialize(int screenWidth, int screenHeight, bool vsync, HWND hwnd, bool fullscreen, float screenDepth, float screenNear) { HRESULT result; IDXGIFactory* factory; IDXGIAdapter* adapter; IDXGIOutput* adapterOutput; unsigned int numModes, i, numerator, denominator; unsigned long long stringLength; DXGI_MODE_DESC* displayModeList; DXGI_ADAPTER_DESC adapterDesc; int error; DXGI_SWAP_CHAIN_DESC swapChainDesc; D3D_FEATURE_LEVEL featureLevel; ID3D11Texture2D* backBufferPtr; D3D11_TEXTURE2D_DESC depthBufferDesc; D3D11_DEPTH_STENCIL_DESC depthStencilDesc; D3D11_DEPTH_STENCIL_VIEW_DESC depthStencilViewDesc; D3D11_RASTERIZER_DESC rasterDesc; D3D11_VIEWPORT viewport; float fieldOfView, screenAspect; m_vsync_enabled = vsync; D3D11_DEPTH_STENCIL_DESC depthDisabledStencilDesc; //Create a DirectX graphics interface factory result = CreateDXGIFactory(__uuidof(IDXGIFactory), (void**)&factory); if (FAILED(result)) { return false; } //use the factory to create an adapter for the primary graphics interface (video card) result = factory->EnumAdapters(0, &adapter); if (FAILED(result)) { return false; } //Enumerate the primary adapter output(monitor) result = adapter->EnumOutputs(0, &adapterOutput); if (FAILED(result)) { return false; } //Get the number of modes that fit the DXGI_FORMAT_R8G8BA8_UNORM display format for the adapter output(monitor) result = adapterOutput->GetDisplayModeList(DXGI_FORMAT_R8G8B8A8_UNORM, DXGI_ENUM_MODES_INTERLACED, &numModes, NULL); if (FAILED(result)) { return false; } //Create a list to hold all the possible display modes for this video/monitor card combination displayModeList = new DXGI_MODE_DESC[numModes]; if (!displayModeList) { return false; } //fill the display mode list result = adapterOutput->GetDisplayModeList(DXGI_FORMAT_R8G8B8A8_UNORM, DXGI_ENUM_MODES_INTERLACED, &numModes, displayModeList); if (FAILED(result)) { return false; } //go through all display modes and find the one that matches width and height for (int i = 0;i < numModes;i++) { if (displayModeList[i].Width == (unsigned int)screenWidth) { if (displayModeList[i].Height == (unsigned int) screenHeight) { numerator = displayModeList[i].RefreshRate.Numerator; denominator = displayModeList[i].RefreshRate.Denominator; } } } //Get the video card description result = adapter->GetDesc(&adapterDesc); if (FAILED(result)) { return false; } //Store the dedicated video card memory in megabytes m_videoCardMemory = (int)(adapterDesc.DedicatedVideoMemory / 1024 / 1024); //Convert the name of the video card to a character array and store it error = wcstombs_s(&stringLength, m_videoCardDescription, 128, adapterDesc.Description, 128); if (error != 0) { return false; } //Release the display model list delete[] displayModeList; displayModeList = 0; //Release the adapter output adapterOutput->Release(); adapterOutput = 0; //Release the adapter adapter->Release(); adapter = 0; //release the factory factory->Release(); factory = 0; 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 = screenWidth; swapChainDesc.BufferDesc.Height = screenHeight; //set regular 32bit surface for the back buffer swapChainDesc.BufferDesc.Format = DXGI_FORMAT_R8G8B8A8_UNORM; //Set refresh rate of back buffer if (m_vsync_enabled) { swapChainDesc.BufferDesc.RefreshRate.Numerator = numerator; swapChainDesc.BufferDesc.RefreshRate.Denominator = denominator; } else { swapChainDesc.BufferDesc.RefreshRate.Numerator = 0; swapChainDesc.BufferDesc.RefreshRate.Denominator = 1; } //Set the usage of the back buffer swapChainDesc.BufferUsage = DXGI_USAGE_RENDER_TARGET_OUTPUT; //set the handle for the window to render to swapChainDesc.OutputWindow = hwnd; //Turn multisampling off swapChainDesc.SampleDesc.Count = 1; swapChainDesc.SampleDesc.Quality = 0; if (fullscreen) { swapChainDesc.Windowed = false; } else { swapChainDesc.Windowed = true; } 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; //dont set the advanced flags swapChainDesc.Flags = 0; featureLevel = D3D_FEATURE_LEVEL_11_0; //Create the swap chain,Direc3D device and Direct3D device context result = D3D11CreateDeviceAndSwapChain(NULL, D3D_DRIVER_TYPE_HARDWARE, NULL, 0, &featureLevel, 1, D3D11_SDK_VERSION, &swapChainDesc, &m_swapChain, &m_device, NULL, &m_deviceContext); if (FAILED(result)) { return false; } //Get the pointer to the back buffer result = m_swapChain->GetBuffer(0, __uuidof(ID3D11Texture2D), (LPVOID*)&backBufferPtr); if (FAILED(result)) { return false; } //Create the render target view with the back buffer point result = m_device->CreateRenderTargetView(backBufferPtr, NULL, &m_renderTargetView); if (FAILED(result)) { return false; } //Release the pointer to the back buffer backBufferPtr->Release(); backBufferPtr = 0; ZeroMemory(&depthBufferDesc, sizeof(depthBufferDesc)); //Initalize the description of depth buffer depthBufferDesc.Width = screenWidth; depthBufferDesc.Height = screenHeight; depthBufferDesc.MipLevels = 1; depthBufferDesc.ArraySize = 1; depthBufferDesc.Format = DXGI_FORMAT_D24_UNORM_S8_UINT; depthBufferDesc.SampleDesc.Count = 1; depthBufferDesc.SampleDesc.Quality = 0; depthBufferDesc.Usage = D3D11_USAGE_DEFAULT; depthBufferDesc.BindFlags = D3D11_BIND_DEPTH_STENCIL; depthBufferDesc.CPUAccessFlags = 0; depthBufferDesc.MiscFlags = 0; //Create the texture for the depth buffer result = m_device->CreateTexture2D(&depthBufferDesc, NULL, &m_depthStencilBuffer); if (FAILED(result)) { return false; } //Initialize the description of the stencil state ZeroMemory(&depthStencilDesc, sizeof(depthStencilDesc)); //Set up description of stencil state depthStencilDesc.DepthEnable = true; depthStencilDesc.DepthWriteMask = D3D11_DEPTH_WRITE_MASK_ALL; depthStencilDesc.DepthFunc = D3D11_COMPARISON_LESS; depthStencilDesc.StencilEnable = true; depthStencilDesc.StencilReadMask = 0xFF; depthStencilDesc.StencilWriteMask = 0xFF; //stencil operations if pixel is front facing depthStencilDesc.FrontFace.StencilFailOp = D3D11_STENCIL_OP_KEEP; depthStencilDesc.FrontFace.StencilDepthFailOp = D3D11_STENCIL_OP_INCR; depthStencilDesc.FrontFace.StencilPassOp = D3D11_STENCIL_OP_KEEP; depthStencilDesc.FrontFace.StencilFunc = D3D11_COMPARISON_ALWAYS; //stencil operation if pixel is back facing depthStencilDesc.BackFace.StencilFailOp = D3D11_STENCIL_OP_KEEP; depthStencilDesc.BackFace.StencilDepthFailOp = D3D11_STENCIL_OP_DECR; depthStencilDesc.BackFace.StencilPassOp = D3D11_STENCIL_OP_KEEP; depthStencilDesc.BackFace.StencilFunc = D3D11_COMPARISON_ALWAYS; //create depth stencil state result = m_device->CreateDepthStencilState(&depthStencilDesc, &m_depthStencilState); if (FAILED(result)) { return false; } //set the depth stencil state m_deviceContext->OMSetDepthStencilState(m_depthStencilState, 1); //initalize the depth stencil view ZeroMemory(&depthStencilViewDesc, sizeof(depthStencilViewDesc)); //set up the depth stencil view description depthStencilViewDesc.Format = DXGI_FORMAT_D24_UNORM_S8_UINT; depthStencilViewDesc.ViewDimension = D3D11_DSV_DIMENSION_TEXTURE2D; depthStencilViewDesc.Texture2D.MipSlice = 0; //create the depth stencil view result = m_device->CreateDepthStencilView(m_depthStencilBuffer, &depthStencilViewDesc, &m_depthStencilView); if (FAILED(result)) { return false; } //bind the render target view and depth stencil buffer to the output render pipeline m_deviceContext->OMSetRenderTargets(1, &m_renderTargetView, m_depthStencilView); //set up the raster description which will determine how and what polygons will be drawn rasterDesc.AntialiasedLineEnable = false; rasterDesc.CullMode = D3D11_CULL_BACK; rasterDesc.DepthBias = 0; rasterDesc.DepthBiasClamp = 0.0f; rasterDesc.DepthClipEnable = true; rasterDesc.FillMode = D3D11_FILL_SOLID; rasterDesc.FrontCounterClockwise = false; rasterDesc.MultisampleEnable = false; rasterDesc.ScissorEnable = false; rasterDesc.SlopeScaledDepthBias = 0.0f; //create the rasterizer state from the description result = m_device->CreateRasterizerState(&rasterDesc, &m_rasterState); if (FAILED(result)) { return false; } //set the raster state m_deviceContext->RSSetState(m_rasterState); //set up viewport for rendering viewport.Width = (float)screenWidth; viewport.Height = (float)screenHeight; viewport.MinDepth = 0.0f; viewport.MaxDepth = 1.0f; viewport.TopLeftX = 0.0f; viewport.TopLeftY = 0.0f; //create the viewport m_deviceContext->RSSetViewports(1, &viewport); //set up the projection matrix fieldOfView = (float) 3.141592654f / 4.0f; screenAspect = (float)screenWidth / (float)screenHeight; //create the projection matrix m_projectionMatrix = XMMatrixPerspectiveFovLH(fieldOfView, screenAspect, screenNear, screenDepth); //initlaize the world matrix to the identity matrix m_worldMatrix = XMMatrixIdentity(); m_orthoMatrix = XMMatrixOrthographicLH((float)screenWidth, (float)screenHeight, screenNear, screenDepth); //clear the second depth stencil sate before setting the parameters ZeroMemory(&depthDisabledStencilDesc, sizeof(depthDisabledStencilDesc)); //create depth stencil state where z buffer is turned off for 2d rendering depthDisabledStencilDesc.DepthEnable = false; depthDisabledStencilDesc.DepthWriteMask = D3D11_DEPTH_WRITE_MASK_ALL; depthDisabledStencilDesc.DepthFunc = D3D11_COMPARISON_LESS; depthDisabledStencilDesc.StencilReadMask = 0xff; depthDisabledStencilDesc.StencilWriteMask = 0xFF; depthDisabledStencilDesc.FrontFace.StencilFailOp = D3D11_STENCIL_OP_KEEP; depthDisabledStencilDesc.FrontFace.StencilDepthFailOp = D3D11_STENCIL_OP_INCR; depthDisabledStencilDesc.FrontFace.StencilPassOp = D3D11_STENCIL_OP_KEEP; depthDisabledStencilDesc.FrontFace.StencilFunc = D3D11_COMPARISON_ALWAYS; depthDisabledStencilDesc.BackFace.StencilFailOp = D3D11_STENCIL_OP_KEEP; depthDisabledStencilDesc.BackFace.StencilDepthFailOp = D3D11_STENCIL_OP_DECR; depthDisabledStencilDesc.BackFace.StencilPassOp = D3D11_STENCIL_OP_KEEP; depthDisabledStencilDesc.BackFace.StencilFunc = D3D11_COMPARISON_ALWAYS; //create state result = m_device->CreateDepthStencilState(&depthDisabledStencilDesc, &m_depthDisabledStencilState); if (FAILED(result)) { return false; } return true; }
bool xGL2RenderApi::__createD10Device() { HRESULT hr = S_OK;; UINT width = m_Width; UINT height = m_Height; if(width == 0 || height == 0) { RECT rc; GetClientRect( m_hMainWnd, &rc ); width = rc.right - rc.left; height = rc.bottom - rc.top; m_Width = width; m_Height = height; } UINT createDeviceFlags = 0; #ifdef _DEBUG createDeviceFlags |= GL2_CREATE_DEVICE_DEBUG; #endif GL2_DRIVER_TYPE driverTypes[] = { GL2_DRIVER_TYPE_HARDWARE, GL2_DRIVER_TYPE_REFERENCE, GL2_DRIVER_TYPE_REFERENCE, GL2_DRIVER_TYPE_REFERENCE, GL2_DRIVER_TYPE_REFERENCE, GL2_DRIVER_TYPE_REFERENCE, }; HMODULE hDriverModule[]= { NULL, LoadLibraryA( "GL2WARP_beta.DLL" ), LoadLibraryW( _XEVOL_ABSPATH_(L"GL2WARP_beta.DLL") ), LoadLibraryA( "GL2WARP.DLL" ), LoadLibraryW( _XEVOL_ABSPATH_(L"GL2WARP.DLL" ) ), NULL, }; UINT numDriverTypes = sizeof(driverTypes) / sizeof(driverTypes[0]); m_Width = width; m_Height = height; ZeroMemory( &m_swapChainDesc, sizeof(m_swapChainDesc) ); m_swapChainDesc.BufferCount = 1; m_swapChainDesc.BufferDesc.Width = width; m_swapChainDesc.BufferDesc.Height = height; m_swapChainDesc.BufferDesc.Format = DXGI_FORMAT_R8G8B8A8_UNORM; m_swapChainDesc.BufferDesc.RefreshRate.Numerator = 60; m_swapChainDesc.BufferDesc.RefreshRate.Denominator = 1; m_swapChainDesc.BufferUsage = DXGI_USAGE_RENDER_TARGET_OUTPUT; m_swapChainDesc.OutputWindow = m_hMainWnd; m_swapChainDesc.SampleDesc.Count = 1; m_swapChainDesc.SampleDesc.Quality = 0; m_swapChainDesc.Windowed = TRUE; //Find all Adapter IDXGIAdapter * pAdapter; std::vector<IDXGIAdapter*> vAdapters; IDXGIFactory* pDXGIFactory = NULL; hr = CreateDXGIFactory(__uuidof(IDXGIFactory), (void**)(&pDXGIFactory) ); while(pDXGIFactory->EnumAdapters(vAdapters.size(), &pAdapter) != DXGI_ERROR_NOT_FOUND) { vAdapters.push_back(pAdapter); } for(int i = 0 ; i < vAdapters.size() ; i ++) { IDXGIAdapter* pAdapter = vAdapters[i]; DXGI_ADAPTER_DESC desc; pAdapter->GetDesc(&desc); std::vector<IDXGIOutput*> vOutputers; IDXGIOutput* pOutputer = NULL; while(pAdapter->EnumOutputs(vOutputers.size(), &pOutputer) != DXGI_ERROR_NOT_FOUND) { vOutputers.push_back(pOutputer); DXGI_OUTPUT_DESC odesc; pOutputer->GetDesc(&odesc); continue; } for( UINT driverTypeIndex = 0; driverTypeIndex < numDriverTypes; driverTypeIndex++ ) { m_driverType = driverTypes[driverTypeIndex]; HMODULE hModule = hDriverModule[driverTypeIndex]; hr = GL2CreateDeviceAndSwapChain( pAdapter, m_driverType, hModule , createDeviceFlags, GL2_SDK_VERSION, &m_swapChainDesc, &m_pSwapChain, &m_pGL2Device ); if( SUCCEEDED( hr ) ) break; } if(m_pGL2Device && m_pSwapChain) { break; } } if( FAILED(hr) ) return false; m_RenderWindow = new xGL2RenderWindow(m_hMainWnd , this); m_RenderWindow->create(m_pSwapChain , width , height); __resetViewPort(); setRenderView(m_RenderWindow); GL2_BLEND_DESC BlendState; ZeroMemory(&BlendState, sizeof(GL2_BLEND_DESC)); BlendState.BlendEnable[0] = FALSE; BlendState.RenderTargetWriteMask[0] = GL2_COLOR_WRITE_ENABLE_ALL; ID3D10BlendState* g_pBlendStateNoBlend = NULL; ID3D10RasterizerState* g_pRasterizerStateNoCull = NULL; m_pGL2Device->CreateBlendState(&BlendState, &g_pBlendStateNoBlend) ; // Create a rasterizer state to disable culling GL2_RASTERIZER_DESC RSDesc; RSDesc.FillMode = GL2_FILL_SOLID; RSDesc.CullMode = GL2_CULL_NONE; RSDesc.FrontCounterClockwise = TRUE; RSDesc.DepthBias = 0; RSDesc.DepthBiasClamp = 0; RSDesc.SlopeScaledDepthBias = 0; RSDesc.ScissorEnable = FALSE; RSDesc.MultisampleEnable = TRUE; RSDesc.AntialiasedLineEnable = FALSE; m_pGL2Device->CreateRasterizerState(&RSDesc, &g_pRasterizerStateNoCull) ; m_pGL2Device->OMSetBlendState(g_pBlendStateNoBlend, 0, 0xffffffff); m_pGL2Device->RSSetState(g_pRasterizerStateNoCull); return true; }
bool D3DClass::Initilize(int screenWidth, int screenHeight, bool vsync, HWND hwnd, bool fullscreen, float screenDepth, float screennear) { HRESULT result; IDXGIFactory* factory; IDXGIAdapter* adapter; IDXGIOutput* adapterOutput; unsigned int numModes, i, numerator, denominator; unsigned long long stringLength; DXGI_MODE_DESC* displayModeList; DXGI_ADAPTER_DESC adapterDesc; int error; DXGI_SWAP_CHAIN_DESC swapChainDesc; D3D_FEATURE_LEVEL featureLevel; ID3D11Texture2D* backBufferPtr; D3D11_TEXTURE2D_DESC depthBufferDesc; D3D11_DEPTH_STENCIL_DESC depthStencilDesc; D3D11_DEPTH_STENCIL_VIEW_DESC depthStencilViewDesc; D3D11_RASTERIZER_DESC rasterDesc; D3D11_VIEWPORT viewport; float fieldOfView, screenAspect; m_vsync_enabled = vsync; //Create DirectX Factory result = CreateDXGIFactory(__uuidof(IDXGIFactory), (void**)&factory); if (FAILED(result)) { return false; } //use factory to create adapter result = factory->EnumAdapters(0, &adapter); if (FAILED(result)) { return false; } //enumerate adapter output (monitor) result = adapter->EnumOutputs(0, &adapterOutput); if (FAILED(result)) { return false; } result = adapterOutput->GetDisplayModeList(DXGI_FORMAT_R8G8B8A8_UNORM, DXGI_ENUM_MODES_INTERLACED, &numModes, NULL); if (FAILED(result)) { return false; } displayModeList = new DXGI_MODE_DESC[numModes]; if (!displayModeList) { return false; } result = adapterOutput->GetDisplayModeList(DXGI_FORMAT_R8G8B8A8_UNORM, DXGI_ENUM_MODES_INTERLACED, &numModes, displayModeList); if (FAILED(result)) { return false; } for (i = 0; i < numModes; i++) { if (displayModeList[i].Width == (unsigned int)screenWidth) { if (displayModeList[i].Height == (unsigned int)screenHeight) { numerator = displayModeList[i].RefreshRate.Numerator; denominator = displayModeList[i].RefreshRate.Denominator; } } } result = adapter->GetDesc(&adapterDesc); if (FAILED(result)) { return false; } m_videoCardMemory = (int)(adapterDesc.DedicatedVideoMemory / 1024 / 1024); unsigned int charSize = 128; //error = wcstombs_s(&stringLength, m_videoCardDescription, charSize, adapterDesc.Description, charSize); //error = wcstombs(m_videoCardDescription, adapterDesc.Description, 128); // check to see if this works // THIS IS EXPERIMENTAL! FIND A BETTER WAY OR FULLY TEST THIS! for (int d = 0; d < 128; d++) { m_videoCardDescription[d] = adapterDesc.Description[d]; } if (!m_videoCardDescription) { return false; } delete[] displayModeList; displayModeList = 0; adapterOutput->Release(); adapterOutput = 0; adapter->Release(); adapter = 0; factory->Release(); factory = 0; ZeroMemory(&swapChainDesc, sizeof(swapChainDesc)); swapChainDesc.BufferCount = 1; // maybe change this? swapChainDesc.BufferDesc.Width = screenWidth; swapChainDesc.BufferDesc.Height = screenHeight; swapChainDesc.BufferDesc.Format = DXGI_FORMAT_R8G8B8A8_UNORM; if (m_vsync_enabled) { swapChainDesc.BufferDesc.RefreshRate.Numerator = numerator; swapChainDesc.BufferDesc.RefreshRate.Denominator = denominator; } else { swapChainDesc.BufferDesc.RefreshRate.Numerator = 0; swapChainDesc.BufferDesc.RefreshRate.Denominator = 1; } swapChainDesc.BufferUsage = DXGI_USAGE_RENDER_TARGET_OUTPUT; swapChainDesc.OutputWindow = hwnd; swapChainDesc.SampleDesc.Count = 1; swapChainDesc.SampleDesc.Quality = 0; if (fullscreen) { swapChainDesc.Windowed = false; } else { swapChainDesc.Windowed = true; } swapChainDesc.BufferDesc.ScanlineOrdering = DXGI_MODE_SCANLINE_ORDER_UNSPECIFIED; swapChainDesc.BufferDesc.Scaling = DXGI_MODE_SCALING_UNSPECIFIED; swapChainDesc.SwapEffect = DXGI_SWAP_EFFECT_DISCARD; swapChainDesc.Flags = 0; featureLevel = D3D_FEATURE_LEVEL_11_0; //Sometimes the call to the default graphics card isnt DX11 when a secondary card is, the user must define which one to use in that case (not coded here) result = D3D11CreateDeviceAndSwapChain(NULL, D3D_DRIVER_TYPE_HARDWARE, NULL, 0, &featureLevel, 1, D3D11_SDK_VERSION, &swapChainDesc, &m_swapChain, &m_device, NULL, &m_deviceContext); if (FAILED(result)) { return false; } result = m_swapChain->GetBuffer(0, __uuidof(ID3D11Texture2D), (LPVOID*)&backBufferPtr); if (FAILED(result)) { return false; } result = m_device->CreateRenderTargetView(backBufferPtr, NULL, &m_renderTargetView); if (FAILED(result)) { return false; } backBufferPtr->Release(); backBufferPtr = 0; ZeroMemory(&depthBufferDesc, sizeof(depthBufferDesc)); depthBufferDesc.Width = screenWidth; depthBufferDesc.Height = screenHeight; depthBufferDesc.MipLevels = 1; depthBufferDesc.ArraySize = 1; depthBufferDesc.Format = DXGI_FORMAT_D24_UNORM_S8_UINT; depthBufferDesc.SampleDesc.Count = 1; depthBufferDesc.SampleDesc.Quality = 0; depthBufferDesc.Usage = D3D11_USAGE_DEFAULT; depthBufferDesc.BindFlags = D3D11_BIND_DEPTH_STENCIL; depthBufferDesc.CPUAccessFlags = 0; depthBufferDesc.MiscFlags = 0; result = m_device->CreateTexture2D(&depthBufferDesc, NULL, &m_depthStencilBuffer); if (FAILED(result)) { return false; } //depth test for each pixel ZeroMemory(&depthStencilDesc, sizeof(depthStencilDesc)); depthStencilDesc.DepthEnable = true; depthStencilDesc.DepthWriteMask = D3D11_DEPTH_WRITE_MASK_ALL; depthStencilDesc.DepthFunc = D3D11_COMPARISON_LESS; depthStencilDesc.StencilEnable = true; depthStencilDesc.StencilReadMask = 0xFF; depthStencilDesc.StencilWriteMask = 0xff; depthStencilDesc.FrontFace.StencilFailOp = D3D11_STENCIL_OP_KEEP; depthStencilDesc.FrontFace.StencilDepthFailOp = D3D11_STENCIL_OP_INCR; depthStencilDesc.FrontFace.StencilPassOp = D3D11_STENCIL_OP_KEEP; depthStencilDesc.FrontFace.StencilFunc = D3D11_COMPARISON_ALWAYS; depthStencilDesc.BackFace.StencilFailOp = D3D11_STENCIL_OP_KEEP; depthStencilDesc.BackFace.StencilDepthFailOp = D3D11_STENCIL_OP_DECR; depthStencilDesc.BackFace.StencilPassOp = D3D11_STENCIL_OP_KEEP; depthStencilDesc.BackFace.StencilFunc = D3D11_COMPARISON_ALWAYS; result = m_device->CreateDepthStencilState(&depthStencilDesc, &m_depthStencilState); if (FAILED(result)) { return false; } m_deviceContext->OMSetDepthStencilState(m_depthStencilState, 1); ZeroMemory(&depthStencilViewDesc, sizeof(depthStencilViewDesc)); depthStencilViewDesc.Format = DXGI_FORMAT_D24_UNORM_S8_UINT; depthStencilViewDesc.ViewDimension = D3D11_DSV_DIMENSION_TEXTURE2D; depthStencilViewDesc.Texture2D.MipSlice = 0; result = m_device->CreateDepthStencilView(m_depthStencilBuffer, &depthStencilViewDesc, &m_depthStencilView); if (FAILED(result)) { return false; } m_deviceContext->OMSetRenderTargets(1, &m_renderTargetView, m_depthStencilView); //rasterizer crap rasterDesc.AntialiasedLineEnable = false; rasterDesc.CullMode = D3D11_CULL_BACK; rasterDesc.DepthBias = 0; rasterDesc.DepthBiasClamp = 0.0f; rasterDesc.DepthClipEnable = true; rasterDesc.FillMode = D3D11_FILL_SOLID; rasterDesc.FrontCounterClockwise = false; rasterDesc.MultisampleEnable = false; rasterDesc.ScissorEnable = false; rasterDesc.SlopeScaledDepthBias = 0.0f; result = m_device->CreateRasterizerState(&rasterDesc, &m_rasterState); if (FAILED(result)) { return false; } m_deviceContext->RSSetState(m_rasterState); //viewport viewport.Width = (float)screenWidth; viewport.Height = (float)screenHeight; viewport.MaxDepth = 1.0f; viewport.MinDepth = 0.0f; viewport.TopLeftX = 0.0f; viewport.TopLeftY = 0.0f; m_deviceContext->RSSetViewports(1, &viewport); fieldOfView = 3.141592654f / 4.0f; screenAspect = (float)screenWidth / (float)screenHeight; m_projectionMatrix = XMMatrixPerspectiveFovLH(fieldOfView, screenAspect, screennear, screenDepth); m_worldMatrix = XMMatrixIdentity(); // view matrix USUALLY camera class will take this plce //used for UI to overlay on the screen m_orthoMatrix = XMMatrixOrthographicLH((float)screenWidth, (float)screenHeight, screennear, screenDepth); return true; }
static int WINRT_AddDisplaysForOutput (_THIS, IDXGIAdapter1 * dxgiAdapter1, int outputIndex) { HRESULT hr; IDXGIOutput * dxgiOutput = NULL; DXGI_OUTPUT_DESC dxgiOutputDesc; SDL_VideoDisplay display; char * displayName = NULL; UINT numModes; DXGI_MODE_DESC * dxgiModes = NULL; int functionResult = -1; /* -1 for failure, 0 for success */ DXGI_MODE_DESC modeToMatch, closestMatch; SDL_zero(display); hr = dxgiAdapter1->EnumOutputs(outputIndex, &dxgiOutput); if (FAILED(hr)) { if (hr != DXGI_ERROR_NOT_FOUND) { WIN_SetErrorFromHRESULT(__FUNCTION__ ", IDXGIAdapter1::EnumOutputs failed", hr); } goto done; } hr = dxgiOutput->GetDesc(&dxgiOutputDesc); if (FAILED(hr)) { WIN_SetErrorFromHRESULT(__FUNCTION__ ", IDXGIOutput::GetDesc failed", hr); goto done; } SDL_zero(modeToMatch); modeToMatch.Format = DXGI_FORMAT_B8G8R8A8_UNORM; modeToMatch.Width = (dxgiOutputDesc.DesktopCoordinates.right - dxgiOutputDesc.DesktopCoordinates.left); modeToMatch.Height = (dxgiOutputDesc.DesktopCoordinates.bottom - dxgiOutputDesc.DesktopCoordinates.top); hr = dxgiOutput->FindClosestMatchingMode(&modeToMatch, &closestMatch, NULL); if (hr == DXGI_ERROR_NOT_CURRENTLY_AVAILABLE) { /* DXGI_ERROR_NOT_CURRENTLY_AVAILABLE gets returned by IDXGIOutput::FindClosestMatchingMode when running under the Windows Simulator, which uses Remote Desktop (formerly known as Terminal Services) under the hood. According to the MSDN docs for the similar function, IDXGIOutput::GetDisplayModeList, DXGI_ERROR_NOT_CURRENTLY_AVAILABLE is returned if and when an app is run under a Terminal Services session, hence the assumption. In this case, just add an SDL display mode, with approximated values. */ SDL_DisplayMode mode; SDL_zero(mode); display.name = "Windows Simulator / Terminal Services Display"; mode.w = (dxgiOutputDesc.DesktopCoordinates.right - dxgiOutputDesc.DesktopCoordinates.left); mode.h = (dxgiOutputDesc.DesktopCoordinates.bottom - dxgiOutputDesc.DesktopCoordinates.top); mode.format = DXGI_FORMAT_B8G8R8A8_UNORM; mode.refresh_rate = 0; /* Display mode is unknown, so just fill in zero, as specified by SDL's header files */ display.desktop_mode = mode; display.current_mode = mode; if ( ! SDL_AddDisplayMode(&display, &mode)) { goto done; } } else if (FAILED(hr)) { WIN_SetErrorFromHRESULT(__FUNCTION__ ", IDXGIOutput::FindClosestMatchingMode failed", hr); goto done; } else { displayName = WIN_StringToUTF8(dxgiOutputDesc.DeviceName); display.name = displayName; WINRT_DXGIModeToSDLDisplayMode(&closestMatch, &display.desktop_mode); display.current_mode = display.desktop_mode; hr = dxgiOutput->GetDisplayModeList(DXGI_FORMAT_B8G8R8A8_UNORM, 0, &numModes, NULL); if (FAILED(hr)) { if (hr == DXGI_ERROR_NOT_CURRENTLY_AVAILABLE) { // TODO, WinRT: make sure display mode(s) are added when using Terminal Services / Windows Simulator } WIN_SetErrorFromHRESULT(__FUNCTION__ ", IDXGIOutput::GetDisplayModeList [get mode list size] failed", hr); goto done; } dxgiModes = (DXGI_MODE_DESC *)SDL_calloc(numModes, sizeof(DXGI_MODE_DESC)); if ( ! dxgiModes) { SDL_OutOfMemory(); goto done; } hr = dxgiOutput->GetDisplayModeList(DXGI_FORMAT_B8G8R8A8_UNORM, 0, &numModes, dxgiModes); if (FAILED(hr)) { WIN_SetErrorFromHRESULT(__FUNCTION__ ", IDXGIOutput::GetDisplayModeList [get mode contents] failed", hr); goto done; } for (UINT i = 0; i < numModes; ++i) { SDL_DisplayMode sdlMode; WINRT_DXGIModeToSDLDisplayMode(&dxgiModes[i], &sdlMode); SDL_AddDisplayMode(&display, &sdlMode); } } if (SDL_AddVideoDisplay(&display) < 0) { goto done; } functionResult = 0; /* 0 for Success! */ done: if (dxgiModes) { SDL_free(dxgiModes); } if (dxgiOutput) { dxgiOutput->Release(); } if (displayName) { SDL_free(displayName); } return functionResult; }
/////////////////////////////////////////////////////////////// // Public Functions /////////////////////////////////////////////////////////////// bool DX11System::Initialize(UINT screenWidth, UINT screenHeight, HWND hWnd) { LogManager::GetInstance().Trace("DX11System initializing..."); HRESULT result; IDXGIFactory* factory; IDXGIAdapter* adapter; IDXGIOutput* adapterOutput; UINT numModes=0, i=0, numerator=0, denominator=0, stringLength=0; DXGI_MODE_DESC* displayModeList; DXGI_ADAPTER_DESC adapterDesc; int error=0; DXGI_SWAP_CHAIN_DESC swapChainDesc; D3D_FEATURE_LEVEL featureLevel; ID3D11Texture2D* backBufferPtr; D3D11_TEXTURE2D_DESC depthBufferDesc; D3D11_DEPTH_STENCIL_DESC depthStencilDesc; D3D11_DEPTH_STENCIL_DESC depthDisabledStencilState; D3D11_DEPTH_STENCIL_VIEW_DESC depthStencilViewDesc; D3D11_RASTERIZER_DESC rasterDesc; D3D11_VIEWPORT viewport; float fieldOfView=0.f, screenAspect=0.f; D3D11_BLEND_DESC blendStateDesc; m_vsync = Settings::GetInstance().GetVSync(); //Create a DirectX Graphics Interface (DXGI) factory result = CreateDXGIFactory(__uuidof(IDXGIFactory), (void**)&factory); if(FAILED(result)) { LogManager::GetInstance().Error("DX11System::Initialize DXGIFactory could not be created"); return false; } //Create an adapter for the primary video card result = factory->EnumAdapters(0, &adapter); if(FAILED(result)) { LogManager::GetInstance().Error("DX11System::Initialize could not create the primary display adapter"); return false; } //Enumerate the primary adapter output result = adapter->EnumOutputs(0, &adapterOutput); if(FAILED(result)) { LogManager::GetInstance().Error("DX11System::Initialize could not enumerate the primary adapter outputs"); return false; } //Get the number of modes supported in this format result = adapterOutput->GetDisplayModeList(DXGI_FORMAT_R8G8B8A8_UNORM, DXGI_ENUM_MODES_INTERLACED, &numModes, nullptr); if(FAILED(result)) { LogManager::GetInstance().Error("DX11System::Initialize could not get the number of supported display modes"); return false; } //Create a list to hold all the possible display modes that fit for this video card / monitor displayModeList = new DXGI_MODE_DESC[numModes]; if(!displayModeList) { LogManager::GetInstance().Error("DX11System::Initialize displayModeList could not be initialized"); return false; } //fill the list result = adapterOutput->GetDisplayModeList(DXGI_FORMAT_R8G8B8A8_UNORM, DXGI_ENUM_MODES_INTERLACED, &numModes, displayModeList); if(FAILED(result)) { LogManager::GetInstance().Error("DX11System::Initialize could not fill the displayModeList"); return false; } //Go through every possible mode that fit our window //Set the refresh rate accordingly for(i = 0; i < numModes; i++) { if(displayModeList[i].Width == (UINT)screenWidth) { if(displayModeList[i].Height == (UINT)screenHeight) { numerator = displayModeList[i].RefreshRate.Numerator; denominator = displayModeList[i].RefreshRate.Denominator; } } } //Get the video card description result = adapter->GetDesc(&adapterDesc); if(FAILED(result)) { LogManager::GetInstance().Error("DX11System::Initialize could not obtain the video card description"); return false; } //Store the dedicated video memory in megabytes m_videoCardMemory = (int)(adapterDesc.DedicatedVideoMemory / 1024 / 1024); LogManager::GetInstance().Trace("Available video card memory %d MB", m_videoCardMemory); //Convert the name of the video card to a character array and store it error = wcstombs_s(&stringLength, m_videoCardDesc, 128, adapterDesc.Description, 128); if(error != 0) { LogManager::GetInstance().Error("Video card name could not be stored"); return false; } LogManager::GetInstance().Trace("Video Card Name: %s", m_videoCardDesc); //Release stuff I don't need delete [] displayModeList; displayModeList = nullptr; adapterOutput->Release(); adapterOutput = nullptr; adapter->Release(); adapter = nullptr; factory->Release(); factory = nullptr; //Initialize the swap chain description ZeroMemory(&swapChainDesc, sizeof(swapChainDesc)); swapChainDesc.BufferCount = 1; swapChainDesc.BufferDesc.Width = screenWidth; swapChainDesc.BufferDesc.Height = screenHeight; swapChainDesc.BufferDesc.Format = DXGI_FORMAT_R8G8B8A8_UNORM; //Set the refresh rate of the back buffer if(m_vsync) { swapChainDesc.BufferDesc.RefreshRate.Numerator = numerator; swapChainDesc.BufferDesc.RefreshRate.Denominator = denominator; } else { swapChainDesc.BufferDesc.RefreshRate.Numerator = 0; swapChainDesc.BufferDesc.RefreshRate.Denominator = 1; } //Set the usage of the back buffer swapChainDesc.BufferUsage = DXGI_USAGE_RENDER_TARGET_OUTPUT; //Set the handle for the window to render to swapChainDesc.OutputWindow = hWnd; //Turn multisampling off swapChainDesc.SampleDesc.Count = 1; swapChainDesc.SampleDesc.Quality = 0; //Set to full screen or windowed swapChainDesc.Windowed = (!(Settings::GetInstance().GetWindowType() & eWindowType_Fullscreen)); //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 swapChainDesc.SwapEffect = DXGI_SWAP_EFFECT_DISCARD; //Don't use advanced flags swapChainDesc.Flags = 0; //Set feature level to DX11 //Set to 10 to run on laptop. if (Settings::GetInstance().GetRenderType() == eRenderType_DX11) featureLevel = D3D_FEATURE_LEVEL_11_0; else if (Settings::GetInstance().GetRenderType() == eRenderType_DX10) featureLevel = D3D_FEATURE_LEVEL_10_0; else featureLevel = D3D_FEATURE_LEVEL_11_0; //Default save the settings file to 11. //Create the swap chain, Direct3D device, and Direct3D device context result = D3D11CreateDeviceAndSwapChain(nullptr, D3D_DRIVER_TYPE_HARDWARE, nullptr, 0, &featureLevel, 1, D3D11_SDK_VERSION, &swapChainDesc, &m_swapChain, &m_device, nullptr, &m_deviceContext); if(FAILED(result)) { LogManager::GetInstance().Warning("DX11System::Initalize could not initialize DX11, trying DX10.."); featureLevel = D3D_FEATURE_LEVEL_10_0; result = D3D11CreateDeviceAndSwapChain(nullptr, D3D_DRIVER_TYPE_HARDWARE, nullptr, 0, &featureLevel, 1, D3D11_SDK_VERSION, &swapChainDesc, &m_swapChain, &m_device, nullptr, &m_deviceContext); if(FAILED(result)) { LogManager::GetInstance().Error("DX11System::Initialize could not create SwapChain, Direct3D device and context (10 and 11 fail)"); return false; } //Save the Settings variable to 10. } //Get the pointer to the back buffer result = m_swapChain->GetBuffer(0, __uuidof(ID3D11Texture2D), (LPVOID*)&backBufferPtr); if(FAILED(result)) { LogManager::GetInstance().Error("DX11System::Initialize could not obtain the back buffer pointer"); return false; } //Create the render target view with the back buffer pointer result = m_device->CreateRenderTargetView(backBufferPtr, nullptr, &m_renderTargetView); if(FAILED(result)) { LogManager::GetInstance().Error("DX11System::Initialize could not create the render target view"); return false; } backBufferPtr->Release(); backBufferPtr = nullptr; //Initialize the description of the depth buffer ZeroMemory(&depthBufferDesc, sizeof(depthBufferDesc)); //Set up the description of the depth buffer depthBufferDesc.Width = screenWidth; depthBufferDesc.Height = screenHeight; depthBufferDesc.MipLevels = 1; depthBufferDesc.ArraySize = 1; depthBufferDesc.Format = DXGI_FORMAT_D24_UNORM_S8_UINT; depthBufferDesc.SampleDesc.Count = 1; depthBufferDesc.SampleDesc.Quality = 0; depthBufferDesc.Usage = D3D11_USAGE_DEFAULT; depthBufferDesc.BindFlags = D3D11_BIND_DEPTH_STENCIL; depthBufferDesc.CPUAccessFlags = 0; depthBufferDesc.MiscFlags = 0; //Create the depth texture result = m_device->CreateTexture2D(&depthBufferDesc, nullptr, &m_depthStencilBuffer); if(FAILED(result)) { LogManager::GetInstance().Error("DX11System::Initialize could not create the depth texture"); return false; } //Initialize the description of the stencil state ZeroMemory(&depthStencilDesc, sizeof(depthStencilDesc)); //Set up the description of the stencil state depthStencilDesc.DepthEnable = true; depthStencilDesc.DepthWriteMask = D3D11_DEPTH_WRITE_MASK_ALL; depthStencilDesc.DepthFunc = D3D11_COMPARISON_LESS; depthStencilDesc.StencilEnable = true; depthStencilDesc.StencilReadMask = 0xFF; depthStencilDesc.StencilWriteMask = 0xFF; //Stencil operations for front facing pixels depthStencilDesc.FrontFace.StencilFailOp = D3D11_STENCIL_OP_KEEP; depthStencilDesc.FrontFace.StencilDepthFailOp = D3D11_STENCIL_OP_INCR; depthStencilDesc.FrontFace.StencilPassOp = D3D11_STENCIL_OP_KEEP; depthStencilDesc.FrontFace.StencilFunc = D3D11_COMPARISON_ALWAYS; //Stencil operations for back facing pixles depthStencilDesc.BackFace.StencilFailOp = D3D11_STENCIL_OP_KEEP; depthStencilDesc.BackFace.StencilDepthFailOp = D3D11_STENCIL_OP_DECR; depthStencilDesc.BackFace.StencilPassOp = D3D11_STENCIL_OP_KEEP; depthStencilDesc.BackFace.StencilFunc = D3D11_COMPARISON_ALWAYS; //Create the depth stencil state result = m_device->CreateDepthStencilState(&depthStencilDesc, &m_depthStencilState); if(FAILED(result)) { LogManager::GetInstance().Error("DX11System::Initialize could not create the depth stencil state"); return false; } //Setup the second depth stencil for 2D ZeroMemory(&depthDisabledStencilState, sizeof(depthDisabledStencilState)); depthDisabledStencilState.DepthEnable = false; //this is the only difference depthDisabledStencilState.DepthWriteMask = D3D11_DEPTH_WRITE_MASK_ALL; depthDisabledStencilState.DepthFunc = D3D11_COMPARISON_LESS; depthDisabledStencilState.StencilEnable = true; depthDisabledStencilState.StencilReadMask = 0xFF; depthDisabledStencilState.StencilWriteMask = 0xFF; depthDisabledStencilState.FrontFace.StencilFailOp = D3D11_STENCIL_OP_KEEP; depthDisabledStencilState.FrontFace.StencilDepthFailOp = D3D11_STENCIL_OP_INCR; depthDisabledStencilState.FrontFace.StencilPassOp = D3D11_STENCIL_OP_KEEP; depthDisabledStencilState.FrontFace.StencilFunc = D3D11_COMPARISON_ALWAYS; depthDisabledStencilState.BackFace.StencilFailOp = D3D11_STENCIL_OP_KEEP; depthDisabledStencilState.BackFace.StencilDepthFailOp = D3D11_STENCIL_OP_DECR; depthDisabledStencilState.BackFace.StencilPassOp = D3D11_STENCIL_OP_KEEP; depthDisabledStencilState.BackFace.StencilFunc = D3D11_COMPARISON_ALWAYS; result = m_device->CreateDepthStencilState(&depthDisabledStencilState, &m_depthDisabledStencilState); if(FAILED(result)) { LogManager::GetInstance().Error("DX11System::Initialize could not create the disabled depth stencil state"); return false; } //Set the DSS m_deviceContext->OMSetDepthStencilState(m_depthStencilState, 1); //Initialize the depth stencil view ZeroMemory(&depthStencilViewDesc, sizeof(depthStencilViewDesc)); //Set it up depthStencilViewDesc.Format = DXGI_FORMAT_D24_UNORM_S8_UINT; depthStencilViewDesc.ViewDimension = D3D11_DSV_DIMENSION_TEXTURE2D; depthStencilViewDesc.Texture2D.MipSlice = 0; //Create it result = m_device->CreateDepthStencilView(m_depthStencilBuffer, &depthStencilViewDesc, &m_depthStencilView); if(FAILED(result)) { LogManager::GetInstance().Error("DX11System::Initialize could not create the depth stencil view"); return false; } //Bind the render target view and depth stencil buffer to the output render pipeline m_deviceContext->OMSetRenderTargets(1, &m_renderTargetView, m_depthStencilView); //Setup the raster decription rasterDesc.AntialiasedLineEnable = false; rasterDesc.CullMode = D3D11_CULL_BACK; rasterDesc.DepthBias = 0; rasterDesc.DepthBiasClamp = 0.0f; rasterDesc.DepthClipEnable = true; rasterDesc.FillMode = D3D11_FILL_SOLID; rasterDesc.FrontCounterClockwise = false; rasterDesc.MultisampleEnable = false; rasterDesc.ScissorEnable = false; rasterDesc.SlopeScaledDepthBias = 0.0f; //Create the rasterizer state result = m_device->CreateRasterizerState(&rasterDesc, &m_rasterState); if(FAILED(result)) { LogManager::GetInstance().Error("DX11System::Initialize could not create the rasterizer state"); return false; } //Now set it m_deviceContext->RSSetState(m_rasterState); //Setup the viewport viewport.Width = (float)screenWidth; viewport.Height = (float)screenHeight; viewport.MinDepth = 0.0f; viewport.MaxDepth = 1.0f; viewport.TopLeftX = 0.0f; viewport.TopLeftY = 0.0f; //Create it m_deviceContext->RSSetViewports(1, &viewport); //Setup projection matrix fieldOfView = (float)D3DX_PI / 4.0f; screenAspect = (float)screenWidth / (float)screenHeight; //Retrieve the zNear and Far float zNear = Settings::GetInstance().GetZNear(); float zFar = Settings::GetInstance().GetZFar(); //Create the projection matrix D3DXMatrixPerspectiveFovLH(&m_projection, fieldOfView, screenAspect, zNear, zFar); //Initlialize world matrix D3DXMatrixIdentity(&m_world); //Create Ortho matrix D3DXMatrixOrthoLH(&m_ortho, (float)screenWidth, (float)screenHeight, zNear, zFar); //Clear the blend state ZeroMemory(&blendStateDesc, sizeof(D3D11_BLEND_DESC)); //Create an alpha enabled blend state blendStateDesc.RenderTarget[0].BlendEnable = TRUE; blendStateDesc.RenderTarget[0].SrcBlend = D3D11_BLEND_SRC_ALPHA; blendStateDesc.RenderTarget[0].DestBlend = D3D11_BLEND_INV_SRC_ALPHA; blendStateDesc.RenderTarget[0].BlendOp = D3D11_BLEND_OP_ADD; blendStateDesc.RenderTarget[0].SrcBlendAlpha = D3D11_BLEND_ONE; blendStateDesc.RenderTarget[0].DestBlendAlpha = D3D11_BLEND_ZERO; blendStateDesc.RenderTarget[0].BlendOpAlpha = D3D11_BLEND_OP_ADD; blendStateDesc.RenderTarget[0].RenderTargetWriteMask = 0x0f; //Create the blend state result = m_device->CreateBlendState(&blendStateDesc, &m_alphaEnableBlendingState); if(FAILED(result)) { LogManager::GetInstance().Error("DX11System::Initialize could not create the enabled blend state"); return false; } //Change it to disable blendStateDesc.RenderTarget[0].BlendEnable = FALSE; //Create the disabled state result = m_device->CreateBlendState(&blendStateDesc, &m_alphaDisableBlendingState); if(FAILED(result)) { LogManager::GetInstance().Error("DX11System::Initialize could not create the disabled blend state"); return false; } LogManager::GetInstance().Trace("DX11System successfully initialized"); return true; }
D3D::D3D(int screenWidth, int screenHeight, bool vsync, HWND hwnd, bool fullscreen, float screenDepth, float screenNear) : wireframe_enabled_(false) { IDXGIFactory* factory; IDXGIAdapter* adapter; IDXGIOutput* adapterOutput; unsigned int numModes, i, numerator, denominator, stringLength; DXGI_MODE_DESC* displayModeList; DXGI_ADAPTER_DESC adapterDesc; DXGI_SWAP_CHAIN_DESC swapChainDesc; D3D_FEATURE_LEVEL featureLevel; ID3D11Texture2D* backBufferPtr; D3D11_TEXTURE2D_DESC depthBufferDesc; D3D11_DEPTH_STENCIL_DESC depthStencilDesc; D3D11_DEPTH_STENCIL_VIEW_DESC depthStencilViewDesc; D3D11_RASTERIZER_DESC rasterDesc; float fieldOfView, screenAspect; D3D11_DEPTH_STENCIL_DESC depthDisabledStencilDesc; D3D11_BLEND_DESC blendStateDescription; // Store the vsync setting. m_vsync_enabled = vsync; // Create a DirectX graphics interface factory. CreateDXGIFactory(__uuidof(IDXGIFactory), (void**)&factory); // Use the factory to create an adapter for the primary graphics interface (video card). factory->EnumAdapters(0, &adapter); // Enumerate the primary adapter output (monitor). adapter->EnumOutputs(0, &adapterOutput); // Get the number of modes that fit the DXGI_FORMAT_R8G8B8A8_UNORM display format for the adapter output (monitor). adapterOutput->GetDisplayModeList(DXGI_FORMAT_R8G8B8A8_UNORM, DXGI_ENUM_MODES_INTERLACED, &numModes, NULL); // Create a list to hold all the possible display modes for this monitor/video card combination. displayModeList = new DXGI_MODE_DESC[numModes]; // Now fill the display mode list structures. adapterOutput->GetDisplayModeList(DXGI_FORMAT_R8G8B8A8_UNORM, DXGI_ENUM_MODES_INTERLACED, &numModes, displayModeList); // Now go through all the display modes and find the one that matches the screen width and height. // When a match is found store the numerator and denominator of the refresh rate for that monitor. for (i = 0; i<numModes; i++) { if (displayModeList[i].Width == (unsigned int)screenWidth) { if (displayModeList[i].Height == (unsigned int)screenHeight) { numerator = displayModeList[i].RefreshRate.Numerator; denominator = displayModeList[i].RefreshRate.Denominator; } } } // Get the adapter (video card) description. adapter->GetDesc(&adapterDesc); // Store the dedicated video card memory in megabytes. m_videoCardMemory = (int)(adapterDesc.DedicatedVideoMemory / 1024 / 1024); // Convert the name of the video card to a character array and store it. wcstombs_s(&stringLength, m_videoCardDescription, 128, adapterDesc.Description, 128); // Release the display mode list. delete[] displayModeList; displayModeList = 0; // Release the adapter output. adapterOutput->Release(); adapterOutput = 0; // Release the adapter. adapter->Release(); adapter = 0; // Release the factory. factory->Release(); factory = 0; // 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 = screenWidth; swapChainDesc.BufferDesc.Height = screenHeight; // Set regular 32-bit surface for the back buffer. swapChainDesc.BufferDesc.Format = DXGI_FORMAT_R8G8B8A8_UNORM; // Set the refresh rate of the back buffer. if (m_vsync_enabled) { swapChainDesc.BufferDesc.RefreshRate.Numerator = numerator; swapChainDesc.BufferDesc.RefreshRate.Denominator = denominator; } else { swapChainDesc.BufferDesc.RefreshRate.Numerator = 0; swapChainDesc.BufferDesc.RefreshRate.Denominator = 1; } // Set the usage of the back buffer. swapChainDesc.BufferUsage = DXGI_USAGE_RENDER_TARGET_OUTPUT; // Set the handle for the window to render to. swapChainDesc.OutputWindow = hwnd; // Turn multisampling off. swapChainDesc.SampleDesc.Count = 1; swapChainDesc.SampleDesc.Quality = 0; // Set to full screen or windowed mode. if (fullscreen) { swapChainDesc.Windowed = false; } else { swapChainDesc.Windowed = true; } // 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; // Set the feature level to DirectX 11. featureLevel = D3D_FEATURE_LEVEL_11_0; // Create the swap chain, Direct3D device, and Direct3D device context. D3D11CreateDeviceAndSwapChain(NULL, D3D_DRIVER_TYPE_HARDWARE, NULL, D3D11_CREATE_DEVICE_DEBUG, &featureLevel, 1, D3D11_SDK_VERSION, &swapChainDesc, &m_swapChain, &m_device, NULL, &m_deviceContext); // Get the pointer to the back buffer. m_swapChain->GetBuffer(0, __uuidof(ID3D11Texture2D), (LPVOID*)&backBufferPtr); // Create the render target view with the back buffer pointer. m_device->CreateRenderTargetView(backBufferPtr, NULL, &m_renderTargetView); // Release pointer to the back buffer as we no longer need it. backBufferPtr->Release(); backBufferPtr = 0; // Initialize the description of the depth buffer. ZeroMemory(&depthBufferDesc, sizeof(depthBufferDesc)); // Set up the description of the depth buffer. depthBufferDesc.Width = screenWidth; depthBufferDesc.Height = screenHeight; depthBufferDesc.MipLevels = 1; depthBufferDesc.ArraySize = 1; depthBufferDesc.Format = DXGI_FORMAT_D24_UNORM_S8_UINT; depthBufferDesc.SampleDesc.Count = 1; depthBufferDesc.SampleDesc.Quality = 0; depthBufferDesc.Usage = D3D11_USAGE_DEFAULT; depthBufferDesc.BindFlags = D3D11_BIND_DEPTH_STENCIL; depthBufferDesc.CPUAccessFlags = 0; depthBufferDesc.MiscFlags = 0; // Create the texture for the depth buffer using the filled out description. m_device->CreateTexture2D(&depthBufferDesc, NULL, &m_depthStencilBuffer); // Initialize the description of the stencil state. ZeroMemory(&depthStencilDesc, sizeof(depthStencilDesc)); // Set up the description of the stencil state. depthStencilDesc.DepthEnable = true; depthStencilDesc.DepthWriteMask = D3D11_DEPTH_WRITE_MASK_ALL; depthStencilDesc.DepthFunc = D3D11_COMPARISON_LESS; depthStencilDesc.StencilEnable = true; depthStencilDesc.StencilReadMask = 0xFF; depthStencilDesc.StencilWriteMask = 0xFF; // Stencil operations if pixel is front-facing. depthStencilDesc.FrontFace.StencilFailOp = D3D11_STENCIL_OP_KEEP; depthStencilDesc.FrontFace.StencilDepthFailOp = D3D11_STENCIL_OP_INCR; depthStencilDesc.FrontFace.StencilPassOp = D3D11_STENCIL_OP_KEEP; depthStencilDesc.FrontFace.StencilFunc = D3D11_COMPARISON_ALWAYS; // Stencil operations if pixel is back-facing. depthStencilDesc.BackFace.StencilFailOp = D3D11_STENCIL_OP_KEEP; depthStencilDesc.BackFace.StencilDepthFailOp = D3D11_STENCIL_OP_DECR; depthStencilDesc.BackFace.StencilPassOp = D3D11_STENCIL_OP_KEEP; depthStencilDesc.BackFace.StencilFunc = D3D11_COMPARISON_ALWAYS; // Create the depth stencil state. m_device->CreateDepthStencilState(&depthStencilDesc, &m_depthStencilState); // Set the depth stencil state. m_deviceContext->OMSetDepthStencilState(m_depthStencilState, 1); // Initialize the depth stencil view. ZeroMemory(&depthStencilViewDesc, sizeof(depthStencilViewDesc)); // Set up the depth stencil view description. depthStencilViewDesc.Format = DXGI_FORMAT_D24_UNORM_S8_UINT; depthStencilViewDesc.ViewDimension = D3D11_DSV_DIMENSION_TEXTURE2D; depthStencilViewDesc.Texture2D.MipSlice = 0; // Create the depth stencil view. m_device->CreateDepthStencilView(m_depthStencilBuffer, &depthStencilViewDesc, &m_depthStencilView); // Bind the render target view and depth stencil buffer to the output render pipeline. m_deviceContext->OMSetRenderTargets(1, &m_renderTargetView, m_depthStencilView); // Setup the raster description which will determine how and what polygons will be drawn. rasterDesc.AntialiasedLineEnable = false; rasterDesc.CullMode = D3D11_CULL_BACK; rasterDesc.DepthBias = 0; rasterDesc.DepthBiasClamp = 0.0f; rasterDesc.DepthClipEnable = true; rasterDesc.FillMode = D3D11_FILL_SOLID; rasterDesc.FrontCounterClockwise = true; rasterDesc.MultisampleEnable = false; rasterDesc.ScissorEnable = false; rasterDesc.SlopeScaledDepthBias = 0.0f; // Create the rasterizer state from the description we just filled out. m_device->CreateRasterizerState(&rasterDesc, &m_rasterState); // Now set the rasterizer state. m_deviceContext->RSSetState(m_rasterState); //create raster state with wireframe enabled rasterDesc.FillMode = D3D11_FILL_WIREFRAME; m_device->CreateRasterizerState(&rasterDesc, &m_rasterStateWF); // Setup the viewport for rendering. viewport.Width = (float)screenWidth; viewport.Height = (float)screenHeight; viewport.MinDepth = 0.0f; viewport.MaxDepth = 1.0f; viewport.TopLeftX = 0.0f; viewport.TopLeftY = 0.0f; // Create the viewport. m_deviceContext->RSSetViewports(1, &viewport); // Setup the projection matrix. fieldOfView = (float)XM_PI / 4.0f; screenAspect = (float)screenWidth / (float)screenHeight; // Create the projection matrix for 3D rendering. m_projectionMatrix = XMMatrixPerspectiveFovLH(fieldOfView, screenAspect, screenNear, screenDepth); // Initialize the world matrix to the identity matrix. m_worldMatrix = XMMatrixIdentity(); // Create an orthographic projection matrix for 2D rendering. m_orthoMatrix = XMMatrixOrthographicLH((float)screenWidth, (float)screenHeight, screenNear, screenDepth); // Clear the second depth stencil state before setting the parameters. ZeroMemory(&depthDisabledStencilDesc, sizeof(depthDisabledStencilDesc)); // Now create a second depth stencil state which turns off the Z buffer for 2D rendering. The only difference is // that DepthEnable is set to false, all other parameters are the same as the other depth stencil state. depthDisabledStencilDesc.DepthEnable = false; depthDisabledStencilDesc.DepthWriteMask = D3D11_DEPTH_WRITE_MASK_ALL; depthDisabledStencilDesc.DepthFunc = D3D11_COMPARISON_LESS; depthDisabledStencilDesc.StencilEnable = true; depthDisabledStencilDesc.StencilReadMask = 0xFF; depthDisabledStencilDesc.StencilWriteMask = 0xFF; depthDisabledStencilDesc.FrontFace.StencilFailOp = D3D11_STENCIL_OP_KEEP; depthDisabledStencilDesc.FrontFace.StencilDepthFailOp = D3D11_STENCIL_OP_INCR; depthDisabledStencilDesc.FrontFace.StencilPassOp = D3D11_STENCIL_OP_KEEP; depthDisabledStencilDesc.FrontFace.StencilFunc = D3D11_COMPARISON_ALWAYS; depthDisabledStencilDesc.BackFace.StencilFailOp = D3D11_STENCIL_OP_KEEP; depthDisabledStencilDesc.BackFace.StencilDepthFailOp = D3D11_STENCIL_OP_DECR; depthDisabledStencilDesc.BackFace.StencilPassOp = D3D11_STENCIL_OP_KEEP; depthDisabledStencilDesc.BackFace.StencilFunc = D3D11_COMPARISON_ALWAYS; // Create the state using the device. m_device->CreateDepthStencilState(&depthDisabledStencilDesc, &m_depthDisabledStencilState); // Clear the blend state description. ZeroMemory(&blendStateDescription, sizeof(D3D11_BLEND_DESC)); // Create an alpha enabled blend state description. blendStateDescription.RenderTarget[0].BlendEnable = TRUE; blendStateDescription.RenderTarget[0].SrcBlend = D3D11_BLEND_SRC_ALPHA; blendStateDescription.RenderTarget[0].DestBlend = D3D11_BLEND_INV_SRC_ALPHA; blendStateDescription.RenderTarget[0].BlendOp = D3D11_BLEND_OP_ADD; blendStateDescription.RenderTarget[0].SrcBlendAlpha = D3D11_BLEND_ONE; blendStateDescription.RenderTarget[0].DestBlendAlpha = D3D11_BLEND_ZERO; blendStateDescription.RenderTarget[0].BlendOpAlpha = D3D11_BLEND_OP_ADD; blendStateDescription.RenderTarget[0].RenderTargetWriteMask = D3D11_COLOR_WRITE_ENABLE_ALL; // Ste's pre multiply //blendStateDescription.RenderTarget[0].BlendEnable = TRUE; //blendStateDescription.RenderTarget[0].SrcBlend = D3D11_BLEND_ONE; //blendStateDescription.RenderTarget[0].DestBlend = D3D11_BLEND_INV_SRC_ALPHA; //blendStateDescription.RenderTarget[0].BlendOp = D3D11_BLEND_OP_ADD; //blendStateDescription.RenderTarget[0].SrcBlendAlpha = D3D11_BLEND_ONE; //blendStateDescription.RenderTarget[0].DestBlendAlpha = D3D11_BLEND_ZERO; //blendStateDescription.RenderTarget[0].BlendOpAlpha = D3D11_BLEND_OP_ADD; //blendStateDescription.RenderTarget[0].RenderTargetWriteMask = D3D11_COLOR_WRITE_ENABLE_ALL; // Create the blend state using the description. m_device->CreateBlendState(&blendStateDescription, &m_alphaEnableBlendingState); // Modify the description to create an alpha disabled blend state description. blendStateDescription.RenderTarget[0].BlendEnable = FALSE; // Create the second blend state using the description. m_device->CreateBlendState(&blendStateDescription, &m_alphaDisableBlendingState); }
int WINAPI WinMain(HINSTANCE ins, HINSTANCE prev, LPSTR cmd, int show) { _CrtSetDbgFlag(_CRTDBG_ALLOC_MEM_DF | _CRTDBG_LEAK_CHECK_DF); // ウィンドウ生成 auto* left_window = new WindowModule(L"Left", 800, 600, ins); left_window->Initialize(); left_window->SetMessageCallback(WM_DESTROY, [](HWND, WPARAM, LPARAM) { PostQuitMessage(0); }); left_window->SetMessageCallback(WM_KEYDOWN, [](HWND h, WPARAM w, LPARAM) { if (w == VK_ESCAPE) { DestroyWindow(h); } }); //auto right_window = new WindowModule(L"Right", 450, 800, ins); //right_window->Initialize(); //right_window->SetMessageCallback(WM_DESTROY, [](HWND, WPARAM, LPARAM) { // PostQuitMessage(0); //}); //right_window->SetMessageCallback(WM_KEYDOWN, [](HWND h, WPARAM w, LPARAM) { // if (w == VK_ESCAPE) { DestroyWindow(h); } //}); // レンダラ作成 auto my_device = CreateDevice(); auto my_context = my_device->GetContext(); auto my_dxgi = CreateDxGiAdapter(); auto device = my_device->GetDevice(); auto context = my_context->GetContext(); // スワップチェイン作成 auto left_swap_chain = my_dxgi->CreateSwapChain(my_device->GetDevice(),left_window->GetWindowHandle()); //auto right_swap_chain = my_dxgi->CreateSwapChain(my_device->GetDevice(),right_window->GetWindowHandle()); // データ作成 auto vs_data = DataContainer::Get("res/shader/VertexShader.cso"); auto ps_data = DataContainer::Get("res/shader/PixelShader.cso"); // シェーダ作成 D3D11_INPUT_ELEMENT_DESC elem_desc[] = { { "POSITION", // セマンティクス 0, // インデックス5 DXGI_FORMAT_R32G32B32_FLOAT, // フォーマット 1, // 入力アセンブラー識別子(?) 0, // オフセット(バイト)(省略化) D3D11_INPUT_PER_VERTEX_DATA, // 入力データクラス識別 0 // ステップレート }, { "COLOR", // セマンティクス 0, // インデックス5 DXGI_FORMAT_R32G32B32A32_FLOAT, // フォーマット 1, // 入力アセンブラー識別子(?) 4*3, // オフセット(バイト)(省略化) D3D11_INPUT_PER_VERTEX_DATA, // 入力データクラス識別 0 // ステップレート }, }; ULONG elem_count = sizeof(elem_desc) / sizeof(elem_desc[0]); auto vertex_shader = new VertexShader(device, vs_data); auto pixel_shader = new PixelShader(device, ps_data); auto input_layout = new InputLayout(device, vs_data, elem_desc, elem_count); // シェーダ適応 vertex_shader->SetVertexShader(context); pixel_shader->SetPixelShader(context); input_layout->SetInputLayout(context); // 頂点バッファ作成 float vertexes[] = { // fu -0.5f, +0.5f, -0.5f, 1, 0, 0, 1, +0.5f, +0.5f, -0.5f, 1, 0, 0, 1, -0.5f, -0.5f, -0.5f, 1, 0, 0, 1, // fd -0.5f, -0.5f, -0.5f, 1, 0, 0, 1, +0.5f, +0.5f, -0.5f, 1, 0, 0, 1, +0.5f, -0.5f, -0.5f, 1, 0, 0, 1, // bu +0.5f, +0.5f, +0.5f, 1, 0, 0, 1, -0.5f, +0.5f, +0.5f, 1, 0, 0, 1, +0.5f, -0.5f, +0.5f, 1, 0, 0, 1, // bd +0.5f, -0.5f, +0.5f, 1, 0, 0, 1, -0.5f, +0.5f, +0.5f, 1, 0, 0, 1, -0.5f, -0.5f, +0.5f, 1, 0, 0, 1, // lu -0.5f, +0.5f, +0.5f, 0, 0, 1, 1, -0.5f, +0.5f, -0.5f, 0, 0, 1, 1, -0.5f, -0.5f, +0.5f, 0, 0, 1, 1, // ld -0.5f, -0.5f, +0.5f, 0, 0, 1, 1, -0.5f, +0.5f, -0.5f, 0, 0, 1, 1, -0.5f, -0.5f, -0.5f, 0, 0, 1, 1, // ru +0.5f, +0.5f, -0.5f, 0, 0, 1, 1, +0.5f, +0.5f, +0.5f, 0, 0, 1, 1, +0.5f, -0.5f, -0.5f, 0, 0, 1, 1, // rd +0.5f, -0.5f, -0.5f, 0, 0, 1, 1, +0.5f, +0.5f, +0.5f, 0, 0, 1, 1, +0.5f, -0.5f, +0.5f, 0, 0, 1, 1, }; auto vertex_buffer = new VertexBuffer(device, vertexes, sizeof(vertexes), sizeof(float) * 7); // ビューポート設定 D3D11_VIEWPORT view_port; view_port.Width = static_cast<float>(1440); view_port.Height = static_cast<float>(900); view_port.MinDepth = 0.f; view_port.MaxDepth = 1.f; view_port.TopLeftX = 0.f; view_port.TopLeftY = 0.f; context->RSSetViewports(1, &view_port); auto adapter = my_dxgi->GetAdapter(); IDXGIOutput* output; adapter->EnumOutputs(0, &output); //left_swap_chain->ResizeBuffer(output); //left_swap_chain->SetOutput(output, true); //left_swap_chain->ResizeBuffer(output, true); output->Release(); struct ConstantBuffer { Matrix world; Matrix view; Matrix projection; }; ConstantBuffer constant_buffer_data; D3D11_BUFFER_DESC constant_buffer_desc = { 0 }; constant_buffer_desc.ByteWidth = sizeof(constant_buffer_data); constant_buffer_desc.Usage = D3D11_USAGE_DEFAULT; constant_buffer_desc.BindFlags = D3D11_BIND_CONSTANT_BUFFER; constant_buffer_desc.CPUAccessFlags = 0; constant_buffer_desc.MiscFlags = 0; constant_buffer_desc.StructureByteStride = sizeof(float); ID3D11Buffer* constant_buffer; HRESULT ret; ret = device->CreateBuffer(&constant_buffer_desc, nullptr, &constant_buffer); _ASSERT_EXPR(SUCCEEDED(ret), L"コンスタントバッファ作成失敗"); float ff = 0; FrameKeeper fk(60, [&]{ left_swap_chain->Clear(context); left_swap_chain->SetRenderTarget(context); ff += 0.1f; constant_buffer_data.world.SetScale(10); constant_buffer_data.world.SetIdentity(); constant_buffer_data.world.RotateY(-ff); constant_buffer_data.view.SetView(Vector3(0, 0, -10), Vector3(0, 0, 1), Vector3(0, 1, 0)); constant_buffer_data.projection.PerthFovL(PI / 8.f, 4.f / 3.f, 0.1f, 1000.f); context->UpdateSubresource(constant_buffer, 0, nullptr, &constant_buffer_data, 0, 0); context->VSSetConstantBuffers(0, 1, &constant_buffer); vertex_buffer->SetVertexBuffer(context, 1); context->IASetPrimitiveTopology(D3D11_PRIMITIVE_TOPOLOGY_TRIANGLELIST); context->Draw(24, 0); left_swap_chain->Present(); //right_swap_chain->Clear(context); //right_swap_chain->SetRenderTarget(context); //right_swap_chain->Present(); }); // メッセージループ constant_buffer_data.world.SetIdentity(); while (left_window->MessageProcessing()) { fk.Step(); } constant_buffer->Release(); delete vertex_buffer; delete input_layout; delete pixel_shader; delete vertex_shader; DataContainer::Unregist("res/shader/vertex.cso"); DataContainer::Unregist("res/shader/pixel.cso"); DataContainer::Unregist("res/shader/geometry.cso"); //right_swap_chain->Release(); left_swap_chain->Release(); my_dxgi->Release(); my_context->Release(); my_device->Release(); // 終了 left_window->Finalize(); //right_window->Finalize(); delete left_window; //delete right_window; return 0; }
bool D3DClass::Initialize(int screenWidth, int screenHeight, bool vsync, HWND hwnd, bool fullscreen, float screenDepth, float screenNear) { HRESULT result; IDXGIFactory* factory; IDXGIAdapter* adapter; IDXGIOutput* adapterOutput; unsigned int numModes, i, numerator, denominator, stringLength; DXGI_MODE_DESC* displayModeList; DXGI_ADAPTER_DESC adapterDesc; int error; DXGI_SWAP_CHAIN_DESC swapChainDesc; D3D_FEATURE_LEVEL featureLevel; ID3D11Texture2D* backBufferPtr; D3D11_TEXTURE2D_DESC depthBufferDesc; D3D11_DEPTH_STENCIL_DESC depthStencilDesc; D3D11_DEPTH_STENCIL_VIEW_DESC depthStencilViewDesc; D3D11_RASTERIZER_DESC rasterDesc; D3D11_VIEWPORT viewport; float fieldOfView, screenAspect; // Store the vsync setting. m_vsync_enabled = vsync; // Create a DX graphics interface factory result = CreateDXGIFactory(__uuidof(IDXGIFactory), (void**)&factory); if (FAILED(result)) { return false; } // Adapter for the primary graphics interface (video card) result = factory->EnumAdapters(0, &adapter); if (FAILED(result)) { return false; } // primary adapter output = monitor result = adapter->EnumOutputs(0, &adapterOutput); if (FAILED(result)) { return false; } // Get the number of modes that fit the DXGI_FORMAT_R8G8B8A8_UNORM display format result = adapterOutput->GetDisplayModeList(DXGI_FORMAT_R8G8B8A8_UNORM, DXGI_ENUM_MODES_INTERLACED, &numModes, NULL); if (FAILED(result)) { return false; } // Create a list to hold all the possible display modes for this monitor/video card combination. displayModeList = new DXGI_MODE_DESC[numModes]; if(!displayModeList) { return false; } // Now fill the display mode list structures. result = adapterOutput->GetDisplayModeList(DXGI_FORMAT_R8G8B8A8_UNORM, DXGI_ENUM_MODES_INTERLACED, &numModes, displayModeList); if(FAILED(result)) { return false; } // Now go through all the display modes and find the one that matches the screen width and height. // When a match is found store the numerator and denominator of the refresh rate for that monitor. for(i=0; i<numModes; i++) { if(displayModeList[i].Width == (unsigned int)screenWidth) { if(displayModeList[i].Height == (unsigned int)screenHeight) { numerator = displayModeList[i].RefreshRate.Numerator; denominator = displayModeList[i].RefreshRate.Denominator; } } } // Get the adapter (video card) description. result = adapter->GetDesc(&adapterDesc); if(FAILED(result)) { return false; } m_videoCardMemory = (int)(adapterDesc.DedicatedVideoMemory / 1024 / 1024); error = wcstombs_s(&stringLength, m_videoCardDescription, 128, adapterDesc.Description, 128); if (error != 0) { return false; } // Release the display mode list. delete[] displayModeList; displayModeList = 0; adapterOutput->Release(); adapterOutput = 0; adapter->Release(); adapter = 0; factory->Release(); factory = 0; ZeroMemory(&swapChainDesc, sizeof(swapChainDesc)); swapChainDesc.BufferCount = 1; swapChainDesc.BufferDesc.Width = screenWidth; swapChainDesc.BufferDesc.Height = screenHeight; swapChainDesc.BufferDesc.Format = DXGI_FORMAT_R8G8B8A8_UNORM; if (m_vsync_enabled) { swapChainDesc.BufferDesc.RefreshRate.Numerator = numerator; swapChainDesc.BufferDesc.RefreshRate.Denominator = denominator; } else { swapChainDesc.BufferDesc.RefreshRate.Numerator = 0; swapChainDesc.BufferDesc.RefreshRate.Denominator = 1; } swapChainDesc.BufferUsage = DXGI_USAGE_RENDER_TARGET_OUTPUT; swapChainDesc.OutputWindow = hwnd; //multisampling off swapChainDesc.SampleDesc.Count = 1; swapChainDesc.SampleDesc.Quality = 0; if (fullscreen) { swapChainDesc.Windowed = false; } else { swapChainDesc.Windowed = true; } //set scan line ordering and scaling to unspecified swapChainDesc.BufferDesc.ScanlineOrdering = DXGI_MODE_SCANLINE_ORDER_UNSPECIFIED; swapChainDesc.BufferDesc.Scaling = DXGI_MODE_SCALING_UNSPECIFIED; // discard back buffer contents after presenting swapChainDesc.SwapEffect = DXGI_SWAP_EFFECT_DISCARD; swapChainDesc.Flags = 0; featureLevel = D3D_FEATURE_LEVEL_11_0; result = D3D11CreateDeviceAndSwapChain( NULL, D3D_DRIVER_TYPE_REFERENCE, NULL, 0, &featureLevel, 1, D3D11_SDK_VERSION, &swapChainDesc, &m_swapChain, &m_device, NULL, &m_deviceContext); if (FAILED(result)) { return false; } // Get the pointer to the back buffer result = m_swapChain->GetBuffer(0, __uuidof(ID3D11Texture2D), (LPVOID*)&backBufferPtr); if (FAILED(result)) { return false; } result = m_device->CreateRenderTargetView(backBufferPtr, NULL, &m_renderTargetView); if (FAILED(result)) { return false; } //Release pointer to the back buffer as we no longer need it backBufferPtr->Release(); backBufferPtr = 0; ZeroMemory(&depthBufferDesc, sizeof(depthBufferDesc)); depthBufferDesc.Width = screenWidth; depthBufferDesc.Height = screenHeight; depthBufferDesc.MipLevels = 1; depthBufferDesc.ArraySize = 1; depthBufferDesc.Format = DXGI_FORMAT_D24_UNORM_S8_UINT; depthBufferDesc.SampleDesc.Count = 1; depthBufferDesc.SampleDesc.Quality = 0; depthBufferDesc.Usage = D3D11_USAGE_DEFAULT; depthBufferDesc.BindFlags = D3D11_BIND_DEPTH_STENCIL; depthBufferDesc.CPUAccessFlags = 0; depthBufferDesc.MiscFlags = 0; result = m_device->CreateTexture2D(&depthBufferDesc, NULL, &m_depthStencilBuffer); if (FAILED(result)) { return false; } ZeroMemory(&depthStencilDesc, sizeof(depthStencilDesc)); depthStencilDesc.DepthEnable = true; depthStencilDesc.DepthWriteMask = D3D11_DEPTH_WRITE_MASK_ALL; depthStencilDesc.DepthFunc = D3D11_COMPARISON_LESS; depthStencilDesc.StencilEnable = true; depthStencilDesc.StencilReadMask = 0xFF; depthStencilDesc.StencilWriteMask = 0xFF; // Stencil operations if pixel is front-facing. depthStencilDesc.FrontFace.StencilFailOp = D3D11_STENCIL_OP_KEEP; depthStencilDesc.FrontFace.StencilDepthFailOp = D3D11_STENCIL_OP_INCR; depthStencilDesc.FrontFace.StencilPassOp = D3D11_STENCIL_OP_KEEP; depthStencilDesc.FrontFace.StencilFunc = D3D11_COMPARISON_ALWAYS; // Stencil operations if pixel is back-facing. depthStencilDesc.BackFace.StencilFailOp = D3D11_STENCIL_OP_KEEP; depthStencilDesc.BackFace.StencilDepthFailOp = D3D11_STENCIL_OP_DECR; depthStencilDesc.BackFace.StencilPassOp = D3D11_STENCIL_OP_KEEP; depthStencilDesc.BackFace.StencilFunc = D3D11_COMPARISON_ALWAYS; // Create the depth stencil state. result = m_device->CreateDepthStencilState(&depthStencilDesc, &m_depthStencilState); if(FAILED(result)) { return false; } // Set the depth stencil state. m_deviceContext->OMSetDepthStencilState(m_depthStencilState, 1); // Initailze the depth stencil view. ZeroMemory(&depthStencilViewDesc, sizeof(depthStencilViewDesc)); // Set up the depth stencil view description. depthStencilViewDesc.Format = DXGI_FORMAT_D24_UNORM_S8_UINT; depthStencilViewDesc.ViewDimension = D3D11_DSV_DIMENSION_TEXTURE2D; depthStencilViewDesc.Texture2D.MipSlice = 0; // Create the depth stencil view. result = m_device->CreateDepthStencilView(m_depthStencilBuffer, &depthStencilViewDesc, &m_depthStencilView); if(FAILED(result)) { return false; } // Bind the render target view and depth stencil buffer to the output render pipeline. m_deviceContext->OMSetRenderTargets(1, &m_renderTargetView, m_depthStencilView); // Setup the raster description which will determine how and what polygons will be drawn. rasterDesc.AntialiasedLineEnable = false; rasterDesc.CullMode = D3D11_CULL_BACK; rasterDesc.DepthBias = 0; rasterDesc.DepthBiasClamp = 0.0f; rasterDesc.DepthClipEnable = true; rasterDesc.FillMode = D3D11_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_device->CreateRasterizerState(&rasterDesc, &m_rasterState); if(FAILED(result)) { return false; } // Now set the rasterizer state. m_deviceContext->RSSetState(m_rasterState); viewport.Width = (float)screenWidth; viewport.Height = (float)screenHeight; viewport.MinDepth = 0.0f; viewport.MaxDepth = 1.0f; viewport.TopLeftX = 0.0f; viewport.TopLeftY = 0.0f; m_deviceContext->RSSetViewports(1, &viewport); fieldOfView = (float)D3DX_PI / 4.0f; screenAspect = (float)screenWidth / (float)screenHeight; D3DXMatrixPerspectiveFovLH(&m_projectionMatrix, fieldOfView, screenAspect, screenNear, screenDepth); // Initialize the world matrix to the identity matrix. D3DXMatrixIdentity(&m_worldMatrix); // Create an orthographic projection matrix for 2D rendering. D3DXMatrixOrthoLH(&m_orthoMatrix, (float)screenWidth, (float)screenHeight, screenNear, screenDepth); return true; }
bool StereoRenderer::FullSetup(int screenWidth, int screenHeight, HWND hwnd, bool fullscreen, float screenDepth, float screenNear) { HRESULT result; IDXGIFactory* factory; IDXGIAdapter* adapter; IDXGIOutput* adapterOutput; unsigned int numModes, i, numerator, denominator, stringLength; DXGI_MODE_DESC* displayModeList; DXGI_ADAPTER_DESC adapterDesc; int error; DXGI_SWAP_CHAIN_DESC swapChainDesc; D3D_FEATURE_LEVEL featureLevel; ID3D11Texture2D* backBufferPtr; D3D11_TEXTURE2D_DESC depthBufferDesc; D3D11_DEPTH_STENCIL_DESC depthStencilDesc; D3D11_DEPTH_STENCIL_VIEW_DESC depthStencilViewDesc; D3D11_RASTERIZER_DESC rasterDesc; D3D11_VIEWPORT viewport; float fieldOfView, screenAspect; // Create a DirectX graphics interface factory. result = CreateDXGIFactory(__uuidof(IDXGIFactory), (void**)&factory); if(FAILED(result)) { return false; } // Use the factory to create an adapter for the primary graphics interface (video card). result = factory->EnumAdapters(0, &adapter); if(FAILED(result)) { return false; } // Enumerate the primary adapter output (monitor). result = adapter->EnumOutputs(0, &adapterOutput); if(FAILED(result)) { return false; } // Get the number of modes that fit the DXGI_FORMAT_R8G8B8A8_UNORM display format for the adapter output (monitor). result = adapterOutput->GetDisplayModeList(DXGI_FORMAT_R8G8B8A8_UNORM, DXGI_ENUM_MODES_INTERLACED, &numModes, NULL); if(FAILED(result)) { return false; } // Create a list to hold all the possible display modes for this monitor/video card combination. displayModeList = new DXGI_MODE_DESC[numModes]; if(!displayModeList) { return false; } // Now fill the display mode list structures. result = adapterOutput->GetDisplayModeList(DXGI_FORMAT_R8G8B8A8_UNORM, DXGI_ENUM_MODES_INTERLACED, &numModes, displayModeList); if(FAILED(result)) { return false; } // Now go through all the display modes and find the one that matches the screen width and height. // When a match is found store the numerator and denominator of the refresh rate for that monitor. for(i=0; i<numModes; i++) { if(displayModeList[i].Width == (unsigned int)screenWidth) { if(displayModeList[i].Height == (unsigned int)screenHeight) { numerator = displayModeList[i].RefreshRate.Numerator; denominator = displayModeList[i].RefreshRate.Denominator; } } } // Get the adapter (video card) description. result = adapter->GetDesc(&adapterDesc); if(FAILED(result)) { return false; } // Release the display mode list. delete [] displayModeList; displayModeList = 0; // Release the adapter output. adapterOutput->Release(); adapterOutput = 0; // Release the adapter. adapter->Release(); adapter = 0; // Release the factory. factory->Release(); factory = 0; // 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 = screenWidth; swapChainDesc.BufferDesc.Height = screenHeight; // Set regular 32-bit surface for the back buffer. swapChainDesc.BufferDesc.Format = DXGI_FORMAT_R8G8B8A8_UNORM; // Set the refresh rate of the back buffer. swapChainDesc.BufferDesc.RefreshRate.Numerator = 60; swapChainDesc.BufferDesc.RefreshRate.Denominator = 1; // Set the usage of the back buffer. swapChainDesc.BufferUsage = DXGI_USAGE_RENDER_TARGET_OUTPUT; // Set the handle for the window to render to. swapChainDesc.OutputWindow = hwnd; // Turn multisampling off. swapChainDesc.SampleDesc.Count = 1; swapChainDesc.SampleDesc.Quality = 0; // Set to full screen or windowed mode. if(fullscreen) { swapChainDesc.Windowed = false; } else { swapChainDesc.Windowed = true; } // 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; // Set the feature level to DirectX 11. featureLevel = D3D_FEATURE_LEVEL_11_0; // Create the swap chain, Direct3D device, and Direct3D device context. result = D3D11CreateDeviceAndSwapChain(NULL, D3D_DRIVER_TYPE_HARDWARE, NULL, D3D11_CREATE_DEVICE_DEBUG, &featureLevel, 1, D3D11_SDK_VERSION, &swapChainDesc, &swapChain, &device, NULL, &context); if(FAILED(result)) { return false; } // Get the pointer to the back buffer. result = swapChain->GetBuffer(0, __uuidof(ID3D11Texture2D), (LPVOID*)&backBufferPtr); if(FAILED(result)) { return false; } // Create the render target view with the back buffer pointer. result = device->CreateRenderTargetView(backBufferPtr, NULL, &rendertarget); if(FAILED(result)) { return false; } // Release pointer to the back buffer as we no longer need it. backBufferPtr->Release(); backBufferPtr = 0; // Initialize the description of the depth buffer. ZeroMemory(&depthBufferDesc, sizeof(depthBufferDesc)); // Set up the description of the depth buffer. depthBufferDesc.Width = screenWidth; depthBufferDesc.Height = screenHeight; depthBufferDesc.MipLevels = 1; depthBufferDesc.ArraySize = 1; depthBufferDesc.Format = DXGI_FORMAT_D24_UNORM_S8_UINT; depthBufferDesc.SampleDesc.Count = 1; depthBufferDesc.SampleDesc.Quality = 0; depthBufferDesc.Usage = D3D11_USAGE_DEFAULT; depthBufferDesc.BindFlags = D3D11_BIND_DEPTH_STENCIL; depthBufferDesc.CPUAccessFlags = 0; depthBufferDesc.MiscFlags = 0; // Create the texture for the depth buffer using the filled out description. result = device->CreateTexture2D(&depthBufferDesc, NULL, &depthstencil); if(FAILED(result)) { return false; } // Initialize the description of the stencil state. ZeroMemory(&depthStencilDesc, sizeof(depthStencilDesc)); // Set up the description of the stencil state. depthStencilDesc.DepthEnable = true; depthStencilDesc.DepthWriteMask = D3D11_DEPTH_WRITE_MASK_ALL; depthStencilDesc.DepthFunc = D3D11_COMPARISON_LESS; depthStencilDesc.StencilEnable = true; depthStencilDesc.StencilReadMask = 0xFF; depthStencilDesc.StencilWriteMask = 0xFF; // Stencil operations if pixel is front-facing. depthStencilDesc.FrontFace.StencilFailOp = D3D11_STENCIL_OP_KEEP; depthStencilDesc.FrontFace.StencilDepthFailOp = D3D11_STENCIL_OP_INCR; depthStencilDesc.FrontFace.StencilPassOp = D3D11_STENCIL_OP_KEEP; depthStencilDesc.FrontFace.StencilFunc = D3D11_COMPARISON_ALWAYS; // Stencil operations if pixel is back-facing. depthStencilDesc.BackFace.StencilFailOp = D3D11_STENCIL_OP_KEEP; depthStencilDesc.BackFace.StencilDepthFailOp = D3D11_STENCIL_OP_DECR; depthStencilDesc.BackFace.StencilPassOp = D3D11_STENCIL_OP_KEEP; depthStencilDesc.BackFace.StencilFunc = D3D11_COMPARISON_ALWAYS; // Create the depth stencil state. result = device->CreateDepthStencilState(&depthStencilDesc, &depthStencilState); if(FAILED(result)) { return false; } // Set the depth stencil state. context->OMSetDepthStencilState(depthStencilState, 1); // Initialize the depth stencil view. ZeroMemory(&depthStencilViewDesc, sizeof(depthStencilViewDesc)); // Set up the depth stencil view description. depthStencilViewDesc.Format = DXGI_FORMAT_D24_UNORM_S8_UINT; depthStencilViewDesc.ViewDimension = D3D11_DSV_DIMENSION_TEXTURE2D; depthStencilViewDesc.Texture2D.MipSlice = 0; // Create the depth stencil view. result = device->CreateDepthStencilView(depthstencil, &depthStencilViewDesc, &depthview); if(FAILED(result)) { return false; } // Bind the render target view and depth stencil buffer to the output render pipeline. context->OMSetRenderTargets(1, &rendertarget, depthview); // Setup the raster description which will determine how and what polygons will be drawn. rasterDesc.AntialiasedLineEnable = false; rasterDesc.CullMode = D3D11_CULL_BACK; rasterDesc.DepthBias = 0; rasterDesc.DepthBiasClamp = 0.0f; rasterDesc.DepthClipEnable = true; rasterDesc.FillMode = D3D11_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 = device->CreateRasterizerState(&rasterDesc, &rasterSolidState); if(FAILED(result)) { return false; } return true; }
bool D3DClass::Initialize(int screenWidth, int screenHeight, bool vsync, HWND hwnd, bool fullscreen, float screenDepth, float screenNear) { HRESULT result; IDXGIFactory* factory; IDXGIAdapter* adapter; IDXGIOutput* adapterOutput; unsigned int numModes, i, numerator, denominator, stringLength; DXGI_MODE_DESC* displayModeList; DXGI_ADAPTER_DESC adapterDesc; int error; DXGI_SWAP_CHAIN_DESC swapChainDesc; D3D_FEATURE_LEVEL featureLevel; ID3D11Texture2D* backBufferPtr; D3D11_TEXTURE2D_DESC depthBufferDesc; D3D11_DEPTH_STENCIL_DESC depthStencilDesc; D3D11_DEPTH_STENCIL_VIEW_DESC depthStencilViewDesc; D3D11_RASTERIZER_DESC rasterDesc; D3D11_VIEWPORT viewport; float fieldOfView, screenAspect; D3D11_DEPTH_STENCIL_DESC depthDisabledStencilDesc; D3D11_BLEND_DESC blendStateDesc; m_vsync_enabled = vsync; result = CreateDXGIFactory(__uuidof(IDXGIFactory), (void**)&factory); if(FAILED(result)) { return false; } result = factory->EnumAdapters(0, &adapter); if(FAILED(result)) { return false; } result = adapter->EnumOutputs(0, &adapterOutput); if(FAILED(result)) { return false; } result = adapterOutput->GetDisplayModeList(DXGI_FORMAT_R8G8B8A8_UNORM, DXGI_ENUM_MODES_INTERLACED, &numModes, NULL); if(FAILED(result)) { return false; } displayModeList = new DXGI_MODE_DESC[numModes]; if(!displayModeList) { return false; } result = adapterOutput->GetDisplayModeList(DXGI_FORMAT_R8G8B8A8_UNORM, DXGI_ENUM_MODES_INTERLACED, &numModes, displayModeList); if(FAILED(result)) { return false; } for(i=0; i<numModes; i++) { if(displayModeList[i].Width == (unsigned int) screenWidth) { if(displayModeList[i].Height == (unsigned int) screenHeight) { numerator = displayModeList[i].RefreshRate.Numerator; denominator = displayModeList[i].RefreshRate.Denominator; } } } result = adapter->GetDesc(&adapterDesc); if(FAILED(result)) { return false; } m_videoCardMemory = (int)(adapterDesc.DedicatedVideoMemory / 1024 / 1024); error = wcstombs_s(&stringLength, m_videoCardDescription, 128, adapterDesc.Description, 128); if(error != 0) { return false; } delete [] displayModeList; displayModeList = 0; adapterOutput->Release(); adapterOutput = 0; adapter->Release(); adapter = 0; factory->Release(); factory = 0; ZeroMemory(&swapChainDesc, sizeof(swapChainDesc)); swapChainDesc.BufferCount = 1; swapChainDesc.BufferDesc.Width = screenWidth; swapChainDesc.BufferDesc.Height = screenHeight; swapChainDesc.BufferDesc.Format = DXGI_FORMAT_R8G8B8A8_UNORM; if(m_vsync_enabled) { swapChainDesc.BufferDesc.RefreshRate.Numerator = numerator; swapChainDesc.BufferDesc.RefreshRate.Denominator = denominator; } else { swapChainDesc.BufferDesc.RefreshRate.Numerator = 0; swapChainDesc.BufferDesc.RefreshRate.Denominator = 1; } swapChainDesc.BufferUsage = DXGI_USAGE_RENDER_TARGET_OUTPUT; swapChainDesc.OutputWindow = hwnd; swapChainDesc.SampleDesc.Count = 1; swapChainDesc.SampleDesc.Quality = 0; if(fullscreen) { swapChainDesc.Windowed = false; } else { swapChainDesc.Windowed = true; } swapChainDesc.BufferDesc.ScanlineOrdering = DXGI_MODE_SCANLINE_ORDER_UNSPECIFIED; swapChainDesc.BufferDesc.Scaling = DXGI_MODE_SCALING_UNSPECIFIED; swapChainDesc.SwapEffect = DXGI_SWAP_EFFECT_DISCARD; swapChainDesc.Flags = 0; featureLevel = D3D_FEATURE_LEVEL_11_0; result = D3D11CreateDeviceAndSwapChain(NULL, D3D_DRIVER_TYPE_HARDWARE, NULL, 0, &featureLevel, 1, D3D11_SDK_VERSION, &swapChainDesc, &m_swapChain, &m_device, NULL, &m_deviceContext); if(FAILED(result)) { return false; } result = m_swapChain->GetBuffer(0, __uuidof(ID3D11Texture2D), (LPVOID*)&backBufferPtr); if(FAILED(result)) { return false; } result = m_device->CreateRenderTargetView(backBufferPtr, NULL, &m_renderTargetView); if(FAILED(result)) { return false; } backBufferPtr->Release(); backBufferPtr = 0; ZeroMemory(&depthBufferDesc, sizeof(depthBufferDesc)); depthBufferDesc.Width = screenWidth; depthBufferDesc.Height = screenHeight; depthBufferDesc.MipLevels = 1; depthBufferDesc.ArraySize = 1; depthBufferDesc.Format = DXGI_FORMAT_D24_UNORM_S8_UINT; depthBufferDesc.SampleDesc.Count = 1; depthBufferDesc.SampleDesc.Quality = 0; depthBufferDesc.Usage = D3D11_USAGE_DEFAULT; depthBufferDesc.BindFlags = D3D11_BIND_DEPTH_STENCIL; depthBufferDesc.CPUAccessFlags = 0; depthBufferDesc.MiscFlags = 0; result = m_device->CreateTexture2D(&depthBufferDesc, NULL, &m_depthStencilBuffer); if(FAILED(result)) { return false; } ZeroMemory(&depthStencilDesc, sizeof(depthStencilDesc)); depthStencilDesc.DepthEnable = true; depthStencilDesc.DepthWriteMask = D3D11_DEPTH_WRITE_MASK_ALL; depthStencilDesc.DepthFunc = D3D11_COMPARISON_LESS; depthStencilDesc.StencilEnable = true; depthStencilDesc.StencilReadMask = 0xFF; depthStencilDesc.StencilWriteMask = 0XFF; depthStencilDesc.FrontFace.StencilFailOp = D3D11_STENCIL_OP_KEEP; depthStencilDesc.FrontFace.StencilDepthFailOp = D3D11_STENCIL_OP_INCR; depthStencilDesc.FrontFace.StencilPassOp = D3D11_STENCIL_OP_KEEP; depthStencilDesc.FrontFace.StencilFunc = D3D11_COMPARISON_ALWAYS; depthStencilDesc.BackFace.StencilFailOp = D3D11_STENCIL_OP_KEEP; depthStencilDesc.BackFace.StencilDepthFailOp = D3D11_STENCIL_OP_DECR; depthStencilDesc.BackFace.StencilPassOp = D3D11_STENCIL_OP_KEEP; depthStencilDesc.BackFace.StencilFunc = D3D11_COMPARISON_ALWAYS; result = m_device->CreateDepthStencilState(&depthStencilDesc, &m_depthStencilState); if(FAILED(result)) { return false; } m_deviceContext->OMSetDepthStencilState(m_depthStencilState, 1); ZeroMemory(&depthStencilViewDesc, sizeof(depthStencilViewDesc)); depthStencilViewDesc.Format = DXGI_FORMAT_D24_UNORM_S8_UINT; depthStencilViewDesc.ViewDimension = D3D11_DSV_DIMENSION_TEXTURE2D; depthStencilViewDesc.Texture2D.MipSlice = 0; result = m_device->CreateDepthStencilView(m_depthStencilBuffer, &depthStencilViewDesc, &m_depthStencilView); if(FAILED(result)) { return false; } m_deviceContext->OMSetRenderTargets(1, &m_renderTargetView, m_depthStencilView); rasterDesc.AntialiasedLineEnable = false; rasterDesc.CullMode = D3D11_CULL_BACK; rasterDesc.DepthBias = 0; rasterDesc.DepthBiasClamp = 0.0f; rasterDesc.DepthClipEnable = false; rasterDesc.FillMode = D3D11_FILL_SOLID; rasterDesc.FrontCounterClockwise = false; rasterDesc.MultisampleEnable = false; rasterDesc.ScissorEnable = false; rasterDesc.SlopeScaledDepthBias = 0.0f; result = m_device->CreateRasterizerState(&rasterDesc, &m_rasterState); if(FAILED(result)) { return false; } m_deviceContext->RSSetState(m_rasterState); viewport.Width = (float)screenWidth; viewport.Height = (float)screenHeight; viewport.MinDepth = 0.0f; viewport.MaxDepth = 1.0f; viewport.TopLeftX = 0.0f; viewport.TopLeftY = 0.0f; m_deviceContext->RSSetViewports(1, &viewport); fieldOfView = (float)DirectX::XM_PI / 4.0f; screenAspect = (float)screenWidth / (float)screenHeight; m_projectionMatrix = DirectX::XMMatrixPerspectiveFovLH(fieldOfView, screenAspect, screenNear, screenDepth); m_worldMatrix = DirectX::XMMatrixIdentity(); m_orthoMatrix = DirectX::XMMatrixOrthographicLH((float)screenWidth, (float)screenHeight, screenNear, screenDepth); ZeroMemory(&depthDisabledStencilDesc, sizeof(depthDisabledStencilDesc)); depthDisabledStencilDesc.DepthEnable = false; depthDisabledStencilDesc.DepthWriteMask = D3D11_DEPTH_WRITE_MASK_ALL; depthDisabledStencilDesc.DepthFunc = D3D11_COMPARISON_LESS; depthDisabledStencilDesc.StencilEnable = true; depthDisabledStencilDesc.StencilReadMask = 0xFF; depthDisabledStencilDesc.StencilWriteMask = 0XFF; depthDisabledStencilDesc.FrontFace.StencilFailOp = D3D11_STENCIL_OP_KEEP; depthDisabledStencilDesc.FrontFace.StencilDepthFailOp = D3D11_STENCIL_OP_INCR; depthDisabledStencilDesc.FrontFace.StencilPassOp = D3D11_STENCIL_OP_KEEP; depthDisabledStencilDesc.FrontFace.StencilFunc = D3D11_COMPARISON_ALWAYS; depthDisabledStencilDesc.BackFace.StencilFailOp = D3D11_STENCIL_OP_KEEP; depthDisabledStencilDesc.BackFace.StencilDepthFailOp = D3D11_STENCIL_OP_DECR; depthDisabledStencilDesc.BackFace.StencilPassOp = D3D11_STENCIL_OP_KEEP; depthDisabledStencilDesc.BackFace.StencilFunc = D3D11_COMPARISON_ALWAYS; result = m_device->CreateDepthStencilState(&depthDisabledStencilDesc, &m_depthDisabledStencilState); if(FAILED(result)) { return false; } ZeroMemory(&blendStateDesc, sizeof(D3D11_BLEND_DESC)); blendStateDesc.RenderTarget[0].BlendEnable = TRUE; blendStateDesc.RenderTarget[0].SrcBlend = D3D11_BLEND_ONE; blendStateDesc.RenderTarget[0].DestBlend = D3D11_BLEND_INV_SRC_ALPHA; blendStateDesc.RenderTarget[0].BlendOp = D3D11_BLEND_OP_ADD; blendStateDesc.RenderTarget[0].SrcBlendAlpha = D3D11_BLEND_ONE; blendStateDesc.RenderTarget[0].DestBlendAlpha = D3D11_BLEND_ZERO; blendStateDesc.RenderTarget[0].BlendOpAlpha = D3D11_BLEND_OP_ADD; blendStateDesc.RenderTarget[0].RenderTargetWriteMask = 0x0f; result = m_device->CreateBlendState(&blendStateDesc, &m_alphaEnableBlendingState); if(FAILED(result)) { return false; } blendStateDesc.RenderTarget[0].BlendEnable = FALSE; result = m_device->CreateBlendState(&blendStateDesc, &m_alphaDisableBlendingState); if(FAILED(result)) { return false; } return true; }
bool D3DClass::Initialize(int screenWidth, int screenHeight, bool vsync, HWND hwnd, bool fullscreen, float screenDepth, float screenNear) { //set vsync enabled variable m_vsync_enabled = vsync; //----- get refresh rate from monitor / video card //create DirectX graphics interface factory HRESULT result; IDXGIFactory* factory; result = CreateDXGIFactory(__uuidof(IDXGIFactory), (void**)&factory); if(FAILED(result)) return false; //use factory to create adapter for primary graphics interface (video card) IDXGIAdapter* adapter; result = factory->EnumAdapters(0, &adapter); if(FAILED(result)) return false; //enumerate primary adapter output IDXGIOutput* adapterOutput; result = adapter->EnumOutputs(0, &adapterOutput); if(FAILED(result)) return false; //get amount of modes that fit in the DXGI_FORMAT_R8G8B8A8_UNORM display format for adapter output (monitor) unsigned int numModes; result = adapterOutput->GetDisplayModeList(DXGI_FORMAT_R8G8B8A8_UNORM, DXGI_ENUM_MODES_INTERLACED, & numModes, NULL); if(FAILED(result)) return false; //create list to hold all possible display modes for this monitor/video card combination DXGI_MODE_DESC* displayModeList; displayModeList = new DXGI_MODE_DESC[numModes]; if(!displayModeList) return false; //fill the display mode list structures result = adapterOutput->GetDisplayModeList(DXGI_FORMAT_R8G8B8A8_UNORM, DXGI_ENUM_MODES_INTERLACED, & numModes, displayModeList); if(FAILED(result)) return false; //go through all display modes and find one that matches the screen width and height //when finding a match, store the enumaerator and denominator of the refresh rate for this monitor unsigned int numerator, denominator; for(unsigned int i = 0; i < numModes; i++) { if(displayModeList[i].Width == (unsigned int)screenWidth) if(displayModeList[i].Height == (unsigned int)screenHeight) { numerator = displayModeList[i].RefreshRate.Numerator; denominator = displayModeList[i].RefreshRate.Denominator; } } //----- release the structures delete [] displayModeList; displayModeList = 0; adapterOutput->Release(); adapterOutput = 0; adapter->Release(); adapter = 0; factory->Release(); factory = 0; //----- //----- start DirectX initialization //init swap chain (front and back buffer) - first graphics will be drawn in back buffer, then swapped with front buffer to display results DXGI_SWAP_CHAIN_DESC swapChainDesc; ZeroMemory(&swapChainDesc, sizeof(swapChainDesc)); //set to single back buffer swapChainDesc.BufferCount = 1; //set width and height of back buffer swapChainDesc.BufferDesc.Width = screenWidth; swapChainDesc.BufferDesc.Height = screenHeight; //set back buffer to 32bit surface swapChainDesc.BufferDesc.Format = DXGI_FORMAT_B8G8R8A8_UNORM; //----- //set frame rate of back buffer if(m_vsync_enabled) { swapChainDesc.BufferDesc.RefreshRate.Numerator = numerator; swapChainDesc.BufferDesc.RefreshRate.Denominator = denominator; } else { swapChainDesc.BufferDesc.RefreshRate.Numerator = 0; swapChainDesc.BufferDesc.RefreshRate.Denominator = 1; } //set usage of back buffer swapChainDesc.BufferUsage = DXGI_USAGE_RENDER_TARGET_OUTPUT; //set handle for window to render to swapChainDesc.OutputWindow = hwnd; //turn multisampling off swapChainDesc.SampleDesc.Count = 1; swapChainDesc.SampleDesc.Quality = 0; //set full screen mode accordingly if(fullscreen) swapChainDesc.Windowed = false; else swapChainDesc.Windowed = true; //set scan line ordering and scaling to unspecified swapChainDesc.BufferDesc.ScanlineOrdering = DXGI_MODE_SCANLINE_ORDER_UNSPECIFIED; swapChainDesc.BufferDesc.Scaling = DXGI_MODE_SCALING_UNSPECIFIED; //discard back buffer contents after presenting swapChainDesc.SwapEffect = DXGI_SWAP_EFFECT_DISCARD; //unset advanced flags swapChainDesc.Flags = 0; //set up feature level D3D_FEATURE_LEVEL featureLevel; featureLevel = D3D_FEATURE_LEVEL_11_0; //create swap chain, Direct3D device and device context result = D3D11CreateDeviceAndSwapChain(NULL, D3D_DRIVER_TYPE_HARDWARE, NULL, 0, &featureLevel, 1, D3D11_SDK_VERSION, &swapChainDesc, &m_swapChain, &m_device, NULL, &m_deviceContext); if(FAILED(result)) return false; //get pointer to back buffer ID3D11Texture2D* backBufferPtr; result = m_swapChain->GetBuffer(0, __uuidof(ID3D11Texture2D), (LPVOID*)&backBufferPtr); if(FAILED(result)) return false; //create render target view result = m_device->CreateRenderTargetView(backBufferPtr, NULL, &m_renderTargetView); if(FAILED(result)) return false; //release pointer to back buffer backBufferPtr->Release(); backBufferPtr = 0; //----- set up depth buffer desc - for rendering polygons in 3D space // + depth/stencil buffer to achieve effects like motion blur D3D11_TEXTURE2D_DESC depthBufferDesc; ZeroMemory(&depthBufferDesc, sizeof(depthBufferDesc)); //set up description values depthBufferDesc.Width = screenWidth; depthBufferDesc.Height = screenHeight; depthBufferDesc.MipLevels = 1; depthBufferDesc.ArraySize = 1; depthBufferDesc.Format = DXGI_FORMAT_D24_UNORM_S8_UINT; depthBufferDesc.SampleDesc.Count = 1; depthBufferDesc.SampleDesc.Quality = 0; depthBufferDesc.Usage = D3D11_USAGE_DEFAULT; depthBufferDesc.BindFlags = D3D11_BIND_DEPTH_STENCIL; depthBufferDesc.CPUAccessFlags = 0; depthBufferDesc.MiscFlags = 0; //create depth/stencil buffer result = m_device->CreateTexture2D(&depthBufferDesc, NULL, &m_depthStencilBuffer); if(FAILED(result)) return false; //set up stencil buffer values D3D11_DEPTH_STENCIL_DESC depthStencilDesc; ZeroMemory(&depthStencilDesc, sizeof(depthStencilDesc)); // Set up the description of the stencil state. depthStencilDesc.DepthEnable = true; depthStencilDesc.DepthWriteMask = D3D11_DEPTH_WRITE_MASK_ALL; depthStencilDesc.DepthFunc = D3D11_COMPARISON_LESS; depthStencilDesc.StencilEnable = true; depthStencilDesc.StencilReadMask = 0xFF; depthStencilDesc.StencilWriteMask = 0xFF; // Stencil operations if pixel is front-facing. depthStencilDesc.FrontFace.StencilFailOp = D3D11_STENCIL_OP_KEEP; depthStencilDesc.FrontFace.StencilDepthFailOp = D3D11_STENCIL_OP_INCR; depthStencilDesc.FrontFace.StencilPassOp = D3D11_STENCIL_OP_KEEP; depthStencilDesc.FrontFace.StencilFunc = D3D11_COMPARISON_ALWAYS; // Stencil operations if pixel is back-facing. depthStencilDesc.BackFace.StencilFailOp = D3D11_STENCIL_OP_KEEP; depthStencilDesc.BackFace.StencilDepthFailOp = D3D11_STENCIL_OP_DECR; depthStencilDesc.BackFace.StencilPassOp = D3D11_STENCIL_OP_KEEP; depthStencilDesc.BackFace.StencilFunc = D3D11_COMPARISON_ALWAYS; //create depth stencil state result = m_device->CreateDepthStencilState(&depthStencilDesc, &m_depthStencilState); if(FAILED(result)) return false; //set the state to take its effect m_deviceContext->OMSetDepthStencilState(m_depthStencilState, 1); //init depth stencil view desc D3D11_DEPTH_STENCIL_VIEW_DESC depthStencilViewDesc; ZeroMemory(&depthStencilViewDesc, sizeof(depthStencilViewDesc)); //set up desc depthStencilViewDesc.Format = DXGI_FORMAT_D24_UNORM_S8_UINT; depthStencilViewDesc.ViewDimension = D3D11_DSV_DIMENSION_TEXTURE2D; depthStencilViewDesc.Texture2D.MipSlice = 0; //create the depth stencil view result = m_device->CreateDepthStencilView(m_depthStencilBuffer, &depthStencilViewDesc, &m_depthStencilView); if(FAILED(result)) return false; //bind render target view and depth stencil buffer to output render pipeline m_deviceContext->OMSetRenderTargets(1, &m_renderTargetView, m_depthStencilView); // Setup the viewport for rendering. m_viewport.Width = (float)screenWidth; m_viewport.Height = (float)screenHeight; m_viewport.MinDepth = 0.0f; m_viewport.MaxDepth = 1.0f; m_viewport.TopLeftX = 0.0f; m_viewport.TopLeftY = 0.0f; // Create the viewport. m_deviceContext->RSSetViewports(1, &m_viewport); //create rasterize state - controls how polygons are rendered (e.g. wireframe mode or drawing both front and back faces) D3D11_RASTERIZER_DESC rasterDesc; rasterDesc.AntialiasedLineEnable = false; rasterDesc.CullMode = D3D11_CULL_BACK; rasterDesc.DepthBias = 0; rasterDesc.DepthBiasClamp = 0.0f; rasterDesc.DepthClipEnable = true; rasterDesc.FillMode = D3D11_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_device->CreateRasterizerState(&rasterDesc, &m_rasterState); if(FAILED(result)) return false; //set rasterizer state m_deviceContext->RSSetState(m_rasterState); //set up viewport to clip space coordinates to render target space //in this case, the entire window D3D11_VIEWPORT viewport; viewport.Width = (float)screenWidth; viewport.Height = (float)screenHeight; viewport.MinDepth = 0.0f; viewport.MaxDepth = 1.0f; viewport.TopLeftX = 0.0f; viewport.TopLeftY = 0.0f; // Create the viewport. m_deviceContext->RSSetViewports(1, &viewport); //create projection matrix --> translates 3D scene into 2D viewport space; necessary for shaders float fieldOfView, screenAspect; fieldOfView = (float)D3DX_PI * 0.25f; screenAspect = (float)screenWidth / (float)screenHeight; D3DXMatrixPerspectiveFovLH(&m_projectionMatrix, fieldOfView, screenAspect, screenNear, screenDepth); //create world matrix --> convert vertices of objects into vertices for 3D scene --> necessary to manipulate objects in 3D //necessary for shader rendering too D3DXMatrixIdentity(&m_worldMatrix); //create orthographic projection matrix --> rendering 2D elements like UI elements on the screen and skipping 3D rendering on those places //e.g. UI elements and text D3DXMatrixOrthoLH(&m_orthoMatrix, (float)screenWidth, (float)screenHeight, screenNear, screenDepth); // Clear the second depth stencil state before setting the parameters. D3D11_DEPTH_STENCIL_DESC depthDisabledStencilDesc; ZeroMemory(&depthDisabledStencilDesc, sizeof(depthDisabledStencilDesc)); // Now create a second depth stencil state which turns off the Z buffer for 2D rendering. The only difference is // that DepthEnable is set to false, all other parameters are the same as the other depth stencil state. depthDisabledStencilDesc.DepthEnable = false; depthDisabledStencilDesc.DepthWriteMask = D3D11_DEPTH_WRITE_MASK_ALL; depthDisabledStencilDesc.DepthFunc = D3D11_COMPARISON_LESS; depthDisabledStencilDesc.StencilEnable = true; depthDisabledStencilDesc.StencilReadMask = 0xFF; depthDisabledStencilDesc.StencilWriteMask = 0xFF; depthDisabledStencilDesc.FrontFace.StencilFailOp = D3D11_STENCIL_OP_KEEP; depthDisabledStencilDesc.FrontFace.StencilDepthFailOp = D3D11_STENCIL_OP_INCR; depthDisabledStencilDesc.FrontFace.StencilPassOp = D3D11_STENCIL_OP_KEEP; depthDisabledStencilDesc.FrontFace.StencilFunc = D3D11_COMPARISON_ALWAYS; depthDisabledStencilDesc.BackFace.StencilFailOp = D3D11_STENCIL_OP_KEEP; depthDisabledStencilDesc.BackFace.StencilDepthFailOp = D3D11_STENCIL_OP_DECR; depthDisabledStencilDesc.BackFace.StencilPassOp = D3D11_STENCIL_OP_KEEP; depthDisabledStencilDesc.BackFace.StencilFunc = D3D11_COMPARISON_ALWAYS; // Create the state using the device result = m_device->CreateDepthStencilState(&depthDisabledStencilDesc, &m_depthDisabledStencilState); if(FAILED(result)) return false; // Clear the blend state description D3D11_BLEND_DESC blendStateDescription; ZeroMemory(&blendStateDescription, sizeof(D3D11_BLEND_DESC)); // Create an alpha enabled blend state description. blendStateDescription.RenderTarget[0].BlendEnable = TRUE; blendStateDescription.RenderTarget[0].SrcBlend = D3D11_BLEND_ONE; blendStateDescription.RenderTarget[0].DestBlend = D3D11_BLEND_INV_SRC_ALPHA; blendStateDescription.RenderTarget[0].BlendOp = D3D11_BLEND_OP_ADD; blendStateDescription.RenderTarget[0].SrcBlendAlpha = D3D11_BLEND_ONE; blendStateDescription.RenderTarget[0].DestBlendAlpha = D3D11_BLEND_ZERO; blendStateDescription.RenderTarget[0].BlendOpAlpha = D3D11_BLEND_OP_ADD; blendStateDescription.RenderTarget[0].RenderTargetWriteMask = 0x0f; // Create the blend state using the description. result = m_device->CreateBlendState(&blendStateDescription, &m_alphaEnableBlendingState); if(FAILED(result)) return false; // Modify the description to create an alpha disabled blend state description. blendStateDescription.RenderTarget[0].BlendEnable = FALSE; // Create the second blend state using the description. result = m_device->CreateBlendState(&blendStateDescription, &m_alphaDisableBlendingState); if(FAILED(result)) return false; return true; }
HRESULT Create(HWND wnd) { hWnd = wnd; HRESULT hr; RECT client; GetClientRect(hWnd, &client); xres = client.right - client.left; yres = client.bottom - client.top; hr = LoadDXGI(); if (SUCCEEDED(hr)) hr = LoadD3D(); if (SUCCEEDED(hr)) hr = LoadD3DCompiler(); if (FAILED(hr)) { UnloadDXGI(); UnloadD3D(); UnloadD3DCompiler(); return hr; } IDXGIFactory* factory; IDXGIAdapter* adapter; IDXGIOutput* output; hr = PCreateDXGIFactory(__uuidof(IDXGIFactory), (void**)&factory); if (FAILED(hr)) MessageBox(wnd, _T("Failed to create IDXGIFactory object"), _T("Dolphin Direct3D 11 backend"), MB_OK | MB_ICONERROR); hr = factory->EnumAdapters(g_ActiveConfig.iAdapter, &adapter); if (FAILED(hr)) { // try using the first one hr = factory->EnumAdapters(0, &adapter); if (FAILED(hr)) MessageBox(wnd, _T("Failed to enumerate adapters"), _T("Dolphin Direct3D 11 backend"), MB_OK | MB_ICONERROR); } // TODO: Make this configurable hr = adapter->EnumOutputs(0, &output); if (FAILED(hr)) { // try using the first one hr = adapter->EnumOutputs(0, &output); if (FAILED(hr)) MessageBox(wnd, _T("Failed to enumerate outputs"), _T("Dolphin Direct3D 11 backend"), MB_OK | MB_ICONERROR); } // get supported AA modes aa_modes = EnumAAModes(adapter); if (g_Config.iMultisampleMode >= (int)aa_modes.size()) { g_Config.iMultisampleMode = 0; UpdateActiveConfig(); } DXGI_SWAP_CHAIN_DESC swap_chain_desc; memset(&swap_chain_desc, 0, sizeof(swap_chain_desc)); swap_chain_desc.BufferCount = 1; swap_chain_desc.BufferUsage = DXGI_USAGE_RENDER_TARGET_OUTPUT; swap_chain_desc.OutputWindow = wnd; swap_chain_desc.SampleDesc.Count = 1; swap_chain_desc.SampleDesc.Quality = 0; swap_chain_desc.Windowed = TRUE; DXGI_MODE_DESC mode_desc; memset(&mode_desc, 0, sizeof(mode_desc)); mode_desc.Width = xres; mode_desc.Height = yres; mode_desc.Format = DXGI_FORMAT_R8G8B8A8_UNORM; mode_desc.Scaling = DXGI_MODE_SCALING_UNSPECIFIED; hr = output->FindClosestMatchingMode(&mode_desc, &swap_chain_desc.BufferDesc, NULL); if (FAILED(hr)) MessageBox(wnd, _T("Failed to find a supported video mode"), _T("Dolphin Direct3D 11 backend"), MB_OK | MB_ICONERROR); // forcing buffer resolution to xres and yres.. TODO: The new video mode might not actually be supported! swap_chain_desc.BufferDesc.Width = xres; swap_chain_desc.BufferDesc.Height = yres; #if defined(_DEBUG) || defined(DEBUGFAST) // Creating debug devices can sometimes fail if the user doesn't have the correct // version of the DirectX SDK. If it does, simply fallback to a non-debug device. { hr = PD3D11CreateDeviceAndSwapChain(adapter, D3D_DRIVER_TYPE_UNKNOWN, NULL, D3D11_CREATE_DEVICE_SINGLETHREADED | D3D11_CREATE_DEVICE_DEBUG, supported_feature_levels, NUM_SUPPORTED_FEATURE_LEVELS, D3D11_SDK_VERSION, &swap_chain_desc, &swapchain, &device, &featlevel, &context); } if (FAILED(hr)) #endif { hr = PD3D11CreateDeviceAndSwapChain(adapter, D3D_DRIVER_TYPE_UNKNOWN, NULL, D3D11_CREATE_DEVICE_SINGLETHREADED, supported_feature_levels, NUM_SUPPORTED_FEATURE_LEVELS, D3D11_SDK_VERSION, &swap_chain_desc, &swapchain, &device, &featlevel, &context); } if (FAILED(hr)) { MessageBox(wnd, _T("Failed to initialize Direct3D.\nMake sure your video card supports at least D3D 10.0"), _T("Dolphin Direct3D 11 backend"), MB_OK | MB_ICONERROR); SAFE_RELEASE(device); SAFE_RELEASE(context); SAFE_RELEASE(swapchain); return E_FAIL; } SetDebugObjectName((ID3D11DeviceChild*)context, "device context"); SAFE_RELEASE(factory); SAFE_RELEASE(output); SAFE_RELEASE(adapter); ID3D11Texture2D* buf; hr = swapchain->GetBuffer(0, IID_ID3D11Texture2D, (void**)&buf); if (FAILED(hr)) { MessageBox(wnd, _T("Failed to get swapchain buffer"), _T("Dolphin Direct3D 11 backend"), MB_OK | MB_ICONERROR); SAFE_RELEASE(device); SAFE_RELEASE(context); SAFE_RELEASE(swapchain); return E_FAIL; } backbuf = new D3DTexture2D(buf, D3D11_BIND_RENDER_TARGET); SAFE_RELEASE(buf); CHECK(backbuf!=NULL, "Create back buffer texture"); SetDebugObjectName((ID3D11DeviceChild*)backbuf->GetTex(), "backbuffer texture"); SetDebugObjectName((ID3D11DeviceChild*)backbuf->GetRTV(), "backbuffer render target view"); context->OMSetRenderTargets(1, &backbuf->GetRTV(), NULL); // BGRA textures are easier to deal with in TextureCache, but might not be supported by the hardware UINT format_support; device->CheckFormatSupport(DXGI_FORMAT_B8G8R8A8_UNORM, &format_support); bgra_textures_supported = (format_support & D3D11_FORMAT_SUPPORT_TEXTURE2D) != 0; stateman = new StateManager; return S_OK; }
bool InitDirect3D(RENDERER_SETTINGS * pSetup) { DXGI_FORMAT format = DXGI_FORMAT_R8G8B8A8_UNORM; DXGI_SWAP_CHAIN_DESC desc; ZeroMemory(&desc, sizeof(DXGI_SWAP_CHAIN_DESC)); desc.BufferCount = 1; desc.BufferDesc.Width = pSetup->nWidth; desc.BufferDesc.Height = pSetup->nHeight; desc.BufferDesc.Format = format; if (pSetup->bVsync) { bVsync = true; IDXGIFactory1 * pFactory = NULL; HRESULT hr = CreateDXGIFactory1(__uuidof(IDXGIFactory1), (void**)&pFactory); if (pFactory) { IDXGIAdapter1 * pAdapter = NULL; pFactory->EnumAdapters1( 0, &pAdapter ); if (pAdapter) { IDXGIOutput * pOutput = NULL; pAdapter->EnumOutputs( 0, &pOutput ); if (pOutput) { unsigned int nModeCount = 0; pOutput->GetDisplayModeList( format, DXGI_ENUM_MODES_INTERLACED | DXGI_ENUM_MODES_SCALING, &nModeCount, NULL); DXGI_MODE_DESC * pModes = new DXGI_MODE_DESC[ nModeCount ]; pOutput->GetDisplayModeList( format, DXGI_ENUM_MODES_INTERLACED | DXGI_ENUM_MODES_SCALING, &nModeCount, pModes); for (int i=0; i<nModeCount; i++) { if (pModes[i].Width == pSetup->nWidth && pModes[i].Height == pSetup->nHeight) { desc.BufferDesc = pModes[i]; break; } } delete[] pModes; pOutput->Release(); } pAdapter->Release(); } pFactory->Release(); } } desc.BufferUsage = DXGI_USAGE_RENDER_TARGET_OUTPUT; desc.OutputWindow = hWnd; desc.SampleDesc.Count = 1; desc.Windowed = pSetup->windowMode != RENDERER_WINDOWMODE_FULLSCREEN; DWORD deviceCreationFlags = 0; #ifdef _DEBUG //deviceCreationFlags |= D3D11_CREATE_DEVICE_DEBUG; #endif if (D3D11CreateDeviceAndSwapChain( NULL, D3D_DRIVER_TYPE_HARDWARE, NULL, deviceCreationFlags, NULL, NULL, D3D11_SDK_VERSION, &desc, &pSwapChain, &pDevice, NULL, &pContext) != S_OK) { printf("[Renderer] D3D11CreateDeviceAndSwapChain failed\n"); return false; } pSwapChain->GetBuffer(0, __uuidof(ID3D11Texture2D), (void**)&pBackBuffer); pDevice->CreateRenderTargetView(pBackBuffer, NULL, &pRenderTarget); pBackBuffer->Release(); pContext->OMSetRenderTargets(1, &pRenderTarget, NULL); // create staging texture for frame grabbing D3D11_TEXTURE2D_DESC description; pBackBuffer->GetDesc( &description ); description.BindFlags = 0; description.CPUAccessFlags = D3D11_CPU_ACCESS_READ | D3D11_CPU_ACCESS_WRITE; description.Usage = D3D11_USAGE_STAGING; HRESULT hr = pDevice->CreateTexture2D( &description, NULL, &pFrameGrabTexture ); return true; }
bool D3D::InitializeD3D(int screenWidth, int screenHeight, bool vsync, HWND hwnd, bool fullscreen) { HRESULT result; //used to test things are created ok. vsync; //---------------------------------------------------------------------------------------------- // Fetch the numerator and denominator for refresh rate and video card description. // Create DirectX Graphics Interface factory. IDXGIFactory* factory; result = CreateDXGIFactory(__uuidof(IDXGIFactory), (void**)&factory); if(FAILED(result)) return false; // Create adapter. IDXGIAdapter* adapter; result = factory->EnumAdapters(0, &adapter); if(FAILED(result)) return false; // Enumerate primary adapter output (monitor). IDXGIOutput* adapterOutput; result = adapter->EnumOutputs(0, &adapterOutput); if(FAILED(result)) return false; // Get the number of modes that fit the DXGI_R8G8B8A8_UNORM display format for adpater output. unsigned int numModes; result = adapterOutput->GetDisplayModeList(DXGI_FORMAT_R8G8B8A8_UNORM, DXGI_ENUM_MODES_INTERLACED, &numModes, NULL); if(FAILED(result)) return false; // Create a list to hold all possible display modes. DXGI_MODE_DESC* displayModeList; displayModeList = new DXGI_MODE_DESC[numModes]; if(!displayModeList) return false; // Fill list. result = adapterOutput->GetDisplayModeList(DXGI_FORMAT_R8G8B8A8_UNORM, DXGI_ENUM_MODES_INTERLACED, &numModes, displayModeList); if(FAILED(result)) return false; // Loop through modes and find one that matches screen width and height, store numerator and // denominator for corresponding refresh rate. unsigned int numerator, denominator; for(unsigned int i = 0; i < numModes; ++i) { if(displayModeList[i].Width == (unsigned int)screenWidth && displayModeList[i].Height == (unsigned int)screenHeight) { numerator = displayModeList[i].RefreshRate.Numerator; denominator = displayModeList[i].RefreshRate.Denominator; } } // Get adapter description. DXGI_ADAPTER_DESC adapterDesc; result = adapter->GetDesc(&adapterDesc); if(FAILED(result)) return false; // Store dedicated video card memory (in mb). m_videoCardMemory = (int)(adapterDesc.DedicatedVideoMemory / 1024 / 1024); // Convert the name of the video card to char array and store. unsigned int stringLength; int error = wcstombs_s(&stringLength, m_videoCardDesc, 128, adapterDesc.Description, 128); if(error != 0) return false; // Release unneeded memory. delete[] displayModeList; displayModeList = 0; adapterOutput->Release(); adapterOutput = 0; adapter->Release(); adapter = 0; factory->Release(); factory = 0; //---------------------------------------------------------------------------------------------- //---------------------------------------------------------------------------------------------- // Set up SwapChain description and create swap chain. DXGI_SWAP_CHAIN_DESC swapChainDesc; ZeroMemory(&swapChainDesc, sizeof(swapChainDesc)); // Setup back buffer. swapChainDesc.BufferCount = 1; swapChainDesc.BufferDesc.Width = screenWidth; swapChainDesc.BufferDesc.Height = screenHeight; swapChainDesc.BufferDesc.Format = DXGI_FORMAT_R8G8B8A8_UNORM; // Refresh Rate. if(m_vsyncEnabled) { swapChainDesc.BufferDesc.RefreshRate.Numerator = numerator; swapChainDesc.BufferDesc.RefreshRate.Denominator = denominator; } else { // Draw as soon as possible. swapChainDesc.BufferDesc.RefreshRate.Numerator = 0; swapChainDesc.BufferDesc.RefreshRate.Denominator = 1; } swapChainDesc.BufferUsage = DXGI_USAGE_RENDER_TARGET_OUTPUT; swapChainDesc.OutputWindow = hwnd; // Turn off multisampling. swapChainDesc.SampleDesc.Count = 1; swapChainDesc.SampleDesc.Quality = 0; swapChainDesc.Windowed = !fullscreen; swapChainDesc.BufferDesc.ScanlineOrdering = DXGI_MODE_SCANLINE_ORDER_UNSPECIFIED; swapChainDesc.BufferDesc.Scaling = DXGI_MODE_SCALING_UNSPECIFIED; swapChainDesc.SwapEffect = DXGI_SWAP_EFFECT_DISCARD; swapChainDesc.Flags = 0; // Create the swap chain. D3D_FEATURE_LEVEL featureLevel = D3D_FEATURE_LEVEL_11_0; result = D3D11CreateDeviceAndSwapChain(NULL, D3D_DRIVER_TYPE_HARDWARE, NULL, 0, &featureLevel, 1, D3D11_SDK_VERSION, &swapChainDesc, &m_swapChain, &m_device, NULL, &m_deviceContext); if(FAILED(result)) return false; //---------------------------------------------------------------------------------------------- //---------------------------------------------------------------------------------------------- // Set up render target view. ID3D11Texture2D* backBufferPtr; result = m_swapChain->GetBuffer(0, __uuidof(ID3D11Texture2D), (LPVOID*)&backBufferPtr); if(FAILED(result)) return false; // Create render target view with back buffer ptr. result = m_device->CreateRenderTargetView(backBufferPtr, NULL, &m_renderTargetView); if(FAILED(result)) return false; backBufferPtr->Release(); backBufferPtr = 0; //---------------------------------------------------------------------------------------------- //---------------------------------------------------------------------------------------------- // Set up depthStencilBuffer. D3D11_TEXTURE2D_DESC depthBufferDesc; ZeroMemory(&depthBufferDesc, sizeof(depthBufferDesc)); // Set up description. depthBufferDesc.Width = screenWidth; depthBufferDesc.Height = screenHeight; depthBufferDesc.MipLevels = 1; depthBufferDesc.ArraySize = 1; depthBufferDesc.Format = DXGI_FORMAT_D24_UNORM_S8_UINT; depthBufferDesc.SampleDesc.Count = 1; depthBufferDesc.SampleDesc.Quality = 0; depthBufferDesc.Usage = D3D11_USAGE_DEFAULT; depthBufferDesc.BindFlags = D3D11_BIND_DEPTH_STENCIL; depthBufferDesc.CPUAccessFlags = 0; depthBufferDesc.MiscFlags = 0; // Create depth/stencil buffer. result = m_device->CreateTexture2D(&depthBufferDesc, NULL, &m_depthStencilBuffer); if(FAILED(result)) return false; // Setup depth stencil description. D3D11_DEPTH_STENCIL_DESC depthStencilDesc; ZeroMemory(&depthStencilDesc, sizeof(depthStencilDesc)); depthStencilDesc.DepthEnable = true; depthStencilDesc.DepthWriteMask = D3D11_DEPTH_WRITE_MASK_ALL; depthStencilDesc.DepthFunc = D3D11_COMPARISON_LESS; depthStencilDesc.StencilEnable = true; depthStencilDesc.StencilReadMask = 0xFF; depthStencilDesc.StencilWriteMask = 0xFF; depthStencilDesc.FrontFace.StencilFailOp = D3D11_STENCIL_OP_KEEP; depthStencilDesc.FrontFace.StencilDepthFailOp = D3D11_STENCIL_OP_INCR; depthStencilDesc.FrontFace.StencilPassOp = D3D11_STENCIL_OP_KEEP; depthStencilDesc.FrontFace.StencilFunc = D3D11_COMPARISON_ALWAYS; depthStencilDesc.BackFace.StencilFailOp = D3D11_STENCIL_OP_KEEP; depthStencilDesc.BackFace.StencilDepthFailOp = D3D11_STENCIL_OP_DECR; depthStencilDesc.BackFace.StencilPassOp = D3D11_STENCIL_OP_KEEP; depthStencilDesc.BackFace.StencilFunc = D3D11_COMPARISON_ALWAYS; // Create depth stencil state. result = m_device->CreateDepthStencilState(&depthStencilDesc, &m_depthStencilState); if(FAILED(result)) return false; // Set depth stencil state. m_deviceContext->OMSetDepthStencilState(m_depthStencilState, 1); //---------------------------------------------------------------------------------------------- //---------------------------------------------------------------------------------------------- // Create second depth stencil state with depth disabled. (for 2D rendering) D3D11_DEPTH_STENCIL_DESC depthDisabledStencilDesc; ZeroMemory(&depthDisabledStencilDesc, sizeof(depthDisabledStencilDesc)); depthDisabledStencilDesc.DepthEnable = false; depthDisabledStencilDesc.DepthWriteMask = D3D11_DEPTH_WRITE_MASK_ALL; depthDisabledStencilDesc.DepthFunc = D3D11_COMPARISON_LESS; depthDisabledStencilDesc.StencilEnable = true; depthDisabledStencilDesc.StencilReadMask = 0xFF; depthDisabledStencilDesc.StencilWriteMask = 0xFF; depthDisabledStencilDesc.FrontFace.StencilFailOp = D3D11_STENCIL_OP_KEEP; depthDisabledStencilDesc.FrontFace.StencilDepthFailOp = D3D11_STENCIL_OP_DECR; depthDisabledStencilDesc.FrontFace.StencilPassOp = D3D11_STENCIL_OP_KEEP; depthDisabledStencilDesc.FrontFace.StencilFunc = D3D11_COMPARISON_ALWAYS; depthDisabledStencilDesc.BackFace.StencilFailOp = D3D11_STENCIL_OP_KEEP; depthDisabledStencilDesc.BackFace.StencilDepthFailOp = D3D11_STENCIL_OP_DECR; depthDisabledStencilDesc.BackFace.StencilPassOp = D3D11_STENCIL_OP_KEEP; depthDisabledStencilDesc.BackFace.StencilFunc = D3D11_COMPARISON_ALWAYS; result = m_device->CreateDepthStencilState(&depthDisabledStencilDesc, &m_depthDisabledStencilState); if(FAILED(result)) return false; //---------------------------------------------------------------------------------------------- //---------------------------------------------------------------------------------------------- // Create description of the view of the depth stencil buffer. // Do this so D3D knows to use the depth buffer as a depth stencil texture. D3D11_DEPTH_STENCIL_VIEW_DESC depthStencilViewDesc; ZeroMemory(&depthStencilViewDesc, sizeof(depthStencilViewDesc)); depthStencilViewDesc.Format = DXGI_FORMAT_D24_UNORM_S8_UINT; depthStencilViewDesc.ViewDimension = D3D11_DSV_DIMENSION_TEXTURE2D; depthStencilViewDesc.Texture2D.MipSlice = 0; result = m_device->CreateDepthStencilView(m_depthStencilBuffer, &depthStencilViewDesc, &m_depthStencilView); if(FAILED(result)) return false; // Bind render target view and depth stencil buffer to output render pipeline. m_deviceContext->OMSetRenderTargets(1, &m_renderTargetView, m_depthStencilView); //---------------------------------------------------------------------------------------------- //---------------------------------------------------------------------------------------------- // Create rasterizer state and viewport. D3D11_RASTERIZER_DESC rasterDesc; rasterDesc.AntialiasedLineEnable = false; rasterDesc.CullMode = D3D11_CULL_BACK; rasterDesc.DepthBias = 0; rasterDesc.DepthBiasClamp = 0.0f; rasterDesc.DepthClipEnable = true; rasterDesc.FillMode = D3D11_FILL_SOLID; rasterDesc.FrontCounterClockwise = false; rasterDesc.MultisampleEnable = false; rasterDesc.ScissorEnable = false; rasterDesc.SlopeScaledDepthBias = 0.0; result = m_device->CreateRasterizerState(&rasterDesc, &m_rasterState); if(FAILED(result)) return false; m_deviceContext->RSSetState(m_rasterState); // Set up viewport. D3D11_VIEWPORT viewport; viewport.Width = (float)screenWidth; viewport.Height = (float)screenHeight; viewport.MinDepth = 0.0f; viewport.MaxDepth = 1.0f; viewport.TopLeftX = 0.0f; viewport.TopLeftY = 0.0f; m_deviceContext->RSSetViewports(1, &viewport); //---------------------------------------------------------------------------------------------- //---------------------------------------------------------------------------------------------- // Create blend states. D3D11_BLEND_DESC blendStateDesc; ZeroMemory(&blendStateDesc, sizeof(D3D11_BLEND_DESC)); blendStateDesc.RenderTarget[0].BlendEnable = TRUE; blendStateDesc.RenderTarget[0].SrcBlend = D3D11_BLEND_ONE; blendStateDesc.RenderTarget[0].DestBlend = D3D11_BLEND_ONE; blendStateDesc.RenderTarget[0].BlendOp = D3D11_BLEND_OP_ADD; blendStateDesc.RenderTarget[0].SrcBlendAlpha = D3D11_BLEND_ONE; blendStateDesc.RenderTarget[0].DestBlendAlpha = D3D11_BLEND_ZERO; blendStateDesc.RenderTarget[0].BlendOpAlpha = D3D11_BLEND_OP_ADD; blendStateDesc.RenderTarget[0].RenderTargetWriteMask = 0x0f; result = m_device->CreateBlendState(&blendStateDesc, &m_alphaEnableBlendingState); if(FAILED(result)) { return false; } blendStateDesc.RenderTarget[0].BlendEnable = FALSE; result = m_device->CreateBlendState(&blendStateDesc, &m_alphaDisableBlendingState); if(FAILED(result)) { return false; } //---------------------------------------------------------------------------------------------- return true; }