// Let's find a suitable pixel format -- first try with antialiasing func BestwglChoosePixelFormatARB(procs *C.wglProcs, hdc C.HDC, bitsPerPixel uint, settings *ContextSettings) C.int { if settings.AntialiasingLevel <= 0 { return 0 } if procs.p_wglChoosePixelFormatARB == nil { return 0 } AttribIList := [...]C.int{ C.WGL_DRAW_TO_WINDOW_ARB, C.GL_TRUE, C.WGL_SUPPORT_OPENGL_ARB, C.GL_TRUE, C.WGL_ACCELERATION_ARB, C.WGL_FULL_ACCELERATION_ARB, C.WGL_DOUBLE_BUFFER_ARB, C.GL_TRUE, C.WGL_SAMPLE_BUFFERS_ARB, C.GL_TRUE, // turn on antialiasing C.WGL_SAMPLES_ARB, C.int(settings.AntialiasingLevel), 0, 0, } AttribFList := []C.FLOAT{0, 0} // Let's check how many formats are supporting our requirements const formats_size = 128 var formats [formats_size]C.int var nbFormats C.UINT for settings.AntialiasingLevel > 0 { if C.__wglChoosePixelFormatARB(procs, hdc, &AttribIList[0], &AttribFList[0], formats_size, &formats[0], &nbFormats) == C.TRUE && nbFormats > 0 { break } nbFormats = 0 // reset this // Decrease the antialiasing level until we find a valid one settings.AntialiasingLevel-- AttribIList[11]-- } bestScore := uint(1<<32 - 1) var bestFormat C.int for i := C.UINT(0); bestScore != 0 && i < nbFormats; i++ { // Get the current format's attributes attributes := C.PIXELFORMATDESCRIPTOR{ nSize: C.PIXELFORMATDESCRIPTOR_size, nVersion: 1, } if C.__DescribePixelFormat(hdc, formats[i], C.PIXELFORMATDESCRIPTOR_size, &attributes) == 0 { return 0 } // Evaluate the current configuration color := uint(attributes.cRedBits + attributes.cGreenBits + attributes.cBlueBits + attributes.cAlphaBits) score := EvaluateFormat(bitsPerPixel, *settings, color, uint(attributes.cDepthBits), uint(attributes.cStencilBits), settings.AntialiasingLevel) // Keep it if it's better than the current best if score < bestScore { bestScore = score bestFormat = formats[i] } } return bestFormat }
func createContext(procs *C.wglProcs, sharedContext C.HGLRC, hdc C.HDC, bitsPerPixel uint, settings *ContextSettings) C.HGLRC { bestFormat := BestwglChoosePixelFormatARB(procs, hdc, bitsPerPixel, settings) if bestFormat == 0 { bestFormat = BestChoosePixelFormat(hdc, bitsPerPixel, settings) } if bestFormat == 0 { return nil // Failed to find a suitable pixel format for device context -- cannot create OpenGL context } // Extract the depth and stencil bits from the chosen format actualFormat := C.PIXELFORMATDESCRIPTOR{ nSize: C.PIXELFORMATDESCRIPTOR_size, nVersion: 1, } if C.__DescribePixelFormat(hdc, bestFormat, C.PIXELFORMATDESCRIPTOR_size, &actualFormat) == 0 { return nil } settings.DepthBits = uint(actualFormat.cDepthBits) settings.StencilBits = uint(actualFormat.cStencilBits) // Set the chosen pixel format if C.SetPixelFormat(hdc, bestFormat, &actualFormat) == C.FALSE { return nil // Failed to set pixel format for device context -- cannot create OpenGL context } if procs.p_wglCreateContextAttribsARB != nil { for settings.MajorVersion >= 3 { attributes := [...]C.int{ C.WGL_CONTEXT_MAJOR_VERSION_ARB, C.int(settings.MajorVersion), C.WGL_CONTEXT_MINOR_VERSION_ARB, C.int(settings.MinorVersion), C.WGL_CONTEXT_PROFILE_MASK_ARB, C.WGL_CONTEXT_COMPATIBILITY_PROFILE_BIT_ARB, 0, 0, } if context := C.__wglCreateContextAttribsARB(procs, hdc, sharedContext, &attributes[0]); context != nil { return context } // If we couldn't create the context, lower the version number and try again -- stop at 3.0 // Invalid version numbers will be generated by this algorithm (like 3.9), but we really don't care if settings.MinorVersion > 0 { // If the minor version is not 0, we decrease it and try again settings.MinorVersion-- } else { // If the minor version is 0, we decrease the major version settings.MajorVersion-- settings.MinorVersion = 9 } } } // set the context version to 2.0 (arbitrary) settings.MajorVersion = 2 settings.MinorVersion = 0 context := C.wglCreateContext(hdc) if context == nil { return nil // Failed to create an OpenGL context for this window } // Share this context with others C.wglShareLists(sharedContext, context) return context }