// Return a list of available and usable framebuffer configs // static GLboolean choosePixelFormat(_GLFWwindow* window, const _GLFWfbconfig* desired, int* result) { _GLFWfbconfig* usableConfigs; const _GLFWfbconfig* closest; int i, nativeCount, usableCount; if (window->wgl.ARB_pixel_format) { nativeCount = getPixelFormatAttrib(window, 1, WGL_NUMBER_PIXEL_FORMATS_ARB); } else { nativeCount = DescribePixelFormat(window->wgl.dc, 1, sizeof(PIXELFORMATDESCRIPTOR), NULL); } if (!nativeCount) { _glfwInputError(GLFW_API_UNAVAILABLE, "WGL: No pixel formats found"); return GL_FALSE; } usableConfigs = calloc(nativeCount, sizeof(_GLFWfbconfig)); usableCount = 0; for (i = 0; i < nativeCount; i++) { const int n = i + 1; _GLFWfbconfig* u = usableConfigs + usableCount; if (window->wgl.ARB_pixel_format) { // Get pixel format attributes through WGL_ARB_pixel_format if (!getPixelFormatAttrib(window, n, WGL_SUPPORT_OPENGL_ARB) || !getPixelFormatAttrib(window, n, WGL_DRAW_TO_WINDOW_ARB) || !getPixelFormatAttrib(window, n, WGL_DOUBLE_BUFFER_ARB)) { continue; } if (getPixelFormatAttrib(window, n, WGL_PIXEL_TYPE_ARB) != WGL_TYPE_RGBA_ARB) { continue; } if (getPixelFormatAttrib(window, n, WGL_ACCELERATION_ARB) == WGL_NO_ACCELERATION_ARB) { continue; } u->redBits = getPixelFormatAttrib(window, n, WGL_RED_BITS_ARB); u->greenBits = getPixelFormatAttrib(window, n, WGL_GREEN_BITS_ARB); u->blueBits = getPixelFormatAttrib(window, n, WGL_BLUE_BITS_ARB); u->alphaBits = getPixelFormatAttrib(window, n, WGL_ALPHA_BITS_ARB); u->depthBits = getPixelFormatAttrib(window, n, WGL_DEPTH_BITS_ARB); u->stencilBits = getPixelFormatAttrib(window, n, WGL_STENCIL_BITS_ARB); u->accumRedBits = getPixelFormatAttrib(window, n, WGL_ACCUM_RED_BITS_ARB); u->accumGreenBits = getPixelFormatAttrib(window, n, WGL_ACCUM_GREEN_BITS_ARB); u->accumBlueBits = getPixelFormatAttrib(window, n, WGL_ACCUM_BLUE_BITS_ARB); u->accumAlphaBits = getPixelFormatAttrib(window, n, WGL_ACCUM_ALPHA_BITS_ARB); u->auxBuffers = getPixelFormatAttrib(window, n, WGL_AUX_BUFFERS_ARB); u->stereo = getPixelFormatAttrib(window, n, WGL_STEREO_ARB); if (window->wgl.ARB_multisample) u->samples = getPixelFormatAttrib(window, n, WGL_SAMPLES_ARB); if (window->wgl.ARB_framebuffer_sRGB) u->sRGB = getPixelFormatAttrib(window, n, WGL_FRAMEBUFFER_SRGB_CAPABLE_ARB); } else { PIXELFORMATDESCRIPTOR pfd; // Get pixel format attributes through old-fashioned PFDs if (!DescribePixelFormat(window->wgl.dc, n, sizeof(PIXELFORMATDESCRIPTOR), &pfd)) { continue; } if (!(pfd.dwFlags & PFD_DRAW_TO_WINDOW) || !(pfd.dwFlags & PFD_SUPPORT_OPENGL) || !(pfd.dwFlags & PFD_DOUBLEBUFFER)) { continue; } if (!(pfd.dwFlags & PFD_GENERIC_ACCELERATED) && (pfd.dwFlags & PFD_GENERIC_FORMAT)) { continue; } if (pfd.iPixelType != PFD_TYPE_RGBA) continue; u->redBits = pfd.cRedBits; u->greenBits = pfd.cGreenBits; u->blueBits = pfd.cBlueBits; u->alphaBits = pfd.cAlphaBits; u->depthBits = pfd.cDepthBits; u->stencilBits = pfd.cStencilBits; u->accumRedBits = pfd.cAccumRedBits; u->accumGreenBits = pfd.cAccumGreenBits; u->accumBlueBits = pfd.cAccumBlueBits; u->accumAlphaBits = pfd.cAccumAlphaBits; u->auxBuffers = pfd.cAuxBuffers; u->stereo = (pfd.dwFlags & PFD_STEREO) ? GL_TRUE : GL_FALSE; } u->wgl = n; usableCount++; } closest = _glfwChooseFBConfig(desired, usableConfigs, usableCount); if (!closest) { free(usableConfigs); return GL_FALSE; } *result = closest->wgl; free(usableConfigs); return GL_TRUE; }
static _GLFWfbconfig* getFBConfigs(_GLFWwindow* window, unsigned int* found) { _GLFWfbconfig* fbconfigs; PIXELFORMATDESCRIPTOR pfd; int i, available; *found = 0; if (window->WGL.ARB_pixel_format) { available = getPixelFormatAttrib(window, 1, WGL_NUMBER_PIXEL_FORMATS_ARB); } else { available = DescribePixelFormat(window->WGL.DC, 1, sizeof(PIXELFORMATDESCRIPTOR), NULL); } if (!available) { _glfwSetError(GLFW_API_UNAVAILABLE, "WGL: No pixel formats found"); return NULL; } fbconfigs = (_GLFWfbconfig*) malloc(sizeof(_GLFWfbconfig) * available); if (!fbconfigs) { _glfwSetError(GLFW_OUT_OF_MEMORY, NULL); return NULL; } for (i = 1; i <= available; i++) { _GLFWfbconfig* f = fbconfigs + *found; if (window->WGL.ARB_pixel_format) { // Get pixel format attributes through WGL_ARB_pixel_format if (!getPixelFormatAttrib(window, i, WGL_SUPPORT_OPENGL_ARB) || !getPixelFormatAttrib(window, i, WGL_DRAW_TO_WINDOW_ARB) || !getPixelFormatAttrib(window, i, WGL_DOUBLE_BUFFER_ARB)) { continue; } if (getPixelFormatAttrib(window, i, WGL_PIXEL_TYPE_ARB) != WGL_TYPE_RGBA_ARB) { continue; } if (getPixelFormatAttrib(window, i, WGL_ACCELERATION_ARB) == WGL_NO_ACCELERATION_ARB) { continue; } f->redBits = getPixelFormatAttrib(window, i, WGL_RED_BITS_ARB); f->greenBits = getPixelFormatAttrib(window, i, WGL_GREEN_BITS_ARB); f->blueBits = getPixelFormatAttrib(window, i, WGL_BLUE_BITS_ARB); f->alphaBits = getPixelFormatAttrib(window, i, WGL_ALPHA_BITS_ARB); f->depthBits = getPixelFormatAttrib(window, i, WGL_DEPTH_BITS_ARB); f->stencilBits = getPixelFormatAttrib(window, i, WGL_STENCIL_BITS_ARB); f->accumRedBits = getPixelFormatAttrib(window, i, WGL_ACCUM_RED_BITS_ARB); f->accumGreenBits = getPixelFormatAttrib(window, i, WGL_ACCUM_GREEN_BITS_ARB); f->accumBlueBits = getPixelFormatAttrib(window, i, WGL_ACCUM_BLUE_BITS_ARB); f->accumAlphaBits = getPixelFormatAttrib(window, i, WGL_ACCUM_ALPHA_BITS_ARB); f->auxBuffers = getPixelFormatAttrib(window, i, WGL_AUX_BUFFERS_ARB); f->stereo = getPixelFormatAttrib(window, i, WGL_STEREO_ARB); if (window->WGL.ARB_multisample) f->samples = getPixelFormatAttrib(window, i, WGL_SAMPLES_ARB); else f->samples = 0; if (window->WGL.ARB_framebuffer_sRGB) f->sRGB = getPixelFormatAttrib(window, i, WGL_FRAMEBUFFER_SRGB_CAPABLE_ARB); else f->sRGB = GL_FALSE; } else { // Get pixel format attributes through old-fashioned PFDs if (!DescribePixelFormat(window->WGL.DC, i, sizeof(PIXELFORMATDESCRIPTOR), &pfd)) { continue; } if (!(pfd.dwFlags & PFD_DRAW_TO_WINDOW) || !(pfd.dwFlags & PFD_SUPPORT_OPENGL) || !(pfd.dwFlags & PFD_DOUBLEBUFFER)) { continue; } if (!(pfd.dwFlags & PFD_GENERIC_ACCELERATED) && (pfd.dwFlags & PFD_GENERIC_FORMAT)) { continue; } if (pfd.iPixelType != PFD_TYPE_RGBA) continue; f->redBits = pfd.cRedBits; f->greenBits = pfd.cGreenBits; f->blueBits = pfd.cBlueBits; f->alphaBits = pfd.cAlphaBits; f->depthBits = pfd.cDepthBits; f->stencilBits = pfd.cStencilBits; f->accumRedBits = pfd.cAccumRedBits; f->accumGreenBits = pfd.cAccumGreenBits; f->accumBlueBits = pfd.cAccumBlueBits; f->accumAlphaBits = pfd.cAccumAlphaBits; f->auxBuffers = pfd.cAuxBuffers; f->stereo = (pfd.dwFlags & PFD_STEREO) ? GL_TRUE : GL_FALSE; // PFD pixel formats do not support FSAA f->samples = 0; // PFD pixel formats do not support sRGB f->sRGB = GL_FALSE; } f->platformID = i; (*found)++; } if (*found == 0) { _glfwSetError(GLFW_PLATFORM_ERROR, "Win32/WGL: No usable pixel formats found"); free(fbconfigs); return NULL; } return fbconfigs; }
// Return a list of available and usable framebuffer configs // static GLFWbool choosePixelFormat(_GLFWwindow* window, const _GLFWfbconfig* desired, int* result) { _GLFWfbconfig* usableConfigs; const _GLFWfbconfig* closest; int i, nativeCount, usableCount; if (_glfw.wgl.ARB_pixel_format) { nativeCount = getPixelFormatAttrib(window, 1, WGL_NUMBER_PIXEL_FORMATS_ARB); } else { nativeCount = DescribePixelFormat(window->context.wgl.dc, 1, sizeof(PIXELFORMATDESCRIPTOR), NULL); } usableConfigs = calloc(nativeCount, sizeof(_GLFWfbconfig)); usableCount = 0; for (i = 0; i < nativeCount; i++) { const int n = i + 1; _GLFWfbconfig* u = usableConfigs + usableCount; if (_glfw.wgl.ARB_pixel_format) { // Get pixel format attributes through "modern" extension if (!getPixelFormatAttrib(window, n, WGL_SUPPORT_OPENGL_ARB) || !getPixelFormatAttrib(window, n, WGL_DRAW_TO_WINDOW_ARB)) { continue; } if (getPixelFormatAttrib(window, n, WGL_PIXEL_TYPE_ARB) != WGL_TYPE_RGBA_ARB) { continue; } if (getPixelFormatAttrib(window, n, WGL_ACCELERATION_ARB) == WGL_NO_ACCELERATION_ARB) { continue; } u->redBits = getPixelFormatAttrib(window, n, WGL_RED_BITS_ARB); u->greenBits = getPixelFormatAttrib(window, n, WGL_GREEN_BITS_ARB); u->blueBits = getPixelFormatAttrib(window, n, WGL_BLUE_BITS_ARB); u->alphaBits = getPixelFormatAttrib(window, n, WGL_ALPHA_BITS_ARB); u->depthBits = getPixelFormatAttrib(window, n, WGL_DEPTH_BITS_ARB); u->stencilBits = getPixelFormatAttrib(window, n, WGL_STENCIL_BITS_ARB); u->accumRedBits = getPixelFormatAttrib(window, n, WGL_ACCUM_RED_BITS_ARB); u->accumGreenBits = getPixelFormatAttrib(window, n, WGL_ACCUM_GREEN_BITS_ARB); u->accumBlueBits = getPixelFormatAttrib(window, n, WGL_ACCUM_BLUE_BITS_ARB); u->accumAlphaBits = getPixelFormatAttrib(window, n, WGL_ACCUM_ALPHA_BITS_ARB); u->auxBuffers = getPixelFormatAttrib(window, n, WGL_AUX_BUFFERS_ARB); if (getPixelFormatAttrib(window, n, WGL_STEREO_ARB)) u->stereo = GLFW_TRUE; if (getPixelFormatAttrib(window, n, WGL_DOUBLE_BUFFER_ARB)) u->doublebuffer = GLFW_TRUE; if (_glfw.wgl.ARB_multisample) u->samples = getPixelFormatAttrib(window, n, WGL_SAMPLES_ARB); if (_glfw.wgl.ARB_framebuffer_sRGB || _glfw.wgl.EXT_framebuffer_sRGB) { if (getPixelFormatAttrib(window, n, WGL_FRAMEBUFFER_SRGB_CAPABLE_ARB)) u->sRGB = GLFW_TRUE; } } else { PIXELFORMATDESCRIPTOR pfd; // Get pixel format attributes through legacy PFDs if (!DescribePixelFormat(window->context.wgl.dc, n, sizeof(PIXELFORMATDESCRIPTOR), &pfd)) { continue; } if (!(pfd.dwFlags & PFD_DRAW_TO_WINDOW) || !(pfd.dwFlags & PFD_SUPPORT_OPENGL)) { continue; } if (!(pfd.dwFlags & PFD_GENERIC_ACCELERATED) && (pfd.dwFlags & PFD_GENERIC_FORMAT)) { continue; } if (pfd.iPixelType != PFD_TYPE_RGBA) continue; u->redBits = pfd.cRedBits; u->greenBits = pfd.cGreenBits; u->blueBits = pfd.cBlueBits; u->alphaBits = pfd.cAlphaBits; u->depthBits = pfd.cDepthBits; u->stencilBits = pfd.cStencilBits; u->accumRedBits = pfd.cAccumRedBits; u->accumGreenBits = pfd.cAccumGreenBits; u->accumBlueBits = pfd.cAccumBlueBits; u->accumAlphaBits = pfd.cAccumAlphaBits; u->auxBuffers = pfd.cAuxBuffers; if (pfd.dwFlags & PFD_STEREO) u->stereo = GLFW_TRUE; if (pfd.dwFlags & PFD_DOUBLEBUFFER) u->doublebuffer = GLFW_TRUE; } u->handle = n; usableCount++; } if (!usableCount) { _glfwInputError(GLFW_API_UNAVAILABLE, "WGL: The driver does not appear to support OpenGL"); free(usableConfigs); return GLFW_FALSE; } closest = _glfwChooseFBConfig(desired, usableConfigs, usableCount); if (!closest) { _glfwInputError(GLFW_FORMAT_UNAVAILABLE, "WGL: Failed to find a suitable pixel format"); free(usableConfigs); return GLFW_FALSE; } *result = (int) closest->handle; free(usableConfigs); return GLFW_TRUE; }
void OSGLContext_win::createGLContext(const FramebufferConfig& pixelFormatAttrs, int major, int minor, bool coreProfile, const GLRendererID &rendererID, const OSGLContext_win* shareContext) { const OSGLContext_wgl_data* wglInfo = appPTR->getWGLData(); assert(wglInfo); if (!wglInfo) { throw std::invalid_argument("No wgl info"); } bool useNVGPUAffinity = rendererID.rendererHandle && wglInfo->NV_gpu_affinity; if (useNVGPUAffinity) { HGPUNV GpuMask[2] = {(HGPUNV)rendererID.rendererHandle, NULL}; _dc = wglInfo->CreateAffinityDCNV(GpuMask); } else { _dc = GetDC(_windowHandle); } if (!_dc) { throw std::runtime_error("WGL: Failed to retrieve DC for window"); } std::vector<FramebufferConfig> usableConfigs; int nativeCount = 0, usableCount = 0; if (wglInfo->ARB_pixel_format) { nativeCount = getPixelFormatAttrib(wglInfo, 1, WGL_NUMBER_PIXEL_FORMATS_ARB); } else { nativeCount = DescribePixelFormat(_dc, 1, sizeof(PIXELFORMATDESCRIPTOR), NULL); } usableConfigs.resize(nativeCount); for (int i = 0; i < nativeCount; ++i) { const int n = i + 1; FramebufferConfig& u = usableConfigs[usableCount]; if (wglInfo->ARB_pixel_format) { // Get pixel format attributes through "modern" extension if ( !getPixelFormatAttrib(wglInfo, n, WGL_SUPPORT_OPENGL_ARB) || !getPixelFormatAttrib(wglInfo, n, WGL_DRAW_TO_WINDOW_ARB) ) { continue; } if (getPixelFormatAttrib(wglInfo, n, WGL_PIXEL_TYPE_ARB) != WGL_TYPE_RGBA_ARB) { continue; } if (getPixelFormatAttrib(wglInfo, n, WGL_ACCELERATION_ARB) == WGL_NO_ACCELERATION_ARB) { continue; } u.redBits = getPixelFormatAttrib(wglInfo, n, WGL_RED_BITS_ARB); u.greenBits = getPixelFormatAttrib(wglInfo, n, WGL_GREEN_BITS_ARB); u.blueBits = getPixelFormatAttrib(wglInfo, n, WGL_BLUE_BITS_ARB); u.alphaBits = getPixelFormatAttrib(wglInfo, n, WGL_ALPHA_BITS_ARB); u.depthBits = getPixelFormatAttrib(wglInfo, n, WGL_DEPTH_BITS_ARB); u.stencilBits = getPixelFormatAttrib(wglInfo, n, WGL_STENCIL_BITS_ARB); u.accumRedBits = getPixelFormatAttrib(wglInfo, n, WGL_ACCUM_RED_BITS_ARB); u.accumGreenBits = getPixelFormatAttrib(wglInfo, n, WGL_ACCUM_GREEN_BITS_ARB); u.accumBlueBits = getPixelFormatAttrib(wglInfo, n, WGL_ACCUM_BLUE_BITS_ARB); u.accumAlphaBits = getPixelFormatAttrib(wglInfo, n, WGL_ACCUM_ALPHA_BITS_ARB); u.auxBuffers = getPixelFormatAttrib(wglInfo, n, WGL_AUX_BUFFERS_ARB); if ( getPixelFormatAttrib(wglInfo, n, WGL_STEREO_ARB) ) { u.stereo = GL_TRUE; } if ( getPixelFormatAttrib(wglInfo, n, WGL_DOUBLE_BUFFER_ARB) ) { u.doublebuffer = GL_TRUE; } if (wglInfo->ARB_multisample) { u.samples = getPixelFormatAttrib(wglInfo, n, WGL_SAMPLES_ARB); } if (wglInfo->ARB_framebuffer_sRGB || wglInfo->EXT_framebuffer_sRGB) { if ( getPixelFormatAttrib(wglInfo, n, WGL_FRAMEBUFFER_SRGB_CAPABLE_ARB) ) { u.sRGB = GL_TRUE; } } } else { PIXELFORMATDESCRIPTOR pfd; // Get pixel format attributes through legacy PFDs if ( !DescribePixelFormat(_dc, n, sizeof(PIXELFORMATDESCRIPTOR), &pfd) ) { continue; } if ( !(pfd.dwFlags & PFD_DRAW_TO_WINDOW) || !(pfd.dwFlags & PFD_SUPPORT_OPENGL) ) { continue; } if ( !(pfd.dwFlags & PFD_GENERIC_ACCELERATED) && (pfd.dwFlags & PFD_GENERIC_FORMAT) ) { continue; } if (pfd.iPixelType != PFD_TYPE_RGBA) { continue; } u.redBits = pfd.cRedBits; u.greenBits = pfd.cGreenBits; u.blueBits = pfd.cBlueBits; u.alphaBits = pfd.cAlphaBits; u.depthBits = pfd.cDepthBits; u.stencilBits = pfd.cStencilBits; u.accumRedBits = pfd.cAccumRedBits; u.accumGreenBits = pfd.cAccumGreenBits; u.accumBlueBits = pfd.cAccumBlueBits; u.accumAlphaBits = pfd.cAccumAlphaBits; u.auxBuffers = pfd.cAuxBuffers; if (pfd.dwFlags & PFD_STEREO) { u.stereo = GL_TRUE; } if (pfd.dwFlags & PFD_DOUBLEBUFFER) { u.doublebuffer = GL_TRUE; } } u.handle = n; ++usableCount; } if (!usableCount) { throw std::runtime_error("WGL: The driver does not appear to support OpenGL"); } FramebufferConfig closestConfig = OSGLContext::chooseFBConfig(pixelFormatAttrs, usableConfigs, usableCount); int pixelFormat = closestConfig.handle; PIXELFORMATDESCRIPTOR pfd; HGLRC share = shareContext ? shareContext->_handle : 0; if ( !DescribePixelFormat(_dc, pixelFormat, sizeof(pfd), &pfd) ) { throw std::runtime_error("WGL: Failed to retrieve PFD for selected pixel format"); } if ( !SetPixelFormat(_dc, pixelFormat, &pfd) ) { throw std::runtime_error("WGL: Failed to set selected pixel format"); } if (useNVGPUAffinity) { _handle = wglInfo->CreateContext(_dc); } else if ( (rendererID.renderID > 0) && wglInfo->AMD_gpu_association ) { std::vector<int> attribs; setAttribs(major, minor, coreProfile, attribs); _handle = wglInfo->CreateAssociatedContextAttribsAMD( (UINT)rendererID.renderID, share, &attribs[0] ); } else if (wglInfo->ARB_create_context) { std::vector<int> attribs; setAttribs(major, minor, coreProfile, attribs); _handle = wglInfo->CreateContextAttribsARB(_dc, share, &attribs[0]); } else { _handle = wglInfo->CreateContext(_dc); } if (!_handle) { throw std::runtime_error("WGL: Failed to create OpenGL context"); } } // createGLContext