Exemple #1
0
func (window *Win32Window) GetHDC() unsafe.Pointer {
	if window.hdc != nil {
		return unsafe.Pointer(&window.hdc)
	}

	window.hdc = C.GetDC(window.hwnd)

	px := C.PIXELFORMATDESCRIPTOR{
		dwFlags:    0x00000001 | 0x00000020 | 0x00000004,
		iPixelType: 0,
		cColorBits: 32,
		cDepthBits: 32,
		iLayerType: 0,
	}

	px.nSize = (C.WORD)(unsafe.Sizeof(px))

	pxFormat := C.ChoosePX(window.hdc, &px)
	if pxFormat == 0 {
		return nil
	}

	res := C.SetPixelFormat(window.hdc, pxFormat, &px)
	if res == 0 {
		return nil
	}

	return unsafe.Pointer(&window.hdc)
}
func (ic *contextInternal) initializeFromSettings(settings ContextSettings, width, height int) ThreadError {
	ic.deactivateSignal = make(chan bool)
	ic.settings = settings

	ic.window = createHiddenWindow(width, height)
	if ic.window == nil {
		// C.GetLastError()
		return NewThreadError(fmt.Errorf("could not create window (%d)", C.GetLastError()), true)
	}
	ic.ownsWindow = true

	ic.hdc = C.GetDC(ic.window)
	if ic.hdc == nil {
		return NewThreadError(errors.New("no device context"), true)
	}

	if sharedContext == nil { // if there is no shared context, we are it
		ic.isSharedContext = true

		pfd := C.PIXELFORMATDESCRIPTOR{
			nSize:      C.PIXELFORMATDESCRIPTOR_size, // size of this pfd
			nVersion:   1,                            // version number
			iPixelType: C.PFD_TYPE_RGBA,              // RGBA type
			cColorBits: 24,                           // 24-bit color depth
			cDepthBits: 32,                           // 32-bit z-buffer
			iLayerType: C.PFD_MAIN_PLANE,             // main layer

			// support window | OpenGL | double buffer
			dwFlags: C.PFD_DRAW_TO_WINDOW | C.PFD_SUPPORT_OPENGL | C.PFD_DOUBLEBUFFER,
		}

		// get the best available match of pixel format for the device context
		// make that the pixel format of the device context
		if iPixelFormat := C.ChoosePixelFormat(ic.hdc, &pfd); iPixelFormat == 0 {
			return NewThreadError(fmt.Errorf("sharedContext: ChoosePixelFormat failed (%d)", C.GetLastError()), true)
		} else if C.SetPixelFormat(ic.hdc, iPixelFormat, &pfd) == C.FALSE {
			return NewThreadError(fmt.Errorf("sharedContext: SetPixelFormat failed (%d)", C.GetLastError()), true)
		}

		ic.context = C.wglCreateContext(ic.hdc)
		if ic.context == nil {
			return NewThreadError(fmt.Errorf("sharedContext: wglCreateContext failed (%d)", C.GetLastError()), true)
		}
	} else { // otherwise we push the commands onto the shared context thread

		bitsPerPixel := GetDefaultMonitor().GetDesktopMode().BitsPerPixel
		ic.context = createContext(&sharedContext.internal.procs, sharedContext.internal.context, ic.hdc, bitsPerPixel, &ic.settings)
		if ic.context == nil {
			return NewThreadError(fmt.Errorf("could not create context (%d)", C.GetLastError()), true)
		}
	}
	// signal because we start out deactivated
	ic.signalDeactivation()
	return nil
}
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
}