00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015 #include "wglGraphicsWindow.h"
00016 #include "config_wgldisplay.h"
00017 #include "config_windisplay.h"
00018 #include "wglGraphicsPipe.h"
00019 #include "pStatTimer.h"
00020 #include "glgsg.h"
00021
00022 #include <wingdi.h>
00023
00024 TypeHandle wglGraphicsWindow::_type_handle;
00025
00026
00027
00028
00029
00030
00031 wglGraphicsWindow::
00032 wglGraphicsWindow(GraphicsEngine *engine, GraphicsPipe *pipe,
00033 const string &name,
00034 const FrameBufferProperties &fb_prop,
00035 const WindowProperties &win_prop,
00036 int flags,
00037 GraphicsStateGuardian *gsg,
00038 GraphicsOutput *host) :
00039 WinGraphicsWindow(engine, pipe, name, fb_prop, win_prop, flags, gsg, host)
00040 {
00041 _hdc = (HDC)0;
00042 }
00043
00044
00045
00046
00047
00048
00049 wglGraphicsWindow::
00050 ~wglGraphicsWindow() {
00051 }
00052
00053
00054
00055
00056
00057
00058
00059
00060
00061
00062 bool wglGraphicsWindow::
00063 begin_frame(FrameMode mode, Thread *current_thread) {
00064
00065 begin_frame_spam(mode);
00066 if (_gsg == (GraphicsStateGuardian *)NULL) {
00067 return false;
00068 }
00069
00070 if (!get_unexposed_draw() && !_got_expose_event) {
00071 if (wgldisplay_cat.is_spam()) {
00072 wgldisplay_cat.spam()
00073 << "Not drawing " << this << ": unexposed.\n";
00074 }
00075 return false;
00076 }
00077
00078 if (wgldisplay_cat.is_spam()) {
00079 wgldisplay_cat.spam()
00080 << "Drawing " << this << ": exposed.\n";
00081 }
00082
00083 wglGraphicsStateGuardian *wglgsg;
00084 DCAST_INTO_R(wglgsg, _gsg, false);
00085
00086 HGLRC context = wglgsg->get_context(_hdc);
00087 nassertr(context, false);
00088
00089 wglGraphicsPipe::wgl_make_current(_hdc, context, &_make_current_pcollector);
00090 wglgsg->reset_if_new();
00091
00092 if (mode == FM_render) {
00093 clear_cube_map_selection();
00094 }
00095
00096 _gsg->set_current_properties(&get_fb_properties());
00097 return _gsg->begin_frame(current_thread);
00098 }
00099
00100
00101
00102
00103
00104
00105
00106
00107 void wglGraphicsWindow::
00108 end_frame(FrameMode mode, Thread *current_thread) {
00109 end_frame_spam(mode);
00110
00111 nassertv(_gsg != (GraphicsStateGuardian *)NULL);
00112
00113 if (mode == FM_render) {
00114 copy_to_textures();
00115 }
00116
00117 _gsg->end_frame(current_thread);
00118
00119 if (mode == FM_render) {
00120 trigger_flip();
00121 clear_cube_map_selection();
00122 }
00123 }
00124
00125
00126
00127
00128
00129
00130
00131
00132
00133
00134
00135
00136
00137
00138
00139 void wglGraphicsWindow::
00140 begin_flip() {
00141 }
00142
00143
00144
00145
00146
00147
00148
00149
00150
00151
00152
00153
00154
00155
00156
00157 void wglGraphicsWindow::
00158 ready_flip() {
00159 if (_hdc) {
00160
00161
00162
00163
00164
00165 wglGraphicsStateGuardian *wglgsg;
00166 DCAST_INTO_V(wglgsg, _gsg);
00167 HGLRC context = wglgsg->get_context(_hdc);
00168 nassertv(context);
00169 wglGraphicsPipe::wgl_make_current(_hdc, context, &_make_current_pcollector);
00170 wglgsg->finish();
00171 }
00172 }
00173
00174
00175
00176
00177
00178
00179
00180
00181
00182
00183
00184 void wglGraphicsWindow::
00185 end_flip() {
00186 if (_hdc != NULL && _flip_ready) {
00187
00188
00189
00190
00191
00192 wglGraphicsStateGuardian *wglgsg;
00193 DCAST_INTO_V(wglgsg, _gsg);
00194 HGLRC context = wglgsg->get_context(_hdc);
00195 nassertv(context);
00196 wglGraphicsPipe::wgl_make_current(_hdc, context, &_make_current_pcollector);
00197 SwapBuffers(_hdc);
00198 }
00199 WinGraphicsWindow::end_flip();
00200 }
00201
00202
00203
00204
00205
00206
00207
00208 void wglGraphicsWindow::
00209 close_window() {
00210 if (_gsg != (GraphicsStateGuardian *)NULL) {
00211 wglGraphicsPipe::wgl_make_current(_hdc, NULL, &_make_current_pcollector);
00212 _gsg.clear();
00213 }
00214 ReleaseDC(_hWnd, _hdc);
00215 _hdc = (HDC)0;
00216 WinGraphicsWindow::close_window();
00217 }
00218
00219
00220
00221
00222
00223
00224
00225
00226 bool wglGraphicsWindow::
00227 open_window() {
00228 if (!WinGraphicsWindow::open_window()) {
00229 return false;
00230 }
00231
00232
00233
00234 wglGraphicsStateGuardian *wglgsg;
00235 if (_gsg == 0) {
00236
00237 wglgsg = new wglGraphicsStateGuardian(_engine, _pipe, NULL);
00238 wglgsg->choose_pixel_format(_fb_properties, false);
00239 _gsg = wglgsg;
00240 } else {
00241
00242
00243 DCAST_INTO_R(wglgsg, _gsg, false);
00244 if (!wglgsg->get_fb_properties().subsumes(_fb_properties)) {
00245 wglgsg = new wglGraphicsStateGuardian(_engine, _pipe, wglgsg);
00246 wglgsg->choose_pixel_format(_fb_properties, false);
00247 _gsg = wglgsg;
00248 }
00249 }
00250
00251
00252
00253 _hdc = GetDC(_hWnd);
00254 int pfnum = wglgsg->get_pfnum();
00255 PIXELFORMATDESCRIPTOR pixelformat;
00256 DescribePixelFormat(_hdc, pfnum, sizeof(PIXELFORMATDESCRIPTOR),
00257 &pixelformat);
00258
00259 #ifdef NOTIFY_DEBUG
00260 char msg[200];
00261 sprintf(msg, "Selected GL PixelFormat is #%d", pfnum);
00262 print_pfd(&pixelformat, msg);
00263 #endif
00264
00265 BOOL set_pfnum = SetPixelFormat(_hdc, pfnum, &pixelformat);
00266
00267 if (!set_pfnum) {
00268 if (wglgsg->fail_pfnum()) {
00269 wgldisplay_cat.error()
00270 << "SetPixelFormat(" << pfnum << ") failed; trying "
00271 << wglgsg->get_pfnum() << " instead\n";
00272
00273 pfnum = wglgsg->get_pfnum();
00274 DescribePixelFormat(_hdc, pfnum, sizeof(PIXELFORMATDESCRIPTOR),
00275 &pixelformat);
00276
00277 #ifdef NOTIFY_DEBUG
00278 sprintf(msg, "Selected GL PixelFormat is #%d", pfnum);
00279 print_pfd(&pixelformat, msg);
00280 #endif
00281
00282 DescribePixelFormat(_hdc, pfnum, sizeof(PIXELFORMATDESCRIPTOR),
00283 &pixelformat);
00284 set_pfnum = SetPixelFormat(_hdc, pfnum, &pixelformat);
00285 }
00286 }
00287
00288 if (!set_pfnum) {
00289 wgldisplay_cat.error()
00290 << "SetPixelFormat(" << pfnum << ") failed after window create\n";
00291 close_window();
00292 return false;
00293 }
00294
00295 #ifndef NDEBUG
00296 if (gl_force_invalid) {
00297 wgldisplay_cat.error()
00298 << "Artificially failing window.\n";
00299 close_window();
00300 return false;
00301 }
00302 #endif // NDEBUG
00303
00304
00305 setup_colormap(pixelformat);
00306
00307
00308 wglGraphicsPipe::wgl_make_current(_hdc, wglgsg->get_context(_hdc), &_make_current_pcollector);
00309 wglgsg->reset_if_new();
00310 wglgsg->report_my_gl_errors();
00311 if (!wglgsg->get_fb_properties().verify_hardware_software
00312 (_fb_properties,wglgsg->get_gl_renderer())) {
00313 close_window();
00314 return false;
00315 }
00316 _fb_properties = wglgsg->get_fb_properties();
00317
00318 return true;
00319 }
00320
00321
00322
00323
00324
00325
00326
00327
00328 void wglGraphicsWindow::
00329 setup_colormap(const PIXELFORMATDESCRIPTOR &pixelformat) {
00330 LOGPALETTE *logical;
00331 int n;
00332
00333 if (!(pixelformat.dwFlags & PFD_NEED_PALETTE ||
00334 pixelformat.iPixelType == PFD_TYPE_COLORINDEX))
00335 return;
00336
00337 n = 1 << pixelformat.cColorBits;
00338
00339
00340
00341 logical = (LOGPALETTE*)malloc(sizeof(LOGPALETTE) +
00342 sizeof(PALETTEENTRY) * n);
00343 memset(logical, 0, sizeof(LOGPALETTE) + sizeof(PALETTEENTRY) * n);
00344
00345
00346 logical->palVersion = 0x300;
00347 logical->palNumEntries = n;
00348
00349
00350 GetSystemPaletteEntries(_hdc, 0, 256, &logical->palPalEntry[0]);
00351
00352 if (pixelformat.iPixelType == PFD_TYPE_RGBA) {
00353 int redMask = (1 << pixelformat.cRedBits) - 1;
00354 int greenMask = (1 << pixelformat.cGreenBits) - 1;
00355 int blueMask = (1 << pixelformat.cBlueBits) - 1;
00356 int i;
00357
00358
00359 for (i = 0; i < n; ++i) {
00360 logical->palPalEntry[i].peRed =
00361 (((i >> pixelformat.cRedShift) & redMask) * 255) / redMask;
00362 logical->palPalEntry[i].peGreen =
00363 (((i >> pixelformat.cGreenShift) & greenMask) * 255) / greenMask;
00364 logical->palPalEntry[i].peBlue =
00365 (((i >> pixelformat.cBlueShift) & blueMask) * 255) / blueMask;
00366 logical->palPalEntry[i].peFlags = 0;
00367 }
00368 }
00369
00370 _colormap = CreatePalette(logical);
00371 free(logical);
00372
00373 SelectPalette(_hdc, _colormap, FALSE);
00374 RealizePalette(_hdc);
00375 }
00376
00377 #ifdef NOTIFY_DEBUG
00378
00379
00380 static char *OGLDrvStrings[3] = {"Software","MCD","ICD"};
00381
00382
00383
00384
00385
00386
00387
00388 void wglGraphicsWindow::
00389 print_pfd(PIXELFORMATDESCRIPTOR *pfd, char *msg) {
00390 if (!wgldisplay_cat.is_debug()) {
00391 return;
00392 }
00393
00394 OGLDriverType drvtype;
00395 if ((pfd->dwFlags & PFD_GENERIC_ACCELERATED) &&
00396 (pfd->dwFlags & PFD_GENERIC_FORMAT)) {
00397 drvtype=MCD;
00398 } else if (!(pfd->dwFlags & PFD_GENERIC_ACCELERATED) && !(pfd->dwFlags & PFD_GENERIC_FORMAT)) {
00399 drvtype=ICD;
00400 } else {
00401 drvtype=Software;
00402 }
00403
00404 #define PRINT_FLAG(FLG) ((pfd->dwFlags & PFD_##FLG) ? (" PFD_" #FLG "|") : "")
00405 wgldisplay_cat.debug()
00406 << "================================\n";
00407
00408 wgldisplay_cat.debug()
00409 << msg << ", " << OGLDrvStrings[drvtype] << " driver\n"
00410 << "PFD flags: 0x" << (void*)pfd->dwFlags << " ("
00411 << PRINT_FLAG(GENERIC_ACCELERATED)
00412 << PRINT_FLAG(GENERIC_FORMAT)
00413 << PRINT_FLAG(DOUBLEBUFFER)
00414 << PRINT_FLAG(SUPPORT_OPENGL)
00415 << PRINT_FLAG(SUPPORT_GDI)
00416 << PRINT_FLAG(STEREO)
00417 << PRINT_FLAG(DRAW_TO_WINDOW)
00418 << PRINT_FLAG(DRAW_TO_BITMAP)
00419 << PRINT_FLAG(SWAP_EXCHANGE)
00420 << PRINT_FLAG(SWAP_COPY)
00421 << PRINT_FLAG(SWAP_LAYER_BUFFERS)
00422 << PRINT_FLAG(NEED_PALETTE)
00423 << PRINT_FLAG(NEED_SYSTEM_PALETTE)
00424 << PRINT_FLAG(SUPPORT_DIRECTDRAW) << ")\n"
00425 << "PFD iPixelType: "
00426 << ((pfd->iPixelType==PFD_TYPE_RGBA) ? "PFD_TYPE_RGBA":"PFD_TYPE_COLORINDEX")
00427 << endl
00428 << "PFD cColorBits: " << (DWORD)pfd->cColorBits
00429 << " R: " << (DWORD)pfd->cRedBits
00430 <<" G: " << (DWORD)pfd->cGreenBits
00431 <<" B: " << (DWORD)pfd->cBlueBits << endl
00432 << "PFD cAlphaBits: " << (DWORD)pfd->cAlphaBits
00433 << " DepthBits: " << (DWORD)pfd->cDepthBits
00434 <<" StencilBits: " << (DWORD)pfd->cStencilBits
00435 <<" AccumBits: " << (DWORD)pfd->cAccumBits
00436 << endl;
00437 }
00438 #endif
00439