Panda3D
 All Classes Functions Variables Enumerations
tinyWinGraphicsWindow.cxx
00001 // Filename: tinyWinGraphicsWindow.cxx
00002 // Created by:  drose (06May08)
00003 //
00004 ////////////////////////////////////////////////////////////////////
00005 //
00006 // PANDA 3D SOFTWARE
00007 // Copyright (c) Carnegie Mellon University.  All rights reserved.
00008 //
00009 // All use of this software is subject to the terms of the revised BSD
00010 // license.  You should have received a copy of this license along
00011 // with this source code in a file named "LICENSE."
00012 //
00013 ////////////////////////////////////////////////////////////////////
00014 
00015 #include "pandabase.h"
00016 
00017 #ifdef WIN32
00018 
00019 #include "tinyWinGraphicsWindow.h"
00020 #include "config_tinydisplay.h"
00021 #include "config_windisplay.h"
00022 #include "tinyWinGraphicsPipe.h"
00023 #include "tinyGraphicsStateGuardian.h"
00024 #include "pStatTimer.h"
00025 
00026 #include <wingdi.h>
00027 
00028 TypeHandle TinyWinGraphicsWindow::_type_handle;
00029 
00030 ////////////////////////////////////////////////////////////////////
00031 //     Function: TinyWinGraphicsWindow::Constructor
00032 //       Access: Public
00033 //  Description:
00034 ////////////////////////////////////////////////////////////////////
00035 TinyWinGraphicsWindow::
00036 TinyWinGraphicsWindow(GraphicsEngine *engine, GraphicsPipe *pipe, 
00037                       const string &name,
00038                       const FrameBufferProperties &fb_prop,
00039                       const WindowProperties &win_prop,
00040                       int flags,
00041                       GraphicsStateGuardian *gsg,
00042                       GraphicsOutput *host) :
00043   WinGraphicsWindow(engine, pipe, name, fb_prop, win_prop, flags, gsg, host)
00044 {
00045   _frame_buffer = NULL;
00046   _hdc = (HDC)0;
00047   update_pixel_factor();
00048 }
00049 
00050 ////////////////////////////////////////////////////////////////////
00051 //     Function: TinyWinGraphicsWindow::Destructor
00052 //       Access: Public, Virtual
00053 //  Description:
00054 ////////////////////////////////////////////////////////////////////
00055 TinyWinGraphicsWindow::
00056 ~TinyWinGraphicsWindow() {
00057 }
00058 
00059 ////////////////////////////////////////////////////////////////////
00060 //     Function: TinyWinGraphicsWindow::begin_frame
00061 //       Access: Public, Virtual
00062 //  Description: This function will be called within the draw thread
00063 //               before beginning rendering for a given frame.  It
00064 //               should do whatever setup is required, and return true
00065 //               if the frame should be rendered, or false if it
00066 //               should be skipped.
00067 ////////////////////////////////////////////////////////////////////
00068 bool TinyWinGraphicsWindow::
00069 begin_frame(FrameMode mode, Thread *current_thread) {
00070   begin_frame_spam(mode);
00071   if (_gsg == (GraphicsStateGuardian *)NULL) {
00072     return false;
00073   }
00074 
00075   if (!get_unexposed_draw() && !_got_expose_event) {
00076     if (tinydisplay_cat.is_spam()) {
00077       tinydisplay_cat.spam()
00078         << "Not drawing " << this << ": unexposed.\n";
00079     }
00080     return false;
00081   }
00082 
00083   TinyGraphicsStateGuardian *tinygsg;
00084   DCAST_INTO_R(tinygsg, _gsg, false);
00085 
00086   tinygsg->_current_frame_buffer = _frame_buffer;
00087   tinygsg->reset_if_new();
00088   
00089   _gsg->set_current_properties(&get_fb_properties());
00090   return _gsg->begin_frame(current_thread);
00091 }
00092 
00093 ////////////////////////////////////////////////////////////////////
00094 //     Function: TinyWinGraphicsWindow::end_frame
00095 //       Access: Public, Virtual
00096 //  Description: This function will be called within the draw thread
00097 //               after rendering is completed for a given frame.  It
00098 //               should do whatever finalization is required.
00099 ////////////////////////////////////////////////////////////////////
00100 void TinyWinGraphicsWindow::
00101 end_frame(FrameMode mode, Thread *current_thread) {
00102   end_frame_spam(mode);
00103   nassertv(_gsg != (GraphicsStateGuardian *)NULL);
00104 
00105   if (mode == FM_render) {
00106     // end_render_texture();
00107     copy_to_textures();
00108   }
00109 
00110   _gsg->end_frame(current_thread);
00111 
00112   if (mode == FM_render) {
00113     trigger_flip();
00114     clear_cube_map_selection();
00115   }
00116 }
00117 
00118 ////////////////////////////////////////////////////////////////////
00119 //     Function: TinyWinGraphicsWindow::end_flip
00120 //       Access: Public, Virtual
00121 //  Description: This function will be called within the draw thread
00122 //               after begin_flip() has been called on all windows, to
00123 //               finish the exchange of the front and back buffers.
00124 //
00125 //               This should cause the window to wait for the flip, if
00126 //               necessary.
00127 ////////////////////////////////////////////////////////////////////
00128 void TinyWinGraphicsWindow::
00129 end_flip() {
00130   if (!_flip_ready) {
00131     GraphicsWindow::end_flip();
00132     return;
00133   }
00134 
00135   HBITMAP bm = CreateCompatibleBitmap(_hdc, _frame_buffer->xsize, _frame_buffer->ysize);
00136   HDC bmdc = CreateCompatibleDC(_hdc);
00137   SelectObject(bmdc, bm);
00138 
00139   int fb_xsize = get_fb_x_size();
00140   int fb_ysize = get_fb_y_size();
00141   int fb_ytop = _frame_buffer->ysize - fb_ysize;
00142 
00143   SetDIBits(_hdc, bm, fb_ytop, fb_ysize, _frame_buffer->pbuf,
00144             &_bitmap_info, DIB_RGB_COLORS);
00145 
00146   if (fb_xsize == _frame_buffer->xsize) {
00147     BitBlt(_hdc, 0, 0, fb_xsize, fb_ysize,
00148            bmdc, 0, 0, SRCCOPY);
00149   } else {
00150     //    SetStretchBltMode(_hdc, HALFTONE);
00151     StretchBlt(_hdc, 0, 0, _frame_buffer->xsize, _frame_buffer->ysize,
00152                bmdc, 0, 0,fb_xsize, fb_ysize,
00153                SRCCOPY);
00154   }
00155     
00156   DeleteDC(bmdc);
00157   DeleteObject(bm);
00158   GdiFlush();
00159   GraphicsWindow::end_flip();
00160 }
00161 
00162 ////////////////////////////////////////////////////////////////////
00163 //     Function: TinyWinGraphicsWindow::supports_pixel_zoom
00164 //       Access: Published, Virtual
00165 //  Description: Returns true if a call to set_pixel_zoom() will be
00166 //               respected, false if it will be ignored.  If this
00167 //               returns false, then get_pixel_factor() will always
00168 //               return 1.0, regardless of what value you specify for
00169 //               set_pixel_zoom().
00170 //
00171 //               This may return false if the underlying renderer
00172 //               doesn't support pixel zooming, or if you have called
00173 //               this on a DisplayRegion that doesn't have both
00174 //               set_clear_color() and set_clear_depth() enabled.
00175 ////////////////////////////////////////////////////////////////////
00176 bool TinyWinGraphicsWindow::
00177 supports_pixel_zoom() const {
00178   return true;
00179 }
00180 
00181 ////////////////////////////////////////////////////////////////////
00182 //     Function: TinyWinGraphicsWindow::close_window
00183 //       Access: Protected, Virtual
00184 //  Description: Closes the window right now.  Called from the window
00185 //               thread.
00186 ////////////////////////////////////////////////////////////////////
00187 void TinyWinGraphicsWindow::
00188 close_window() {
00189   if (_gsg != (GraphicsStateGuardian *)NULL) {
00190     TinyGraphicsStateGuardian *tinygsg;
00191     DCAST_INTO_V(tinygsg, _gsg);
00192     tinygsg->_current_frame_buffer = NULL;
00193     _gsg.clear();
00194   }
00195 
00196   ReleaseDC(_hWnd, _hdc);
00197   _hdc = (HDC)0;
00198   WinGraphicsWindow::close_window();
00199 }
00200 
00201 ////////////////////////////////////////////////////////////////////
00202 //     Function: TinyWinGraphicsWindow::open_window
00203 //       Access: Protected, Virtual
00204 //  Description: Opens the window right now.  Called from the window
00205 //               thread.  Returns true if the window is successfully
00206 //               opened, or false if there was a problem.
00207 ////////////////////////////////////////////////////////////////////
00208 bool TinyWinGraphicsWindow::
00209 open_window() {
00210   if (!WinGraphicsWindow::open_window()) {
00211     return false;
00212   }
00213 
00214   // GSG Creation/Initialization
00215   TinyGraphicsStateGuardian *tinygsg;
00216   if (_gsg == 0) {
00217     // There is no old gsg.  Create a new one.
00218     tinygsg = new TinyGraphicsStateGuardian(_engine, _pipe, NULL);
00219     _gsg = tinygsg;
00220   } else {
00221     DCAST_INTO_R(tinygsg, _gsg, false);
00222   }
00223   
00224   _hdc = GetDC(_hWnd);
00225 
00226   create_frame_buffer();
00227   if (_frame_buffer == NULL) {
00228     tinydisplay_cat.error()
00229       << "Could not create frame buffer.\n";
00230     return false;
00231   }
00232 
00233   tinygsg->_current_frame_buffer = _frame_buffer;
00234   
00235   tinygsg->reset_if_new();
00236   if (!tinygsg->is_valid()) {
00237     close_window();
00238     return false;
00239   }
00240 
00241   return true;
00242 }
00243 
00244 ////////////////////////////////////////////////////////////////////
00245 //     Function: WinGraphicsWindow::handle_reshape
00246 //       Access: Protected, Virtual
00247 //  Description: Called in the window thread when the window size or
00248 //               location is changed, this updates the properties
00249 //               structure accordingly.
00250 ////////////////////////////////////////////////////////////////////
00251 void TinyWinGraphicsWindow::
00252 handle_reshape() {
00253   WinGraphicsWindow::handle_reshape();
00254   ZB_resize(_frame_buffer, NULL, _properties.get_x_size(), _properties.get_y_size());
00255   setup_bitmap_info();
00256 }
00257 
00258 ////////////////////////////////////////////////////////////////////
00259 //     Function: WinGraphicsWindow::do_fullscreen_resize
00260 //       Access: Protected, Virtual
00261 //  Description: Called in the window thread when the window size or
00262 //               location is changed, this updates the properties
00263 //               structure accordingly.
00264 ////////////////////////////////////////////////////////////////////
00265 bool TinyWinGraphicsWindow::
00266 do_fullscreen_resize(int x_size, int y_size) {
00267   bool result = WinGraphicsWindow::do_fullscreen_resize(x_size, y_size);
00268   ZB_resize(_frame_buffer, NULL, _properties.get_x_size(), _properties.get_y_size());
00269   setup_bitmap_info();
00270   return result;
00271 }
00272 
00273 ////////////////////////////////////////////////////////////////////
00274 //     Function: TinyWinGraphicsWindow::create_frame_buffer
00275 //       Access: Private
00276 //  Description: Creates a suitable frame buffer for the current
00277 //               window size.
00278 ////////////////////////////////////////////////////////////////////
00279 void TinyWinGraphicsWindow::
00280 create_frame_buffer() {
00281   if (_frame_buffer != NULL) {
00282     ZB_close(_frame_buffer);
00283     _frame_buffer = NULL;
00284   }
00285 
00286   _frame_buffer = ZB_open(_properties.get_x_size(), _properties.get_y_size(), ZB_MODE_RGBA, 0, 0, 0, 0);
00287   setup_bitmap_info();
00288 }
00289 
00290 ////////////////////////////////////////////////////////////////////
00291 //     Function: TinyWinGraphicsWindow::setup_bitmap_info
00292 //       Access: Private
00293 //  Description: Determines the BITMAPINFO stuff for blitting the
00294 //               frame buffer to the window.
00295 ////////////////////////////////////////////////////////////////////
00296 void TinyWinGraphicsWindow::
00297 setup_bitmap_info() {
00298   _bitmap_info.bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
00299   _bitmap_info.bmiHeader.biWidth = _frame_buffer->xsize;
00300   _bitmap_info.bmiHeader.biHeight = -_frame_buffer->ysize;
00301   _bitmap_info.bmiHeader.biPlanes = 1;
00302   _bitmap_info.bmiHeader.biBitCount = 32;
00303   _bitmap_info.bmiHeader.biCompression = BI_RGB;
00304   _bitmap_info.bmiHeader.biSizeImage = _frame_buffer->linesize * _frame_buffer->ysize;
00305   _bitmap_info.bmiHeader.biXPelsPerMeter = 0;
00306   _bitmap_info.bmiHeader.biYPelsPerMeter = 0;
00307   _bitmap_info.bmiHeader.biClrUsed = 0;
00308   _bitmap_info.bmiHeader.biClrImportant = 0;
00309 }
00310 
00311 #endif  // WIN32
 All Classes Functions Variables Enumerations