00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
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
00032
00033
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
00052
00053
00054
00055 TinyWinGraphicsWindow::
00056 ~TinyWinGraphicsWindow() {
00057 }
00058
00059
00060
00061
00062
00063
00064
00065
00066
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
00095
00096
00097
00098
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
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
00120
00121
00122
00123
00124
00125
00126
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
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
00164
00165
00166
00167
00168
00169
00170
00171
00172
00173
00174
00175
00176 bool TinyWinGraphicsWindow::
00177 supports_pixel_zoom() const {
00178 return true;
00179 }
00180
00181
00182
00183
00184
00185
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
00203
00204
00205
00206
00207
00208 bool TinyWinGraphicsWindow::
00209 open_window() {
00210 if (!WinGraphicsWindow::open_window()) {
00211 return false;
00212 }
00213
00214
00215 TinyGraphicsStateGuardian *tinygsg;
00216 if (_gsg == 0) {
00217
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
00246
00247
00248
00249
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
00260
00261
00262
00263
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
00275
00276
00277
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
00292
00293
00294
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