void OpenGLWindowProvider::create(DisplayWindowSite *new_site, const DisplayWindowDescription &desc) { site = new_site; fullscreen = desc.is_fullscreen(); win32_window.create(site, desc); if (!opengl_context) { HWND handle = win32_window.get_hwnd(); dwm_layered = false; if (desc.is_layered() && !DwmFunctions::is_composition_enabled()) { create_shadow_window(handle); } else { if (desc.is_layered()) dwm_layered = true; } desc.is_layered() ? double_buffered = false : double_buffered = true; // Only can use Layered windows that are single buffered with OpenGL (via shadow window) ( PFD_DOUBLEBUFFER_DONTCARE set in OpenGLCreationHelper::set_multisampling_pixel_format) device_context = GetDC(handle); HGLRC share_context = get_share_context(); OpenGLCreationHelper helper(handle, device_context); helper.set_multisampling_pixel_format(desc); int gl_major = opengl_desc.get_version_major(); int gl_minor = opengl_desc.get_version_minor(); if (opengl_desc.get_allow_lower_versions() == false) { opengl_context = helper.create_opengl3_context(share_context, gl_major, gl_minor, opengl_desc); if (!opengl_context) throw Exception(string_format("This application requires OpenGL %1.%2 or above. Try updating your drivers, or upgrade to a newer graphics card.", gl_major, gl_minor)); } else { static const char opengl_version_list[] = { // Clanlib supported version pairs 4, 5, 4, 4, 4, 3, 4, 2, 4, 1, 4, 0, 3, 3, 3, 2, 3, 1, 3, 0, 0, 0, // End of list }; const char *opengl_version_list_ptr = opengl_version_list; do { int major = *(opengl_version_list_ptr++); if (major == 0) break; int minor = *(opengl_version_list_ptr++); // Find the appropriate version in the list if (major > gl_major) continue; if (major == gl_major) { if (minor > gl_minor) continue; } opengl_context = helper.create_opengl3_context(share_context, major, minor, opengl_desc); } while (!opengl_context); if (!opengl_context) opengl_context = helper.create_opengl2_context(share_context); if (!opengl_context) throw Exception("This application requires OpenGL. Try updating your drivers, or upgrade to a newer graphics card."); } bool use_gl3; int desc_version_major = opengl_desc.get_version_major(); int desc_version_minor = opengl_desc.get_version_minor(); // Do not attempt GL3, if not requested that version if (desc_version_major < 3) { use_gl3 = false; } else if (!opengl_desc.get_allow_lower_versions()) // Else, if we do not allow lower versions, only attempt GL3 { use_gl3 = true; } else { // Choose the target depending on the current opengl version int gl_version_major; int gl_version_minor; get_opengl_version(gl_version_major, gl_version_minor); if (gl_version_major < 3) { use_gl3 = false; } else { use_gl3 = true; } } if (use_gl3) { using_gl3 = true; gc = GraphicContext(new GL3GraphicContextProvider(this)); } else { using_gl3 = false; gc = GraphicContext(new GL1GraphicContextProvider(this)); } } wglSwapIntervalEXT = (ptr_wglSwapIntervalEXT)OpenGL::get_proc_address("wglSwapIntervalEXT"); swap_interval = desc.get_swap_interval(); if (wglSwapIntervalEXT && swap_interval != -1) wglSwapIntervalEXT(swap_interval); }
void OpenGLCreationHelper::set_multisampling_pixel_format(const DisplayWindowDescription &desc) { PIXELFORMATDESCRIPTOR pfd; memset(&pfd, 0, sizeof(PIXELFORMATDESCRIPTOR)); pfd.nSize = sizeof(PIXELFORMATDESCRIPTOR); pfd.nVersion = 1; pfd.dwFlags = PFD_DRAW_TO_WINDOW | PFD_SUPPORT_OPENGL; pfd.iPixelType = PFD_TYPE_RGBA; pfd.dwFlags |= PFD_DOUBLEBUFFER; pfd.cColorBits = 24; pfd.cRedBits = 4; pfd.cGreenBits = 4; pfd.cBlueBits = 4; pfd.cAlphaBits = 4; pfd.cDepthBits = desc.get_depth_size(); pfd.cStencilBits = desc.get_stencil_size(); if (desc.is_layered()) { pfd.cAlphaBits = 8; pfd.dwFlags |= PFD_DOUBLEBUFFER_DONTCARE; // | PFD_DRAW_TO_BITMAP } if (desc.get_multisampling() < 1) { int pixelformat = ChoosePixelFormat(hdc, &pfd); SetPixelFormat(hdc, pixelformat, &pfd); } else { int pixelformat = ChoosePixelFormat(hdc, &pfd); set_active(); ptr_wglChoosePixelFormatEXT wglChoosePixelFormatEXT = (ptr_wglChoosePixelFormatEXT)wglGetProcAddress("wglChoosePixelFormatEXT"); if (wglChoosePixelFormatEXT == 0) wglChoosePixelFormatEXT = (ptr_wglChoosePixelFormatEXT)wglGetProcAddress("wglChoosePixelFormatARB"); reset_active(); if (wglChoosePixelFormatEXT) { std::vector<FLOAT> float_attributes; std::vector<int> int_attributes; int_attributes.push_back(WGL_DRAW_TO_WINDOW); int_attributes.push_back(GL_TRUE); int_attributes.push_back(WGL_ACCELERATION); int_attributes.push_back(WGL_FULL_ACCELERATION); int_attributes.push_back(WGL_DOUBLE_BUFFER); int_attributes.push_back(GL_TRUE); int_attributes.push_back(WGL_COLOR_BITS); int_attributes.push_back(4 + 4 + 4); int_attributes.push_back(WGL_ALPHA_BITS); int_attributes.push_back(4); int_attributes.push_back(WGL_DEPTH_BITS); int_attributes.push_back(desc.get_depth_size()); int_attributes.push_back(WGL_STENCIL_BITS); int_attributes.push_back(desc.get_stencil_size()); int_attributes.push_back(WGL_SAMPLE_BUFFERS); int_attributes.push_back(GL_TRUE); int_attributes.push_back(WGL_SAMPLES); int_attributes.push_back(desc.get_multisampling()); float_attributes.push_back(0.0f); float_attributes.push_back(0.0f); int_attributes.push_back(0); int_attributes.push_back(0); int new_pixelformat = pixelformat; UINT num_formats = 0; BOOL result = wglChoosePixelFormatEXT(hdc, &int_attributes[0], &float_attributes[0], 1, &new_pixelformat, &num_formats); if (result == TRUE && num_formats > 0) pixelformat = new_pixelformat; } SetPixelFormat(hdc, pixelformat, &pfd); } }