00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015 #include "wglGraphicsStateGuardian.h"
00016 #include "wglGraphicsBuffer.h"
00017 #include "string_utils.h"
00018
00019 TypeHandle wglGraphicsStateGuardian::_type_handle;
00020
00021 const char * const wglGraphicsStateGuardian::_twindow_class_name = "wglGraphicsStateGuardian";
00022 bool wglGraphicsStateGuardian::_twindow_class_registered = false;
00023
00024
00025
00026
00027
00028
00029 wglGraphicsStateGuardian::
00030 wglGraphicsStateGuardian(GraphicsEngine *engine, GraphicsPipe *pipe,
00031 wglGraphicsStateGuardian *share_with) :
00032 GLGraphicsStateGuardian(engine, pipe),
00033 _share_with(share_with)
00034 {
00035 _made_context = false;
00036 _context = (HGLRC)NULL;
00037
00038 _twindow = (HWND)0;
00039 _twindow_dc = (HDC)0;
00040
00041 _pfnum = -1;
00042 _pfnum_supports_pbuffer = false;
00043 _pfnum_properties.clear();
00044
00045 _supports_pbuffer = false;
00046 _supports_pixel_format = false;
00047 _supports_wgl_multisample = false;
00048 _supports_wgl_render_texture = false;
00049
00050 get_gamma_table();
00051 atexit(atexit_function);
00052 }
00053
00054
00055
00056
00057
00058
00059 wglGraphicsStateGuardian::
00060 ~wglGraphicsStateGuardian() {
00061 release_twindow();
00062 if (_context != (HGLRC)NULL) {
00063 wglDeleteContext(_context);
00064 _context = (HGLRC)NULL;
00065 }
00066 }
00067
00068
00069
00070
00071
00072
00073
00074
00075
00076
00077
00078
00079
00080
00081
00082
00083
00084
00085
00086 bool wglGraphicsStateGuardian::
00087 fail_pfnum() {
00088 if (_pfnum == _pre_pfnum) {
00089 return false;
00090 }
00091
00092 _pfnum = _pre_pfnum;
00093 _pfnum_supports_pbuffer = false;
00094 _pfnum_properties = _pre_pfnum_properties;
00095 return true;
00096 }
00097
00098
00099
00100
00101
00102
00103
00104 void wglGraphicsStateGuardian::
00105 get_properties(FrameBufferProperties &properties, HDC hdc, int pfnum) {
00106
00107 PIXELFORMATDESCRIPTOR pfd;
00108 ZeroMemory(&pfd,sizeof(PIXELFORMATDESCRIPTOR));
00109 pfd.nSize = sizeof(PIXELFORMATDESCRIPTOR);
00110 pfd.nVersion = 1;
00111
00112 DescribePixelFormat(hdc, pfnum, sizeof(PIXELFORMATDESCRIPTOR), &pfd);
00113
00114 properties.clear();
00115 properties.set_all_specified();
00116
00117 if (((pfd.dwFlags & PFD_SUPPORT_OPENGL) == 0)||
00118 ((pfd.dwFlags & PFD_DRAW_TO_WINDOW) == 0)) {
00119
00120
00121 return;
00122 }
00123
00124 if (pfd.iPixelType == PFD_TYPE_COLORINDEX) {
00125 properties.set_indexed_color(1);
00126 } else {
00127 properties.set_rgb_color(1);
00128 }
00129
00130 int mode = 0;
00131 if (pfd.dwFlags & PFD_DOUBLEBUFFER) {
00132 properties.set_back_buffers(1);
00133 }
00134 if (pfd.dwFlags & PFD_STEREO) {
00135 properties.set_stereo(1);
00136 }
00137 if (pfd.dwFlags & PFD_GENERIC_FORMAT) {
00138 properties.set_force_software(1);
00139 } else {
00140 properties.set_force_hardware(1);
00141 }
00142
00143 if (pfd.cColorBits != 0) {
00144 properties.set_color_bits(pfd.cColorBits);
00145 }
00146 if (pfd.cAlphaBits != 0) {
00147 properties.set_alpha_bits(pfd.cAlphaBits);
00148 }
00149 if (pfd.cDepthBits != 0) {
00150 properties.set_depth_bits(pfd.cDepthBits);
00151 }
00152 if (pfd.cStencilBits != 0) {
00153 properties.set_stencil_bits(pfd.cStencilBits);
00154 }
00155
00156
00157 }
00158
00159
00160
00161
00162
00163
00164
00165
00166 bool wglGraphicsStateGuardian::
00167 get_properties_advanced(FrameBufferProperties &properties,
00168 HDC window_dc, int pfnum) {
00169
00170 static const int max_attrib_list = 32;
00171 int iattrib_list[max_attrib_list];
00172 int ivalue_list[max_attrib_list];
00173 int ni = 0;
00174
00175 int acceleration_i, pixel_type_i, double_buffer_i, stereo_i,
00176 color_bits_i, alpha_bits_i, accum_bits_i, depth_bits_i,
00177 stencil_bits_i, multisamples_i;
00178
00179 iattrib_list[acceleration_i = ni++] = WGL_ACCELERATION_ARB;
00180 iattrib_list[pixel_type_i = ni++] = WGL_PIXEL_TYPE_ARB;
00181 iattrib_list[double_buffer_i = ni++] = WGL_DOUBLE_BUFFER_ARB;
00182 iattrib_list[stereo_i = ni++] = WGL_STEREO_ARB;
00183 iattrib_list[color_bits_i = ni++] = WGL_COLOR_BITS_ARB;
00184 iattrib_list[alpha_bits_i = ni++] = WGL_ALPHA_BITS_ARB;
00185 iattrib_list[accum_bits_i = ni++] = WGL_ACCUM_BITS_ARB;
00186 iattrib_list[depth_bits_i = ni++] = WGL_DEPTH_BITS_ARB;
00187 iattrib_list[stencil_bits_i = ni++] = WGL_STENCIL_BITS_ARB;
00188
00189 if (_supports_wgl_multisample) {
00190 iattrib_list[multisamples_i = ni++] = WGL_SAMPLES_ARB;
00191 }
00192
00193
00194 nassertr(ni <= max_attrib_list, false);
00195
00196 if (!_wglGetPixelFormatAttribivARB(window_dc, pfnum, 0,
00197 ni, iattrib_list, ivalue_list)) {
00198 return false;
00199 }
00200
00201 properties.clear();
00202 properties.set_all_specified();
00203
00204 int frame_buffer_mode = 0;
00205 if (ivalue_list[acceleration_i] == WGL_NO_ACCELERATION_ARB) {
00206 properties.set_force_software(1);
00207 } else {
00208 properties.set_force_hardware(1);
00209 }
00210
00211 if (ivalue_list[pixel_type_i] == WGL_TYPE_COLORINDEX_ARB) {
00212 properties.set_indexed_color(1);
00213 } else {
00214 properties.set_rgb_color(1);
00215 }
00216
00217 if (ivalue_list[double_buffer_i]) {
00218 properties.set_back_buffers(1);
00219 }
00220
00221 if (ivalue_list[stereo_i]) {
00222 properties.set_stereo(1);
00223 }
00224
00225 if (ivalue_list[alpha_bits_i] != 0) {
00226 properties.set_alpha_bits(ivalue_list[alpha_bits_i]);
00227 }
00228
00229 if (ivalue_list[accum_bits_i] != 0) {
00230 properties.set_accum_bits(ivalue_list[accum_bits_i]);
00231 }
00232
00233 if (ivalue_list[depth_bits_i] != 0) {
00234 properties.set_depth_bits(ivalue_list[depth_bits_i]);
00235 }
00236
00237 if (ivalue_list[stencil_bits_i] != 0) {
00238 properties.set_stencil_bits(ivalue_list[stencil_bits_i]);
00239 }
00240
00241 if (_supports_wgl_multisample) {
00242 if (ivalue_list[multisamples_i] != 0) {
00243 properties.set_multisamples(ivalue_list[multisamples_i]);
00244 }
00245 }
00246
00247 properties.set_color_bits(ivalue_list[color_bits_i]);
00248
00249 return true;
00250 }
00251
00252
00253
00254
00255
00256
00257
00258 void wglGraphicsStateGuardian::
00259 choose_pixel_format(const FrameBufferProperties &properties,
00260 bool need_pbuffer) {
00261
00262
00263
00264
00265
00266
00267 if (gl_force_pixfmt.has_value()) {
00268 wgldisplay_cat.info()
00269 << "overriding pixfmt choice with gl-force-pixfmt("
00270 << gl_force_pixfmt << ")\n";
00271 _pfnum = gl_force_pixfmt;
00272 _pfnum_properties = properties;
00273 _pfnum_supports_pbuffer = true;
00274 return;
00275 }
00276
00277 int best_pfnum = 0;
00278 int best_quality = 0;
00279 FrameBufferProperties best_prop;
00280
00281 HDC hdc = GetDC(NULL);
00282
00283 int max_pfnum = DescribePixelFormat(hdc, 1, 0, NULL);
00284
00285 for (int pfnum = 0; pfnum<max_pfnum; ++pfnum) {
00286 FrameBufferProperties pfprop;
00287 get_properties(pfprop, hdc, pfnum);
00288 int quality = pfprop.get_quality(properties);
00289 if (quality > best_quality) {
00290 best_pfnum = pfnum;
00291 best_quality = quality;
00292 best_prop = pfprop;
00293 }
00294 }
00295
00296 ReleaseDC(NULL, hdc);
00297
00298 _pfnum = best_pfnum;
00299 _pfnum_supports_pbuffer = false;
00300 _pfnum_properties = best_prop;
00301 _pre_pfnum = _pfnum;
00302 _pre_pfnum_properties = _pfnum_properties;
00303
00304 if (best_quality == 0) {
00305 wgldisplay_cat.error()
00306 << "Could not find a usable pixel format.\n";
00307 return;
00308 }
00309
00310 if (wgldisplay_cat.is_debug()) {
00311 wgldisplay_cat.debug()
00312 << "Preliminary pixfmt #" << _pfnum << " = "
00313 << _pfnum_properties << "\n";
00314 }
00315
00316
00317
00318
00319
00320
00321
00322
00323
00324 HDC twindow_dc = get_twindow_dc();
00325 if (twindow_dc == 0) {
00326 return;
00327 }
00328
00329 HGLRC twindow_ctx = wglCreateContext(twindow_dc);
00330 if (twindow_ctx == 0) {
00331 return;
00332 }
00333
00334 wglGraphicsPipe::wgl_make_current(twindow_dc, twindow_ctx, NULL);
00335
00336 _extensions.clear();
00337 save_extensions((const char *)GLP(GetString)(GL_EXTENSIONS));
00338 get_extra_extensions();
00339 _supports_pixel_format = has_extension("WGL_ARB_pixel_format");
00340 _supports_wgl_multisample = has_extension("WGL_ARB_multisample");
00341 _extensions.clear();
00342
00343 if (!_supports_pixel_format) {
00344 wglDeleteContext(twindow_ctx);
00345 return;
00346 }
00347
00348 _wglGetPixelFormatAttribivARB =
00349 (PFNWGLGETPIXELFORMATATTRIBIVARBPROC)wglGetProcAddress("wglGetPixelFormatAttribivARB");
00350 _wglGetPixelFormatAttribfvARB =
00351 (PFNWGLGETPIXELFORMATATTRIBFVARBPROC)wglGetProcAddress("wglGetPixelFormatAttribfvARB");
00352 _wglChoosePixelFormatARB =
00353 (PFNWGLCHOOSEPIXELFORMATARBPROC)wglGetProcAddress("wglChoosePixelFormatARB");
00354
00355 if (_wglGetPixelFormatAttribivARB == NULL ||
00356 _wglGetPixelFormatAttribfvARB == NULL ||
00357 _wglChoosePixelFormatARB == NULL) {
00358 wgldisplay_cat.error()
00359 << "Driver claims to support WGL_ARB_pixel_format extension, but does not define all functions.\n";
00360 wglDeleteContext(twindow_ctx);
00361 return;
00362 }
00363
00364
00365
00366
00367 static const int max_attrib_list = 64;
00368 int iattrib_list[max_attrib_list];
00369 float fattrib_list[max_attrib_list];
00370 int ni = 0;
00371 int nf = 0;
00372
00373 iattrib_list[ni++] = WGL_SUPPORT_OPENGL_ARB;
00374 iattrib_list[ni++] = true;
00375 iattrib_list[ni++] = WGL_PIXEL_TYPE_ARB;
00376 iattrib_list[ni++] = WGL_TYPE_RGBA_ARB;
00377
00378 if (need_pbuffer) {
00379 iattrib_list[ni++] = WGL_DRAW_TO_PBUFFER_ARB;
00380 iattrib_list[ni++] = true;
00381 if (_pfnum_properties.get_alpha_bits()) {
00382 iattrib_list[ni++] = WGL_BIND_TO_TEXTURE_RGBA_ARB;
00383 iattrib_list[ni++] = true;
00384 } else {
00385 iattrib_list[ni++] = WGL_BIND_TO_TEXTURE_RGB_ARB;
00386 iattrib_list[ni++] = true;
00387 }
00388 }
00389
00390 nassertv(ni < max_attrib_list && nf < max_attrib_list);
00391 iattrib_list[ni] = 0;
00392 fattrib_list[nf] = 0;
00393
00394 static const int max_pformats = 1024;
00395 int pformat[max_pformats];
00396 memset(pformat, 0, sizeof(pformat));
00397 int nformats = 0;
00398
00399 if (!_wglChoosePixelFormatARB(twindow_dc, iattrib_list, fattrib_list,
00400 max_pformats, pformat, (unsigned int *)&nformats)) {
00401 nformats = 0;
00402 }
00403 nformats = min(nformats, max_pformats);
00404
00405 if (wgldisplay_cat.is_debug()) {
00406 wgldisplay_cat.debug()
00407 << "Found " << nformats << " advanced formats: [";
00408 for (int i = 0; i < nformats; i++) {
00409 wgldisplay_cat.debug(false)
00410 << " " << pformat[i];
00411 }
00412 wgldisplay_cat.debug(false)
00413 << " ]\n";
00414 }
00415
00416 if (nformats > 0) {
00417 if (need_pbuffer) {
00418 best_quality = 0;
00419 }
00420
00421 for (int i = 0; i < nformats; i++) {
00422 FrameBufferProperties pfprop;
00423 if (get_properties_advanced(pfprop, twindow_dc, pformat[i])) {
00424 int quality = pfprop.get_quality(properties);
00425 if (quality > best_quality) {
00426 best_pfnum = pformat[i];
00427 best_quality = quality;
00428 best_prop = pfprop;
00429 }
00430 }
00431 }
00432
00433 _pfnum = best_pfnum;
00434 _pfnum_supports_pbuffer = need_pbuffer;
00435 _pfnum_properties = best_prop;
00436
00437 if (wgldisplay_cat.is_debug()) {
00438 wgldisplay_cat.debug()
00439 << "Selected advanced pixfmt #" << _pfnum << " = "
00440 << _pfnum_properties << "\n";
00441 }
00442 }
00443
00444 wglDeleteContext(twindow_ctx);
00445 release_twindow();
00446 }
00447
00448
00449
00450
00451
00452
00453
00454 void wglGraphicsStateGuardian::
00455 reset() {
00456 GLGraphicsStateGuardian::reset();
00457
00458 _supports_swap_control = has_extension("WGL_EXT_swap_control");
00459
00460 if (_supports_swap_control) {
00461 _wglSwapIntervalEXT =
00462 (PFNWGLSWAPINTERVALEXTPROC)wglGetProcAddress("wglSwapIntervalEXT");
00463 if (_wglSwapIntervalEXT == NULL) {
00464 wgldisplay_cat.error()
00465 << "Driver claims to support WGL_EXT_swap_control extension, but does not define all functions.\n";
00466 _supports_swap_control = false;
00467 }
00468 }
00469
00470 if (_supports_swap_control) {
00471
00472
00473 _wglSwapIntervalEXT(sync_video ? 1 : 0);
00474 }
00475
00476 _supports_pbuffer = has_extension("WGL_ARB_pbuffer");
00477
00478 if (_supports_pbuffer) {
00479 _wglCreatePbufferARB =
00480 (PFNWGLCREATEPBUFFERARBPROC)wglGetProcAddress("wglCreatePbufferARB");
00481 _wglGetPbufferDCARB =
00482 (PFNWGLGETPBUFFERDCARBPROC)wglGetProcAddress("wglGetPbufferDCARB");
00483 _wglReleasePbufferDCARB =
00484 (PFNWGLRELEASEPBUFFERDCARBPROC)wglGetProcAddress("wglReleasePbufferDCARB");
00485 _wglDestroyPbufferARB =
00486 (PFNWGLDESTROYPBUFFERARBPROC)wglGetProcAddress("wglDestroyPbufferARB");
00487 _wglQueryPbufferARB =
00488 (PFNWGLQUERYPBUFFERARBPROC)wglGetProcAddress("wglQueryPbufferARB");
00489
00490 if (_wglCreatePbufferARB == NULL ||
00491 _wglGetPbufferDCARB == NULL ||
00492 _wglReleasePbufferDCARB == NULL ||
00493 _wglDestroyPbufferARB == NULL ||
00494 _wglQueryPbufferARB == NULL) {
00495 wgldisplay_cat.error()
00496 << "Driver claims to support WGL_ARB_pbuffer extension, but does not define all functions.\n";
00497 _supports_pbuffer = false;
00498 }
00499 }
00500
00501 _supports_pixel_format = has_extension("WGL_ARB_pixel_format");
00502
00503 if (_supports_pixel_format) {
00504 _wglGetPixelFormatAttribivARB =
00505 (PFNWGLGETPIXELFORMATATTRIBIVARBPROC)wglGetProcAddress("wglGetPixelFormatAttribivARB");
00506 _wglGetPixelFormatAttribfvARB =
00507 (PFNWGLGETPIXELFORMATATTRIBFVARBPROC)wglGetProcAddress("wglGetPixelFormatAttribfvARB");
00508 _wglChoosePixelFormatARB =
00509 (PFNWGLCHOOSEPIXELFORMATARBPROC)wglGetProcAddress("wglChoosePixelFormatARB");
00510
00511 if (_wglGetPixelFormatAttribivARB == NULL ||
00512 _wglGetPixelFormatAttribfvARB == NULL ||
00513 _wglChoosePixelFormatARB == NULL) {
00514 wgldisplay_cat.error()
00515 << "Driver claims to support WGL_ARB_pixel_format extension, but does not define all functions.\n";
00516 _supports_pixel_format = false;
00517 }
00518 }
00519
00520 _supports_wgl_multisample = has_extension("WGL_ARB_multisample");
00521
00522 _supports_wgl_render_texture = has_extension("WGL_ARB_render_texture");
00523
00524 if (_supports_wgl_render_texture) {
00525 _wglBindTexImageARB =
00526 (PFNWGLBINDTEXIMAGEARBPROC)wglGetProcAddress("wglBindTexImageARB");
00527 _wglReleaseTexImageARB =
00528 (PFNWGLRELEASETEXIMAGEARBPROC)wglGetProcAddress("wglReleaseTexImageARB");
00529 _wglSetPbufferAttribARB =
00530 (PFNWGLSETPBUFFERATTRIBARBPROC)wglGetProcAddress("wglSetPbufferAttribARB");
00531 if (_wglBindTexImageARB == NULL ||
00532 _wglReleaseTexImageARB == NULL ||
00533 _wglSetPbufferAttribARB == NULL) {
00534 wgldisplay_cat.error()
00535 << "Driver claims to support WGL_ARB_render_texture, but does not define all functions.\n";
00536 _supports_wgl_render_texture = false;
00537 }
00538 }
00539 }
00540
00541
00542
00543
00544
00545
00546
00547
00548
00549 void wglGraphicsStateGuardian::
00550 get_extra_extensions() {
00551
00552
00553
00554
00555
00556 PFNWGLGETEXTENSIONSSTRINGARBPROC wglGetExtensionsStringARB =
00557 (PFNWGLGETEXTENSIONSSTRINGARBPROC)wglGetProcAddress("wglGetExtensionsStringARB");
00558 if (wglGetExtensionsStringARB != NULL) {
00559 HDC hdc = wglGetCurrentDC();
00560 if (hdc != 0) {
00561 save_extensions((const char *)wglGetExtensionsStringARB(hdc));
00562 return;
00563 }
00564 }
00565
00566
00567
00568 PFNWGLGETEXTENSIONSSTRINGEXTPROC wglGetExtensionsStringEXT =
00569 (PFNWGLGETEXTENSIONSSTRINGEXTPROC)wglGetProcAddress("wglGetExtensionsStringEXT");
00570 if (wglGetExtensionsStringEXT != NULL) {
00571 save_extensions((const char *)wglGetExtensionsStringEXT());
00572 }
00573 }
00574
00575
00576
00577
00578
00579
00580
00581
00582
00583
00584
00585 void *wglGraphicsStateGuardian::
00586 do_get_extension_func(const char *prefix, const char *name) {
00587 string fullname = string(prefix) + string(name);
00588 return wglGetProcAddress(fullname.c_str());
00589 }
00590
00591
00592
00593
00594
00595
00596
00597
00598
00599 void wglGraphicsStateGuardian::
00600 make_context(HDC hdc) {
00601
00602 nassertv(!_made_context);
00603
00604 _made_context = true;
00605
00606
00607 wglGraphicsPipe::_current_valid = false;
00608 _context = wglCreateContext(hdc);
00609
00610 if (_context == NULL) {
00611 wgldisplay_cat.error()
00612 << "Could not create GL context.\n";
00613 _is_valid = false;
00614 return;
00615 }
00616
00617
00618 if (_share_with != (wglGraphicsStateGuardian *)NULL) {
00619 HGLRC share_context = _share_with->get_share_context();
00620 if (share_context == NULL) {
00621
00622
00623 _share_with->redirect_share_pool(this);
00624
00625 } else {
00626 if (!wglShareLists(share_context, _context)) {
00627 wgldisplay_cat.error()
00628 << "Could not share texture contexts between wglGraphicsStateGuardians.\n";
00629
00630
00631 _is_valid = false;
00632
00633 } else {
00634 _prepared_objects = _share_with->get_prepared_objects();
00635 }
00636 }
00637
00638 _share_with = (wglGraphicsStateGuardian *)NULL;
00639 }
00640 }
00641
00642
00643
00644
00645
00646
00647
00648
00649
00650
00651
00652
00653 HGLRC wglGraphicsStateGuardian::
00654 get_share_context() const {
00655 if (_made_context) {
00656 return _context;
00657 }
00658 if (_share_with != (wglGraphicsStateGuardian *)NULL) {
00659 return _share_with->get_share_context();
00660 }
00661 return NULL;
00662 }
00663
00664
00665
00666
00667
00668
00669
00670
00671
00672
00673
00674
00675
00676
00677 void wglGraphicsStateGuardian::
00678 redirect_share_pool(wglGraphicsStateGuardian *share_with) {
00679 nassertv(!_made_context);
00680 if (_share_with != (wglGraphicsStateGuardian *)NULL) {
00681 _share_with->redirect_share_pool(share_with);
00682 } else {
00683 _share_with = share_with;
00684 }
00685 }
00686
00687
00688
00689
00690
00691
00692
00693
00694
00695
00696
00697 bool wglGraphicsStateGuardian::
00698 make_twindow() {
00699 release_twindow();
00700
00701 DWORD window_style = 0;
00702
00703 register_twindow_class();
00704 HINSTANCE hinstance = GetModuleHandle(NULL);
00705 _twindow = CreateWindow(_twindow_class_name, "twindow", window_style,
00706 0, 0, 1, 1, NULL, NULL, hinstance, 0);
00707
00708 if (!_twindow) {
00709 wgldisplay_cat.error()
00710 << "CreateWindow() failed!" << endl;
00711 return false;
00712 }
00713
00714 ShowWindow(_twindow, SW_HIDE);
00715
00716 _twindow_dc = GetDC(_twindow);
00717
00718 PIXELFORMATDESCRIPTOR pixelformat;
00719 if (!SetPixelFormat(_twindow_dc, _pfnum, &pixelformat)) {
00720 wgldisplay_cat.error()
00721 << "SetPixelFormat(" << _pfnum << ") failed after window create\n";
00722 release_twindow();
00723 return false;
00724 }
00725
00726 return true;
00727 }
00728
00729
00730
00731
00732
00733
00734
00735
00736 void wglGraphicsStateGuardian::
00737 release_twindow() {
00738 if (_twindow_dc) {
00739 ReleaseDC(_twindow, _twindow_dc);
00740 _twindow_dc = 0;
00741 }
00742 if (_twindow) {
00743 DestroyWindow(_twindow);
00744 _twindow = 0;
00745 }
00746 }
00747
00748
00749
00750
00751
00752
00753
00754
00755 void wglGraphicsStateGuardian::
00756 register_twindow_class() {
00757 if (_twindow_class_registered) {
00758 return;
00759 }
00760
00761 WNDCLASS wc;
00762
00763 HINSTANCE instance = GetModuleHandle(NULL);
00764
00765
00766 ZeroMemory(&wc, sizeof(WNDCLASS));
00767 wc.style = CS_OWNDC;
00768 wc.lpfnWndProc = DefWindowProc;
00769 wc.hInstance = instance;
00770 wc.lpszClassName = _twindow_class_name;
00771
00772 if (!RegisterClass(&wc)) {
00773 wgldisplay_cat.error()
00774 << "could not register window class!" << endl;
00775 return;
00776 }
00777 _twindow_class_registered = true;
00778 }
00779
00780 #define GAMMA_1 (255.0 * 256.0)
00781
00782 static bool _gamma_table_initialized = false;
00783 static unsigned short _orignial_gamma_table [256 * 3];
00784
00785 void _create_gamma_table (PN_stdfloat gamma, unsigned short *original_red_table, unsigned short *original_green_table, unsigned short *original_blue_table, unsigned short *red_table, unsigned short *green_table, unsigned short *blue_table) {
00786 int i;
00787 double gamma_correction;
00788
00789 if (gamma <= 0.0) {
00790
00791 gamma = 1.0;
00792 }
00793 gamma_correction = 1.0 / (double) gamma;
00794
00795 for (i = 0; i < 256; i++) {
00796 double r;
00797 double g;
00798 double b;
00799
00800 if (original_red_table) {
00801 r = (double) original_red_table [i] / GAMMA_1;
00802 g = (double) original_green_table [i] / GAMMA_1;
00803 b = (double) original_blue_table [i] / GAMMA_1;
00804 }
00805 else {
00806 r = ((double) i / 255.0);
00807 g = r;
00808 b = r;
00809 }
00810
00811 r = pow (r, gamma_correction);
00812 g = pow (g, gamma_correction);
00813 b = pow (b, gamma_correction);
00814
00815 if (r > 1.00) {
00816 r = 1.0;
00817 }
00818 if (g > 1.00) {
00819 g = 1.0;
00820 }
00821 if (b > 1.00) {
00822 b = 1.0;
00823 }
00824
00825 r = r * GAMMA_1;
00826 g = g * GAMMA_1;
00827 b = b * GAMMA_1;
00828
00829 red_table [i] = r;
00830 green_table [i] = g;
00831 blue_table [i] = b;
00832 }
00833 }
00834
00835
00836
00837
00838
00839
00840 bool wglGraphicsStateGuardian::
00841 get_gamma_table(void) {
00842 bool get;
00843
00844 get = false;
00845 if (_gamma_table_initialized == false) {
00846 HDC hdc = GetDC(NULL);
00847
00848 if (hdc) {
00849 if (GetDeviceGammaRamp (hdc, (LPVOID) _orignial_gamma_table)) {
00850 _gamma_table_initialized = true;
00851 get = true;
00852 }
00853
00854 ReleaseDC (NULL, hdc);
00855 }
00856 }
00857
00858 return get;
00859 }
00860
00861
00862
00863
00864
00865
00866
00867 bool wglGraphicsStateGuardian::
00868 static_set_gamma(bool restore, PN_stdfloat gamma) {
00869 bool set;
00870 HDC hdc = GetDC(NULL);
00871
00872 set = false;
00873 if (hdc) {
00874 unsigned short ramp [256 * 3];
00875
00876 if (restore && _gamma_table_initialized) {
00877 _create_gamma_table (gamma, &_orignial_gamma_table [0], &_orignial_gamma_table [256], &_orignial_gamma_table [512], &ramp [0], &ramp [256], &ramp [512]);
00878 }
00879 else {
00880 _create_gamma_table (gamma, 0, 0, 0, &ramp [0], &ramp [256], &ramp [512]);
00881 }
00882
00883 if (SetDeviceGammaRamp (hdc, ramp)) {
00884 set = true;
00885 }
00886
00887 ReleaseDC (NULL, hdc);
00888 }
00889
00890 return set;
00891 }
00892
00893
00894
00895
00896
00897
00898
00899 bool wglGraphicsStateGuardian::
00900 set_gamma(PN_stdfloat gamma) {
00901 bool set;
00902
00903 set = static_set_gamma(false, gamma);
00904 if (set) {
00905 _gamma = gamma;
00906 }
00907
00908 return set;
00909 }
00910
00911
00912
00913
00914
00915
00916 void wglGraphicsStateGuardian::
00917 restore_gamma() {
00918 static_set_gamma(true, 1.0f);
00919 }
00920
00921
00922
00923
00924
00925
00926 void wglGraphicsStateGuardian::
00927 atexit_function(void) {
00928 static_set_gamma(true, 1.0);
00929 }