RenderWindow.cpp 4.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152
  1. #include "stdafx.h"
  2. #include "RenderWindow.h"
  3. CRenderWindow::CRenderWindow()
  4. {
  5. }
  6. void CRenderWindow::Start()
  7. {
  8. ZeroMemory(&bmi_, sizeof(bmi_));
  9. bmi_.bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
  10. bmi_.bmiHeader.biPlanes = 1;
  11. bmi_.bmiHeader.biBitCount = 32;
  12. bmi_.bmiHeader.biCompression = BI_RGB;
  13. bmi_.bmiHeader.biWidth = 1280;
  14. bmi_.bmiHeader.biHeight = -720;
  15. bmi_.bmiHeader.biSizeImage =
  16. 1280 * 720 * (bmi_.bmiHeader.biBitCount >> 3);
  17. image_.reset(new uint8_t[bmi_.bmiHeader.biSizeImage]);
  18. m_Thread = std::thread(&CRenderWindow::Run, this);
  19. }
  20. void CRenderWindow::Run()
  21. {
  22. m_bRun = true;
  23. WNDCLASSEX wcex;
  24. wcex.cbSize = sizeof(WNDCLASSEX);
  25. wcex.style = CS_HREDRAW | CS_VREDRAW;
  26. wcex.lpfnWndProc = CRenderWindow::WndProc;
  27. wcex.cbClsExtra = 0;
  28. wcex.cbWndExtra = 0;
  29. wcex.hInstance = GetModuleHandle(nullptr);
  30. wcex.hIcon = 0;
  31. wcex.hCursor = LoadCursor(nullptr, IDC_ARROW);
  32. wcex.hbrBackground = (HBRUSH)(COLOR_WINDOW + 1);
  33. wcex.lpszMenuName = NULL;
  34. char cName[MAX_PATH] = { 0 };
  35. GetModuleFileNameA(wcex.hInstance, cName, sizeof(cName));
  36. char* szApp = strrchr(cName, '\\') + 1;
  37. strchr(szApp, '.')[0] = '\0';
  38. wcex.lpszClassName = szApp;
  39. wcex.hIconSm = 0;
  40. RegisterClassEx(&wcex);
  41. m_hWnd = CreateWindow(szApp, nullptr, WS_OVERLAPPED | WS_CAPTION | WS_SYSMENU | WS_THICKFRAME | WS_MINIMIZEBOX | WS_MAXIMIZEBOX, 0, 0, 1280, 720, NULL, NULL, wcex.hInstance, 0);
  42. SetWindowLongPtr(m_hWnd, GWLP_USERDATA, (LONG_PTR)this);
  43. ShowWindow(m_hWnd, SW_SHOW);
  44. UpdateWindow(m_hWnd);
  45. MSG msg;
  46. while (GetMessage(&msg, nullptr, 0, 0))
  47. {
  48. if (msg.message == WM_DESTROY) break;
  49. TranslateMessage(&msg);
  50. DispatchMessage(&msg);
  51. }
  52. }
  53. LRESULT CRenderWindow::WndProc(HWND hWnd, UINT wMsg, WPARAM wParam, LPARAM lParam)
  54. {
  55. switch (wMsg)
  56. {
  57. case WM_PAINT:
  58. {
  59. CRenderWindow* lThis = (CRenderWindow*)(GetWindowLongPtr(hWnd, GWLP_USERDATA));
  60. if (lThis != nullptr)
  61. {
  62. lThis->OnPaint(hWnd);
  63. return 1;
  64. }
  65. }
  66. break;
  67. case WM_DESTROY:
  68. PostQuitMessage(0);
  69. break;
  70. }
  71. return DefWindowProc(hWnd, wMsg, wParam, lParam);
  72. }
  73. void CRenderWindow::OnPaint(HWND hWnd)
  74. {
  75. PAINTSTRUCT ps;
  76. HDC hdc = BeginPaint(hWnd, &ps);
  77. // TODO: Add any drawing code that uses hdc here...
  78. if (start_)
  79. {
  80. RECT rc;
  81. ::GetClientRect(hWnd, &rc);
  82. //const uint8_t* image =
  83. //AutoLock<VideoRenderer> local_lock(renderer);
  84. //const BITMAPINFO& bmi = renderer->bmi();
  85. // std::lock_guard < std::mutex> l(buffer_lock_);
  86. int height = abs(bmi_.bmiHeader.biHeight);
  87. int width = bmi_.bmiHeader.biWidth;
  88. HDC dc_mem = ::CreateCompatibleDC(ps.hdc);
  89. ::SetStretchBltMode(dc_mem, HALFTONE);
  90. HDC all_dc[] = { ps.hdc, dc_mem };
  91. for (size_t i = 0; i < _countof(all_dc); ++i) {
  92. SetMapMode(all_dc[i], MM_ISOTROPIC);
  93. SetWindowExtEx(all_dc[i], width, height, NULL);
  94. SetViewportExtEx(all_dc[i], rc.right, rc.bottom, NULL);
  95. }
  96. HBITMAP bmp_mem = ::CreateCompatibleBitmap(ps.hdc, rc.right, rc.bottom);
  97. HGDIOBJ bmp_old = ::SelectObject(dc_mem, bmp_mem);
  98. POINT logical_area = { rc.right, rc.bottom };
  99. DPtoLP(ps.hdc, &logical_area, 1);
  100. HBRUSH brush = ::CreateSolidBrush(RGB(0, 0, 0));
  101. RECT logical_rect = { 0, 0, logical_area.x, logical_area.y };
  102. ::FillRect(dc_mem, &logical_rect, brush);
  103. ::DeleteObject(brush);
  104. int x = (logical_area.x / 2) - (width / 2);
  105. int y = (logical_area.y / 2) - (height / 2);
  106. StretchDIBits(dc_mem, x, y, width, height, 0, 0, width, height, image_.get(),
  107. &bmi_, DIB_RGB_COLORS, SRCCOPY);
  108. BitBlt(ps.hdc, 0, 0, logical_area.x, logical_area.y, dc_mem, 0, 0,
  109. SRCCOPY);
  110. // Cleanup.
  111. ::SelectObject(dc_mem, bmp_old);
  112. ::DeleteObject(bmp_mem);
  113. ::DeleteDC(dc_mem);
  114. }
  115. EndPaint(hWnd, &ps);
  116. }
  117. void CRenderWindow::OnRender(std::unique_ptr<uint8_t>& pBuffer, int32_t width, int32_t height)
  118. {
  119. SetSize(width, height);
  120. if (pBuffer==nullptr) return;
  121. memcpy(image_.get(), pBuffer.get(), bmi_.bmiHeader.biSizeImage);
  122. ::InvalidateRect(m_hWnd, NULL, FALSE);
  123. }
  124. void CRenderWindow::SetSize(int32_t width, int32_t height)
  125. {
  126. if (width == bmi_.bmiHeader.biWidth && height == -bmi_.bmiHeader.biHeight) {
  127. return;
  128. }
  129. bmi_.bmiHeader.biWidth = width;
  130. bmi_.bmiHeader.biHeight = -height;
  131. bmi_.bmiHeader.biSizeImage =
  132. width * height * (bmi_.bmiHeader.biBitCount >> 3);
  133. image_.reset(new uint8_t[bmi_.bmiHeader.biSizeImage]);
  134. }