tinyWinGraphicsWindow.cxx 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305
  1. // Filename: tinyWinGraphicsWindow.cxx
  2. // Created by: drose (06May08)
  3. //
  4. ////////////////////////////////////////////////////////////////////
  5. //
  6. // PANDA 3D SOFTWARE
  7. // Copyright (c) Carnegie Mellon University. All rights reserved.
  8. //
  9. // All use of this software is subject to the terms of the revised BSD
  10. // license. You should have received a copy of this license along
  11. // with this source code in a file named "LICENSE."
  12. //
  13. ////////////////////////////////////////////////////////////////////
  14. #include "pandabase.h"
  15. #ifdef WIN32
  16. #include "tinyWinGraphicsWindow.h"
  17. #include "config_tinydisplay.h"
  18. #include "config_windisplay.h"
  19. #include "tinyWinGraphicsPipe.h"
  20. #include "tinyGraphicsStateGuardian.h"
  21. #include "pStatTimer.h"
  22. #include <wingdi.h>
  23. TypeHandle TinyWinGraphicsWindow::_type_handle;
  24. ////////////////////////////////////////////////////////////////////
  25. // Function: TinyWinGraphicsWindow::Constructor
  26. // Access: Public
  27. // Description:
  28. ////////////////////////////////////////////////////////////////////
  29. TinyWinGraphicsWindow::
  30. TinyWinGraphicsWindow(GraphicsEngine *engine, GraphicsPipe *pipe,
  31. const string &name,
  32. const FrameBufferProperties &fb_prop,
  33. const WindowProperties &win_prop,
  34. int flags,
  35. GraphicsStateGuardian *gsg,
  36. GraphicsOutput *host) :
  37. WinGraphicsWindow(engine, pipe, name, fb_prop, win_prop, flags, gsg, host)
  38. {
  39. _frame_buffer = NULL;
  40. _hdc = (HDC)0;
  41. update_pixel_factor();
  42. }
  43. ////////////////////////////////////////////////////////////////////
  44. // Function: TinyWinGraphicsWindow::Destructor
  45. // Access: Public, Virtual
  46. // Description:
  47. ////////////////////////////////////////////////////////////////////
  48. TinyWinGraphicsWindow::
  49. ~TinyWinGraphicsWindow() {
  50. }
  51. ////////////////////////////////////////////////////////////////////
  52. // Function: TinyWinGraphicsWindow::begin_frame
  53. // Access: Public, Virtual
  54. // Description: This function will be called within the draw thread
  55. // before beginning rendering for a given frame. It
  56. // should do whatever setup is required, and return true
  57. // if the frame should be rendered, or false if it
  58. // should be skipped.
  59. ////////////////////////////////////////////////////////////////////
  60. bool TinyWinGraphicsWindow::
  61. begin_frame(FrameMode mode, Thread *current_thread) {
  62. begin_frame_spam(mode);
  63. if (_gsg == (GraphicsStateGuardian *)NULL) {
  64. return false;
  65. }
  66. TinyGraphicsStateGuardian *tinygsg;
  67. DCAST_INTO_R(tinygsg, _gsg, false);
  68. tinygsg->_current_frame_buffer = _frame_buffer;
  69. tinygsg->reset_if_new();
  70. _gsg->set_current_properties(&get_fb_properties());
  71. return _gsg->begin_frame(current_thread);
  72. }
  73. ////////////////////////////////////////////////////////////////////
  74. // Function: TinyWinGraphicsWindow::end_frame
  75. // Access: Public, Virtual
  76. // Description: This function will be called within the draw thread
  77. // after rendering is completed for a given frame. It
  78. // should do whatever finalization is required.
  79. ////////////////////////////////////////////////////////////////////
  80. void TinyWinGraphicsWindow::
  81. end_frame(FrameMode mode, Thread *current_thread) {
  82. end_frame_spam(mode);
  83. nassertv(_gsg != (GraphicsStateGuardian *)NULL);
  84. if (mode == FM_render) {
  85. // end_render_texture();
  86. copy_to_textures();
  87. }
  88. _gsg->end_frame(current_thread);
  89. if (mode == FM_render) {
  90. trigger_flip();
  91. if (_one_shot) {
  92. prepare_for_deletion();
  93. }
  94. clear_cube_map_selection();
  95. }
  96. }
  97. ////////////////////////////////////////////////////////////////////
  98. // Function: TinyWinGraphicsWindow::begin_flip
  99. // Access: Public, Virtual
  100. // Description: This function will be called within the draw thread
  101. // after end_frame() has been called on all windows, to
  102. // initiate the exchange of the front and back buffers.
  103. //
  104. // This should instruct the window to prepare for the
  105. // flip at the next video sync, but it should not wait.
  106. //
  107. // We have the two separate functions, begin_flip() and
  108. // end_flip(), to make it easier to flip all of the
  109. // windows at the same time.
  110. ////////////////////////////////////////////////////////////////////
  111. void TinyWinGraphicsWindow::
  112. begin_flip() {
  113. HBITMAP bm = CreateCompatibleBitmap(_hdc, _frame_buffer->xsize, _frame_buffer->ysize);
  114. HDC bmdc = CreateCompatibleDC(_hdc);
  115. SelectObject(bmdc, bm);
  116. int fb_xsize = get_fb_x_size();
  117. int fb_ysize = get_fb_y_size();
  118. int fb_ytop = _frame_buffer->ysize - fb_ysize;
  119. SetDIBits(_hdc, bm, fb_ytop, fb_ysize, _frame_buffer->pbuf,
  120. &_bitmap_info, DIB_RGB_COLORS);
  121. if (fb_xsize == _frame_buffer->xsize) {
  122. BitBlt(_hdc, 0, 0, fb_xsize, fb_ysize,
  123. bmdc, 0, 0, SRCCOPY);
  124. } else {
  125. // SetStretchBltMode(_hdc, HALFTONE);
  126. StretchBlt(_hdc, 0, 0, _frame_buffer->xsize, _frame_buffer->ysize,
  127. bmdc, 0, 0,fb_xsize, fb_ysize,
  128. SRCCOPY);
  129. }
  130. DeleteDC(bmdc);
  131. DeleteObject(bm);
  132. GdiFlush();
  133. }
  134. ////////////////////////////////////////////////////////////////////
  135. // Function: TinyWinGraphicsWindow::supports_pixel_zoom
  136. // Access: Published, Virtual
  137. // Description: Returns true if a call to set_pixel_zoom() will be
  138. // respected, false if it will be ignored. If this
  139. // returns false, then get_pixel_factor() will always
  140. // return 1.0, regardless of what value you specify for
  141. // set_pixel_zoom().
  142. //
  143. // This may return false if the underlying renderer
  144. // doesn't support pixel zooming, or if you have called
  145. // this on a DisplayRegion that doesn't have both
  146. // set_clear_color() and set_clear_depth() enabled.
  147. ////////////////////////////////////////////////////////////////////
  148. bool TinyWinGraphicsWindow::
  149. supports_pixel_zoom() const {
  150. return true;
  151. }
  152. ////////////////////////////////////////////////////////////////////
  153. // Function: TinyWinGraphicsWindow::close_window
  154. // Access: Protected, Virtual
  155. // Description: Closes the window right now. Called from the window
  156. // thread.
  157. ////////////////////////////////////////////////////////////////////
  158. void TinyWinGraphicsWindow::
  159. close_window() {
  160. if (_gsg != (GraphicsStateGuardian *)NULL) {
  161. TinyGraphicsStateGuardian *tinygsg;
  162. DCAST_INTO_V(tinygsg, _gsg);
  163. tinygsg->_current_frame_buffer = NULL;
  164. _gsg.clear();
  165. _active = false;
  166. }
  167. ReleaseDC(_hWnd, _hdc);
  168. _hdc = (HDC)0;
  169. WinGraphicsWindow::close_window();
  170. }
  171. ////////////////////////////////////////////////////////////////////
  172. // Function: TinyWinGraphicsWindow::open_window
  173. // Access: Protected, Virtual
  174. // Description: Opens the window right now. Called from the window
  175. // thread. Returns true if the window is successfully
  176. // opened, or false if there was a problem.
  177. ////////////////////////////////////////////////////////////////////
  178. bool TinyWinGraphicsWindow::
  179. open_window() {
  180. if (!WinGraphicsWindow::open_window()) {
  181. return false;
  182. }
  183. // GSG Creation/Initialization
  184. TinyGraphicsStateGuardian *tinygsg;
  185. if (_gsg == 0) {
  186. // There is no old gsg. Create a new one.
  187. tinygsg = new TinyGraphicsStateGuardian(_engine, _pipe, NULL);
  188. _gsg = tinygsg;
  189. } else {
  190. DCAST_INTO_R(tinygsg, _gsg, false);
  191. }
  192. _hdc = GetDC(_hWnd);
  193. create_frame_buffer();
  194. if (_frame_buffer == NULL) {
  195. tinydisplay_cat.error()
  196. << "Could not create frame buffer.\n";
  197. return false;
  198. }
  199. tinygsg->_current_frame_buffer = _frame_buffer;
  200. tinygsg->reset_if_new();
  201. if (!tinygsg->is_valid()) {
  202. close_window();
  203. return false;
  204. }
  205. return true;
  206. }
  207. ////////////////////////////////////////////////////////////////////
  208. // Function: WinGraphicsWindow::handle_reshape
  209. // Access: Protected, Virtual
  210. // Description: Called in the window thread when the window size or
  211. // location is changed, this updates the properties
  212. // structure accordingly.
  213. ////////////////////////////////////////////////////////////////////
  214. void TinyWinGraphicsWindow::
  215. handle_reshape() {
  216. WinGraphicsWindow::handle_reshape();
  217. ZB_resize(_frame_buffer, NULL, _properties.get_x_size(), _properties.get_y_size());
  218. setup_bitmap_info();
  219. }
  220. ////////////////////////////////////////////////////////////////////
  221. // Function: WinGraphicsWindow::do_fullscreen_resize
  222. // Access: Protected, Virtual
  223. // Description: Called in the window thread when the window size or
  224. // location is changed, this updates the properties
  225. // structure accordingly.
  226. ////////////////////////////////////////////////////////////////////
  227. bool TinyWinGraphicsWindow::
  228. do_fullscreen_resize(int x_size, int y_size) {
  229. bool result = WinGraphicsWindow::do_fullscreen_resize(x_size, y_size);
  230. ZB_resize(_frame_buffer, NULL, _properties.get_x_size(), _properties.get_y_size());
  231. setup_bitmap_info();
  232. return result;
  233. }
  234. ////////////////////////////////////////////////////////////////////
  235. // Function: TinyWinGraphicsWindow::create_frame_buffer
  236. // Access: Private
  237. // Description: Creates a suitable frame buffer for the current
  238. // window size.
  239. ////////////////////////////////////////////////////////////////////
  240. void TinyWinGraphicsWindow::
  241. create_frame_buffer() {
  242. if (_frame_buffer != NULL) {
  243. ZB_close(_frame_buffer);
  244. _frame_buffer = NULL;
  245. }
  246. _frame_buffer = ZB_open(_properties.get_x_size(), _properties.get_y_size(), ZB_MODE_RGBA, 0, 0, 0, 0);
  247. setup_bitmap_info();
  248. }
  249. ////////////////////////////////////////////////////////////////////
  250. // Function: TinyWinGraphicsWindow::setup_bitmap_info
  251. // Access: Private
  252. // Description: Determines the BITMAPINFO stuff for blitting the
  253. // frame buffer to the window.
  254. ////////////////////////////////////////////////////////////////////
  255. void TinyWinGraphicsWindow::
  256. setup_bitmap_info() {
  257. _bitmap_info.bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
  258. _bitmap_info.bmiHeader.biWidth = _frame_buffer->xsize;
  259. _bitmap_info.bmiHeader.biHeight = -_frame_buffer->ysize;
  260. _bitmap_info.bmiHeader.biPlanes = 1;
  261. _bitmap_info.bmiHeader.biBitCount = 32;
  262. _bitmap_info.bmiHeader.biCompression = BI_RGB;
  263. _bitmap_info.bmiHeader.biSizeImage = _frame_buffer->linesize * _frame_buffer->ysize;
  264. _bitmap_info.bmiHeader.biXPelsPerMeter = 0;
  265. _bitmap_info.bmiHeader.biYPelsPerMeter = 0;
  266. _bitmap_info.bmiHeader.biClrUsed = 0;
  267. _bitmap_info.bmiHeader.biClrImportant = 0;
  268. }
  269. #endif // WIN32