CmD3D11VideoModeList.cpp 3.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109
  1. #include "CmD3D11VideoModeList.h"
  2. #include "CmException.h"
  3. #include "CmD3D11VideoMode.h"
  4. #include "CmD3D11Driver.h"
  5. namespace CamelotEngine
  6. {
  7. D3D11VideoModeList::D3D11VideoModeList(D3D11Driver* driver, UINT32 adapterOutput = 0)
  8. {
  9. if(driver == nullptr)
  10. CM_EXCEPT(InvalidParametersException, "driver parameter is NULL");
  11. mDriver = driver;
  12. enumerate(adapterOutput);
  13. }
  14. D3D11VideoModeList::~D3D11VideoModeList()
  15. {
  16. mDriver = NULL;
  17. mModeList.clear();
  18. }
  19. void D3D11VideoModeList::enumerate(UINT32 adapterOutput)
  20. {
  21. UINT adapter = mDriver->getAdapterNumber();
  22. HRESULT hr;
  23. IDXGIOutput* output;
  24. hr = mDriver->getDeviceAdapter()->EnumOutputs(adapterOutput, &output);
  25. if(hr == DXGI_ERROR_NOT_FOUND)
  26. CM_EXCEPT(InvalidParametersException, "Adapter output " + toString(adapterOutput) + " not found!");
  27. if(FAILED(hr))
  28. CM_EXCEPT(InternalErrorException, "Error while enumerating adapter output video modes. Output index: " + toString(adapterOutput));
  29. DXGI_OUTPUT_DESC outputDesc;
  30. output->GetDesc(&outputDesc);
  31. UINT32 numModes = 0;
  32. hr = output->GetDisplayModeList(DXGI_FORMAT_R8G8B8A8_UNORM, 0, &numModes, 0);
  33. if(FAILED(hr))
  34. {
  35. SAFE_RELEASE(output);
  36. CM_EXCEPT(InternalErrorException, "Error while enumerating adapter output video modes. Output index: " + toString(adapterOutput));
  37. }
  38. DXGI_MODE_DESC* modeDesc = new DXGI_MODE_DESC[numModes];
  39. hr = output->GetDisplayModeList(DXGI_FORMAT_R8G8B8A8_UNORM, 0, &numModes, modeDesc);
  40. if(FAILED(hr))
  41. {
  42. SAFE_RELEASE(output);
  43. CM_EXCEPT(InternalErrorException, "Error while enumerating adapter output video modes. Output index: " + toString(adapterOutput));
  44. }
  45. SAFE_RELEASE(output);
  46. for(UINT32 i = 0; i < numModes; i++)
  47. {
  48. DXGI_MODE_DESC displayMode = modeDesc[i];
  49. // Filter out low-resolutions
  50. if(displayMode.Width < 640 || displayMode.Height < 400)
  51. continue;
  52. // Check to see if it is already in the list (to filter out refresh rates)
  53. bool found = false;
  54. for(auto it = mModeList.begin(); it != mModeList.end(); it++)
  55. {
  56. DXGI_MODE_DESC existingMode = it->getModeDesc();
  57. if( existingMode.Width == displayMode.Width &&
  58. existingMode.Height == displayMode.Height &&
  59. existingMode.Format == displayMode.Format &&
  60. existingMode.RefreshRate.Numerator == displayMode.RefreshRate.Numerator &&
  61. existingMode.RefreshRate.Denominator == displayMode.RefreshRate.Denominator
  62. )
  63. {
  64. found = true;
  65. break;
  66. }
  67. }
  68. if(!found)
  69. mModeList.push_back(D3D11VideoMode(outputDesc, displayMode));
  70. }
  71. }
  72. UINT32 D3D11VideoModeList::count() const
  73. {
  74. return (UINT32)mModeList.size();
  75. }
  76. const D3D11VideoMode& D3D11VideoModeList::item(UINT32 idx) const
  77. {
  78. return mModeList.at(idx);
  79. }
  80. const D3D11VideoMode& D3D11VideoModeList::item(const String &name) const
  81. {
  82. for (auto iter = mModeList.begin(); iter != mModeList.end(); ++iter)
  83. {
  84. if (iter->getDescription() == name)
  85. return (*iter);
  86. }
  87. CM_EXCEPT(InvalidParametersException, "Cannot find video mode with the specified name.");
  88. }
  89. }