Blender V4.3
GHOST_ContextWGL.cc
Go to the documentation of this file.
1/* SPDX-FileCopyrightText: 2013 Blender Authors
2 *
3 * SPDX-License-Identifier: GPL-2.0-or-later */
4
11#include "GHOST_ContextWGL.hh"
12
13#include <tchar.h>
14
15#include <cassert>
16#include <cstdio>
17#include <vector>
18
19HGLRC GHOST_ContextWGL::s_sharedHGLRC = nullptr;
20int GHOST_ContextWGL::s_sharedCount = 0;
21
22/* Some third-generation Intel video-cards are constantly bring problems */
24{
25 return strstr((const char *)glGetString(GL_VENDOR), "Intel") != nullptr;
26}
27
29 bool alphaBackground,
30 HWND hWnd,
31 HDC hDC,
32 int contextProfileMask,
33 int contextMajorVersion,
34 int contextMinorVersion,
35 int contextFlags,
36 int contextResetNotificationStrategy)
37 : GHOST_Context(stereoVisual),
38 m_hWnd(hWnd),
39 m_hDC(hDC),
40 m_contextProfileMask(contextProfileMask),
41 m_contextMajorVersion(contextMajorVersion),
42 m_contextMinorVersion(contextMinorVersion),
43 m_contextFlags(contextFlags),
44 m_alphaBackground(alphaBackground),
45 m_contextResetNotificationStrategy(contextResetNotificationStrategy),
46 m_hGLRC(nullptr)
47#ifndef NDEBUG
48 ,
49 m_dummyVendor(nullptr),
50 m_dummyRenderer(nullptr),
51 m_dummyVersion(nullptr)
52#endif
53{
54 assert(m_hDC != nullptr);
55}
56
58{
59 if (m_hGLRC != nullptr) {
60 if (m_hGLRC == ::wglGetCurrentContext())
61 WIN32_CHK(::wglMakeCurrent(nullptr, nullptr));
62
63 if (m_hGLRC != s_sharedHGLRC || s_sharedCount == 1) {
64 assert(s_sharedCount > 0);
65
66 s_sharedCount--;
67
68 if (s_sharedCount == 0) {
69 s_sharedHGLRC = nullptr;
70 }
71
72 WIN32_CHK(::wglDeleteContext(m_hGLRC));
73 }
74 }
75
76#ifndef NDEBUG
77 if (m_dummyRenderer) {
78 free((void *)m_dummyRenderer);
79 free((void *)m_dummyVendor);
80 free((void *)m_dummyVersion);
81 }
82#endif
83}
84
86{
87 return WIN32_CHK(::SwapBuffers(m_hDC)) ? GHOST_kSuccess : GHOST_kFailure;
88}
89
91{
92 if (epoxy_has_wgl_extension(m_hDC, "WGL_EXT_swap_control")) {
93 return WIN32_CHK(::wglSwapIntervalEXT(interval)) == TRUE ? GHOST_kSuccess : GHOST_kFailure;
94 }
95 else {
96 return GHOST_kFailure;
97 }
98}
99
101{
102 if (epoxy_has_wgl_extension(m_hDC, "WGL_EXT_swap_control")) {
103 intervalOut = ::wglGetSwapIntervalEXT();
104 return GHOST_kSuccess;
105 }
106 else {
107 return GHOST_kFailure;
108 }
109}
110
112{
113 if (WIN32_CHK(::wglMakeCurrent(m_hDC, m_hGLRC))) {
114 return GHOST_kSuccess;
115 }
116 else {
117 return GHOST_kFailure;
118 }
119}
120
122{
123 if (WIN32_CHK(::wglMakeCurrent(nullptr, nullptr))) {
124 return GHOST_kSuccess;
125 }
126 else {
127 return GHOST_kFailure;
128 }
129}
130
131/* Ron Fosner's code for weighting pixel formats and forcing software.
132 * See http://www.opengl.org/resources/faq/technical/weight.cpp
133 */
134static int weight_pixel_format(PIXELFORMATDESCRIPTOR &pfd, PIXELFORMATDESCRIPTOR &preferredPFD)
135{
136 int weight = 0;
137
138 /* assume desktop color depth is 32 bits per pixel */
139
140 /* cull unusable pixel formats */
141 /* if no formats can be found, can we determine why it was rejected? */
142 if (!(pfd.dwFlags & PFD_SUPPORT_OPENGL) || !(pfd.dwFlags & PFD_DRAW_TO_WINDOW) ||
143 !(pfd.dwFlags & PFD_DOUBLEBUFFER) || /* Blender _needs_ this. */
144 !(pfd.iPixelType == PFD_TYPE_RGBA) ||
145 (pfd.cColorBits > 32) || /* 64 bit formats disable AERO. */
146 (pfd.dwFlags & PFD_GENERIC_FORMAT)) /* No software renderers. */
147 {
148 return 0;
149 }
150
151 weight = 1; /* it's usable */
152
153 weight += pfd.cColorBits - 8;
154
155 if (preferredPFD.cAlphaBits > 0 && pfd.cAlphaBits > 0) {
156 weight++;
157 }
158#ifdef WIN32_COMPOSITING
159 if ((preferredPFD.dwFlags & PFD_SUPPORT_COMPOSITION) && (pfd.dwFlags & PFD_SUPPORT_COMPOSITION))
160 weight++;
161#endif
162
163 return weight;
164}
165
166/*
167 * A modification of Ron Fosner's replacement for ChoosePixelFormat
168 * returns 0 on error, else returns the pixel format number to be used
169 */
170static int choose_pixel_format_legacy(HDC hDC, PIXELFORMATDESCRIPTOR &preferredPFD)
171{
172 int iPixelFormat = 0;
173 int weight = 0;
174
175 int iStereoPixelFormat = 0;
176 int stereoWeight = 0;
177
178 /* choose a pixel format using the useless Windows function in case we come up empty handed */
179 int iLastResortPixelFormat = ::ChoosePixelFormat(hDC, &preferredPFD);
180
181 WIN32_CHK(iLastResortPixelFormat != 0);
182
183 int lastPFD = ::DescribePixelFormat(hDC, 1, sizeof(PIXELFORMATDESCRIPTOR), nullptr);
184
185 WIN32_CHK(lastPFD != 0);
186
187 for (int i = 1; i <= lastPFD; i++) {
188 PIXELFORMATDESCRIPTOR pfd;
189 int check = ::DescribePixelFormat(hDC, i, sizeof(PIXELFORMATDESCRIPTOR), &pfd);
190
191 WIN32_CHK(check == lastPFD);
192
193 int w = weight_pixel_format(pfd, preferredPFD);
194
195 if (w > weight) {
196 weight = w;
197 iPixelFormat = i;
198 }
199
200 if (w > stereoWeight && (preferredPFD.dwFlags & pfd.dwFlags & PFD_STEREO)) {
201 stereoWeight = w;
202 iStereoPixelFormat = i;
203 }
204 }
205
206 /* choose any available stereo format over a non-stereo format */
207 if (iStereoPixelFormat != 0) {
208 iPixelFormat = iStereoPixelFormat;
209 }
210
211 if (iPixelFormat == 0) {
212 fprintf(stderr, "Warning! Using result of ChoosePixelFormat.\n");
213 iPixelFormat = iLastResortPixelFormat;
214 }
215
216 return iPixelFormat;
217}
218
224static HWND clone_window(HWND hWnd, LPVOID lpParam)
225{
226 int count;
227
228 SetLastError(NO_ERROR);
229
230 DWORD dwExStyle = GetWindowLong(hWnd, GWL_EXSTYLE);
231 WIN32_CHK(GetLastError() == NO_ERROR);
232
233 WCHAR lpClassName[100] = L"";
234 count = GetClassNameW(hWnd, lpClassName, sizeof(lpClassName));
235 WIN32_CHK(count != 0);
236
237 WCHAR lpWindowName[100] = L"";
238 count = GetWindowTextW(hWnd, lpWindowName, sizeof(lpWindowName));
239 WIN32_CHK(count != 0);
240
241 DWORD dwStyle = GetWindowLong(hWnd, GWL_STYLE);
242 WIN32_CHK(GetLastError() == NO_ERROR);
243
244 RECT rect;
245 GetWindowRect(hWnd, &rect);
246 WIN32_CHK(GetLastError() == NO_ERROR);
247
248 HWND hWndParent = (HWND)GetWindowLongPtr(hWnd, GWLP_HWNDPARENT);
249 WIN32_CHK(GetLastError() == NO_ERROR);
250
251 HMENU hMenu = GetMenu(hWnd);
252 WIN32_CHK(GetLastError() == NO_ERROR);
253
254 HINSTANCE hInstance = (HINSTANCE)GetWindowLongPtr(hWnd, GWLP_HINSTANCE);
255 WIN32_CHK(GetLastError() == NO_ERROR);
256
257 HWND hwndCloned = CreateWindowExW(dwExStyle,
258 lpClassName,
259 lpWindowName,
260 dwStyle,
261 rect.left,
262 rect.top,
263 rect.right - rect.left,
264 rect.bottom - rect.top,
265 hWndParent,
266 hMenu,
267 hInstance,
268 lpParam);
269
270 WIN32_CHK(hwndCloned != nullptr);
271
272 return hwndCloned;
273}
274
275static void makeAttribList(std::vector<int> &out, bool stereoVisual, bool needAlpha)
276{
277 out.clear();
278 out.reserve(30);
279
280 out.push_back(WGL_SUPPORT_OPENGL_ARB);
281 out.push_back(GL_TRUE);
282
283 out.push_back(WGL_DRAW_TO_WINDOW_ARB);
284 out.push_back(GL_TRUE);
285
286 out.push_back(WGL_DOUBLE_BUFFER_ARB);
287 out.push_back(GL_TRUE);
288
289 out.push_back(WGL_ACCELERATION_ARB);
290 out.push_back(WGL_FULL_ACCELERATION_ARB);
291
292 if (stereoVisual) {
293 out.push_back(WGL_STEREO_ARB);
294 out.push_back(GL_TRUE);
295 }
296
297 out.push_back(WGL_PIXEL_TYPE_ARB);
298 out.push_back(WGL_TYPE_RGBA_ARB);
299
300 out.push_back(WGL_COLOR_BITS_ARB);
301 out.push_back(24);
302
303 if (needAlpha) {
304 out.push_back(WGL_ALPHA_BITS_ARB);
305 out.push_back(8);
306 }
307
308 out.push_back(0);
309}
310
311/* Temporary context used to create the actual context. We need ARB pixel format
312 * and context extensions, which are only available within a context. */
314 HWND dummyHWND = nullptr;
315
316 HDC dummyHDC = nullptr;
317 HGLRC dummyHGLRC = nullptr;
318
319 HDC prevHDC = nullptr;
320 HGLRC prevHGLRC = nullptr;
321
323
324 PIXELFORMATDESCRIPTOR preferredPFD;
325
330
331 DummyContextWGL(HDC hDC, HWND hWnd, bool stereoVisual, bool needAlpha)
332 {
333 preferredPFD = {
334 sizeof(PIXELFORMATDESCRIPTOR), /* size */
335 1, /* version */
336 (DWORD)(PFD_SUPPORT_OPENGL | PFD_DRAW_TO_WINDOW |
337 PFD_DOUBLEBUFFER | /* support double-buffering */
338 (stereoVisual ? PFD_STEREO : 0) | /* support stereo */
339 (
340#ifdef WIN32_COMPOSITING
341 /* Support composition for transparent background. */
342 needAlpha ? PFD_SUPPORT_COMPOSITION :
343#endif
344 0)),
345 PFD_TYPE_RGBA, /* color type */
346 (BYTE)(needAlpha ? 32 : 24), /* preferred color depth */
347 0,
348 0,
349 0,
350 0,
351 0,
352 0, /* color bits (ignored) */
353 (BYTE)(needAlpha ? 8 : 0), /* alpha buffer */
354 0, /* alpha shift (ignored) */
355 0, /* no accumulation buffer */
356 0,
357 0,
358 0,
359 0, /* Accumulation bits (ignored). */
360 0, /* depth buffer */
361 0, /* stencil buffer */
362 0, /* no auxiliary buffers */
363 PFD_MAIN_PLANE, /* main layer */
364 0, /* reserved */
365 0,
366 0,
367 0 /* layer, visible, and damage masks (ignored) */
368 };
369
370 SetLastError(NO_ERROR);
371
372 prevHDC = ::wglGetCurrentDC();
373 WIN32_CHK(GetLastError() == NO_ERROR);
374
375 prevHGLRC = ::wglGetCurrentContext();
376 WIN32_CHK(GetLastError() == NO_ERROR);
377
379
380 if (dummyPixelFormat == 0) {
381 return;
382 }
383
384 PIXELFORMATDESCRIPTOR chosenPFD;
385 if (!WIN32_CHK(::DescribePixelFormat(
386 hDC, dummyPixelFormat, sizeof(PIXELFORMATDESCRIPTOR), &chosenPFD)))
387 {
388 return;
389 }
390
391 if (hWnd) {
392 dummyHWND = clone_window(hWnd, nullptr);
393
394 if (dummyHWND == nullptr) {
395 return;
396 }
397
398 dummyHDC = GetDC(dummyHWND);
399 }
400
401 if (!WIN32_CHK(dummyHDC != nullptr)) {
402 return;
403 }
404
405 if (!WIN32_CHK(::SetPixelFormat(dummyHDC, dummyPixelFormat, &chosenPFD))) {
406 return;
407 }
408
409 dummyHGLRC = ::wglCreateContext(dummyHDC);
410
411 if (!WIN32_CHK(dummyHGLRC != nullptr)) {
412 return;
413 }
414
415 if (!WIN32_CHK(::wglMakeCurrent(dummyHDC, dummyHGLRC))) {
416 return;
417 }
418
419 has_WGL_ARB_pixel_format = epoxy_has_wgl_extension(hDC, "WGL_ARB_pixel_format");
420 has_WGL_ARB_create_context = epoxy_has_wgl_extension(hDC, "WGL_ARB_create_context");
421 has_WGL_ARB_create_context_profile = epoxy_has_wgl_extension(hDC,
422 "WGL_ARB_create_context_profile");
423 has_WGL_ARB_create_context_robustness = epoxy_has_wgl_extension(
424 hDC, "WGL_ARB_create_context_robustness");
425 }
426
428 {
429 WIN32_CHK(::wglMakeCurrent(prevHDC, prevHGLRC));
430
431 if (dummyHGLRC != nullptr)
432 WIN32_CHK(::wglDeleteContext(dummyHGLRC));
433
434 if (dummyHWND != nullptr) {
435 if (dummyHDC != nullptr)
436 WIN32_CHK(::ReleaseDC(dummyHWND, dummyHDC));
437
438 WIN32_CHK(::DestroyWindow(dummyHWND));
439 }
440 }
441};
442
443int GHOST_ContextWGL::_choose_pixel_format_arb_1(bool stereoVisual, bool needAlpha)
444{
445 std::vector<int> iAttributes;
446
447#define _MAX_PIXEL_FORMATS 32
448
449 int iPixelFormat = 0;
450 int iPixelFormats[_MAX_PIXEL_FORMATS];
451
452 makeAttribList(iAttributes, stereoVisual, needAlpha);
453
454 uint nNumFormats;
455 WIN32_CHK(wglChoosePixelFormatARB(
456 m_hDC, &(iAttributes[0]), nullptr, _MAX_PIXEL_FORMATS, iPixelFormats, &nNumFormats));
457
458 if (nNumFormats > 0) {
459 iPixelFormat = iPixelFormats[0];
460
461#ifdef WIN32_COMPOSITING
462 if (needAlpha) {
463 // scan through all pixel format to make sure one supports compositing
464 PIXELFORMATDESCRIPTOR pfd;
465 int i;
466
467 for (i = 0; i < nNumFormats; i++) {
468 if (DescribePixelFormat(m_hDC, iPixelFormats[i], sizeof(PIXELFORMATDESCRIPTOR), &pfd)) {
469 if (pfd.dwFlags & PFD_SUPPORT_COMPOSITION) {
470 iPixelFormat = iPixelFormats[i];
471 break;
472 }
473 }
474 }
475 if (i == nNumFormats) {
476 fprintf(stderr, "Warning! Unable to find a pixel format with compositing capability.\n");
477 }
478 }
479#endif
480 }
481
482 // check pixel format
483 if (iPixelFormat != 0) {
484 if (needAlpha) {
485 int alphaBits, iQuery = WGL_ALPHA_BITS_ARB;
486 wglGetPixelFormatAttribivARB(m_hDC, iPixelFormat, 0, 1, &iQuery, &alphaBits);
487 if (alphaBits == 0) {
488 fprintf(stderr, "Warning! Unable to find a frame buffer with alpha channel.\n");
489 }
490 }
491 }
492 return iPixelFormat;
493}
494
495int GHOST_ContextWGL::choose_pixel_format_arb(bool stereoVisual, bool needAlpha)
496{
497 int iPixelFormat;
498
499 iPixelFormat = _choose_pixel_format_arb_1(stereoVisual, needAlpha);
500
501 if (iPixelFormat == 0 && stereoVisual) {
502 fprintf(stderr, "Warning! Unable to find a stereo pixel format.\n");
503
504 iPixelFormat = _choose_pixel_format_arb_1(false, needAlpha);
505
506 m_stereoVisual = false; // set context property to actual value
507 }
508
509 return iPixelFormat;
510}
511
512#ifndef NDEBUG
513static void reportContextString(const char *name, const char *dummy, const char *context)
514{
515 fprintf(stderr, "%s: %s\n", name, context);
516
517 if (dummy && strcmp(dummy, context) != 0)
518 fprintf(stderr, "Warning! Dummy %s: %s\n", name, dummy);
519}
520#endif
521
523{
524 SetLastError(NO_ERROR);
525
526 HGLRC prevHGLRC = ::wglGetCurrentContext();
527 WIN32_CHK(GetLastError() == NO_ERROR);
528
529 HDC prevHDC = ::wglGetCurrentDC();
530 WIN32_CHK(GetLastError() == NO_ERROR);
531
532 {
533 const bool needAlpha = m_alphaBackground;
534 DummyContextWGL dummy(m_hDC, m_hWnd, m_stereoVisual, needAlpha);
535
536 if (!dummy.has_WGL_ARB_create_context || ::GetPixelFormat(m_hDC) == 0) {
537 int iPixelFormat = 0;
538
539 if (dummy.has_WGL_ARB_pixel_format) {
540 iPixelFormat = choose_pixel_format_arb(m_stereoVisual, needAlpha);
541 }
542
543 if (iPixelFormat == 0)
544 iPixelFormat = choose_pixel_format_legacy(m_hDC, dummy.preferredPFD);
545
546 if (iPixelFormat == 0) {
547 goto error;
548 }
549
550 PIXELFORMATDESCRIPTOR chosenPFD;
551 int lastPFD = ::DescribePixelFormat(
552 m_hDC, iPixelFormat, sizeof(PIXELFORMATDESCRIPTOR), &chosenPFD);
553
554 if (!WIN32_CHK(lastPFD != 0)) {
555 goto error;
556 }
557
558 if (needAlpha && chosenPFD.cAlphaBits == 0) {
559 fprintf(stderr, "Warning! Unable to find a pixel format with an alpha channel.\n");
560 }
561
562 if (!WIN32_CHK(::SetPixelFormat(m_hDC, iPixelFormat, &chosenPFD))) {
563 goto error;
564 }
565 }
566
567 if (dummy.has_WGL_ARB_create_context) {
568 int profileBitCore = m_contextProfileMask & WGL_CONTEXT_CORE_PROFILE_BIT_ARB;
569 int profileBitCompat = m_contextProfileMask & WGL_CONTEXT_COMPATIBILITY_PROFILE_BIT_ARB;
570
571 if (!dummy.has_WGL_ARB_create_context_profile && profileBitCore) {
572 fprintf(stderr, "Warning! OpenGL core profile not available.\n");
573 }
574
575 if (!dummy.has_WGL_ARB_create_context_profile && profileBitCompat) {
576 fprintf(stderr, "Warning! OpenGL compatibility profile not available.\n");
577 }
578
579 int profileMask = 0;
580
581 if (dummy.has_WGL_ARB_create_context_profile && profileBitCore) {
582 profileMask |= profileBitCore;
583 }
584
585 if (dummy.has_WGL_ARB_create_context_profile && profileBitCompat) {
586 profileMask |= profileBitCompat;
587 }
588
589 if (profileMask != m_contextProfileMask) {
590 fprintf(stderr, "Warning! Ignoring untested OpenGL context profile mask bits.");
591 }
592
593 std::vector<int> iAttributes;
594
595 if (profileMask) {
596 iAttributes.push_back(WGL_CONTEXT_PROFILE_MASK_ARB);
597 iAttributes.push_back(profileMask);
598 }
599
600 if (m_contextMajorVersion != 0) {
601 iAttributes.push_back(WGL_CONTEXT_MAJOR_VERSION_ARB);
602 iAttributes.push_back(m_contextMajorVersion);
603 }
604
605 if (m_contextMinorVersion != 0) {
606 iAttributes.push_back(WGL_CONTEXT_MINOR_VERSION_ARB);
607 iAttributes.push_back(m_contextMinorVersion);
608 }
609
610 if (m_contextFlags != 0) {
611 iAttributes.push_back(WGL_CONTEXT_FLAGS_ARB);
612 iAttributes.push_back(m_contextFlags);
613 }
614
615 if (m_contextResetNotificationStrategy != 0) {
617 iAttributes.push_back(WGL_CONTEXT_RESET_NOTIFICATION_STRATEGY_ARB);
618 iAttributes.push_back(m_contextResetNotificationStrategy);
619 }
620 else {
621 fprintf(stderr, "Warning! Cannot set the reset notification strategy.");
622 }
623 }
624
625 iAttributes.push_back(0);
626
627 m_hGLRC = ::wglCreateContextAttribsARB(m_hDC, nullptr, &(iAttributes[0]));
628 }
629 }
630
631 /* Silence warnings interpreted as errors by users when trying to get
632 * a context with version higher than 3.3 Core. */
633 {
634 const bool silent = m_contextMajorVersion > 3;
635 if (!WIN32_CHK_SILENT(m_hGLRC != nullptr, silent)) {
636 goto error;
637 }
638 }
639
640 s_sharedCount++;
641
642 if (s_sharedHGLRC == nullptr) {
643 s_sharedHGLRC = m_hGLRC;
644 }
645 else if (!WIN32_CHK(::wglShareLists(s_sharedHGLRC, m_hGLRC))) {
646 goto error;
647 }
648
649 if (!WIN32_CHK(::wglMakeCurrent(m_hDC, m_hGLRC))) {
650 goto error;
651 }
652
653 if (is_crappy_intel_card()) {
654 /* Some Intel cards with context 4.1 or 4.2
655 * don't have the point sprite enabled by default.
656 *
657 * However GL_POINT_SPRITE was removed in 3.2 and is now permanently ON.
658 * Then use brute force. */
659 glEnable(GL_POINT_SPRITE);
660 }
661
662 initClearGL();
663 ::SwapBuffers(m_hDC);
664
665#ifndef NDEBUG
666 {
667 const char *vendor = reinterpret_cast<const char *>(glGetString(GL_VENDOR));
668 const char *renderer = reinterpret_cast<const char *>(glGetString(GL_RENDERER));
669 const char *version = reinterpret_cast<const char *>(glGetString(GL_VERSION));
670
671 reportContextString("Vendor", m_dummyVendor, vendor);
672 reportContextString("Renderer", m_dummyRenderer, renderer);
673 reportContextString("Version", m_dummyVersion, version);
674
675 fprintf(stderr, "Context Version: %d.%d\n", m_contextMajorVersion, m_contextMinorVersion);
676 }
677#endif
678
679 return GHOST_kSuccess;
680error:
681 ::wglMakeCurrent(prevHDC, prevHGLRC);
682 return GHOST_kFailure;
683}
684
686{
687 GHOST_TSuccess success = m_hGLRC != s_sharedHGLRC || s_sharedCount == 1 ? GHOST_kSuccess :
689
690 m_hWnd = nullptr;
691 m_hDC = nullptr;
692
693 return success;
694}
void BLI_kdtree_nd_ free(KDTree *tree)
unsigned int uint
static void makeAttribList(std::vector< int > &out, bool stereoVisual, bool needAlpha)
static int choose_pixel_format_legacy(HDC hDC, PIXELFORMATDESCRIPTOR &preferredPFD)
#define _MAX_PIXEL_FORMATS
static int weight_pixel_format(PIXELFORMATDESCRIPTOR &pfd, PIXELFORMATDESCRIPTOR &preferredPFD)
static void reportContextString(const char *name, const char *dummy, const char *context)
static bool is_crappy_intel_card()
static HWND clone_window(HWND hWnd, LPVOID lpParam)
GHOST_TSuccess
Definition GHOST_Types.h:87
@ GHOST_kFailure
Definition GHOST_Types.h:87
@ GHOST_kSuccess
Definition GHOST_Types.h:87
SIMD_FORCE_INLINE const btScalar & w() const
Return the w value.
Definition btQuadWord.h:119
GHOST_ContextWGL(bool stereoVisual, bool alphaBackground, HWND hWnd, HDC hDC, int contextProfileMask, int contextMajorVersion, int contextMinorVersion, int contextFlags, int contextResetNotificationStrategy)
GHOST_TSuccess activateDrawingContext()
GHOST_TSuccess getSwapInterval(int &intervalOut)
GHOST_TSuccess swapBuffers()
GHOST_TSuccess releaseNativeHandles()
GHOST_TSuccess initializeDrawingContext()
GHOST_TSuccess releaseDrawingContext()
GHOST_TSuccess setSwapInterval(int interval)
int count
#define L
static void error(const char *str)
bool has_WGL_ARB_create_context_robustness
PIXELFORMATDESCRIPTOR preferredPFD
DummyContextWGL(HDC hDC, HWND hWnd, bool stereoVisual, bool needAlpha)
bool has_WGL_ARB_create_context_profile