/// <summary> /// This is called immediately after the surface is first created. /// </summary> /// <param name="holder"> /// The SurfaceHolder whose surface is being created. /// </param> public void SurfaceCreated(ISurfaceHolder holder) { // Problem with static constructors? Ensure manual initialization Egl.Initialize(); Gl.Initialize(); // Get actual native window handle _NativeWindowHandle = ANativeWindow_fromSurface(JNIEnv.Handle, holder.Surface.Handle); // Create device context _DeviceContext = DeviceContext.Create(IntPtr.Zero, _NativeWindowHandle); _DeviceContext.IncRef(); // Set pixel format DevicePixelFormatCollection pixelFormats = _DeviceContext.PixelsFormats; DevicePixelFormat controlReqFormat = new DevicePixelFormat(); controlReqFormat.RgbaUnsigned = true; controlReqFormat.RenderWindow = true; controlReqFormat.ColorBits = 24; //controlReqFormat.DepthBits = (int)DepthBits; //controlReqFormat.StencilBits = (int)StencilBits; //controlReqFormat.MultisampleBits = (int)MultisampleBits; //controlReqFormat.DoubleBuffer = true; List <DevicePixelFormat> matchingPixelFormats = pixelFormats.Choose(controlReqFormat); if (matchingPixelFormats.Count == 0) { throw new InvalidOperationException("unable to find a suitable pixel format"); } _DeviceContext.SetPixelFormat(matchingPixelFormats[0]); // Create OpenGL context using compatibility profile if ((_RenderContext = _DeviceContext.CreateContext(IntPtr.Zero)) == IntPtr.Zero) { throw new InvalidOperationException("unable to create render context"); } // Make context current if (_DeviceContext.MakeCurrent(_RenderContext) == false) { throw new InvalidOperationException("unable to make context current"); } // Raise relative event OnContextCreated(); StartRendering(30.0f); }
/// <summary> /// Create the GlControl context, eventually shared with others. /// </summary> protected void CreateDesktopContext() { if (_RenderContext != IntPtr.Zero) { throw new InvalidOperationException("context already created"); } IntPtr sharingContext = IntPtr.Zero; bool shareResources = ContextSharing == ContextSharingOption.OwnContext && ContextSharingGroup != null; if (shareResources) { List <IntPtr> sharingContextes; if (_SharingGroups.TryGetValue(ContextSharingGroup, out sharingContextes)) { sharingContext = sharingContextes.Count > 0 ? sharingContextes[0] : IntPtr.Zero; } else { _SharingGroups.Add(ContextSharingGroup, new List <IntPtr>()); } } if (Gl.PlatformExtensions.CreateContext_ARB) { List <int> attributes = new List <int>(); uint contextProfile = 0, contextFlags = 0; bool debuggerAttached = Debugger.IsAttached; #region WGL_ARB_create_context|GLX_ARB_create_context // The default values for WGL_CONTEXT_MAJOR_VERSION_ARB and WGL_CONTEXT_MINOR_VERSION_ARB are 1 and 0 respectively. In this // case, implementations will typically return the most recent version of OpenGL they support which is backwards compatible with OpenGL 1.0 // (e.g. 3.0, 3.1 + GL_ARB_compatibility, or 3.2 compatibility profile) [from WGL_ARB_create_context spec] Debug.Assert(Wgl.CONTEXT_MAJOR_VERSION_ARB == Glx.CONTEXT_MAJOR_VERSION_ARB); Debug.Assert(Wgl.CONTEXT_MINOR_VERSION_ARB == Glx.CONTEXT_MINOR_VERSION_ARB); if (ContextVersion != null) { attributes.AddRange(new int[] { Wgl.CONTEXT_MAJOR_VERSION_ARB, ContextVersion.Major, Wgl.CONTEXT_MINOR_VERSION_ARB, ContextVersion.Minor }); } else { // Note: this shouldn't be necessary since defaults are defined. However, on certains drivers this arguments are // required for specifying CONTEXT_FLAGS_ARB and CONTEXT_PROFILE_MASK_ARB attributes: // - Required by NVIDIA 266.72 on GeForce GT 540M on Windows 7 x64 attributes.AddRange(new int[] { Wgl.CONTEXT_MAJOR_VERSION_ARB, 1, Wgl.CONTEXT_MINOR_VERSION_ARB, 0 }); } if ((_DebugContextBit == AttributePermission.Enabled) || (debuggerAttached && _DebugContextBit == AttributePermission.EnabledInDebugger)) { Debug.Assert(Wgl.CONTEXT_DEBUG_BIT_ARB == Glx.CONTEXT_DEBUG_BIT_ARB); contextFlags |= Wgl.CONTEXT_DEBUG_BIT_ARB; } if ((_ForwardCompatibleContextBit == AttributePermission.Enabled) || (debuggerAttached && _ForwardCompatibleContextBit == AttributePermission.EnabledInDebugger)) { Debug.Assert(Wgl.CONTEXT_FORWARD_COMPATIBLE_BIT_ARB == Glx.CONTEXT_FORWARD_COMPATIBLE_BIT_ARB); contextFlags |= Wgl.CONTEXT_FORWARD_COMPATIBLE_BIT_ARB; } #endregion #region WGL_ARB_create_context_profile|GLX_ARB_create_context_profile if (Gl.PlatformExtensions.CreateContextProfile_ARB) { switch (_ProfileType) { case ProfileType.Core: Debug.Assert(Wgl.CONTEXT_CORE_PROFILE_BIT_ARB == Glx.CONTEXT_CORE_PROFILE_BIT_ARB); contextProfile |= Wgl.CONTEXT_CORE_PROFILE_BIT_ARB; break; case ProfileType.Compatibility: Debug.Assert(Wgl.CONTEXT_COMPATIBILITY_PROFILE_BIT_ARB == Glx.CONTEXT_COMPATIBILITY_PROFILE_BIT_ARB); contextProfile |= Wgl.CONTEXT_COMPATIBILITY_PROFILE_BIT_ARB; break; } } #endregion #region WGL_ARB_create_context_robustness|GLX_ARB_create_context_robustness if (Gl.PlatformExtensions.CreateContextRobustness_ARB) { if ((_RobustContextBit == AttributePermission.Enabled) || (debuggerAttached && _RobustContextBit == AttributePermission.EnabledInDebugger)) { Debug.Assert(Wgl.CONTEXT_ROBUST_ACCESS_BIT_ARB == Glx.CONTEXT_ROBUST_ACCESS_BIT_ARB); contextFlags |= Wgl.CONTEXT_ROBUST_ACCESS_BIT_ARB; } } #endregion Debug.Assert(Wgl.CONTEXT_FLAGS_ARB == Glx.CONTEXT_FLAGS_ARB); if (contextFlags != 0) { attributes.AddRange(new int[] { Wgl.CONTEXT_FLAGS_ARB, unchecked ((int)contextFlags) }); } Debug.Assert(Wgl.CONTEXT_PROFILE_MASK_ARB == Glx.CONTEXT_PROFILE_MASK_ARB); Debug.Assert(contextProfile == 0 || Gl.PlatformExtensions.CreateContextProfile_ARB); if (contextProfile != 0) { attributes.AddRange(new int[] { Wgl.CONTEXT_PROFILE_MASK_ARB, unchecked ((int)contextProfile) }); } attributes.Add(0); if ((_RenderContext = _DeviceContext.CreateContextAttrib(sharingContext, attributes.ToArray())) == IntPtr.Zero) { throw new InvalidOperationException(String.Format("unable to create render context ({0})", Gl.GetError())); } } else { // Create OpenGL context using compatibility profile if ((_RenderContext = _DeviceContext.CreateContext(sharingContext)) == IntPtr.Zero) { throw new InvalidOperationException("unable to create render context"); } } // Allow other GlControl instances to reuse this GlControl context if (shareResources) { if (_SharingControls.ContainsKey(ContextSharingGroup)) { throw new InvalidOperationException(String.Format("another GlControl has created sharing group {0}", ContextSharingGroup)); } _SharingControls.Add(ContextSharingGroup, this); } // Allow other GlControl instances to share resources with this context if (shareResources == true) { List <IntPtr> sharingContextes; // Get the list previously created _SharingGroups.TryGetValue(ContextSharingGroup, out sharingContextes); // ...and register this context among the others sharingContextes.Add(_RenderContext); } }