Example #1
0
// 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
}
Example #2
0
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
}