19HGLRC GHOST_ContextWGL::s_sharedHGLRC =
nullptr;
20int GHOST_ContextWGL::s_sharedCount = 0;
25 return strstr((
const char *)glGetString(GL_VENDOR),
"Intel") !=
nullptr;
32 int contextProfileMask,
33 int contextMajorVersion,
34 int contextMinorVersion,
36 int contextResetNotificationStrategy)
40 m_contextProfileMask(contextProfileMask),
41 m_contextMajorVersion(contextMajorVersion),
42 m_contextMinorVersion(contextMinorVersion),
43 m_contextFlags(contextFlags),
44 m_alphaBackground(alphaBackground),
45 m_contextResetNotificationStrategy(contextResetNotificationStrategy),
49 m_dummyVendor(nullptr),
50 m_dummyRenderer(nullptr),
51 m_dummyVersion(nullptr)
54 assert(m_hDC !=
nullptr);
59 if (m_hGLRC !=
nullptr) {
60 if (m_hGLRC == ::wglGetCurrentContext())
61 WIN32_CHK(::wglMakeCurrent(
nullptr,
nullptr));
63 if (m_hGLRC != s_sharedHGLRC || s_sharedCount == 1) {
64 assert(s_sharedCount > 0);
68 if (s_sharedCount == 0) {
69 s_sharedHGLRC =
nullptr;
72 WIN32_CHK(::wglDeleteContext(m_hGLRC));
77 if (m_dummyRenderer) {
78 free((
void *)m_dummyRenderer);
79 free((
void *)m_dummyVendor);
80 free((
void *)m_dummyVersion);
92 if (epoxy_has_wgl_extension(m_hDC,
"WGL_EXT_swap_control")) {
102 if (epoxy_has_wgl_extension(m_hDC,
"WGL_EXT_swap_control")) {
103 intervalOut = ::wglGetSwapIntervalEXT();
113 if (WIN32_CHK(::wglMakeCurrent(m_hDC, m_hGLRC))) {
123 if (WIN32_CHK(::wglMakeCurrent(
nullptr,
nullptr))) {
142 if (!(pfd.dwFlags & PFD_SUPPORT_OPENGL) || !(pfd.dwFlags & PFD_DRAW_TO_WINDOW) ||
143 !(pfd.dwFlags & PFD_DOUBLEBUFFER) ||
144 !(pfd.iPixelType == PFD_TYPE_RGBA) ||
145 (pfd.cColorBits > 32) ||
146 (pfd.dwFlags & PFD_GENERIC_FORMAT))
153 weight += pfd.cColorBits - 8;
155 if (preferredPFD.cAlphaBits > 0 && pfd.cAlphaBits > 0) {
158#ifdef WIN32_COMPOSITING
159 if ((preferredPFD.dwFlags & PFD_SUPPORT_COMPOSITION) && (pfd.dwFlags & PFD_SUPPORT_COMPOSITION))
172 int iPixelFormat = 0;
175 int iStereoPixelFormat = 0;
176 int stereoWeight = 0;
179 int iLastResortPixelFormat = ::ChoosePixelFormat(hDC, &preferredPFD);
181 WIN32_CHK(iLastResortPixelFormat != 0);
183 int lastPFD = ::DescribePixelFormat(hDC, 1,
sizeof(PIXELFORMATDESCRIPTOR),
nullptr);
185 WIN32_CHK(lastPFD != 0);
187 for (
int i = 1; i <= lastPFD; i++) {
188 PIXELFORMATDESCRIPTOR pfd;
189 int check = ::DescribePixelFormat(hDC, i,
sizeof(PIXELFORMATDESCRIPTOR), &pfd);
191 WIN32_CHK(check == lastPFD);
200 if (
w > stereoWeight && (preferredPFD.dwFlags & pfd.dwFlags & PFD_STEREO)) {
202 iStereoPixelFormat = i;
207 if (iStereoPixelFormat != 0) {
208 iPixelFormat = iStereoPixelFormat;
211 if (iPixelFormat == 0) {
212 fprintf(stderr,
"Warning! Using result of ChoosePixelFormat.\n");
213 iPixelFormat = iLastResortPixelFormat;
228 SetLastError(NO_ERROR);
230 DWORD dwExStyle = GetWindowLong(hWnd, GWL_EXSTYLE);
231 WIN32_CHK(GetLastError() == NO_ERROR);
233 WCHAR lpClassName[100] =
L"";
234 count = GetClassNameW(hWnd, lpClassName,
sizeof(lpClassName));
235 WIN32_CHK(
count != 0);
237 WCHAR lpWindowName[100] =
L"";
238 count = GetWindowTextW(hWnd, lpWindowName,
sizeof(lpWindowName));
239 WIN32_CHK(
count != 0);
241 DWORD dwStyle = GetWindowLong(hWnd, GWL_STYLE);
242 WIN32_CHK(GetLastError() == NO_ERROR);
245 GetWindowRect(hWnd, &rect);
246 WIN32_CHK(GetLastError() == NO_ERROR);
248 HWND hWndParent = (HWND)GetWindowLongPtr(hWnd, GWLP_HWNDPARENT);
249 WIN32_CHK(GetLastError() == NO_ERROR);
251 HMENU hMenu = GetMenu(hWnd);
252 WIN32_CHK(GetLastError() == NO_ERROR);
254 HINSTANCE hInstance = (HINSTANCE)GetWindowLongPtr(hWnd, GWLP_HINSTANCE);
255 WIN32_CHK(GetLastError() == NO_ERROR);
257 HWND hwndCloned = CreateWindowExW(dwExStyle,
263 rect.right - rect.left,
264 rect.bottom - rect.top,
270 WIN32_CHK(hwndCloned !=
nullptr);
275static void makeAttribList(std::vector<int> &out,
bool stereoVisual,
bool needAlpha)
280 out.push_back(WGL_SUPPORT_OPENGL_ARB);
281 out.push_back(GL_TRUE);
283 out.push_back(WGL_DRAW_TO_WINDOW_ARB);
284 out.push_back(GL_TRUE);
286 out.push_back(WGL_DOUBLE_BUFFER_ARB);
287 out.push_back(GL_TRUE);
289 out.push_back(WGL_ACCELERATION_ARB);
290 out.push_back(WGL_FULL_ACCELERATION_ARB);
293 out.push_back(WGL_STEREO_ARB);
294 out.push_back(GL_TRUE);
297 out.push_back(WGL_PIXEL_TYPE_ARB);
298 out.push_back(WGL_TYPE_RGBA_ARB);
300 out.push_back(WGL_COLOR_BITS_ARB);
304 out.push_back(WGL_ALPHA_BITS_ARB);
334 sizeof(PIXELFORMATDESCRIPTOR),
336 (DWORD)(PFD_SUPPORT_OPENGL | PFD_DRAW_TO_WINDOW |
338 (stereoVisual ? PFD_STEREO : 0) |
340#ifdef WIN32_COMPOSITING
342 needAlpha ? PFD_SUPPORT_COMPOSITION :
346 (BYTE)(needAlpha ? 32 : 24),
353 (BYTE)(needAlpha ? 8 : 0),
370 SetLastError(NO_ERROR);
373 WIN32_CHK(GetLastError() == NO_ERROR);
376 WIN32_CHK(GetLastError() == NO_ERROR);
384 PIXELFORMATDESCRIPTOR chosenPFD;
385 if (!WIN32_CHK(::DescribePixelFormat(
401 if (!WIN32_CHK(
dummyHDC !=
nullptr)) {
422 "WGL_ARB_create_context_profile");
424 hDC,
"WGL_ARB_create_context_robustness");
443int GHOST_ContextWGL::_choose_pixel_format_arb_1(
bool stereoVisual,
bool needAlpha)
445 std::vector<int> iAttributes;
447#define _MAX_PIXEL_FORMATS 32
449 int iPixelFormat = 0;
455 WIN32_CHK(wglChoosePixelFormatARB(
458 if (nNumFormats > 0) {
459 iPixelFormat = iPixelFormats[0];
461#ifdef WIN32_COMPOSITING
464 PIXELFORMATDESCRIPTOR pfd;
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];
475 if (i == nNumFormats) {
476 fprintf(stderr,
"Warning! Unable to find a pixel format with compositing capability.\n");
483 if (iPixelFormat != 0) {
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");
495int GHOST_ContextWGL::choose_pixel_format_arb(
bool stereoVisual,
bool needAlpha)
499 iPixelFormat = _choose_pixel_format_arb_1(stereoVisual, needAlpha);
501 if (iPixelFormat == 0 && stereoVisual) {
502 fprintf(stderr,
"Warning! Unable to find a stereo pixel format.\n");
504 iPixelFormat = _choose_pixel_format_arb_1(
false, needAlpha);
515 fprintf(stderr,
"%s: %s\n", name, context);
517 if (dummy && strcmp(dummy, context) != 0)
518 fprintf(stderr,
"Warning! Dummy %s: %s\n", name, dummy);
524 SetLastError(NO_ERROR);
526 HGLRC prevHGLRC = ::wglGetCurrentContext();
527 WIN32_CHK(GetLastError() == NO_ERROR);
529 HDC prevHDC = ::wglGetCurrentDC();
530 WIN32_CHK(GetLastError() == NO_ERROR);
533 const bool needAlpha = m_alphaBackground;
537 int iPixelFormat = 0;
540 iPixelFormat = choose_pixel_format_arb(
m_stereoVisual, needAlpha);
543 if (iPixelFormat == 0)
546 if (iPixelFormat == 0) {
550 PIXELFORMATDESCRIPTOR chosenPFD;
551 int lastPFD = ::DescribePixelFormat(
552 m_hDC, iPixelFormat,
sizeof(PIXELFORMATDESCRIPTOR), &chosenPFD);
554 if (!WIN32_CHK(lastPFD != 0)) {
558 if (needAlpha && chosenPFD.cAlphaBits == 0) {
559 fprintf(stderr,
"Warning! Unable to find a pixel format with an alpha channel.\n");
562 if (!WIN32_CHK(::SetPixelFormat(m_hDC, iPixelFormat, &chosenPFD))) {
568 int profileBitCore = m_contextProfileMask & WGL_CONTEXT_CORE_PROFILE_BIT_ARB;
569 int profileBitCompat = m_contextProfileMask & WGL_CONTEXT_COMPATIBILITY_PROFILE_BIT_ARB;
572 fprintf(stderr,
"Warning! OpenGL core profile not available.\n");
576 fprintf(stderr,
"Warning! OpenGL compatibility profile not available.\n");
582 profileMask |= profileBitCore;
586 profileMask |= profileBitCompat;
589 if (profileMask != m_contextProfileMask) {
590 fprintf(stderr,
"Warning! Ignoring untested OpenGL context profile mask bits.");
593 std::vector<int> iAttributes;
596 iAttributes.push_back(WGL_CONTEXT_PROFILE_MASK_ARB);
597 iAttributes.push_back(profileMask);
600 if (m_contextMajorVersion != 0) {
601 iAttributes.push_back(WGL_CONTEXT_MAJOR_VERSION_ARB);
602 iAttributes.push_back(m_contextMajorVersion);
605 if (m_contextMinorVersion != 0) {
606 iAttributes.push_back(WGL_CONTEXT_MINOR_VERSION_ARB);
607 iAttributes.push_back(m_contextMinorVersion);
610 if (m_contextFlags != 0) {
611 iAttributes.push_back(WGL_CONTEXT_FLAGS_ARB);
612 iAttributes.push_back(m_contextFlags);
615 if (m_contextResetNotificationStrategy != 0) {
617 iAttributes.push_back(WGL_CONTEXT_RESET_NOTIFICATION_STRATEGY_ARB);
618 iAttributes.push_back(m_contextResetNotificationStrategy);
621 fprintf(stderr,
"Warning! Cannot set the reset notification strategy.");
625 iAttributes.push_back(0);
627 m_hGLRC = ::wglCreateContextAttribsARB(m_hDC,
nullptr, &(iAttributes[0]));
634 const bool silent = m_contextMajorVersion > 3;
635 if (!WIN32_CHK_SILENT(m_hGLRC !=
nullptr, silent)) {
642 if (s_sharedHGLRC ==
nullptr) {
643 s_sharedHGLRC = m_hGLRC;
645 else if (!WIN32_CHK(::wglShareLists(s_sharedHGLRC, m_hGLRC))) {
649 if (!WIN32_CHK(::wglMakeCurrent(m_hDC, m_hGLRC))) {
659 glEnable(GL_POINT_SPRITE);
663 ::SwapBuffers(m_hDC);
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));
675 fprintf(stderr,
"Context Version: %d.%d\n", m_contextMajorVersion, m_contextMinorVersion);
681 ::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)
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 error(const char *str)
bool has_WGL_ARB_create_context_robustness
bool has_WGL_ARB_pixel_format
PIXELFORMATDESCRIPTOR preferredPFD
DummyContextWGL(HDC hDC, HWND hWnd, bool stereoVisual, bool needAlpha)
bool has_WGL_ARB_create_context_profile
bool has_WGL_ARB_create_context