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(); } }
bool CDirectEngine::CollectAdapters( Vector2<unsigned int> aWindowSize, Vector2<int>& aNumDenumerator ) { HRESULT result = S_OK; IDXGIFactory* factory; DXGI_MODE_DESC* displayModeList = nullptr; unsigned int numModes = 0; unsigned int i = 0; unsigned int denominator = 0; unsigned int numerator = 0; 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). IDXGIAdapter* adapter = nullptr; int adapterIndex = 0; std::vector<DXGI_ADAPTER_DESC> myAdapterDescs; std::vector<IDXGIAdapter*> myAdapters; while( factory->EnumAdapters( adapterIndex, &adapter ) != DXGI_ERROR_NOT_FOUND ) { DXGI_ADAPTER_DESC adapterDesc; adapter->GetDesc( &adapterDesc ); myAdapterDescs.push_back( adapterDesc ); myAdapters.push_back( adapter ); ++adapterIndex; } if( adapterIndex == 0 ) { return false; } INFO_PRINT( "%s", "Video card(s) detected: " ); for( DXGI_ADAPTER_DESC desc : myAdapterDescs ) { INFO_PRINT( "%ls", desc.Description ); } INFO_PRINT( "%s%ls", "Using primary graphic card: ", myAdapterDescs[0].Description ); // Enumerate the primary adapter output (monitor). IDXGIOutput* pOutput = nullptr; if( myAdapters[0]->EnumOutputs( 0, &pOutput ) == DXGI_ERROR_NOT_FOUND ) { return false; } // Get the number of modes that fit the DXGI_FORMAT_R8G8B8A8_UNORM display format for the adapter output (monitor). result = pOutput->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 = pOutput->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)aWindowSize.x ) { if( displayModeList[i].Height == (unsigned int)aWindowSize.y ) { numerator = displayModeList[i].RefreshRate.Numerator; denominator = displayModeList[i].RefreshRate.Denominator; } } } // Get the adapter (video card) description. result = myAdapters[0]->GetDesc( &myAdapterDescs[0] ); if( FAILED( result ) ) { return false; } // Store the dedicated video card memory in megabytes. myVideoCardMemory = (int)( myAdapterDescs[0].DedicatedVideoMemory / 1024 / 1024 ); // Release the display mode list. delete[] displayModeList; displayModeList = 0; // Release the adapter output. pOutput->Release(); pOutput = 0; // Release the adapter. myAdapters[0]->Release(); myAdapters[0] = 0; // Release the factory. factory->Release(); factory = 0; if( myEnableVSync == true ) { aNumDenumerator.x = numerator; aNumDenumerator.y = denominator; } else { aNumDenumerator.x = 0; aNumDenumerator.y = 1; } return true; }
bool graphicD3d::Initialize(int screenWidth, int screenHeight, bool vsync, HWND hwnd, bool fullscreen, float screenDepth, float screenNear) { HRESULT hr; IDXGIFactory* factory; IDXGIAdapter* adapter; IDXGIOutput* adapterOutput; UINT nummodes, numerator, denominator; DXGI_MODE_DESC* displayModelist; DXGI_ADAPTER_DESC adapterDesc; DXGI_SWAP_CHAIN_DESC swapchainDesc; D3D11_TEXTURE2D_DESC depthBufferDesc; D3D11_DEPTH_STENCIL_DESC depthStencilDesc; D3D11_DEPTH_STENCIL_VIEW_DESC depthStencilViewDesc; D3D11_RASTERIZER_DESC rasterDesc; D3D11_VIEWPORT viewport; // 수직동기화 설정 ( true / false ) m_vsync = vsync; //DirectX Graphic Infrastructure 인터페이스 팩토리 만들기. hr = CreateDXGIFactory(__uuidof(IDXGIFactory), (void**)&factory); if (FAILED(hr)) return false; //첫번째 그래픽 카드 어댑터 만들기. hr = factory->EnumAdapters(0, &adapter); if (FAILED(hr)) return false; //첫번째 모니터의 어댑터 만들기. hr = adapter->EnumOutputs(0, &adapterOutput); if (FAILED(hr)) return false; //DXGI_FORMAT_R8G8B8A8_UNORM 모니터 출력 포멧에 맞는 모드의 개수 구하기. hr = adapterOutput->GetDisplayModeList(DXGI_FORMAT_R8G8B8A8_UNORM, DXGI_ENUM_MODES_INTERLACED, &nummodes, NULL); if (FAILED(hr)) return false; //사용 가능한 모든 모니터와 그래픽카드 조합을 저장할 리스트 생성. displayModelist = new DXGI_MODE_DESC[nummodes]; if (!displayModelist) return false; //displayModelist 에 값들 채워넣기. hr = adapterOutput->GetDisplayModeList(DXGI_FORMAT_R8G8B8A8_UNORM, DXGI_ENUM_MODES_INTERLACED, &nummodes, displayModelist); if (FAILED(hr)) return false; //그래픽 카드와 모니터의 화면 너비/높이 조합을 찾기 완료. //모니터의 refresh rate 의 분모 와 분자 값을 저장. for (int i = 0; i < nummodes; i++) { if (displayModelist[i].Width == (UINT)screenWidth && displayModelist[i].Height == (UINT)screenHeight) { numerator = displayModelist[i].RefreshRate.Numerator; denominator = displayModelist[i].RefreshRate.Denominator; } } /* */ //그래픽 카드 정보 가져오기. hr = adapter->GetDesc(&adapterDesc); if (FAILED(hr)) return false; //그래픽 카드 메모리 크기 가져오기. ( MegaBytes ) m_videoMemory = UINT(adapterDesc.DedicatedVideoMemory / 1024 / 1024); //그래픽 카드 이름 가져오기. lstrcpynW(m_videoDescription, adapterDesc.Description, 128); /* */ // 원하는 정보 조회 끝나면, 해당 리소스들 해제 delete [] displayModelist; displayModelist = nullptr; //모니터 출력 어댑터 해제 adapterOutput->Release(); adapterOutput = nullptr; //그래픽카드 어댑터 해제 adapter->Release(); adapter = nullptr; //팩토리 해제 factory->Release(); factory = nullptr; /* 스왑체인 설정 */ ZeroMemory( &swapchainDesc, sizeof( swapchainDesc ) ); //백버퍼 개수를 1개로 설정. swapchainDesc.BufferCount = 1; swapchainDesc.BufferDesc.Width = screenWidth; swapchainDesc.BufferDesc.Height = screenHeight; swapchainDesc.BufferDesc.Format = DXGI_FORMAT_R8G8B8A8_UNORM; if (m_vsync) { //vsync 수치에 맞춰서 page flip 이 일어난다. swapchainDesc.BufferDesc.RefreshRate.Numerator = numerator; swapchainDesc.BufferDesc.RefreshRate.Denominator = denominator; } else { //vsync 와 상관없이 최대한 많이 그리게 한다. 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; } //스캔라인 정렬 및 사용여부를 안함 (unspecified) 으로 설정. swapchainDesc.BufferDesc.ScanlineOrdering = DXGI_MODE_SCANLINE_ORDER_UNSPECIFIED; swapchainDesc.BufferDesc.Scaling = DXGI_MODE_SCALING_UNSPECIFIED; //출력 후 백버퍼 내용 버림으로 설정. swapchainDesc.SwapEffect = DXGI_SWAP_EFFECT_DISCARD; //추가 옵션 플랙 사용 안함. swapchainDesc.Flags = 0; /* 디바이스 설정 */ UINT createDeviceFlags = 0; #ifdef _DEBUG createDeviceFlags |= D3D11_CREATE_DEVICE_DEBUG; #endif //그래픽 카드가 dx11 지원되면 HARDWARE, //실패하면 REFERENCE 로 처리된다. ( 속도는 HARDWARE 대비 1/1000 정도 느림 ) D3D_DRIVER_TYPE driverTypes[] = { D3D_DRIVER_TYPE_HARDWARE, D3D_DRIVER_TYPE_WARP, D3D_DRIVER_TYPE_REFERENCE, }; UINT numDriverTypes = ARRAYSIZE( driverTypes ); //directx 버젼 설정 D3D_FEATURE_LEVEL featureLevels[] = { D3D_FEATURE_LEVEL_11_0, D3D_FEATURE_LEVEL_10_1, D3D_FEATURE_LEVEL_10_0, }; UINT numFeatureLevels = ARRAYSIZE( featureLevels ); for( UINT driverTypeIndex = 0; driverTypeIndex < numDriverTypes; driverTypeIndex++ ) { m_driverType = driverTypes[driverTypeIndex]; hr = D3D11CreateDeviceAndSwapChain( NULL, m_driverType, NULL, createDeviceFlags, featureLevels, numFeatureLevels, D3D11_SDK_VERSION, &swapchainDesc, &m_swapChain, &m_device, &m_featureLevel, &m_deviceContext ); if( SUCCEEDED( hr ) ) break; } if( FAILED( hr ) ) return false; /* 렌더타겟뷰 (render target view) 만들기 */ //백버퍼 포인터를 가져오기. ID3D11Texture2D* pBackBuffer = NULL; hr = m_swapChain->GetBuffer(0, __uuidof(ID3D11Texture2D), (LPVOID*)&pBackBuffer); if( FAILED( hr ) ) return false; //백버퍼 포인터로 렌더타겟뷰 생성. hr = m_device->CreateRenderTargetView( pBackBuffer, NULL, &m_renderTargetView ); if( FAILED( hr ) ) return false; //렌더타겟 생성되면 백버퍼 포인터 필요없으므로 제거. pBackBuffer->Release(); pBackBuffer = nullptr; /* 깊이버퍼 (depth buffer) 만들기 (옵션) */ 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; //깊이버퍼 2D텍스쳐 생성 hr = m_device->CreateTexture2D(&depthBufferDesc, NULL, &m_depthStencilbuffer); if (FAILED(hr)) 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; //깊이 스텐실 상태 생성 hr = m_device->CreateDepthStencilState(&depthStencilDesc, &m_depthStencilState); if (FAILED(hr)) 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; // 깊이-스텐실 뷰를 생성. hr = m_device->CreateDepthStencilView(m_depthStencilbuffer, &depthStencilViewDesc, &m_depthStencilView); if (FAILED(hr)) return false; /* 디바이스 컨텍스트에 렌더타겟뷰 와 깊이스텐실뷰를 적용. */ m_deviceContext->OMSetRenderTargets(1, &m_renderTargetView, m_depthStencilView); /* 래스터라이징 설정 (옵션) - 도형을 어떻게 그릴지 결정 ( 와이어프레임, 2 side 렌더링 등등.. ) */ 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; //디바이스로 래스터라이징 상태 생성. hr = m_device->CreateRasterizerState(&rasterDesc, &m_rasterState); if (FAILED(hr)) 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; viewport.TopLeftY = 0; m_deviceContext->RSSetViewports( 1, &viewport ); /* 투영 행렬 ( projection matrix ) 생성 - 3d 화면을 2d 뷰포트 공간으로 변환 - 복사본으로 셰이더에서 사용 할 수 있게 한다. */ float fieldOfView = (float)XM_PI / 4.0f; float screenAspect = (float)screenWidth / (float)screenHeight; m_projectionMatrix = XMMatrixPerspectiveFovLH(fieldOfView, screenAspect, screenNear, screenDepth); /* 월드 행렬 ( world matrix ) 생성 - 오브젝트들을 3d 좌표로 변환하기 위한 행렬 - 이동 / 회전 / 크기 에 사용. - 복사본으로 셰이더에 사용 할 수 있게 한다. */ // 월드 행렬을 단위 행렬로 초기화 m_worldMatrix = XMMatrixIdentity(); /* 뷰 행렬 ( view matrix ) - 카메라에서 따로 생성하기 위해 일단 생략. */ /* 정사영 행렬 ( Orthographic matix 생성 ) - 원근감이 없는 행렬 - 2d 이미지나 UI 등을 표현할 때 사용. */ // 2D 렌더링에 사용될 정사영 행렬을 생성. m_orthoMatrix = XMMatrixOrthographicLH((float)screenWidth, (float)screenHeight, screenNear, screenDepth); return true; }
bool D3D11::getScreenSettings( D3D11::ScreenMode & mode, int screenWidth, int screenHeight ) { HRESULT result; int error; IDXGIFactory* factory; IDXGIAdapter* adapter; IDXGIOutput* adapterOutput; DXGI_MODE_DESC* displayModeList; DXGI_ADAPTER_DESC adapterDesc; unsigned int numModes, i, stringLength; // 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. mode.height = screenHeight; mode.width = screenWidth; for(i=0; i<numModes; i++) { if(displayModeList[i].Width == (unsigned int)screenWidth) { if(displayModeList[i].Height == (unsigned int)screenHeight) { mode.numerator = displayModeList[i].RefreshRate.Numerator; mode.denominator = displayModeList[i].RefreshRate.Denominator; } } } // Get the adapter (video card) description. result = adapter->GetDesc(&adapterDesc); if(FAILED(result)) { return false; } // Store the dedicated video card memory in megabytes. mVideoCardMemory = (int)(adapterDesc.DedicatedVideoMemory / 1024 / 1024); // Convert the name of the video card to a character array and store it. //todo: fix this for x64 builds //error = wcstombs_s(&stringLength, mVideoCardDescription, 128, adapterDesc.Description, 128); error = 0; if(error != 0) { 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; return true; }
bool D3D12MemoryManagement::HandleMessage(HWND hwnd, UINT Message, WPARAM wParam, LPARAM lParam) { bool bHandled = DX12Framework::HandleMessage(hwnd, Message, wParam, lParam); if (bHandled) { return true; } switch (Message) { case WM_MOUSEWHEEL: { // Use mouse wheel to apply camera zoom. m_pCapturedCamera->OnMouseWheel(GET_WHEEL_DELTA_WPARAM(wParam)); return true; } case WM_LBUTTONDOWN: { // Use left mouse button and movement for panning. m_MouseX = (int)LOWORD(lParam); m_MouseY = (int)HIWORD(lParam); m_bMouseDown = true; SetCapture(m_Hwnd); return true; } case WM_LBUTTONUP: { m_bMouseDown = false; ReleaseCapture(); return true; } case WM_MOUSEMOVE: { if (m_bMouseDown) { int xPos = (int)(short)LOWORD(lParam); int yPos = (int)(short)HIWORD(lParam); float DeltaScrollX = (float)(xPos - m_MouseX); float DeltaScrollY = (float)(yPos - m_MouseY); if (m_pCapturedCamera == &m_ViewportCamera) { m_pCapturedCamera->OnMouseMove(PointF{ DeltaScrollX, DeltaScrollY }); } else { // // Move the debug camera relative to the viewport camera's coordinate space. // float zoom = m_pCapturedCamera->GetZoom() / m_ViewportCamera.GetZoom(); m_pCapturedCamera->OnMouseMove(PointF{ -DeltaScrollX * zoom, -DeltaScrollY * zoom }); } m_MouseX = xPos; m_MouseY = yPos; } return true; } // // On window resize, adjust the camera perspective to match the new window size. // case WM_SIZE: { RectF NewProjection = { -m_WindowWidth / 2.0f, -m_WindowHeight / 2.0f, m_WindowWidth / 2.0f, m_WindowHeight / 2.0f, }; m_pCapturedCamera->SetOrthographicProjection(NewProjection); return true; } case WM_KEYDOWN: { if (wParam == GetVirtualKeyFromCharacter('s')) // Toggle 's'tats. { m_bRenderStats = !m_bRenderStats; } else if (wParam == GetVirtualKeyFromCharacter('m')) // View 'm'ip coloring. { m_bDrawMipColors = !m_bDrawMipColors; } else if (wParam == GetVirtualKeyFromCharacter('v')) // Toggle 'v'sync. { m_bPresentOnVsync = !m_bPresentOnVsync; } #if(_DEBUG) // // In debug builds, allow simulated device removed errors for testing purposes. // else if (wParam == GetVirtualKeyFromCharacter('r')) // Simulate 'r'emove device. { m_SimulatedRenderResult = DXGI_ERROR_DEVICE_REMOVED; if (m_NewAdapterIndex == 0xFFFFFFFF) { m_NewAdapterIndex = 0; } else { // Toggle adapters 0 and 1. m_NewAdapterIndex = !m_NewAdapterIndex; } } else if (wParam == GetVirtualKeyFromCharacter('e')) // Simulate remove device without adapter toggle. { m_SimulatedRenderResult = DXGI_ERROR_DEVICE_REMOVED; } #endif else if (wParam == GetVirtualKeyFromCharacter('c')) // Toggle 'c'amera. { // // Toggle captured viewport - switched which viewport the mouse controls. // if (m_pCapturedCamera == &m_ViewportCamera) { m_pCapturedCamera = &m_DebugCamera; } else { m_pCapturedCamera = &m_ViewportCamera; } } else if (wParam == GetVirtualKeyFromCharacter('d')) // 'D'etach camera. { // // Toggle scene viewport - switches which camera is used as the scene camera // which determines prefetching and display behavior. // if (m_pSceneCamera == &m_ViewportCamera) { m_pSceneCamera = &m_DebugCamera; } else { m_pSceneCamera = &m_ViewportCamera; m_pCapturedCamera = &m_ViewportCamera; } } else if (wParam == GetVirtualKeyFromCharacter('f')) // Toggle 'f'ullscreen mode. { HRESULT hr = S_OK; if (m_bFullscreen) { SetWindowLongPtr(m_Hwnd, GWL_STYLE, WS_OVERLAPPEDWINDOW); SetWindowPos( m_Hwnd, nullptr, m_WindowRect.left, m_WindowRect.top, m_WindowRect.right - m_WindowRect.left, m_WindowRect.bottom - m_WindowRect.top, 0); } else { IDXGIOutput* pDXGIOutput; hr = m_pDXGISwapChain->GetContainingOutput(&pDXGIOutput); if (SUCCEEDED(hr)) { DXGI_OUTPUT_DESC Desc; pDXGIOutput->GetDesc(&Desc); GetWindowRect(m_Hwnd, &m_WindowRect); SetWindowLongPtr(m_Hwnd, GWL_STYLE, WS_POPUP); SetWindowPos( m_Hwnd, HWND_TOP, Desc.DesktopCoordinates.left, Desc.DesktopCoordinates.top, Desc.DesktopCoordinates.right - Desc.DesktopCoordinates.left, Desc.DesktopCoordinates.bottom - Desc.DesktopCoordinates.top, SWP_FRAMECHANGED | SWP_SHOWWINDOW); pDXGIOutput->Release(); } } if (SUCCEEDED(hr)) { ShowWindow(m_Hwnd, SW_SHOWNORMAL); m_bFullscreen = !m_bFullscreen; } } // // Budget overrides in debug builds. // else if (wParam == VK_OEM_PLUS || wParam == VK_ADD) // '+' - Increase budget. { UINT64 CurrentOverride = GetLocalBudgetOverride(); CurrentOverride += _128MB; SetLocalBudgetOverride(CurrentOverride); } else if (wParam == VK_OEM_MINUS || wParam == VK_SUBTRACT) // '-' - Decrease budget. { UINT64 CurrentOverride = GetLocalBudgetOverride(); if (CurrentOverride > _128MB) { CurrentOverride -= _128MB; } else { CurrentOverride = 0; } SetLocalBudgetOverride(CurrentOverride); } return true; } } return false; }
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; // vsync(수직동기화) 설정을 저장합니다. m_vsync_enabled = vsync; // DirectX 그래픽 인터페이스 팩토리를 만듭니다. 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; } // DXGI_FORMAT_R8G8B8A8_UNORM 모니터 출력 디스플레이 포맷에 맞는 모드의 개수를 구합니다. 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; } } } // 아답터(그래픽카드)의 description을 가져옵니다. result = adapter->GetDesc(&adapterDesc); if (FAILED(result)) { return false; } // 현재 그래픽카드의 메모리 용량을 메가바이트 단위로 저장합니다. m_videoCardMemory = (int)(adapterDesc.DedicatedVideoMemory / 1024 / 1024); // 그래픽카드의 이름을 char형 문자열 배열로 바꾼 뒤 저장합니다. 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; // 스왑 체인 description을 초기화합니다. ZeroMemory(&swapChainDesc, sizeof(swapChainDesc)); // 하나의 백버퍼만을 사용하도록 합니다. swapChainDesc.BufferCount = 1; // 백버퍼의 너비와 높이를 설정합니다. swapChainDesc.BufferDesc.Width = screenWidth; swapChainDesc.BufferDesc.Height = screenHeight; // 백퍼버로 일반적인 32bit의 서페이스를 지정합니다. 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; // 스캔라인의 정렬과 스캔라이닝을 지정되지 않으므로 (unspecified) 설정합니다. swapChainDesc.BufferDesc.ScanlineOrdering = DXGI_MODE_SCANLINE_ORDER_UNSPECIFIED; swapChainDesc.BufferDesc.Scaling = DXGI_MODE_SCALING_UNSPECIFIED; // 출력된 이후의 백버퍼의 내용을 버리도록 합니다. swapChainDesc.SwapEffect = DXGI_SWAP_EFFECT_DISCARD; // 추가 옵션 플래그를 사용하지 않습니다. swapChainDesc.Flags = 0; // 피쳐 레벨을 DirectX 11로 설정합니다. featureLevel = D3D_FEATURE_LEVEL_11_0; // 스왑 체인, Direct3D 디바이스, Direct3D 디바이스 컨텍스트를 생성합니다. 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; // 깊이 버퍼의 description을 초기화합니다. ZeroMemory(&depthBufferDesc, sizeof(depthBufferDesc)); // 깊이 버퍼의 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; // description을 사용하여 깊이 버퍼의 텍스쳐를 생성합니다. result = m_device->CreateTexture2D(&depthBufferDesc, NULL, &m_depthStencilBuffer); if (FAILED(result)) return false; // 스텐실 상태의 description을 초기화합니다. ZeroMemory(&depthStencilDesc, sizeof(depthStencilDesc)); // 스텐실 상태의 description을 작성합니다. 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; // 깊이 - 스텐실 상태를 생성합니다. result = m_device->CreateDepthStencilState(&depthStencilDesc, &m_depthStencilState); if (FAILED(result)) return false; // 깊이 - 스텐실 상태를 설정합니다. m_deviceContext->OMSetDepthStencilState(m_depthStencilState, 1); // 깊이 - 스텐실 뷰의 description을 초기화 합니다. ZeroMemory(&depthStencilViewDesc, sizeof(depthStencilViewDesc)); // 깊이 - 스텐실 부의 description을 작성합니다. 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); // 어떤 도형을 어떻게 그릴 것인지 결정하는 래스터화기 description을 작성합니다. 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; // 작성한 description으로부터 래스터화기 상태를 생성합니다. 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)D3DX_PI / 4.0f; screenAspect = (float)screenWidth / (float)screenHeight; // 3D 렌더링을 위한 투영 행렬을 생성합니다. D3DXMatrixPerspectiveFovLH(&m_projectionMatrix, fieldOfView, screenAspect, screenNear, screenDepth); // 월드 행렬을 단위 행렬로 초기화 합니다. D3DXMatrixIdentity(&m_worldMatrix); // 2D 렌더링에 사용될 정사영 행렬을 생성합니다. D3DXMatrixOrthoLH(&m_orthoMatrix, (float)screenWidth, (float)screenHeight, screenNear, screenDepth); return true; }
bool D3DClass::Initialize(int screenHeight, int screenWidth, HWND hwnd, bool vsync, bool fullscreen) { D3D_FEATURE_LEVEL featureLevel; HRESULT result; D3D12_COMMAND_QUEUE_DESC commandQueueDesc; IDXGIFactory4* factory; IDXGIAdapter* adapter; IDXGIOutput* adapterOutput; unsigned int numModes, i, numerator, denominator, renderTargetViewDescriptorSize; unsigned long long stringLength; DXGI_MODE_DESC* displayModeList; DXGI_ADAPTER_DESC adapterDesc; DXGI_SWAP_CHAIN_DESC swapChainDesc; IDXGISwapChain* swapChain; D3D12_DESCRIPTOR_HEAP_DESC renderTargetViewHeapDesc; D3D12_CPU_DESCRIPTOR_HANDLE renderTargetViewHandle; // Store the vsync setting. m_vsync_enabled = vsync; // Set the feature level to DirectX 12.1 to enable using all the DirectX 12 features. // Note: Not all cards support full DirectX 12, this feature level may need to be reduced on some cards to 12.0. featureLevel = D3D_FEATURE_LEVEL_11_0; // Create the Direct3D 12 device. result = D3D12CreateDevice(NULL, featureLevel, __uuidof(ID3D12Device), (void**)&m_device); if (FAILED(result)) { MessageBox(hwnd, L"Could not create a DirectX 12.1 device. The default video card does not support DirectX 12.1.", L"DirectX Device Failure", MB_OK); return false; } // Initialize the description of the command queue. ZeroMemory(&commandQueueDesc, sizeof(commandQueueDesc)); // Set up the description of the command queue. commandQueueDesc.Type = D3D12_COMMAND_LIST_TYPE_DIRECT; commandQueueDesc.Priority = D3D12_COMMAND_QUEUE_PRIORITY_NORMAL; commandQueueDesc.Flags = D3D12_COMMAND_QUEUE_FLAG_NONE; commandQueueDesc.NodeMask = 0; // Create the command queue. m_device->CreateCommandQueue(&commandQueueDesc, __uuidof(ID3D12CommandQueue), (void**)&m_commandQueue); // Create a DirectX graphics interface factory. CreateDXGIFactory1(__uuidof(IDXGIFactory4), (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 height and width. // 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].Height == (unsigned int)screenHeight) { if (displayModeList[i].Width == (unsigned int)screenWidth) { 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 = nullptr; // Release the adapter output. adapterOutput->Release(); adapterOutput = nullptr; // Release the adapter. adapter->Release(); adapter = nullptr; // Initialize the swap chain description. ZeroMemory(&swapChainDesc, sizeof(swapChainDesc)); // Set the swap chain to use double buffering. swapChainDesc.BufferCount = 2; // Set the height and width of the back buffers in the swap chain. swapChainDesc.BufferDesc.Height = screenHeight; swapChainDesc.BufferDesc.Width = screenWidth; // Set a regular 32-bit surface for the back buffers. swapChainDesc.BufferDesc.Format = DXGI_FORMAT_R8G8B8A8_UNORM; // Set the usage of the back buffers to be render target outputs. swapChainDesc.BufferUsage = DXGI_USAGE_RENDER_TARGET_OUTPUT; // Set the swap effect to discard the previous buffer contents after swapping. swapChainDesc.SwapEffect = DXGI_SWAP_EFFECT_FLIP_DISCARD; // Set the handle for the window to render to. swapChainDesc.OutputWindow = hwnd; // Set to full screen or windowed mode. swapChainDesc.Windowed = !fullscreen; // 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; } // Turn multisampling off. swapChainDesc.SampleDesc.Count = 1; swapChainDesc.SampleDesc.Quality = 0; // Set the scan line ordering and scaling to unspecified. swapChainDesc.BufferDesc.ScanlineOrdering = DXGI_MODE_SCANLINE_ORDER_UNSPECIFIED; swapChainDesc.BufferDesc.Scaling = DXGI_MODE_SCALING_UNSPECIFIED; // Don't set the advanced flags. swapChainDesc.Flags = 0; // Finally create the swap chain using the swap chain description. factory->CreateSwapChain(m_commandQueue, &swapChainDesc, &swapChain); // Next upgrade the IDXGISwapChain to a IDXGISwapChain3 interface and store it in a private member variable named m_swapChain. // This will allow us to use the newer functionality such as getting the current back buffer index. swapChain->QueryInterface(__uuidof(IDXGISwapChain3), (void**)&m_swapChain); // Clear pointer to original swap chain interface since we are using version 3 instead (m_swapChain). swapChain = nullptr; // Release the factory now that the swap chain has been created. factory->Release(); factory = nullptr; // Initialize the render target view heap description for the two back buffers. ZeroMemory(&renderTargetViewHeapDesc, sizeof(renderTargetViewHeapDesc)); // Set the number of descriptors to two for our two back buffers. Also set the heap tyupe to render target views. renderTargetViewHeapDesc.NumDescriptors = 2; renderTargetViewHeapDesc.Type = D3D12_DESCRIPTOR_HEAP_TYPE_RTV; renderTargetViewHeapDesc.Flags = D3D12_DESCRIPTOR_HEAP_FLAG_NONE; // Create the render target view heap for the back buffers. m_device->CreateDescriptorHeap(&renderTargetViewHeapDesc, __uuidof(ID3D12DescriptorHeap), (void**)&m_renderTargetViewHeap); // Get a handle to the starting memory location in the render target view heap to identify where the render target views will be located for the two back buffers. renderTargetViewHandle = m_renderTargetViewHeap->GetCPUDescriptorHandleForHeapStart(); // Get the size of the memory location for the render target view descriptors. renderTargetViewDescriptorSize = m_device->GetDescriptorHandleIncrementSize(D3D12_DESCRIPTOR_HEAP_TYPE_RTV); // Get a pointer to the first back buffer from the swap chain. m_swapChain->GetBuffer(0, __uuidof(ID3D12Resource), (void**)&m_backBufferRenderTarget[0]); // Create a render target view for the first back buffer. m_device->CreateRenderTargetView(m_backBufferRenderTarget[0], NULL, renderTargetViewHandle); // Increment the view handle to the next descriptor location in the render target view heap. renderTargetViewHandle.ptr += renderTargetViewDescriptorSize; // Get a pointer to the second back buffer from the swap chain. m_swapChain->GetBuffer(1, __uuidof(ID3D12Resource), (void**)&m_backBufferRenderTarget[1]); // Create a render target view for the second back buffer. m_device->CreateRenderTargetView(m_backBufferRenderTarget[1], NULL, renderTargetViewHandle); // Finally get the initial index to which buffer is the current back buffer. m_bufferIndex = m_swapChain->GetCurrentBackBufferIndex(); // Create a command allocator. m_device->CreateCommandAllocator(D3D12_COMMAND_LIST_TYPE_DIRECT, __uuidof(ID3D12CommandAllocator), (void**)&m_commandAllocator); // Create a fence for GPU synchronization. m_device->CreateFence(0, D3D12_FENCE_FLAG_NONE, __uuidof(ID3D12Fence), (void**)&m_fence); // Create an event object for the fence. m_fenceEvent = CreateEvent(nullptr, false, false, nullptr); // Initialize the starting fence value. m_fenceValue = 1; CD3DX12_ROOT_SIGNATURE_DESC rootSignatureDesc; rootSignatureDesc.Init(0, nullptr, 0, nullptr, D3D12_ROOT_SIGNATURE_FLAG_ALLOW_INPUT_ASSEMBLER_INPUT_LAYOUT); ID3DBlob* signature; ID3DBlob* error; D3D12SerializeRootSignature( &rootSignatureDesc, D3D_ROOT_SIGNATURE_VERSION_1, &signature, &error); m_device->CreateRootSignature( 0, signature->GetBufferPointer(), signature->GetBufferSize(), IID_PPV_ARGS(&m_rootSignature)); //Create pipeline state, load and compiler shaders. //Note here to change D3DCOMPILE_DEBUG | D3DCOMPILE_SKIP_OPTIMIZATION for debug UINT compileFlags = D3DCOMPILE_DEBUG | D3DCOMPILE_SKIP_OPTIMIZATION; D3DReadFileToBlob(L"DefaultVS.cso", &m_vertexShader); D3DReadFileToBlob(L"DefaultHS.cso", &m_hullShader); D3DReadFileToBlob(L"DefaultDS.cso", &m_domainShader); D3DReadFileToBlob(L"DefaultPS.cso", &m_pixelShader); std::array<D3D12_INPUT_ELEMENT_DESC, 2> inputElementDescs = { D3D12_INPUT_ELEMENT_DESC{ "POSITION", 0, DXGI_FORMAT_R32G32B32_FLOAT, 0, 0, D3D12_INPUT_CLASSIFICATION_PER_VERTEX_DATA, 0 }, D3D12_INPUT_ELEMENT_DESC{ "COLOR", 0, DXGI_FORMAT_R32G32B32_FLOAT, 0, 12, D3D12_INPUT_CLASSIFICATION_PER_VERTEX_DATA, 0 } }; D3D12_GRAPHICS_PIPELINE_STATE_DESC pipelineDesc = {}; pipelineDesc.InputLayout = { inputElementDescs.data() , (UINT)inputElementDescs.size() }; pipelineDesc.pRootSignature = m_rootSignature; pipelineDesc.VS = { m_vertexShader->GetBufferPointer(), m_vertexShader->GetBufferSize() }; pipelineDesc.PS = { m_pixelShader->GetBufferPointer(), m_pixelShader->GetBufferSize() }; pipelineDesc.HS = { m_hullShader->GetBufferPointer(), m_hullShader->GetBufferSize() }; pipelineDesc.DS = { m_domainShader->GetBufferPointer(), m_domainShader->GetBufferSize() }; pipelineDesc.RasterizerState = CD3DX12_RASTERIZER_DESC(D3D12_DEFAULT_WIREFRAME); pipelineDesc.BlendState = CD3DX12_BLEND_DESC(D3D12_DEFAULT); pipelineDesc.DepthStencilState.DepthEnable = false; pipelineDesc.DepthStencilState.StencilEnable = false; pipelineDesc.SampleMask = UINT_MAX; pipelineDesc.PrimitiveTopologyType = D3D12_PRIMITIVE_TOPOLOGY_TYPE_PATCH; pipelineDesc.NumRenderTargets = 1; pipelineDesc.RTVFormats[0] = DXGI_FORMAT_B8G8R8A8_UNORM; pipelineDesc.SampleDesc.Count = 1; m_device->CreateGraphicsPipelineState(&pipelineDesc, IID_PPV_ARGS(&m_pipelineState)); // Create a basic command list. m_device->CreateCommandList( 0, D3D12_COMMAND_LIST_TYPE_DIRECT, m_commandAllocator, m_pipelineState, IID_PPV_ARGS(&m_commandList)); // Initially we need to close the command list during initialization as it is created in a recording state. m_commandList->Close(); Vertex triangleVertices[] = { { { 0.0f, 0.5f, 0.f }, { 1.f, 0.f, 0.f, 1.f } }, { { 0.5f, -0.5f, 0.f },{ 0.f, 1.f, 0.f, 1.f } }, { { -0.5f, -0.5f, 0.f },{ 0.f, 0.f, 1.f, 1.f } }, }; const UINT vertexBufferSize = sizeof(triangleVertices); m_device->CreateCommittedResource( &CD3DX12_HEAP_PROPERTIES(D3D12_HEAP_TYPE_UPLOAD), D3D12_HEAP_FLAG_NONE, &CD3DX12_RESOURCE_DESC::Buffer(vertexBufferSize), D3D12_RESOURCE_STATE_GENERIC_READ, nullptr, IID_PPV_ARGS(&m_vertexBuffer)); UINT8* pVertexDataBegin; CD3DX12_RANGE readRange(0, 0); m_vertexBuffer->Map(0, &readRange, reinterpret_cast<void**>(&pVertexDataBegin)); memcpy(pVertexDataBegin, triangleVertices, vertexBufferSize); m_vertexBuffer->Unmap(0, nullptr); m_vertexBufferView.BufferLocation = m_vertexBuffer->GetGPUVirtualAddress(); m_vertexBufferView.StrideInBytes = sizeof(Vertex); m_vertexBufferView.SizeInBytes = vertexBufferSize; m_viewport.Height = screenHeight; m_viewport.Width = screenWidth; m_viewport.MaxDepth = 1000.f; m_viewport.MinDepth = 0.1f; m_viewport.TopLeftX = 0.f; m_viewport.TopLeftY = 0.f; m_scissorRect.left = 0; m_scissorRect.right = screenWidth; m_scissorRect.top = 0; m_scissorRect.bottom = screenHeight; unsigned long long fenceToWaitFor = m_fenceValue; m_commandQueue->Signal(m_fence, fenceToWaitFor); m_fenceValue++; // Wait until the GPU is done rendering. if (m_fence->GetCompletedValue() < fenceToWaitFor) { m_fence->SetEventOnCompletion(fenceToWaitFor, m_fenceEvent); WaitForSingleObject(m_fenceEvent, INFINITE); } return true; }
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 DXManager::Initialize(int screenWidth, int screenHeight, bool vsync, HWND hwnd, bool fullscreen) { HRESULT result; IDXGIFactory* factory; IDXGIAdapter* adapter; IDXGIOutput* adapterOutput; unsigned int numModes, numerator = 0, denominator = 0, stringLength; DXGI_MODE_DESC* displayModeList; DXGI_ADAPTER_DESC adapterDesc; int error; ID3D11Texture2D* backBufferPtr; //store vsync setting m_vsync_enabled = vsync; //Create a DirectX graphic 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 result = factory->EnumAdapters(0, &adapter); if(FAILED(result)) { return false; } //Enumerate the primary adapter output 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 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 modes for this monitor/video card combination displayModeList = new DXGI_MODE_DESC[numModes]; //Fill the display mode list result = adapterOutput->GetDisplayModeList(DXGI_FORMAT_R8G8B8A8_UNORM, DXGI_ENUM_MODES_INTERLACED, &numModes, displayModeList); if(FAILED(result)) { return false; } for(int i = 0; i < (int)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; } } } if(numerator == 0 && denominator == 0) { return false; } //Get the adapter description result = adapter->GetDesc(&adapterDesc); if(FAILED(result)) { return false; } //Store the video card memory in megabytes m_videoCardMemory = (int)(adapterDesc.DedicatedVideoMemory / 1024 / 1024); //Convert the name of the video card to a character array error = wcstombs_s(&stringLength, m_videoCardDescription, 128, adapterDesc.Description, 128); if(error != 0) { return false; } //release memory delete [] displayModeList; displayModeList = 0; adapterOutput->Release(); adapterOutput = 0; adapter->Release(); adapter = 0; factory->Release(); factory = 0; if(!InitializeSwapChain(hwnd, fullscreen, screenWidth, screenHeight, numerator, denominator)) { 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 result = m_device->CreateRenderTargetView(backBufferPtr, NULL, &m_renderTargetView); if(FAILED(result)) { return false; } //release back buffer backBufferPtr->Release(); backBufferPtr = 0; if(!InitializeDepthBuffer(screenWidth, screenHeight)) { return false; } if(!InitializeDepthStencilBuffer()) { return false; } if(!InitializeStencilView()) { return false; } //bind the render target view and depth stencil buffer to the output render pipeline m_deviceContext->OMSetRenderTargets(1, &m_renderTargetView, m_depthStencilView); if(!InitializeRasterizerState()) { return false; } InitializeViewport(screenWidth, screenHeight); if(!InitializeAlphaBlending()) { return false; } if(!InitializeZBuffer()) { 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; }
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 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; }
/////////////////////////////////////////////////////////////// // 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; }
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; }
bool D3D10App::initAPI(const DXGI_FORMAT backBufferFmt, const DXGI_FORMAT depthBufferFmt, const int samples, const uint flags){ backBufferFormat = backBufferFmt; depthBufferFormat = depthBufferFmt; msaaSamples = samples; // if (screen >= GetSystemMetrics(SM_CMONITORS)) screen = 0; IDXGIFactory *dxgiFactory; if (FAILED(CreateDXGIFactory(__uuidof(IDXGIFactory), (void **) &dxgiFactory))){ ErrorMsg("Couldn't create DXGIFactory"); return false; } IDXGIAdapter *dxgiAdapter; if (dxgiFactory->EnumAdapters(0, &dxgiAdapter) == DXGI_ERROR_NOT_FOUND){ ErrorMsg("No adapters found"); return false; } // DXGI_ADAPTER_DESC adapterDesc; // dxgiAdapter->GetDesc(&adapterDesc); IDXGIOutput *dxgiOutput; if (dxgiAdapter->EnumOutputs(0, &dxgiOutput) == DXGI_ERROR_NOT_FOUND){ ErrorMsg("No outputs found"); return false; } DXGI_OUTPUT_DESC oDesc; dxgiOutput->GetDesc(&oDesc); // Find a suitable fullscreen format int targetHz = 85; DXGI_RATIONAL fullScreenRefresh; int fsRefresh = 60; fullScreenRefresh.Numerator = fsRefresh; fullScreenRefresh.Denominator = 1; char str[128]; uint nModes = 0; dxgiOutput->GetDisplayModeList(backBufferFormat, 0, &nModes, NULL); DXGI_MODE_DESC *modes = new DXGI_MODE_DESC[nModes]; dxgiOutput->GetDisplayModeList(backBufferFormat, 0, &nModes, modes); resolution->clear(); for (uint i = 0; i < nModes; i++){ if (modes[i].Width >= 640 && modes[i].Height >= 480){ sprintf(str, "%dx%d", modes[i].Width, modes[i].Height); int index = resolution->addItemUnique(str); if (int(modes[i].Width) == fullscreenWidth && int(modes[i].Height) == fullscreenHeight){ int refresh = modes[i].RefreshRate.Numerator / modes[i].RefreshRate.Denominator; if (abs(refresh - targetHz) < abs(fsRefresh - targetHz)){ fsRefresh = refresh; fullScreenRefresh = modes[i].RefreshRate; } resolution->selectItem(index); } } } delete modes; sprintf(str, "%s (%dx%d)", getTitle(), width, height); DWORD wndFlags = 0; int x, y, w, h; if (fullscreen){ wndFlags |= WS_POPUP; x = y = 0; w = width; h = height; } else { wndFlags |= WS_OVERLAPPEDWINDOW; RECT wRect; wRect.left = 0; wRect.right = width; wRect.top = 0; wRect.bottom = height; AdjustWindowRect(&wRect, wndFlags, FALSE); MONITORINFO monInfo; monInfo.cbSize = sizeof(monInfo); GetMonitorInfo(oDesc.Monitor, &monInfo); w = min(wRect.right - wRect.left, monInfo.rcWork.right - monInfo.rcWork.left); h = min(wRect.bottom - wRect.top, monInfo.rcWork.bottom - monInfo.rcWork.top); x = (monInfo.rcWork.left + monInfo.rcWork.right - w) / 2; y = (monInfo.rcWork.top + monInfo.rcWork.bottom - h) / 2; } hwnd = CreateWindow("Humus", str, wndFlags, x, y, w, h, HWND_DESKTOP, NULL, hInstance, NULL); RECT rect; GetClientRect(hwnd, &rect); // Create device and swap chain DXGI_SWAP_CHAIN_DESC sd; memset(&sd, 0, sizeof(sd)); sd.BufferDesc.Width = rect.right; sd.BufferDesc.Height = rect.bottom; sd.BufferDesc.Format = backBufferFormat; sd.BufferDesc.RefreshRate = fullScreenRefresh; sd.BufferUsage = DXGI_USAGE_RENDER_TARGET_OUTPUT; sd.BufferCount = 1; sd.OutputWindow = hwnd; sd.Windowed = (BOOL) (!fullscreen); sd.SwapEffect = DXGI_SWAP_EFFECT_DISCARD; sd.Flags = DXGI_SWAP_CHAIN_FLAG_ALLOW_MODE_SWITCH; DWORD deviceFlags = D3D10_CREATE_DEVICE_SINGLETHREADED; #ifdef _DEBUG deviceFlags |= D3D10_CREATE_DEVICE_DEBUG; #endif if (FAILED(D3D10CreateDevice(dxgiAdapter, D3D10_DRIVER_TYPE_HARDWARE, NULL, deviceFlags, D3D10_SDK_VERSION, &device))){ ErrorMsg("Couldn't create D3D10 device"); return false; } while (msaaSamples > 0){ UINT nQuality; if (SUCCEEDED(device->CheckMultisampleQualityLevels(backBufferFormat, msaaSamples, &nQuality)) && nQuality > 0){ if ((flags & NO_SETTING_CHANGE) == 0) antiAliasSamples = msaaSamples; break; } else { msaaSamples -= 2; } } sd.SampleDesc.Count = msaaSamples; sd.SampleDesc.Quality = 0; if (FAILED(dxgiFactory->CreateSwapChain(device, &sd, &swapChain))){ ErrorMsg("Couldn't create swapchain"); return false; } // We'll handle Alt-Enter ourselves thank you very much ... dxgiFactory->MakeWindowAssociation(hwnd, DXGI_MWA_NO_WINDOW_CHANGES | DXGI_MWA_NO_ALT_ENTER); dxgiOutput->Release(); dxgiAdapter->Release(); dxgiFactory->Release(); if (!createBuffers()) return false; if (fullscreen){ captureMouse(!configDialog->isVisible()); } renderer = new Direct3D10Renderer(device); ((Direct3D10Renderer *) renderer)->setFrameBuffer(backBufferRTV, depthBufferDSV); antiAlias->selectItem(antiAliasSamples / 2); linearClamp = renderer->addSamplerState(LINEAR, CLAMP, CLAMP, CLAMP); defaultFont = renderer->addFont("../Textures/Fonts/Future.dds", "../Textures/Fonts/Future.font", linearClamp); blendSrcAlpha = renderer->addBlendState(SRC_ALPHA, ONE_MINUS_SRC_ALPHA); noDepthTest = renderer->addDepthState(false, false); noDepthWrite = renderer->addDepthState(true, false); cullNone = renderer->addRasterizerState(CULL_NONE); cullBack = renderer->addRasterizerState(CULL_BACK); cullFront = renderer->addRasterizerState(CULL_FRONT); return true; }
bool D3DManager::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 blendStateDescription; std::vector<IDXGIAdapter*> vAdapters; int largestAdapter = 0; int videoCardMemory; // Store our screen width and height m_ScreenWidth = screenWidth; m_ScreenHeight = screenHeight; // Store the vsync setting. m_vsync_enabled = vsync; // Create a DirectX graphics interface factory. result = CreateDXGIFactory(__uuidof(IDXGIFactory), (void**)&factory); if(FAILED(result)) { log_sxerror("D3DManager", "Failed to create a DXGI factory."); return false; } // Loop through each adapter on the computer for(UINT i = 0; factory->EnumAdapters(i, &adapter) != DXGI_ERROR_NOT_FOUND; ++i) { // Store the adapter vAdapters.push_back(adapter); // Get the adapter (video card) description. result = adapter->GetDesc(&adapterDesc); if(FAILED(result)) { log_sxerror("D3DManager", "Failed to get the video card description."); return false; } // Store the dedicated video card memory in megabytes. videoCardMemory = (int)(adapterDesc.DedicatedVideoMemory / 1024 / 1024); // If the memory is larger than our current memory, save this index if(videoCardMemory > m_videoCardMemory) { m_videoCardMemory = videoCardMemory; largestAdapter = i; // 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) { log_sxerror("D3DManager", "Failed to get the name of the graphics card."); return false; } } } // Enumerate the primary adapter output (monitor). result = vAdapters.at(0)->EnumOutputs(0, &adapterOutput); if(FAILED(result)) { log_sxerror("D3DManager", "Failed to grab the monitor."); 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)) { log_sxerror("D3DManager", "Failed to get a list of display modes."); 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) { log_sxerror("D3DManager", "Failed to create a display mode list for the monitor/gfx card combo."); 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)) { log_sxerror("D3DManager", "Failed to fill the display mode list structures."); 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; } } } // Release the display mode list. delete [] displayModeList; displayModeList = 0; // Release the adapter output. adapterOutput->Release(); adapterOutput = 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 = 60;//numerator; swapChainDesc.BufferDesc.RefreshRate.Denominator = 1;//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; //swapChainDesc.SwapEffect = DXGI_SWAP_EFFECT_SEQUENTIAL; // Don't set the advanced flags. swapChainDesc.Flags = 0; // Grab the highest feature level result = D3D11CreateDevice(vAdapters.at(largestAdapter), D3D_DRIVER_TYPE_UNKNOWN, NULL, 0, NULL, 0, D3D11_SDK_VERSION, NULL, &featureLevel, NULL ); if(FAILED(result)) { log_sxerror("D3DManager", "Failed to retrieve the featurelevel."); ErrorDescription(result); // Try to use the default adapter largestAdapter = 0; result = D3D11CreateDevice(vAdapters.at(largestAdapter), D3D_DRIVER_TYPE_UNKNOWN, NULL, 0, NULL, 0, D3D11_SDK_VERSION, NULL, &featureLevel, NULL ); if(FAILED(result)) { log_sxerror("D3DManager", "Failed to retrieve the featurelevel the second time."); ErrorDescription(result); return false; } } #ifdef _DEBUG // Create the swap chain, Direct3D device, and Direct3D device context. result = D3D11CreateDeviceAndSwapChain(vAdapters.at(largestAdapter), D3D_DRIVER_TYPE_UNKNOWN, NULL, D3D11_CREATE_DEVICE_DEBUG | D3D11_CREATE_DEVICE_BGRA_SUPPORT , &featureLevel, 1, D3D11_SDK_VERSION, &swapChainDesc, &m_swapChain, &m_device, NULL, &m_deviceContext); if(FAILED(result)) { log_sxerror("D3DManager", "Failed to create the Direct3D device, context, and swap chain."); return false; } result = m_device->QueryInterface((IID)IID_ID3D11Debug, (void**)&m_Debug); if(FAILED(result)) { log_sxerror("D3DManager", "Failed to create a debugging interface for the device. Debugging may not work"); } else { result = m_Debug->ReportLiveDeviceObjects(D3D11_RLDO_DETAIL); if(FAILED(result)) { log_sxerror("D3DManager", "Failed to enable detailed object reporting."); } } #else // Create the swap chain, Direct3D device, and Direct3D device context. result = D3D11CreateDeviceAndSwapChain(vAdapters.at(largestAdapter), D3D_DRIVER_TYPE_UNKNOWN, NULL, D3D11_CREATE_DEVICE_BGRA_SUPPORT , &featureLevel, 1, D3D11_SDK_VERSION, &swapChainDesc, &m_swapChain, &m_device, NULL, &m_deviceContext); if(FAILED(result)) { log_sxerror("D3DManager", "Failed to create the Direct3D device, context, and swap chain."); return false; } #endif // Release each adapter. for(auto it = vAdapters.begin(); it != vAdapters.end(); ++it) { (*it)->Release(); (*it) = 0; } // Get the pointer to the back buffer. result = m_swapChain->GetBuffer(0, __uuidof(ID3D11Texture2D), (LPVOID*)&backBufferPtr); if(FAILED(result)) { log_sxerror("D3DManager", "Failed to get a pointer to the back buffer."); return false; } // Create the render target view with the back buffer pointer. result = m_device->CreateRenderTargetView(backBufferPtr, NULL, &m_renderTargetView); if(FAILED(result)) { log_sxerror("D3DManager", "Failed to create the render target view."); 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 = m_device->CreateTexture2D(&depthBufferDesc, NULL, &m_depthStencilBuffer); if(FAILED(result)) { log_sxerror("D3DManager", "Failed to create the depth buffer."); 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 = m_device->CreateDepthStencilState(&depthStencilDesc, &m_depthStencilState); if(FAILED(result)) { log_sxerror("D3DManager", "Failed to create the depth stencil state."); 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)) { log_sxerror("D3DManager", "Failed to 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 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)) { log_sxerror("D3DManager", "Failed to create the rasterizer state."); return false; } // Now set the rasterizer state. m_deviceContext->RSSetState(m_rasterState); // 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; assert(screenWidth != 0); assert(screenHeight != 0); screenAspect = (float)screenWidth / (float)screenHeight; // Create the projection matrix for 3D rendering. XMStoreFloat4x4(&m_projectionMatrix, XMMatrixPerspectiveFovLH(fieldOfView, screenAspect, screenNear, screenDepth)); // Initialize the world and view matrix to the identity matrix. XMStoreFloat4x4(&m_worldMatrix, XMMatrixIdentity()); XMStoreFloat4x4(&m_viewMatrix, XMMatrixIdentity()); // Create an orthographic projection matrix for 2D rendering. XMStoreFloat4x4(&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. result = m_device->CreateDepthStencilState(&depthDisabledStencilDesc, &m_depthDisabledStencilState); if(FAILED(result)) { log_sxerror("D3DManager", "Failed to create the depth disabled stencil state."); return false; } // 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_ZERO; blendStateDescription.RenderTarget[0].DestBlendAlpha = D3D11_BLEND_ZERO; blendStateDescription.RenderTarget[0].BlendOpAlpha = D3D11_BLEND_OP_ADD; blendStateDescription.RenderTarget[0].RenderTargetWriteMask = 0x0f; //blendStateDescription.RenderTarget[0].BlendEnable = true; //blendStateDescription.RenderTarget[0].SrcBlend = D3D11_BLEND_SRC_COLOR; // This one f***s by adding white //blendStateDescription.RenderTarget[0].DestBlend = D3D11_BLEND_DEST_COLOR; // This one produces fail whale, dusky background, lite trees //blendStateDescription.RenderTarget[0].BlendOp = D3D11_BLEND_OP_ADD; //blendStateDescription.RenderTarget[0].SrcBlendAlpha = D3D11_BLEND_SRC_ALPHA; //blendStateDescription.RenderTarget[0].DestBlendAlpha = D3D11_BLEND_DEST_ALPHA; //blendStateDescription.RenderTarget[0].BlendOpAlpha = D3D11_BLEND_OP_ADD; //blendStateDescription.RenderTarget[0].RenderTargetWriteMask = 7; // Create the blend state using the description. result = m_device->CreateBlendState(&blendStateDescription, &m_alphaEnableBlendingState); if(FAILED(result)) { log_sxerror("D3DManager", "Failed to create the alpha blending state."); 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)) { log_sxerror("D3DManager", "Failed to create the alpha disabled blending state."); return false; } return true; }
HRESULT DXManager::getVideoCardInfo() { HRESULT result; IDXGIFactory* factory; IDXGIAdapter* adapter; IDXGIOutput* adapterOutput; DXGI_MODE_DESC* displayModeList; DXGI_ADAPTER_DESC adapterDesc; unsigned int numModes, i, stringLength; int error; 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)m_ScreenWidth) { if (displayModeList[i].Height == (unsigned int)m_ScreenHeight) { mNumerator = displayModeList[i].RefreshRate.Numerator; mDenominator = displayModeList[i].RefreshRate.Denominator; } } } result = adapter->GetDesc(&adapterDesc); if (FAILED(result)) { return false; } m_videoCardMemory = (int)(adapterDesc.DedicatedVideoMemory / 1024 / 1024); //MB Video Ram 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; return S_OK; }
bool RenderCore::Init(int screenWidth, int screenHeight, HWND hWnd) { HRESULT hr; IDXGIAdapter1 *adapter; IDXGIOutput *adapterOutput; IDXGIOutput1 *adapterOutput1; DXGI_ADAPTER_DESC adapterDesc; DXGI_MODE_DESC *displayModeList; DXGI_SWAP_CHAIN_DESC swapChainDesc; ID3D11Texture2D *pBackBuffer; D3D11_TEXTURE2D_DESC depthBufferDesc; D3D11_DEPTH_STENCIL_DESC depthStencilDesc; D3D11_DEPTH_STENCIL_DESC depthDisabledStencilDesc; D3D11_DEPTH_STENCIL_VIEW_DESC depthStencilViewDesc; D3D11_RASTERIZER_DESC rasterDesc; uint32_t numModes, fpsNumerator, fpsDenominator; size_t stringLength; int error; float fov, aspect; if (!EnumerateDisplayAdapters(&g_DXGIAdapters)) { return false; } adapter = g_DXGIAdapters.at(0); hr = adapter->EnumOutputs(0, &adapterOutput); if (FAILED(hr)) { return false; } // desktop duplication stuff hr = adapterOutput->QueryInterface(&adapterOutput1); hr = adapterOutput1->GetDisplayModeList(DXGI_FORMAT_R8G8B8A8_UNORM, DXGI_ENUM_MODES_INTERLACED, &numModes, nullptr); if (FAILED(hr)) { return false; } displayModeList = new DXGI_MODE_DESC[numModes]; if (!displayModeList) { return false; } hr = adapterOutput1->GetDisplayModeList(DXGI_FORMAT_R8G8B8A8_UNORM, DXGI_ENUM_MODES_INTERLACED, &numModes, displayModeList); if (FAILED(hr)) { return false; } for (UINT i = 0; i < numModes; i++) { if (displayModeList[i].Width == (unsigned int)screenWidth) { if (displayModeList[i].Height == (unsigned int)screenHeight) { fpsNumerator = displayModeList[i].RefreshRate.Numerator; fpsDenominator = displayModeList[i].RefreshRate.Denominator; } } } hr = adapter->GetDesc(&adapterDesc); if (FAILED(hr)) { return false; } // retrieve video adapter memory and name m_VideoMemory = (int)(adapterDesc.DedicatedVideoMemory / 1024 / 1024); error = wcstombs_s(&stringLength, m_VideoCardDesc, 128, adapterDesc.Description, 128); if (error != 0) { return false; } DebugOut("Found graphics adapter: %s (%dMB VRAM)\n", m_VideoCardDesc, m_VideoMemory); delete[] displayModeList; displayModeList = nullptr; adapterOutput->Release(); adapter->Release(); // set single back buffer ZeroMemory(&swapChainDesc, sizeof(swapChainDesc)); swapChainDesc.BufferCount = 1; swapChainDesc.BufferDesc.Width = screenWidth; swapChainDesc.BufferDesc.Height = screenHeight; swapChainDesc.BufferDesc.Format = DXGI_FORMAT_R8G8B8A8_UNORM; swapChainDesc.BufferDesc.RefreshRate.Numerator = 60; swapChainDesc.BufferDesc.RefreshRate.Denominator = 1; swapChainDesc.BufferUsage = DXGI_USAGE_RENDER_TARGET_OUTPUT; swapChainDesc.OutputWindow = 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; // create swap chain, direct3d device, and d3d context uint32_t deviceFlags = 0; #define D3D_DEVICE_DEBUG #ifdef D3D_DEVICE_DEBUG deviceFlags |= D3D11_CREATE_DEVICE_DEBUG; #endif D3D_FEATURE_LEVEL featureLevels[] = { D3D_FEATURE_LEVEL_11_1, D3D_FEATURE_LEVEL_11_0, D3D_FEATURE_LEVEL_10_1, D3D_FEATURE_LEVEL_10_0, }; uint32_t numFeatureLevels = ARRAYSIZE(featureLevels); hr = D3D11CreateDeviceAndSwapChain( nullptr, D3D_DRIVER_TYPE_HARDWARE, nullptr, deviceFlags, featureLevels, numFeatureLevels, D3D11_SDK_VERSION, &swapChainDesc, &m_SwapChain, &m_d3d11Device, nullptr, &m_d3d11DeviceContext); if (FAILED(hr)) { DebugOut("D3D11CreateDeviceAndSwapChain failed!\n"); return false; } // enable multithreaded device context protection ID3D10Multithread *contextMT = nullptr; m_d3d11DeviceContext->QueryInterface(&contextMT); if (contextMT) { contextMT->SetMultithreadProtected(true); contextMT->Release(); } else { DebugOut("Fatal error! ID3D10Multithread::SetMultithreadProtected for D3D11 device context failed!\n"); return false; } // get pointer to the back buffer hr = m_SwapChain->GetBuffer(0, __uuidof(ID3D11Texture2D), (LPVOID *)&pBackBuffer); if (FAILED(hr)) { DebugOut("IDXGISwapChain::GetBuffer failed!\n"); return false; } // create render target view from back buffer hr = m_d3d11Device->CreateRenderTargetView(pBackBuffer, nullptr, &m_d3d11RenderTargetView); if (FAILED(hr)) { DebugOut("ID3D11Device::CreateRenderTargetView failed!\n"); return false; } pBackBuffer->Release(); // set up depth buffer description 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 texture for depth buffer hr = m_d3d11Device->CreateTexture2D(&depthBufferDesc, nullptr, &m_d3d11DepthStencilBuffer); if (FAILED(hr)) { DebugOut("ID3D11Device::CreateTexture2D failed! Could not create texture for depth buffer.\n"); return false; } // set up description of stencil state ZeroMemory(&depthStencilDesc, sizeof(depthStencilDesc)); depthStencilDesc.DepthEnable = true; // z-buffer enabled 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 hr = m_d3d11Device->CreateDepthStencilState(&depthStencilDesc, &m_d3d11DepthStencilState); if (FAILED(hr)) { DebugOut("ID3D11Device::CreateDepthStencilState failed!\n"); return false; } // 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. hr = m_d3d11Device->CreateDepthStencilState(&depthDisabledStencilDesc, &m_d3d11DepthStencilDisabledState); if (FAILED(hr)) { return false; } // disable the Z-Buffer ZBufferState(0); // set up depth stencil view description 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 hr = m_d3d11Device->CreateDepthStencilView(m_d3d11DepthStencilBuffer, &depthStencilViewDesc, &m_d3d11DepthStencilView); if (FAILED(hr)) { DebugOut("ID3D11Device::CreateDepthStencilView failed!\n"); return false; } // bind render target view and depth stencil buffer to the output render pipeline m_d3d11DeviceContext->OMSetRenderTargets(1, &m_d3d11RenderTargetView, m_d3d11DepthStencilView); // set up rasterizer description rasterDesc.AntialiasedLineEnable = false; rasterDesc.CullMode = D3D11_CULL_NONE; 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; // create the rasterizer hr = m_d3d11Device->CreateRasterizerState(&rasterDesc, &m_d3d11RasterState); if (FAILED(hr)) { DebugOut("ID3D11Device::CreateRasterizerState failed!"); return false; } m_d3d11DeviceContext->RSSetState(m_d3d11RasterState); // set up viewport for rendering 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_d3d11DeviceContext->RSSetViewports(1, &viewport); fov = (float)PI / 4.0f; aspect = (float)screenWidth / (float)screenHeight; m_ProjectionMatrix = DirectX::XMMatrixPerspectiveFovLH(fov, aspect, SCREEN_NEAR, SCREEN_DEPTH); m_WorldMatrix = DirectX::XMMatrixIdentity(); m_OrthoMatrix = DirectX::XMMatrixOrthographicLH((float)screenWidth, (float)screenHeight, SCREEN_NEAR, SCREEN_DEPTH); // Scene is a textured quad to draw on g_Scene = new Scene(GetDevice(), GetDeviceContext(), screenWidth, screenHeight); //g_Scene2 = new Scene(GetDevice(), GetDeviceContext(), screenWidth, screenHeight); // new DXGI Desktop Duplication object g_DesktopDuplication = new DXGIDuplication(); if (!g_DesktopDuplication->Init(0, 0, &g_DXGIAdapters, GetDevice())) { DebugOut("Failed to init DXGI Desktop Duplication API!\n"); return false; } //g_DesktopDuplication2 = new DXGIDuplication(); //if (!g_DesktopDuplication2->Init(0, 1, &g_DXGIAdapters, GetDevice())) { DebugOut("Failed to init DXGI Desktop Duplication API for Adapter 1/Output 2!\n"); return false; } // initialize Media Foundation g_MFEncoder = new MF_H264_Encoder(m_d3d11Device, m_d3d11DeviceContext); if (!g_MFEncoder->Init()) { DebugOut("Failed to init Media Foundation H.264 Encoder!\n"); return false; } return true; };
void Direct3DManager::CreateWindowDependentResources(Vector2 screenSize, HWND windowHandle, bool vsync /*= false*/, bool fullScreen /*= false*/) { // Wait until all previous GPU work is complete. WaitForGPU(); mOutputSize = screenSize; mUseVsync = vsync; //need to handle if vsync or fullscreen changes mIsFullScreen = fullScreen; // The width and height of the swap chain must be based on the window's // natively-oriented width and height. If the window is not in the native // orientation, the dimensions must be reversed. DXGI_MODE_ROTATION displayRotation = ComputeDisplayRotation(); bool swapDimensions = displayRotation == DXGI_MODE_ROTATION_ROTATE90 || displayRotation == DXGI_MODE_ROTATION_ROTATE270; mOutputSize.X = swapDimensions ? screenSize.Y : screenSize.X; mOutputSize.Y = swapDimensions ? screenSize.X : screenSize.Y; if (mSwapChain != NULL) { ReleaseSwapChainDependentResources(); // If the swap chain already exists, resize it. HRESULT hr = mSwapChain->ResizeBuffers(BACK_BUFFER_COUNT, lround(mOutputSize.X), lround(mOutputSize.Y), DXGI_FORMAT_R8G8B8A8_UNORM, 0); if (hr == DXGI_ERROR_DEVICE_REMOVED || hr == DXGI_ERROR_DEVICE_RESET) { // If the device was removed for any reason, a new device and swap chain will need to be created. mDeviceRemoved = true; // Do not continue execution of this method. DeviceResources will be destroyed and re-created. return; } else { Direct3DUtils::ThrowIfHRESULTFailed(hr); } } else { // Otherwise, create a new one using the same adapter as the existing Direct3D device. IDXGIAdapter* adapter = NULL; IDXGIOutput* adapterOutput = NULL; uint32 numDisplayModes = 0; Direct3DUtils::ThrowIfHRESULTFailed(mDXGIFactory->EnumAdapters(0, &adapter)); Direct3DUtils::ThrowIfHRESULTFailed(adapter->EnumOutputs(0, &adapterOutput)); Direct3DUtils::ThrowIfHRESULTFailed(adapterOutput->GetDisplayModeList(DXGI_FORMAT_R8G8B8A8_UNORM, DXGI_ENUM_MODES_INTERLACED, &numDisplayModes, NULL)); DXGI_MODE_DESC *displayModeList = new DXGI_MODE_DESC[numDisplayModes]; Direct3DUtils::ThrowIfHRESULTFailed(adapterOutput->GetDisplayModeList(DXGI_FORMAT_R8G8B8A8_UNORM, DXGI_ENUM_MODES_INTERLACED, &numDisplayModes, displayModeList)); uint32 numerator = 0; uint32 denominator = 0; for (uint32 i = 0; i < numDisplayModes; i++) { if (displayModeList[i].Height == (uint32)mOutputSize.X) { if (displayModeList[i].Width == (uint32)mOutputSize.Y) { numerator = displayModeList[i].RefreshRate.Numerator; denominator = displayModeList[i].RefreshRate.Denominator; } } } /* DXGI_ADAPTER_DESC adapterDesc; // 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; } */ delete[] displayModeList; displayModeList = NULL; adapterOutput->Release(); adapterOutput = NULL; adapter->Release(); adapter = NULL; DXGI_SWAP_CHAIN_DESC1 swapChainDesc = {}; ZeroMemory(&swapChainDesc, sizeof(swapChainDesc)); swapChainDesc.Width = lround(mOutputSize.X); // Match the size of the window. swapChainDesc.Height = lround(mOutputSize.Y); swapChainDesc.Format = DXGI_FORMAT_R8G8B8A8_UNORM; // This is the most common swap chain format. swapChainDesc.Stereo = false; swapChainDesc.SampleDesc.Count = 1; // Don't use multi-sampling. swapChainDesc.SampleDesc.Quality = 0; swapChainDesc.BufferUsage = DXGI_USAGE_RENDER_TARGET_OUTPUT; swapChainDesc.BufferCount = BACK_BUFFER_COUNT; // Use triple-buffering to minimize latency. swapChainDesc.SwapEffect = DXGI_SWAP_EFFECT_FLIP_DISCARD; // All Windows Universal apps must use _FLIP_ SwapEffects swapChainDesc.Flags = 0; swapChainDesc.Scaling = DXGI_SCALING_NONE; swapChainDesc.AlphaMode = DXGI_ALPHA_MODE_UNSPECIFIED; DXGI_SWAP_CHAIN_FULLSCREEN_DESC swapChainFullScreenDesc = {}; ZeroMemory(&swapChainFullScreenDesc, sizeof(swapChainFullScreenDesc)); swapChainFullScreenDesc.Windowed = !mIsFullScreen; swapChainFullScreenDesc.Scaling = DXGI_MODE_SCALING_UNSPECIFIED; swapChainFullScreenDesc.ScanlineOrdering = DXGI_MODE_SCANLINE_ORDER_UNSPECIFIED; if (mUseVsync) { swapChainFullScreenDesc.RefreshRate.Numerator = numerator; swapChainFullScreenDesc.RefreshRate.Denominator = denominator; } else { swapChainFullScreenDesc.RefreshRate.Numerator = 0; swapChainFullScreenDesc.RefreshRate.Denominator = 1; } IDXGISwapChain1 *swapChain = NULL; Direct3DUtils::ThrowIfHRESULTFailed( mDXGIFactory->CreateSwapChainForHwnd( mContextManager->GetQueueManager()->GetGraphicsQueue()->GetCommandQueue(), windowHandle, &swapChainDesc, &swapChainFullScreenDesc, NULL, &swapChain ) ); Direct3DUtils::ThrowIfHRESULTFailed(swapChain->QueryInterface(__uuidof(IDXGISwapChain3), (void**)&mSwapChain)); } Direct3DUtils::ThrowIfHRESULTFailed(mSwapChain->SetRotation(displayRotation)); BuildSwapChainDependentResources(); // Set the 3D rendering viewport to target the entire window. mScreenViewport = { 0.0f, 0.0f, mOutputSize.X, mOutputSize.Y, 0.0f, 1.0f }; WaitForGPU(); }
void DXRenderer::InitializeDX(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 = 60, denominator = 1, stringLength; DXGI_MODE_DESC* displayModeList; DXGI_ADAPTER_DESC adapterDesc; int error; DXGI_SWAP_CHAIN_DESC swapChainDesc; 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_fScreenDepth = _screenDepth; m_fScreenNear = _screenNear; // Store the vsync setting. m_bVSyncEnabled = _vsync; // Create a DirectX graphics interface factory. result = CreateDXGIFactory(__uuidof(IDXGIFactory), (void**)&factory); if (FAILED(result)) { //return false; std::cout << "Error creating DXGIFactory" << std::endl; } // 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; } // Store the dedicated video card memory in megabytes. m_iVideoCardMemory = (int)(adapterDesc.DedicatedVideoMemory / 1024 / 1024); // Convert the name of the video card to a character array and store it. error = wcstombs_s(&stringLength, m_sVideoCardDescription, 128, adapterDesc.Description, 128); if (error != 0) { //return false; } std::cout << "Video Card: " << m_sVideoCardDescription << std::endl; //Ora si possono liberare tutti gli oggetti e strutture create per ottenere le informazioni sulla scheda video e refresh rate // 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; //Ora inizializziamo DirectX! //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_bVSyncEnabled) { swapChainDesc.BufferDesc.RefreshRate.Numerator = numerator; swapChainDesc.BufferDesc.RefreshRate.Denominator = denominator; } else { 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; } //Proviamo senza questa roba avanzata // 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; D3D_FEATURE_LEVEL featureLevel[] = { // TODO: Modify for supported Direct3D feature levels (see code below related to 11.1 fallback handling) D3D_FEATURE_LEVEL_11_1, D3D_FEATURE_LEVEL_11_0, D3D_FEATURE_LEVEL_10_1, D3D_FEATURE_LEVEL_10_0, D3D_FEATURE_LEVEL_9_3, D3D_FEATURE_LEVEL_9_2, D3D_FEATURE_LEVEL_9_1, }; D3D_DRIVER_TYPE driverTypes[] = { D3D_DRIVER_TYPE_HARDWARE, D3D_DRIVER_TYPE_REFERENCE, D3D_DRIVER_TYPE_SOFTWARE, }; UINT numDriverTypes = sizeof(driverTypes) / sizeof(driverTypes[0]); D3D_DRIVER_TYPE g_driverType; for (UINT driverTypeIndex = 0; driverTypeIndex < numDriverTypes; ++driverTypeIndex) { // Prova ad inizializzare per i tipi di driver definiti g_driverType = driverTypes[driverTypeIndex]; //result = D3D11CreateDevice(nullptr, g_driverType, nullptr, 0, nullptr, 0, D3D11_SDK_VERSION, &m_device, nullptr, &m_deviceContext); result = D3D11CreateDeviceAndSwapChain(nullptr, g_driverType, nullptr, 0, nullptr, 0, D3D11_SDK_VERSION, &swapChainDesc, &m_dSwapChain, &m_dDevice, nullptr, &m_dDeviceContext); // Appena funziona esci if (SUCCEEDED(result)) break; } if (FAILED(result)) { //return false; std::cout << "Error creating SwapChain" << std::endl; } else std::cout << "DirectX SwapChain created successfully." << std::endl; //D3D_FEATURE_LEVEL featureLevel = D3D_FEATURE_LEVEL_11_0; //Creiamo la swapchain, il device e il 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_dSwapChain->GetBuffer(0, __uuidof(ID3D11Texture2D), (LPVOID*)&backBufferPtr); if (FAILED(result)) { //return false; std::cout << "Error creating backbuffer" << std::endl; } // Create the render target view with the back buffer pointer. result = m_dDevice->CreateRenderTargetView(backBufferPtr, NULL, &m_dRenderTargetView); if (FAILED(result)) { //return false; std::cout << "Error creating Render Target View" << std::endl; } // Release pointer to the back buffer as we no longer need it. 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 texture for the depth buffer using the filled out description. result = m_dDevice->CreateTexture2D(&depthBufferDesc, NULL, &m_dDepthStencilBuffer); 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 = m_dDevice->CreateDepthStencilState(&depthStencilDesc, &m_dDepthStencilState); if (FAILED(result)) { //return false; std::cout << "Error creating Depth Stencil State" << std::endl; } // Set the depth stencil state. m_dDeviceContext->OMSetDepthStencilState(m_dDepthStencilState, 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_dDevice->CreateDepthStencilView(m_dDepthStencilBuffer, &depthStencilViewDesc, &m_dDepthStencilView); if (FAILED(result)) { //return false; std::cout << "Error creating Depth Stencil View" << std::endl; } // Bind the render target view and depth stencil buffer to the output render pipeline. m_dDeviceContext->OMSetRenderTargets(1, &m_dRenderTargetView, m_dDepthStencilView); // 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_dDevice->CreateRasterizerState(&rasterDesc, &m_dRasterState); if (FAILED(result)) { //return false; } // Now set the rasterizer state. m_dDeviceContext->RSSetState(m_dRasterState); // 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_dDeviceContext->RSSetViewports(1, &viewport); // Setup the projection matrix. fieldOfView = (float)DirectX::XM_PI / 4.0f; screenAspect = (float)_screenWidth / (float)_screenHeight; //Create constant buffer for the vertex shader D3D11_BUFFER_DESC cbDesc; ZeroMemory(&cbDesc, sizeof(D3D11_BUFFER_DESC)); cbDesc.Usage = D3D11_USAGE_DEFAULT; cbDesc.ByteWidth = sizeof(GFX::ConstantObject); cbDesc.BindFlags = D3D11_BIND_CONSTANT_BUFFER; cbDesc.CPUAccessFlags = 0; cbDesc.MiscFlags = 0; D3D11_SAMPLER_DESC sampDesc; ZeroMemory(&sampDesc, sizeof(sampDesc)); sampDesc.Filter = D3D11_FILTER_MIN_MAG_MIP_LINEAR; sampDesc.AddressU = D3D11_TEXTURE_ADDRESS_WRAP; sampDesc.AddressV = D3D11_TEXTURE_ADDRESS_WRAP; sampDesc.AddressW = D3D11_TEXTURE_ADDRESS_WRAP; sampDesc.ComparisonFunc = D3D11_COMPARISON_NEVER; sampDesc.MinLOD = 0; sampDesc.MaxLOD = D3D11_FLOAT32_MAX; m_dDevice->CreateSamplerState(&sampDesc, &m_dSamplerState); m_dDevice->CreateBuffer(&cbDesc, NULL, &m_bConstObj); m_dDeviceContext->VSSetConstantBuffers(0, 1, &m_bConstObj); std::cout << "DirectX initialized successfully." << std::endl; }
bool D3DRenderer::CreateSwapChain(int screenWidth, int screenHeight, HWND hwnd) { //Get refresh rate, display modes, and initialize the swap chain. HRESULT result; IDXGIDevice* dxgiDevice = 0; IDXGIFactory* dxgiFactory =0; IDXGIAdapter* dxgiAdapter =0; IDXGIOutput* dxgiAdapterOutput; unsigned int numModes, i, numerator, denominator, stringLength; DXGI_MODE_DESC* displayModeList; DXGI_ADAPTER_DESC adapterDesc; int error; DXGI_SWAP_CHAIN_DESC swapChainDesc; this->m_device->QueryInterface(__uuidof(IDXGIDevice), (void**)&dxgiDevice); dxgiDevice->GetParent(__uuidof(IDXGIAdapter), (void**)&dxgiAdapter); dxgiAdapter->GetParent(__uuidof(IDXGIFactory), (void**)&dxgiFactory); result = dxgiFactory->EnumAdapters(0, &dxgiAdapter); if (FAILED(result)) { return false; } result = dxgiAdapter->EnumOutputs(0, &dxgiAdapterOutput); if (FAILED(result)) { return false; } result = dxgiAdapterOutput->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 = dxgiAdapterOutput->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 = dxgiAdapter->GetDesc(&adapterDesc); if (FAILED(result)) { return false; } this->m_videoCardMemory = (int)(adapterDesc.DedicatedVideoMemory / 1024 / 1024); error = wcstombs_s(&stringLength, this->m_videoCardDescription, 128, adapterDesc.Description, 128); if (error != 0) { return false; } //Initialize the swap chain ZeroMemory(&swapChainDesc, sizeof(swapChainDesc)); //Single buffer count swapChainDesc.BufferCount = 1; swapChainDesc.BufferDesc.Width = screenWidth; swapChainDesc.BufferDesc.Height = screenHeight; //Using regular 32bit back buffer swapChainDesc.BufferDesc.Format = DXGI_FORMAT_R8G8B8A8_UNORM; if (this->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 swapChainDesc.BufferUsage = DXGI_USAGE_RENDER_TARGET_OUTPUT; swapChainDesc.OutputWindow = hwnd; //Turn multisamping off. This setting is for MSAA, for our purposes we don't need it. swapChainDesc.SampleDesc.Count = 1; swapChainDesc.SampleDesc.Quality = 0; swapChainDesc.Windowed = true; //Set the scan line ordering swapChainDesc.BufferDesc.ScanlineOrdering = DXGI_MODE_SCANLINE_ORDER_UNSPECIFIED; swapChainDesc.BufferDesc.Scaling = DXGI_MODE_SCALING_UNSPECIFIED; //Tells D3D to discard the back buffer after presenting swapChainDesc.SwapEffect = DXGI_SWAP_EFFECT_DISCARD; //Do not use advanced flags. swapChainDesc.Flags = 0; //Create the swap chain result = dxgiFactory->CreateSwapChain(this->m_device, &swapChainDesc, &this->m_swapChain); if (FAILED(result)) { return false; } delete [] displayModeList; displayModeList = 0; dxgiAdapterOutput->Release(); dxgiAdapterOutput = 0; dxgiAdapter->Release(); dxgiAdapter = 0; dxgiFactory->Release(); dxgiFactory = 0; return true; }
bool CD3D11Driver::init(SCreationParameters& createParam) { HRESULT result; IDXGIFactory* factory; IDXGIAdapter* adapter; IDXGIOutput* adapterOutput; unsigned int numModes, i, numerator = 0, denominator = 1, stringLength; DXGI_MODE_DESC* displayModeList; DXGI_ADAPTER_DESC adapterDesc; int error; D3D11_TEXTURE2D_DESC depthBufferDesc; //D3D11_DEPTH_STENCIL_DESC depthStencilDesc; //D3D11_DEPTH_STENCIL_VIEW_DESC depthStencilViewDesc; //D3D11_RASTERIZER_DESC rasterDesc; //D3D11_VIEWPORT viewport; //const SCreationParameters& params = mDevice->getCreationParameters(); // Create a DirectX graphics interface factory. mBackBufferWidth = createParam.BackBufferWidth; mBackBufferHeight = createParam.BackBufferHeight; 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)createParam.BackBufferWidth) { if (displayModeList[i].Height == (unsigned int)createParam.BackBufferHeight) { 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; } // Store the dedicated video card memory in megabytes. mVideoCardMemory = (int)(adapterDesc.DedicatedVideoMemory / 1024 / 1024); // Convert the name of the video card to a character array and store it. error = wcstombs_s(&stringLength, mVideoCardDescription, 128, adapterDesc.Description, 128); if (error != 0) { 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; UINT createDeviceFlags = 0; #if defined(DEBUG) || defined(_DEBUG) createDeviceFlags |= D3D11_CREATE_DEVICE_DEBUG; #endif D3D_FEATURE_LEVEL featureLevel; /* 如果将这个标志设为DEBUG,则绘制效率大大降低,且帧频极不稳定 */ //createDeviceFlags = 0; HRESULT hr; hr = D3D11CreateDevice(NULL, D3D_DRIVER_TYPE_HARDWARE, NULL, createDeviceFlags, 0, 0, D3D11_SDK_VERSION, &md3dDevice, &featureLevel, &md3dDeviceContext); if (FAILED(hr)) return false; #if defined(DEBUG) || defined(_DEBUG) md3dDevice->QueryInterface(__uuidof(ID3D11Debug), reinterpret_cast<void**>(&md3dDebug)); #endif if (featureLevel != D3D_FEATURE_LEVEL_11_0) { throw std::runtime_error("DirectX11 is not supported!"); return false; } UINT numQualityLevels; md3dDevice->CheckMultisampleQualityLevels(DXGI_FORMAT_R8G8B8A8_UNORM, 4, &numQualityLevels); IDXGIDevice* dxgiDevice = 0; md3dDevice->QueryInterface(__uuidof(IDXGIDevice), (void**)&dxgiDevice); IDXGIAdapter* dxgiAdapter = 0; dxgiDevice->GetParent(__uuidof(IDXGIAdapter), (void**)&dxgiAdapter); IDXGIFactory* dxgiFactory = 0; dxgiAdapter->GetParent(__uuidof(IDXGIFactory), (void**)&dxgiFactory); DXGI_SWAP_CHAIN_DESC swapChainDesc; // Initialize the swap chain description. ZeroMemory(&swapChainDesc, sizeof(swapChainDesc)); // Set the width and height of the back buffer. swapChainDesc.BufferDesc.Width = createParam.BackBufferWidth; swapChainDesc.BufferDesc.Height = createParam.BackBufferHeight; // 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 (createParam.VsyncEnabled) { swapChainDesc.BufferDesc.RefreshRate.Numerator = numerator; swapChainDesc.BufferDesc.RefreshRate.Denominator = denominator; } else { swapChainDesc.BufferDesc.RefreshRate.Numerator = 0; swapChainDesc.BufferDesc.RefreshRate.Denominator = 1; } // Set multisampling. if (createParam.MultiSamplingQuality == 0) { swapChainDesc.SampleDesc.Count = 1; swapChainDesc.SampleDesc.Quality = 0; createParam.MultiSamplingCount = 1; } else { swapChainDesc.SampleDesc.Count = createParam.MultiSamplingCount; UINT numQualityLevels; md3dDevice->CheckMultisampleQualityLevels(DXGI_FORMAT_R8G8B8A8_UNORM, 4, &numQualityLevels); swapChainDesc.SampleDesc.Quality = min(numQualityLevels - 1, createParam.MultiSamplingQuality); createParam.MultiSamplingQuality = swapChainDesc.SampleDesc.Quality; } // set member attributes of class // Set to a single back buffer. swapChainDesc.BufferCount = 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)createParam.BackBufferWindowHandle; // Set to full screen or windowed mode. if (createParam.WindowStyle & EWS_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; hr = dxgiFactory->CreateSwapChain(md3dDevice, &swapChainDesc, &md3dSwapChain); if (FAILED(hr)) return false; ReleaseCOM(dxgiDevice); ReleaseCOM(dxgiAdapter); ReleaseCOM(dxgiFactory); // Get the pointer to the back buffer. ID3D11Texture2D* backBuffer; result = md3dSwapChain->GetBuffer(0, __uuidof(ID3D11Texture2D), (LPVOID*)&backBuffer); if (FAILED(result)) { return false; } md3dDevice->CreateRenderTargetView(backBuffer, 0, &mDefaultRenderTargetView); ReleaseCOM(backBuffer); mDefaultRenderTarget = new CD3D11RenderTarget(md3dDevice, md3dDeviceContext, mDefaultRenderTargetView, createParam.BackBufferWidth, createParam.BackBufferHeight); // Initialize the description of the depth buffer. ZeroMemory(&depthBufferDesc, sizeof(depthBufferDesc)); // Setup the viewport for rendering. setViewport(0, 0, static_cast<f32>(mBackBufferWidth), static_cast<f32>(mBackBufferHeight)); //create resource factory mResourceFactory = new CD3D11ResourceFactory( md3dDevice, md3dDeviceContext, this); IResourceFactory::_setInstance(mResourceFactory); //create geometry creator mGeometryCreator = new CGeometryCreator; IGeometryCreator::_setInstance(mGeometryCreator); //create material manager mMaterialManager = new CMaterialManager; IMaterialManager::_setInstance(mMaterialManager); //create sampler manager mSamplerManager = new CSamplerManager(mResourceFactory); ISamplerManager::_setInstance(mSamplerManager); // create shadermanager mShaderManager = new CShaderManager(mResourceFactory); IShaderManager::_setInstance(mShaderManager); // create inputlayout manager mInputLayoutManager = new CInputLayoutManager(mResourceFactory); IInputLayoutManager::_setInstance(mInputLayoutManager); //create texture manager mTextureManager = new CTextureManager(mDevice, mResourceFactory); ITextureManager::_setInstance(mTextureManager); //create render state manager mRenderStateManager = new CRenderStateManager(mResourceFactory); IRenderStateManager::_setInstance(mRenderStateManager); //create mesh manager mMeshManager = new CMeshManager(mResourceFactory, mGeometryCreator, mTextureManager); IMeshManager::_setInstance(mMeshManager); //create pipeline manager mPipeManager = new CPipelineManager(mResourceFactory); IPipelineManager::_setInstance(mPipeManager); //create resource group manager mResourceGroupManager = new CResourceGroupManager(mTextureManager, mShaderManager, mInputLayoutManager, mRenderStateManager, mPipeManager, mMaterialManager, mMeshManager, mSamplerManager); IResourceGroupManager::_setInstance(mResourceGroupManager); //mResourceFactory->setResourceGroupManager(mResourceGroupManager); // create default depth-stencil-buffer bool multiSampling = (createParam.MultiSamplingCount > 1); mDepthStencilSurface = mTextureManager->createDepthStencilSurface("_default_depth_stencil_surface", 0, 0, createParam.DepthBits, createParam.StencilBits, multiSampling, createParam.MultiSamplingCount, createParam.MultiSamplingQuality, true); if (!mDepthStencilSurface) { GF_PRINT_CONSOLE_INFO("Depth Stencil Surface has failed to be created.\n"); return false; } D3D11DriverState.DepthStencilSurface = mDepthStencilSurface; CD3D11DepthStencilSurface* d3dDepthStencilSurface = dynamic_cast<CD3D11DepthStencilSurface*>(mDepthStencilSurface); mDefaultDepthStencilView = d3dDepthStencilSurface->getDepthStencilView(); D3D11DriverState.DepthStencilView = mDefaultDepthStencilView; // create mShadowMapRasterizeState. This state is only for rendering shadow maps. D3D11_RASTERIZER_DESC shadowRasterizeState; shadowRasterizeState.FillMode = D3D11_FILL_SOLID; shadowRasterizeState.CullMode = D3D11_CULL_BACK; // RENDER BACK FACE shadowRasterizeState.FrontCounterClockwise = TRUE; shadowRasterizeState.DepthBiasClamp = 0.0f; //shadowRasterizeState.DepthBias = 100000; //shadowRasterizeState.SlopeScaledDepthBias = 1.0f; shadowRasterizeState.DepthBias = 0; shadowRasterizeState.SlopeScaledDepthBias = 0; shadowRasterizeState.DepthClipEnable = TRUE; shadowRasterizeState.ScissorEnable = FALSE; shadowRasterizeState.MultisampleEnable = FALSE; shadowRasterizeState.AntialiasedLineEnable = FALSE; hr = md3dDevice->CreateRasterizerState(&shadowRasterizeState, &mShadowMapRasterizeState); if (FAILED(hr)) return false; D3D11DriverState.ShadowMapRasterizerState = mShadowMapRasterizeState; 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; // 保存垂直同步设置 m_vsync_enabled = vsync; // 创建一个DirectX graphics 接口工厂 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; //得到适合 DXGI_FORMAT_R8G8B8A8_UNORM 的显示模式 result = adapterOutput->GetDisplayModeList(DXGI_FORMAT_R8G8B8A8_UNORM, DXGI_ENUM_MODES_INTERLACED, &numModes, nullptr); if(FAILED(result)) return false; displayModeList = new DXGI_MODE_DESC[numModes]; if(!displayModeList) return false; // 保存显示模式到displayModeList中 result = adapterOutput->GetDisplayModeList(DXGI_FORMAT_R8G8B8A8_UNORM, DXGI_ENUM_MODES_INTERLACED, &numModes, displayModeList); if(FAILED(result)) return false; // 遍历所有显示模式,得到刷新率两个参数值numerator 和 denominator for (int i = 0; i < numModes; i++) { if(displayModeList[i].Width == screenWidth) { 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 = nullptr; //释放适配器输出 adapterOutput->Release(); adapterOutput = nullptr; //释放适配器 adapter->Release(); adapter = nullptr; //释放接口工厂 factory->Release(); factory = nullptr; //初始化交换链描述 ZeroMemory(&swapChainDesc, sizeof(swapChainDesc)); // 用1个后缓冲 swapChainDesc.BufferCount = 1; // 帧缓冲的大小和应用程序窗口大小相等 swapChainDesc.BufferDesc.Width = screenWidth; swapChainDesc.BufferDesc.Height = screenHeight; // 后缓冲的surface的格式为DXGI_FORMAT_R8G8B8A8_UNORM 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; // 设定扫描线ordering以及缩放为unspecified swapChainDesc.BufferDesc.ScanlineOrdering = DXGI_MODE_SCANLINE_ORDER_UNSPECIFIED; swapChainDesc.BufferDesc.Scaling = DXGI_MODE_SCALING_UNSPECIFIED; // 后缓冲内容呈现到屏幕后,放弃其内容 swapChainDesc.SwapEffect = DXGI_SWAP_EFFECT_DISCARD; //不设置标志 swapChainDesc.Flags = 0; // 设置feature level为D3D11 // 如果显卡不支持D3D11,我们能够通过设置这个参数,使用D3D10,或者9 featureLevel = D3D_FEATURE_LEVEL_11_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)) return false; // 得到交换链中的后缓冲指针 result = m_swapChain->GetBuffer(0, __uuidof(ID3D11Texture2D), (void**)&backBufferPtr); if(FAILED(result)) return false; // 用后缓冲创建渲染目标视图 result = m_device->CreateRenderTargetView(backBufferPtr, nullptr, &m_renderTargetView); if(FAILED(result)) return false; //释放后缓冲(引用计数减1) backBufferPtr->Release(); backBufferPtr = nullptr; // 初始化深度缓冲描述 ZeroMemory(&depthBufferDesc, sizeof(depthBufferDesc)); //设置深度缓冲描述 depthBufferDesc.Width = screenWidth; depthBufferDesc.Height = screenHeight; depthBufferDesc.MipLevels = 1; //对于深度缓冲为1 depthBufferDesc.ArraySize = 1; //对于深度缓冲为1,对于纹理,这2个参数有更多用途 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, nullptr, &m_depthStencilBuffer); if(FAILED(result)) return false; // 初始化深度模版状态描述 ZeroMemory(&depthStencilDesc, sizeof(depthStencilDesc)); // 设置深度模版状态描述 depthStencilDesc.DepthEnable = true; depthStencilDesc.DepthWriteMask = D3D11_DEPTH_WRITE_MASK_ALL; // D3D11_DEPTH_WRITE_MASK_ZERO禁止写深度缓冲 depthStencilDesc.DepthFunc = D3D11_COMPARISON_LESS; depthStencilDesc.StencilEnable = true; depthStencilDesc.StencilReadMask = 0xFF; depthStencilDesc.StencilWriteMask = 0xFF; // 对于front face 像素使用的模版操作操作 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; // 对于back face像素使用的模版操作模式 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 = 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.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); //初始化world矩阵为单位矩阵 //该矩阵实现局部坐标到世界坐标的转换 D3DXMatrixIdentity(&m_worldMatrix); // 创建正交投影矩阵,主要用来实施2D渲染 D3DXMatrixOrthoLH(&m_orthoMatrix, (float)screenWidth, (float)screenHeight, screenNear, screenDepth); return true; }
void D3D11::init( int screenWidth, int screenHeight, bool vsync, HWND hwnd, bool fullscreen, float screenDepth, float screenNear ) { m_vsyncEnabled = vsync; m_isWindows = fullscreen; IDXGIFactory * pfactory; if(FAILED(CreateDXGIFactory(__uuidof(IDXGIFactory),(void**)&pfactory))) return; IDXGIAdapter * pAdapter; if(FAILED(pfactory->EnumAdapters(0,&pAdapter))) return; IDXGIOutput * out; if(FAILED(pAdapter->EnumOutputs(0,&out))) return; int numModes; DXGI_MODE_DESC * displaymodeList; if(FAILED(out->GetDisplayModeList(DXGI_FORMAT_R8G8B8A8_UNORM,DXGI_ENUM_MODES_INTERLACED,&numModes,NULL))) return; displaymodeList = new DXGI_MODE_DESC[numModes]; if(FAILED(out->GetDisplayModeList(DXGI_FORMAT_R8G8B8A8_UNORM,DXGI_ENUM_MODES_INTERLACED,&numModes,displaymodeList))) return; int numerator,denomerator; for(int i = 0; i < numModes; ++i) { if(displaymodeList[i].Height == screenHeight && displaymodeList[i].Width == screenWidth) { numerator = displaymodeList[i].RefreshRate.Numerator; denomerator = displaymodeList[i].RefreshRate.Denominator; } } DXGI_ADAPTER_DESC desc; if(FAILED(pAdapter->GetDesc(&desc))) return; int length; m_videoCardMemory = static_cast<int>(desc.DedicatedVideoMemory/1024/1024); wcstombs_s(&length,m_videoCardDescription,128,desc.Description,128); delete[] displaymodeList; displaymodeList = NULL; out->Release(); out = NULL; pAdapter->Release(); pAdapter = NULL; pfactory->Release(); pfactory = NULL; DXGI_SWAP_CHAIN_DESC swapChainDesc; ZeroMemory(&swapChainDesc,sizeof(DXGI_SWAP_CHAIN_DESC)); swapChainDesc.BufferCount = 1; swapChainDesc.BufferDesc.Width = screenWidth; swapChainDesc.BufferDesc.Height = screenHeight; swapChainDesc.BufferDesc.Format = DXGI_FORMAT_R8G8B8A8_UNORM; if(m_vsyncEnabled) { swapChainDesc.BufferDesc.RefreshRate.Numerator = numerator; swapChainDesc.BufferDesc.RefreshRate.Denominator = denomerator; } else { swapChainDesc.BufferDesc.RefreshRate.Denominator = 1; swapChainDesc.BufferDesc.RefreshRate.Numerator = 0; } swapChainDesc.Windowed = m_isWindows; swapChainDesc.BufferDesc.ScanlineOrdering = DXGI_MODE_SCANLINE_ORDER_UNSPECIFIED; swapChainDesc.BufferDesc.Scaling = DXGI_MODE_SCALING_UNSPECIFIED; swapChainDesc.SwapEffect = DXGI_SWAP_EFFECT_DISCARD; D3D_FEATURE_LEVEL level = D3D_FEATURE_LEVEL_11_0; if(FAILED(D3D11CreateDeviceAndSwapChain(NULL,D3D_DRIVER_TYPE_HARDWARE,NULL,0, &level,1,D3D11_SDK_VERSION,&swapChainDesc,&m_swapChain,&m_device,NULL,&m_deviceContext))) return; ID3D11Texture2D *backbufferTex; if(FAILED(m_swapChain->GetBuffer(0,__uuidof(ID3D11Texture2D),(LPVOID*)&backbufferTex))) return; if(FAILED(m_device->CreateRenderTargetView(backbufferTex,NULL,&m_renderView))) return; backbufferTex->Release(); backbufferTex = 0; D3D11_TEXTURE2D_DESC depthBufferDesc; 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; if(FAILED(m_device->CreateTexture2D(&depthBufferDesc, NULL, &m_depthStencilBuffer))) return ; D3D11_DEPTH_STENCIL_DESC depthStencilDesc; // 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. if(FAILED(m_device->CreateDepthStencilState(&depthStencilDesc, &m_depthStencilState))) return; // Set the depth stencil state. m_deviceContext->OMSetDepthStencilState(m_depthStencilState, 1); D3D11_DEPTH_STENCIL_VIEW_DESC depthStencilViewDesc; // 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. if(FAILED(m_device->CreateDepthStencilView(m_depthStencilBuffer, &depthStencilViewDesc, &m_depthStencilView))) return ; // Bind the render target view and depth stencil buffer to the output render pipeline. m_deviceContext->OMSetRenderTargets(1, &m_renderView, m_depthStencilView); D3D11_RASTERIZER_DESC rasterDesc; // 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. if(FAILED(m_device->CreateRasterizerState(&rasterDesc, &m_rasterState))) return ; // Now set the rasterizer state. m_deviceContext->RSSetState(m_rasterState); D3D11_VIEWPORT viewport; // 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); float fieldOfView, screenAspect; // Setup the projection matrix. fieldOfView = (float)D3DX_PI / 4.0f; screenAspect = (float)screenWidth / (float)screenHeight; // Create the projection matrix for 3D rendering. D3DXMatrixPerspectiveFovLH(&m_projMat, fieldOfView, screenAspect, screenNear, screenDepth); // Initialize the world matrix to the identity matrix. D3DXMatrixIdentity(&m_worldMat); // Create an orthographic projection matrix for 2D rendering. D3DXMatrixOrthoLH(&m_orthoMat, (float)screenWidth, (float)screenHeight, screenNear, screenDepth); }
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); // Create rasterizer state with wireframe fill mode. D3D11_RASTERIZER_DESC rasterWireframeDesc; rasterWireframeDesc.AntialiasedLineEnable = false; rasterWireframeDesc.CullMode = D3D11_CULL_BACK; rasterWireframeDesc.DepthBias = 0; rasterWireframeDesc.DepthBiasClamp = 0.0f; rasterWireframeDesc.DepthClipEnable = true; rasterWireframeDesc.FillMode = D3D11_FILL_WIREFRAME; rasterWireframeDesc.FrontCounterClockwise = false; rasterWireframeDesc.MultisampleEnable = false; rasterWireframeDesc.ScissorEnable = false; rasterWireframeDesc.SlopeScaledDepthBias = 0.0; result = m_device->CreateRasterizerState(&rasterWireframeDesc, &m_rasterStateWireframe); if(FAILED(result)) return false; // 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; }
bool RenderSystem::init(void* windowHandle, const InitParams& params) { IDXGIFactory1* factory = 0; IDXGIOutput* output = 0; DXGI_MODE_DESC modeDesc; ::ZeroMemory(&modeDesc, sizeof(DXGI_MODE_DESC)); modeDesc.Format = params.srgbTarget ? DXGI_FORMAT_R8G8B8A8_UNORM_SRGB : DXGI_FORMAT_R8G8B8A8_UNORM; modeDesc.Width = params.width; modeDesc.Height = params.height; if (SUCCEEDED(CreateDXGIFactory1(__uuidof(IDXGIFactory1), (void**)&factory))) { IDXGIAdapter1* adapter = 0; for (UINT i = 0; factory->EnumAdapters1(i, &adapter) != DXGI_ERROR_NOT_FOUND; ++i) { if (adapter->CheckInterfaceSupport(__uuidof(ID3D11Device), NULL)) break; adapter->Release(); } D3D_FEATURE_LEVEL supportedFeatureLevels[] = { D3D_FEATURE_LEVEL_11_0, }; UINT flags = 0; #if defined (_DEBUG) flags |= D3D11_CREATE_DEVICE_DEBUG; #endif // _DEBUG if (adapter) { if (SUCCEEDED(D3D11CreateDevice(adapter, D3D_DRIVER_TYPE_UNKNOWN, NULL, flags, supportedFeatureLevels, _countof(supportedFeatureLevels), D3D11_SDK_VERSION, &m_device, NULL, &m_renderContext))) { for (UINT i = 0; adapter->EnumOutputs(i, &output) != DXGI_ERROR_NOT_FOUND; ++i) { if (SUCCEEDED(output->FindClosestMatchingMode(&modeDesc, &modeDesc, m_device))) { // additional checks?? break; } output->Release(); output = 0; } /*if (output) output->Release();*/ } adapter->Release(); } if (m_device) { DXGI_SWAP_CHAIN_DESC sd; ::ZeroMemory(&sd, sizeof(DXGI_SWAP_CHAIN_DESC)); sd.BufferCount = 1; sd.BufferDesc = modeDesc; sd.BufferUsage = D3D11_BIND_RENDER_TARGET; sd.Flags = 0; sd.OutputWindow = (HWND)windowHandle; sd.SampleDesc.Quality = 0; sd.SampleDesc.Count = 1; sd.SwapEffect = DXGI_SWAP_EFFECT_DISCARD; sd.Windowed = TRUE; if (params.msaaSamples > 0) { UINT numLevels = 0; if (SUCCEEDED(m_device->CheckMultisampleQualityLevels(modeDesc.Format, params.msaaSamples, &numLevels)) && numLevels > 0) { sd.SampleDesc.Quality = numLevels-1; sd.SampleDesc.Count = params.msaaSamples; } else { printf("multisample quality not supported"); } } VALIDATE(factory->CreateSwapChain(m_device, &sd, &m_swapChain)); } if (params.fullscreen) { m_isFullScreen = SUCCEEDED(m_swapChain->SetFullscreenState(TRUE, output)); } // setup debug queue factory->MakeWindowAssociation((HWND)windowHandle, DXGI_MWA_NO_ALT_ENTER | DXGI_MWA_NO_WINDOW_CHANGES); if (output) output->Release(); factory->Release(); } m_stateCache = new PipelineStateCache(m_renderContext); createFrameBuffer(); initDefaultResources(); return (m_device && m_swapChain); }
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; }
bool D3DManager::Initialize(int screenWidth, int screenHeight, bool vsync, HWND hwnd, bool fullScreen) { HRESULT result; IDXGIFactory * factory = nullptr; IDXGIAdapter * adapter = nullptr; IDXGIOutput * adapterOutput = nullptr; unsigned int numModes; unsigned int numerator = 0; unsigned int denominator = 0; unsigned int stringLenht; DXGI_MODE_DESC * displayModeList = nullptr; DXGI_ADAPTER_DESC adapterDesc; int error; ID3D11Texture2D * backBuffer = nullptr; // Guardo el vsycn m_vsync_enable = vsync; // Creo una interfas con DirectX (IDXGIFactory) result = CreateDXGIFactory(__uuidof(IDXGIFactory), (void**)&factory); if (FAILED(result)) { // TODO: Informar del Error return false; } // Uso el IDXGIFactory para crear un adapatador(Placa de Video) result = factory->EnumAdapters(0, &adapter); if (FAILED(result)) { // TODO: Informar del Error return false; } // Enumero la cantidad de monitores (Adaptador de salida) result = adapter->EnumOutputs(0, &adapterOutput); if (FAILED(result)) { // TODO: Informar del Error return false; } // Obtengo el numero de modos que se ajustan al formato DXGI_FORMAT_R8G8B8A8 para el monitor result = adapterOutput->GetDisplayModeList(DXGI_FORMAT_R8G8B8A8_UNORM, DXGI_ENUM_MODES_INTERLACED, &numModes, NULL); if (FAILED(result)) { // TODO: Informar del Error return false; } // Creo una lista con todos los posbles modos para esta combinacion placa de video monitor. displayModeList = new DXGI_MODE_DESC[numModes]; // Cargo la lista de display Mode result = adapterOutput->GetDisplayModeList(DXGI_FORMAT_R8G8B8A8_UNORM, DXGI_ENUM_MODES_INTERLACED, &numModes, displayModeList); if (FAILED(result)) { // TODO: Informar del Error return false; } for (int i = 0; i < (int)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; //TODO: Loquidar el for al encontrar el valor correcto } } if (numerator == 0 && denominator == 0) { // Informar Error return false; } // Obtengo la descripcion del adaptador result = adapter->GetDesc(&adapterDesc); if (FAILED(result)) { // TODO: Informar del Error return false; } // Guardo la cantidad de memorya de video m_videoCardMemory = adapterDesc.DedicatedVideoMemory; // Convierto el nombre de la VGA a string char tmp_string[128]; error = wcstombs_s(&stringLenht, tmp_string, 128, adapterDesc.Description, 128); if (error != 0) { // TODO: Informar del Error return false; } m_videoCardDescription = tmp_string; // Released Memory delete [] displayModeList; displayModeList = nullptr; adapterOutput->Release(); adapterOutput = nullptr; adapter->Release(); adapter = nullptr; factory->Release(); factory = nullptr; if (!InitializeSwapChain(hwnd, fullScreen, screenWidth, screenHeight, numerator, denominator)) { // Todo: Informar El Error return false; } // Obtengo el puntero al BackBuffer result = mp_swapChain->GetBuffer(0, __uuidof(ID3D11Texture2D), (LPVOID*)&backBuffer); if (FAILED(result)) { // TODO: Informar del Error return false; } // Creo el render Target View result = mp_device->CreateRenderTargetView(backBuffer, NULL, &mp_renderTargetView); if (FAILED(result)) { // TODO: Informar del Error return false; } // No te Nesesito MUERE backBuffer->Release(); backBuffer = nullptr; if (!InitializeDepthBuffer(screenWidth, screenHeight)) { // TODO: Informar del Error return false; } if (!InitializeDepthStencilBuffer()) { // TODO: Informar del Error return false; } if (!InitializeStencilView()) { // TODO: Informar del Error return false; } mp_deviceContext->OMSetRenderTargets(1, &mp_renderTargetView, mp_depthStencilView); if (!InitializeRasterizerStete()) { // TODO: Informar del Error return false; } InitializeViewport(screenWidth, screenHeight); if (!InitializeAlphaBlending()) { // TODO: Informar del Error return false; } if (!InitializeZBuffer()) { // TODO: Informar del Error 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 blendStateDescription; // Store the vsync setting. m_vsync_enabled = vsync; // 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; } // 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 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. 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 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 = 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 = 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 = 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); // 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 = 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); // 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)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); // 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. result = m_device->CreateDepthStencilState(&depthDisabledStencilDesc, &m_depthDisabledStencilState); if(FAILED(result)) { return false; } // 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_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; }
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; }