18 HGLRC GHOST_ContextWGL::s_sharedHGLRC =
NULL;
19 int GHOST_ContextWGL::s_sharedCount = 0;
24 return strstr((
const char *)glGetString(GL_VENDOR),
"Intel") !=
NULL;
31 int contextProfileMask,
32 int contextMajorVersion,
33 int contextMinorVersion,
35 int contextResetNotificationStrategy)
39 m_contextProfileMask(contextProfileMask),
40 m_contextMajorVersion(contextMajorVersion),
41 m_contextMinorVersion(contextMinorVersion),
42 m_contextFlags(contextFlags),
43 m_alphaBackground(alphaBackground),
44 m_contextResetNotificationStrategy(contextResetNotificationStrategy),
49 m_dummyRenderer(
NULL),
53 assert(m_hDC !=
NULL);
58 if (m_hGLRC !=
NULL) {
59 if (m_hGLRC == ::wglGetCurrentContext())
60 WIN32_CHK(::wglMakeCurrent(
NULL,
NULL));
62 if (m_hGLRC != s_sharedHGLRC || s_sharedCount == 1) {
63 assert(s_sharedCount > 0);
67 if (s_sharedCount == 0)
70 WIN32_CHK(::wglDeleteContext(m_hGLRC));
75 if (m_dummyRenderer) {
76 free((
void *)m_dummyRenderer);
77 free((
void *)m_dummyVendor);
78 free((
void *)m_dummyVersion);
90 if (WGLEW_EXT_swap_control)
98 if (WGLEW_EXT_swap_control) {
99 intervalOut = ::wglGetSwapIntervalEXT();
109 if (WIN32_CHK(::wglMakeCurrent(m_hDC, m_hGLRC))) {
119 if (WIN32_CHK(::wglMakeCurrent(
NULL,
NULL))) {
138 if (!(pfd.dwFlags & PFD_SUPPORT_OPENGL) || !(pfd.dwFlags & PFD_DRAW_TO_WINDOW) ||
139 !(pfd.dwFlags & PFD_DOUBLEBUFFER) ||
140 !(pfd.iPixelType == PFD_TYPE_RGBA) ||
141 (pfd.cColorBits > 32) ||
142 (pfd.dwFlags & PFD_GENERIC_FORMAT))
149 weight += pfd.cColorBits - 8;
151 if (preferredPFD.cAlphaBits > 0 && pfd.cAlphaBits > 0)
153 #ifdef WIN32_COMPOSITING
154 if ((preferredPFD.dwFlags & PFD_SUPPORT_COMPOSITION) && (pfd.dwFlags & PFD_SUPPORT_COMPOSITION))
167 int iPixelFormat = 0;
170 int iStereoPixelFormat = 0;
171 int stereoWeight = 0;
174 int iLastResortPixelFormat = ::ChoosePixelFormat(hDC, &preferredPFD);
176 WIN32_CHK(iLastResortPixelFormat != 0);
178 int lastPFD = ::DescribePixelFormat(hDC, 1,
sizeof(PIXELFORMATDESCRIPTOR),
NULL);
180 WIN32_CHK(lastPFD != 0);
182 for (
int i = 1; i <= lastPFD; i++) {
183 PIXELFORMATDESCRIPTOR pfd;
184 int check = ::DescribePixelFormat(hDC, i,
sizeof(PIXELFORMATDESCRIPTOR), &pfd);
186 WIN32_CHK(check == lastPFD);
195 if (
w > stereoWeight && (preferredPFD.dwFlags & pfd.dwFlags & PFD_STEREO)) {
197 iStereoPixelFormat = i;
202 if (iStereoPixelFormat != 0)
203 iPixelFormat = iStereoPixelFormat;
205 if (iPixelFormat == 0) {
206 fprintf(stderr,
"Warning! Using result of ChoosePixelFormat.\n");
207 iPixelFormat = iLastResortPixelFormat;
222 SetLastError(NO_ERROR);
224 DWORD dwExStyle = GetWindowLong(hWnd, GWL_EXSTYLE);
225 WIN32_CHK(GetLastError() == NO_ERROR);
227 WCHAR lpClassName[100] =
L"";
228 count = GetClassNameW(hWnd, lpClassName,
sizeof(lpClassName));
229 WIN32_CHK(
count != 0);
231 WCHAR lpWindowName[100] =
L"";
232 count = GetWindowTextW(hWnd, lpWindowName,
sizeof(lpWindowName));
233 WIN32_CHK(
count != 0);
235 DWORD dwStyle = GetWindowLong(hWnd, GWL_STYLE);
236 WIN32_CHK(GetLastError() == NO_ERROR);
239 GetWindowRect(hWnd, &rect);
240 WIN32_CHK(GetLastError() == NO_ERROR);
242 HWND hWndParent = (HWND)GetWindowLongPtr(hWnd, GWLP_HWNDPARENT);
243 WIN32_CHK(GetLastError() == NO_ERROR);
245 HMENU hMenu = GetMenu(hWnd);
246 WIN32_CHK(GetLastError() == NO_ERROR);
248 HINSTANCE hInstance = (HINSTANCE)GetWindowLongPtr(hWnd, GWLP_HINSTANCE);
249 WIN32_CHK(GetLastError() == NO_ERROR);
251 HWND hwndCloned = CreateWindowExW(dwExStyle,
257 rect.right - rect.left,
258 rect.bottom - rect.top,
264 WIN32_CHK(hwndCloned !=
NULL);
269 void GHOST_ContextWGL::initContextWGLEW(PIXELFORMATDESCRIPTOR &preferredPFD)
271 HWND dummyHWND =
NULL;
274 HGLRC dummyHGLRC =
NULL;
281 SetLastError(NO_ERROR);
283 prevHDC = ::wglGetCurrentDC();
284 WIN32_CHK(GetLastError() == NO_ERROR);
286 prevHGLRC = ::wglGetCurrentContext();
287 WIN32_CHK(GetLastError() == NO_ERROR);
291 if (iPixelFormat == 0)
294 PIXELFORMATDESCRIPTOR chosenPFD;
296 ::DescribePixelFormat(m_hDC, iPixelFormat,
sizeof(PIXELFORMATDESCRIPTOR), &chosenPFD)))
302 if (dummyHWND ==
NULL)
305 dummyHDC = GetDC(dummyHWND);
308 if (!WIN32_CHK(dummyHDC !=
NULL))
311 if (!WIN32_CHK(::SetPixelFormat(dummyHDC, iPixelFormat, &chosenPFD)))
314 dummyHGLRC = ::wglCreateContext(dummyHDC);
316 if (!WIN32_CHK(dummyHGLRC !=
NULL))
319 if (!WIN32_CHK(::wglMakeCurrent(dummyHDC, dummyHGLRC)))
322 if (
GLEW_CHK(glewInit()) != GLEW_OK) {
323 fprintf(stderr,
"Warning! Dummy GLEW/WGLEW failed to initialize properly.\n");
329 free((
void *)m_dummyRenderer);
330 free((
void *)m_dummyVendor);
331 free((
void *)m_dummyVersion);
333 m_dummyRenderer = _strdup(
reinterpret_cast<const char *
>(glGetString(GL_RENDERER)));
334 m_dummyVendor = _strdup(
reinterpret_cast<const char *
>(glGetString(GL_VENDOR)));
335 m_dummyVersion = _strdup(
reinterpret_cast<const char *
>(glGetString(GL_VERSION)));
339 WIN32_CHK(::wglMakeCurrent(prevHDC, prevHGLRC));
341 if (dummyHGLRC !=
NULL)
342 WIN32_CHK(::wglDeleteContext(dummyHGLRC));
344 if (dummyHWND !=
NULL) {
345 if (dummyHDC !=
NULL)
346 WIN32_CHK(::ReleaseDC(dummyHWND, dummyHDC));
348 WIN32_CHK(::DestroyWindow(dummyHWND));
357 out.push_back(WGL_SUPPORT_OPENGL_ARB);
358 out.push_back(GL_TRUE);
360 out.push_back(WGL_DRAW_TO_WINDOW_ARB);
361 out.push_back(GL_TRUE);
363 out.push_back(WGL_DOUBLE_BUFFER_ARB);
364 out.push_back(GL_TRUE);
366 out.push_back(WGL_ACCELERATION_ARB);
367 out.push_back(WGL_FULL_ACCELERATION_ARB);
370 out.push_back(WGL_STEREO_ARB);
371 out.push_back(GL_TRUE);
374 out.push_back(WGL_PIXEL_TYPE_ARB);
375 out.push_back(WGL_TYPE_RGBA_ARB);
377 out.push_back(WGL_COLOR_BITS_ARB);
381 out.push_back(WGL_ALPHA_BITS_ARB);
388 int GHOST_ContextWGL::_choose_pixel_format_arb_1(
bool stereoVisual,
bool needAlpha)
390 std::vector<int> iAttributes;
392 #define _MAX_PIXEL_FORMATS 32
394 int iPixelFormat = 0;
400 WIN32_CHK(wglChoosePixelFormatARB(
403 if (nNumFormats > 0) {
404 iPixelFormat = iPixelFormats[0];
406 #ifdef WIN32_COMPOSITING
409 PIXELFORMATDESCRIPTOR pfd;
412 for (i = 0; i < nNumFormats; i++) {
413 if (DescribePixelFormat(m_hDC, iPixelFormats[i],
sizeof(PIXELFORMATDESCRIPTOR), &pfd)) {
414 if (pfd.dwFlags & PFD_SUPPORT_COMPOSITION) {
415 iPixelFormat = iPixelFormats[i];
420 if (i == nNumFormats) {
421 fprintf(stderr,
"Warning! Unable to find a pixel format with compositing capability.\n");
428 if (iPixelFormat != 0) {
430 int alphaBits, iQuery = WGL_ALPHA_BITS_ARB;
431 wglGetPixelFormatAttribivARB(m_hDC, iPixelFormat, 0, 1, &iQuery, &alphaBits);
432 if (alphaBits == 0) {
433 fprintf(stderr,
"Warning! Unable to find a frame buffer with alpha channel.\n");
440 int GHOST_ContextWGL::choose_pixel_format_arb(
bool stereoVisual,
bool needAlpha)
444 iPixelFormat = _choose_pixel_format_arb_1(stereoVisual, needAlpha);
446 if (iPixelFormat == 0 && stereoVisual) {
447 fprintf(stderr,
"Warning! Unable to find a stereo pixel format.\n");
449 iPixelFormat = _choose_pixel_format_arb_1(
false, needAlpha);
457 int GHOST_ContextWGL::choose_pixel_format(
bool stereoVisual,
bool needAlpha)
459 PIXELFORMATDESCRIPTOR preferredPFD = {
460 sizeof(PIXELFORMATDESCRIPTOR),
462 (DWORD)(PFD_SUPPORT_OPENGL | PFD_DRAW_TO_WINDOW |
464 (stereoVisual ? PFD_STEREO : 0) |
466 #ifdef WIN32_COMPOSITING
468 needAlpha ? PFD_SUPPORT_COMPOSITION :
472 (BYTE)(needAlpha ? 32 : 24),
479 (BYTE)(needAlpha ? 8 : 0),
496 initContextWGLEW(preferredPFD);
498 int iPixelFormat = 0;
500 if (WGLEW_ARB_pixel_format)
501 iPixelFormat = choose_pixel_format_arb(stereoVisual, needAlpha);
503 if (iPixelFormat == 0)
512 fprintf(stderr,
"%s: %s\n", name,
context);
514 if (dummy && strcmp(dummy,
context) != 0)
515 fprintf(stderr,
"Warning! Dummy %s: %s\n", name, dummy);
521 SetLastError(NO_ERROR);
523 HGLRC prevHGLRC = ::wglGetCurrentContext();
524 WIN32_CHK(GetLastError() == NO_ERROR);
526 HDC prevHDC = ::wglGetCurrentDC();
527 WIN32_CHK(GetLastError() == NO_ERROR);
529 if (!WGLEW_ARB_create_context || ::GetPixelFormat(m_hDC) == 0) {
530 const bool needAlpha = m_alphaBackground;
534 PIXELFORMATDESCRIPTOR chosenPFD;
538 if (iPixelFormat == 0) {
542 lastPFD = ::DescribePixelFormat(
543 m_hDC, iPixelFormat,
sizeof(PIXELFORMATDESCRIPTOR), &chosenPFD);
545 if (!WIN32_CHK(lastPFD != 0)) {
549 if (needAlpha && chosenPFD.cAlphaBits == 0)
550 fprintf(stderr,
"Warning! Unable to find a pixel format with an alpha channel.\n");
552 if (!WIN32_CHK(::SetPixelFormat(m_hDC, iPixelFormat, &chosenPFD))) {
557 if (WGLEW_ARB_create_context) {
558 int profileBitCore = m_contextProfileMask & WGL_CONTEXT_CORE_PROFILE_BIT_ARB;
559 int profileBitCompat = m_contextProfileMask & WGL_CONTEXT_COMPATIBILITY_PROFILE_BIT_ARB;
562 int profileBitES = m_contextProfileMask & WGL_CONTEXT_ES_PROFILE_BIT_EXT;
565 if (!WGLEW_ARB_create_context_profile && profileBitCore)
566 fprintf(stderr,
"Warning! OpenGL core profile not available.\n");
568 if (!WGLEW_ARB_create_context_profile && profileBitCompat)
569 fprintf(stderr,
"Warning! OpenGL compatibility profile not available.\n");
572 if (!WGLEW_EXT_create_context_es_profile && profileBitES && m_contextMajorVersion == 1)
573 fprintf(stderr,
"Warning! OpenGL ES profile not available.\n");
575 if (!WGLEW_EXT_create_context_es2_profile && profileBitES && m_contextMajorVersion == 2)
576 fprintf(stderr,
"Warning! OpenGL ES2 profile not available.\n");
581 if (WGLEW_ARB_create_context_profile && profileBitCore)
582 profileMask |= profileBitCore;
584 if (WGLEW_ARB_create_context_profile && profileBitCompat)
585 profileMask |= profileBitCompat;
588 if (WGLEW_EXT_create_context_es_profile && profileBitES)
589 profileMask |= profileBitES;
592 if (profileMask != m_contextProfileMask)
593 fprintf(stderr,
"Warning! Ignoring untested OpenGL context profile mask bits.");
595 std::vector<int> iAttributes;
598 iAttributes.push_back(WGL_CONTEXT_PROFILE_MASK_ARB);
599 iAttributes.push_back(profileMask);
602 if (m_contextMajorVersion != 0) {
603 iAttributes.push_back(WGL_CONTEXT_MAJOR_VERSION_ARB);
604 iAttributes.push_back(m_contextMajorVersion);
607 if (m_contextMinorVersion != 0) {
608 iAttributes.push_back(WGL_CONTEXT_MINOR_VERSION_ARB);
609 iAttributes.push_back(m_contextMinorVersion);
612 if (m_contextFlags != 0) {
613 iAttributes.push_back(WGL_CONTEXT_FLAGS_ARB);
614 iAttributes.push_back(m_contextFlags);
617 if (m_contextResetNotificationStrategy != 0) {
618 if (WGLEW_ARB_create_context_robustness) {
619 iAttributes.push_back(WGL_CONTEXT_RESET_NOTIFICATION_STRATEGY_ARB);
620 iAttributes.push_back(m_contextResetNotificationStrategy);
623 fprintf(stderr,
"Warning! Cannot set the reset notification strategy.");
627 iAttributes.push_back(0);
629 m_hGLRC = ::wglCreateContextAttribsARB(m_hDC,
NULL, &(iAttributes[0]));
635 const bool silent = m_contextMajorVersion > 3;
636 if (!WIN32_CHK_SILENT(m_hGLRC !=
NULL, silent)) {
643 if (s_sharedHGLRC ==
NULL) {
644 s_sharedHGLRC = m_hGLRC;
646 else if (!WIN32_CHK(::wglShareLists(s_sharedHGLRC, m_hGLRC))) {
650 if (!WIN32_CHK(::wglMakeCurrent(m_hDC, m_hGLRC))) {
666 ::SwapBuffers(m_hDC);
670 const char *vendor =
reinterpret_cast<const char *
>(glGetString(GL_VENDOR));
671 const char *renderer =
reinterpret_cast<const char *
>(glGetString(GL_RENDERER));
672 const char *version =
reinterpret_cast<const char *
>(glGetString(GL_VERSION));
678 fprintf(stderr,
"Context Version: %d.%d\n", m_contextMajorVersion, m_contextMinorVersion);
684 ::wglMakeCurrent(prevHDC, prevHGLRC);
void BLI_kdtree_nd_() free(KDTree *tree)
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)
typedef UINT(API *GHOST_WIN32_GetDpiForWindow)(HWND)
SIMD_FORCE_INLINE const btScalar & w() const
Return the w value.
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)
static void initClearGL()
static void error(const char *str)
static const pxr::TfToken out("out", pxr::TfToken::Immortal)