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);
		}
	}