32 int contextProfileMask,
33 int contextMajorVersion,
34 int contextMinorVersion,
36 int contextResetNotificationStrategy)
40 context_profile_mask_(contextProfileMask),
41 context_major_version_(contextMajorVersion),
42 context_minor_version_(contextMinorVersion),
43 context_flags_(contextFlags),
44 alpha_background_(alphaBackground),
45 context_reset_notification_strategy_(contextResetNotificationStrategy),
147 if (!(pfd.dwFlags & PFD_SUPPORT_OPENGL) || !(pfd.dwFlags & PFD_DRAW_TO_WINDOW) ||
148 !(pfd.dwFlags & PFD_DOUBLEBUFFER) ||
149 !(pfd.iPixelType == PFD_TYPE_RGBA) ||
150 (pfd.cColorBits > 32) ||
151 (pfd.dwFlags & PFD_GENERIC_FORMAT))
158 weight += pfd.cColorBits - 8;
160 if (preferredPFD.cAlphaBits > 0 && pfd.cAlphaBits > 0) {
173 int iPixelFormat = 0;
176 int iStereoPixelFormat = 0;
177 int stereoWeight = 0;
180 int iLastResortPixelFormat = ::ChoosePixelFormat(hDC, &preferredPFD);
182 WIN32_CHK(iLastResortPixelFormat != 0);
184 int lastPFD = ::DescribePixelFormat(hDC, 1,
sizeof(PIXELFORMATDESCRIPTOR),
nullptr);
186 WIN32_CHK(lastPFD != 0);
188 for (
int i = 1;
i <= lastPFD;
i++) {
189 PIXELFORMATDESCRIPTOR pfd;
190 int check = ::DescribePixelFormat(hDC,
i,
sizeof(PIXELFORMATDESCRIPTOR), &pfd);
192 WIN32_CHK(check == lastPFD);
201 if (
w > stereoWeight && (preferredPFD.dwFlags & pfd.dwFlags & PFD_STEREO)) {
203 iStereoPixelFormat =
i;
208 if (iStereoPixelFormat != 0) {
209 iPixelFormat = iStereoPixelFormat;
212 if (iPixelFormat == 0) {
213 fprintf(stderr,
"Warning! Using result of ChoosePixelFormat.\n");
214 iPixelFormat = iLastResortPixelFormat;
229 SetLastError(NO_ERROR);
231 DWORD dwExStyle = GetWindowLong(hWnd, GWL_EXSTYLE);
232 WIN32_CHK(GetLastError() == NO_ERROR);
234 WCHAR lpClassName[100] =
L"";
235 count = GetClassNameW(hWnd, lpClassName,
sizeof(lpClassName));
236 WIN32_CHK(
count != 0);
238 WCHAR lpWindowName[100] =
L"";
239 count = GetWindowTextW(hWnd, lpWindowName,
sizeof(lpWindowName));
240 WIN32_CHK(
count != 0);
242 DWORD dwStyle = GetWindowLong(hWnd, GWL_STYLE);
243 WIN32_CHK(GetLastError() == NO_ERROR);
246 GetWindowRect(hWnd, &rect);
247 WIN32_CHK(GetLastError() == NO_ERROR);
249 HWND hWndParent = (HWND)GetWindowLongPtr(hWnd, GWLP_HWNDPARENT);
250 WIN32_CHK(GetLastError() == NO_ERROR);
252 HMENU hMenu = GetMenu(hWnd);
253 WIN32_CHK(GetLastError() == NO_ERROR);
255 HINSTANCE hInstance = (HINSTANCE)GetWindowLongPtr(hWnd, GWLP_HINSTANCE);
256 WIN32_CHK(GetLastError() == NO_ERROR);
258 HWND hwndCloned = CreateWindowExW(dwExStyle,
264 rect.right - rect.left,
265 rect.bottom - rect.top,
271 WIN32_CHK(hwndCloned !=
nullptr);
281 out.push_back(WGL_SUPPORT_OPENGL_ARB);
282 out.push_back(GL_TRUE);
284 out.push_back(WGL_DRAW_TO_WINDOW_ARB);
285 out.push_back(GL_TRUE);
287 out.push_back(WGL_DOUBLE_BUFFER_ARB);
288 out.push_back(GL_TRUE);
290 out.push_back(WGL_ACCELERATION_ARB);
291 out.push_back(WGL_FULL_ACCELERATION_ARB);
294 out.push_back(WGL_STEREO_ARB);
295 out.push_back(GL_TRUE);
298 out.push_back(WGL_PIXEL_TYPE_ARB);
299 out.push_back(WGL_TYPE_RGBA_ARB);
301 out.push_back(WGL_COLOR_BITS_ARB);
305 out.push_back(WGL_ALPHA_BITS_ARB);
463 wglGetPixelFormatAttribivARB(h_DC_, iPixelFormat, 0, 1, &iQuery, &alphaBits);
502 SetLastError(NO_ERROR);
504 HGLRC prevHGLRC = ::wglGetCurrentContext();
505 WIN32_CHK(GetLastError() == NO_ERROR);
507 HDC prevHDC = ::wglGetCurrentDC();
508 WIN32_CHK(GetLastError() == NO_ERROR);
511 const bool needAlpha = alpha_background_;
515 int iPixelFormat = 0;
518 iPixelFormat = choose_pixel_format_arb(
context_params_.is_stereo_visual, needAlpha);
521 if (iPixelFormat == 0) {
525 if (iPixelFormat == 0) {
529 PIXELFORMATDESCRIPTOR chosenPFD;
530 int lastPFD = ::DescribePixelFormat(
531 h_DC_, iPixelFormat,
sizeof(PIXELFORMATDESCRIPTOR), &chosenPFD);
533 if (!WIN32_CHK(lastPFD != 0)) {
537 if (needAlpha && chosenPFD.cAlphaBits == 0) {
538 fprintf(stderr,
"Warning! Unable to find a pixel format with an alpha channel.\n");
541 if (!WIN32_CHK(::SetPixelFormat(h_DC_, iPixelFormat, &chosenPFD))) {
547 int profileBitCore = context_profile_mask_ & WGL_CONTEXT_CORE_PROFILE_BIT_ARB;
548 int profileBitCompat = context_profile_mask_ & WGL_CONTEXT_COMPATIBILITY_PROFILE_BIT_ARB;
551 fprintf(stderr,
"Warning! OpenGL core profile not available.\n");
555 fprintf(stderr,
"Warning! OpenGL compatibility profile not available.\n");
561 profileMask |= profileBitCore;
565 profileMask |= profileBitCompat;
568 if (profileMask != context_profile_mask_) {
569 fprintf(stderr,
"Warning! Ignoring untested OpenGL context profile mask bits.");
572 std::vector<int> iAttributes;
575 iAttributes.push_back(WGL_CONTEXT_PROFILE_MASK_ARB);
576 iAttributes.push_back(profileMask);
579 if (context_major_version_ != 0) {
580 iAttributes.push_back(WGL_CONTEXT_MAJOR_VERSION_ARB);
581 iAttributes.push_back(context_major_version_);
584 if (context_minor_version_ != 0) {
585 iAttributes.push_back(WGL_CONTEXT_MINOR_VERSION_ARB);
586 iAttributes.push_back(context_minor_version_);
589 if (context_flags_ != 0) {
590 iAttributes.push_back(WGL_CONTEXT_FLAGS_ARB);
591 iAttributes.push_back(context_flags_);
594 if (context_reset_notification_strategy_ != 0) {
596 iAttributes.push_back(WGL_CONTEXT_RESET_NOTIFICATION_STRATEGY_ARB);
597 iAttributes.push_back(context_reset_notification_strategy_);
600 fprintf(stderr,
"Warning! Cannot set the reset notification strategy.");
604 iAttributes.push_back(0);
606 h_GLRC_ = ::wglCreateContextAttribsARB(h_DC_, s_sharedHGLRC, &(iAttributes[0]));
613 const bool silent = context_major_version_ > 3;
614 if (!WIN32_CHK_SILENT(h_GLRC_ !=
nullptr, silent)) {
621 if (s_sharedHGLRC ==
nullptr) {
622 s_sharedHGLRC = h_GLRC_;
625 if (!WIN32_CHK(::wglMakeCurrent(h_DC_, h_GLRC_))) {
642 glEnable(GL_POINT_SPRITE);
646 ::SwapBuffers(h_DC_);
650 const char *vendor =
reinterpret_cast<const char *
>(glGetString(GL_VENDOR));
651 const char *renderer =
reinterpret_cast<const char *
>(glGetString(GL_RENDERER));
652 const char *version =
reinterpret_cast<const char *
>(glGetString(GL_VERSION));
658 fprintf(stderr,
"Context Version: %d.%d\n", context_major_version_, context_minor_version_);
665 ::wglMakeCurrent(prevHDC, prevHGLRC);
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_ContextWGL(const GHOST_ContextParams &context_params, bool alphaBackground, HWND hWnd, HDC hDC, int contextProfileMask, int contextMajorVersion, int contextMinorVersion, int contextFlags, int contextResetNotificationStrategy)
GHOST_TSuccess releaseNativeHandles() override
GHOST_TSuccess releaseDrawingContext() override
GHOST_TSuccess initializeDrawingContext() override
GHOST_TSuccess setSwapInterval(int interval) override
~GHOST_ContextWGL() override
GHOST_TSuccess activateDrawingContext() override
GHOST_TSuccess getSwapInterval(int &interval_out) override
GHOST_TSuccess swapBufferRelease() override
GHOST_Context(const GHOST_ContextParams &context_params)
static GHOST_Context * active_context_
virtual GHOST_TVSyncModes getVSync()
GHOST_ContextParams context_params_
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