/// <summary>
        /// Makes the context current on the calling thread.
        /// </summary>
        /// <param name="ctx">
        /// A <see cref="IntPtr"/> that specify the context to be current on the calling thread, bound to
        /// thise device context. It can be IntPtr.Zero indicating that no context will be current.
        /// </param>
        /// <returns>
        /// It returns a boolean value indicating whether the operation was successful.
        /// </returns>
        /// <exception cref="NotSupportedException">
        /// Exception thrown if the current platform is not supported.
        /// </exception>
        protected override bool MakeCurrentCore(IntPtr ctx)
        {
            if (ctx != IntPtr.Zero)
            {
                // Ensure correct API bound
                if (Version >= Egl.Version_120)
                {
                    int[] contextClientType = new int[1];

                    if (Egl.QueryContext(Display, ctx, Egl.CONTEXT_CLIENT_TYPE, contextClientType))
                    {
                        if (Egl.BindAPI((uint)contextClientType[0]) == false)
                        {
                            throw new InvalidOperationException("no ES API");
                        }
                    }
                }

                return(Egl.MakeCurrent(Display, EglSurface, EglSurface, ctx));
            }
            else
            {
                return(Egl.MakeCurrent(Display, IntPtr.Zero, IntPtr.Zero, IntPtr.Zero));
            }
        }
Exemple #2
0
        /// <summary>
        /// Creates an OpenGL context from a Unix/Linux platform.
        /// </summary>
        /// <returns>
        /// A <see cref="IDeviceContext"/> that specify the device context.
        /// </returns>
        private static IntPtr CreateEglSimpleContext(IDeviceContext rDevice)
        {
            NativeDeviceContext eglDeviceCtx = (NativeDeviceContext)rDevice;
            IntPtr ctx;

            List <int> configAttribs = new List <int>();

            if (eglDeviceCtx.Version >= Egl.Version_120)
            {
                configAttribs.AddRange(new int[] { Egl.RENDERABLE_TYPE, Egl.OPENGL_ES2_BIT });
            }
            configAttribs.AddRange(new int[] {
                Egl.RED_SIZE, 8,
                Egl.GREEN_SIZE, 8,
                Egl.BLUE_SIZE, 8,
            });
            configAttribs.Add(Egl.NONE);

            int[]    configCount = new int[1];
            IntPtr[] configs     = new IntPtr[8];

            if (Egl.BindAPI(Egl.OPENGL_ES_API) == false)
            {
                throw new InvalidOperationException("no ES API");
            }

            if (Egl.ChooseConfig(eglDeviceCtx.Display, configAttribs.ToArray(), configs, configs.Length, configCount) == false)
            {
                throw new InvalidOperationException("unable to choose configuration");
            }
            if (configCount[0] == 0)
            {
                throw new InvalidOperationException("no available configuration");
            }

            List <int> contextAttribs = new List <int>();

            if (eglDeviceCtx.Version >= Egl.Version_130)
            {
                contextAttribs.AddRange(new int[] { Egl.CONTEXT_CLIENT_VERSION, 2 });
            }
            contextAttribs.Add(Egl.NONE);

            if ((ctx = Egl.CreateContext(eglDeviceCtx.Display, configs[configs.Length - 1], IntPtr.Zero, contextAttribs.ToArray())) == IntPtr.Zero)
            {
                throw new InvalidOperationException("unable to create context");
            }

            List <int> surfaceAttribs = new List <int>();

            surfaceAttribs.Add(Egl.NONE);
            // Egl.RENDER_BUFFER, Egl.BACK_BUFFER,

            eglDeviceCtx.Surface = Egl.CreateWindowSurface(eglDeviceCtx.Display, configs[configs.Length - 1], eglDeviceCtx.NativeWindow, surfaceAttribs.ToArray());

            return(ctx);
        }
        /// <summary>
        /// Create a simple context.
        /// </summary>
        /// <returns>
        /// A <see cref="IntPtr"/> that represents the handle of the created context. If the context cannot be
        /// created, it returns IntPtr.Zero.
        /// </returns>
        internal override IntPtr CreateSimpleContext()
        {
            IntPtr ctx;

            int[]    configAttribs = DefaultConfigAttribs;
            int[]    configCount   = new int[1];
            IntPtr[] configs       = new IntPtr[8];

            if (Egl.ChooseConfig(Display, configAttribs, configs, configs.Length, configCount) == false)
            {
                throw new InvalidOperationException("unable to choose configuration");
            }
            if (configCount[0] == 0)
            {
                throw new InvalidOperationException("no available configuration");
            }

            int[] contextAttribs = DefaultContextAttribs;
            int[] surfaceAttribs = { Egl.NONE };

            if (Version >= Egl.Version_120)
            {
                if (Egl.BindAPI(Egl.OPENGL_ES_API) == false)
                {
                    throw new InvalidOperationException("no ES API");
                }
            }

            if ((ctx = Egl.CreateContext(Display, configs[0], IntPtr.Zero, contextAttribs)) == IntPtr.Zero)
            {
                throw new InvalidOperationException("unable to create context");
            }

            if (_NativeSurface.Handle == IntPtr.Zero)
            {
                List <int> pbufferAttribs = new List <int>(surfaceAttribs);

                pbufferAttribs.RemoveAt(pbufferAttribs.Count - 1);
                pbufferAttribs.AddRange(new[] { Egl.WIDTH, 1, Egl.HEIGHT, 1 });
                pbufferAttribs.Add(Egl.NONE);

                _NativeSurface.CreateHandle(configs[0], pbufferAttribs.ToArray());
            }

            return(ctx);
        }
Exemple #4
0
        /// <summary>
        /// Initialize LTS information for the calling thread.
        /// </summary>
        public static void InitializeThread()
        {
#if !MONODROID
            if (Egl.IsRequired == false)
            {
                switch (Platform.CurrentPlatformId)
                {
                case Platform.Id.WindowsNT:
                    Wgl.BindAPI();
                    break;

                case Platform.Id.Linux:
                    Glx.BindAPI();
                    break;

                case Platform.Id.MacOS:
                    if (Glx.IsRequired)
                    {
                        Glx.BindAPI();
                    }
                    else
                    {
                        throw new NotSupportedException("platform MacOS not supported without Glx.IsRequired=true");
                    }
                    break;

                case Platform.Id.Android:
                    Egl.BindAPI();
                    break;

                default:
                    throw new NotSupportedException(String.Format("platform {0} not supported", Platform.CurrentPlatformId));
                }
            }
            else
#endif
            Egl.BindAPI();
        }
        /// <summary>
        /// Creates a context, specifying attributes.
        /// </summary>
        /// <param name="sharedContext">
        /// A <see cref="IntPtr"/> that specify a context that will share objects with the returned one. If
        /// it is IntPtr.Zero, no sharing is performed.
        /// </param>
        /// <param name="attribsList">
        /// A <see cref="T:Int32[]"/> that specifies the attributes list.
        /// </param>
        /// <param name="api">
        /// A <see cref="KhronosVersion"/> that specifies the API to be implemented by the returned context. It can be null indicating the
        /// default API for this DeviceContext implementation. If it is possible, try to determine the API version also.
        /// </param>
        /// <returns>
        /// A <see cref="IntPtr"/> that represents the handle of the created context. If the context cannot be
        /// created, it returns IntPtr.Zero.
        /// </returns>
        /// <exception cref="ArgumentNullException">
        /// Exception thrown if <paramref name="attribsList"/> is null.
        /// </exception>
        /// <exception cref="ArgumentException">
        /// Exception thrown if <paramref name="attribsList"/> length is zero or if the last item of <paramref name="attribsList"/>
        /// is not zero.
        /// </exception>
        public override IntPtr CreateContextAttrib(IntPtr sharedContext, int[] attribsList, KhronosVersion api)
        {
            if (attribsList == null)
            {
                throw new ArgumentNullException(nameof(attribsList));
            }
            if (attribsList.Length == 0)
            {
                throw new ArgumentException("zero length array", nameof(attribsList));
            }
            if (attribsList[attribsList.Length - 1] != Egl.NONE)
            {
                throw new ArgumentException("not EGL_NONE-terminated array", nameof(attribsList));
            }

            IntPtr context;

            // Select surface pixel format automatically
            if (_NativeSurface != null && _NativeSurface.Handle != IntPtr.Zero)
            {
                int[] configId = new int[1];

                if (Egl.QuerySurface(Display, EglSurface, Egl.CONFIG_ID, configId) == false)
                {
                    throw new InvalidOperationException("unable to query EGL surface config ID");
                }

                _Config = ChoosePixelFormat(Display, configId[0]);
            }

            // Bind API
            if (Version >= Egl.Version_120)
            {
                uint apiEnum;

                switch (api.Api)
                {
                case KhronosVersion.ApiGles2:
                case KhronosVersion.ApiGles1:
                case null:
                    // Default
                    apiEnum = Egl.OPENGL_ES_API;
                    break;

                case KhronosVersion.ApiGl:
                    apiEnum = Egl.OPENGL_API;
                    break;

                case KhronosVersion.ApiVg:
                    apiEnum = Egl.OPENVG_API;
                    break;

                default:
                    throw new InvalidOperationException($"'{api}' API not available");
                }
                if (Egl.BindAPI(apiEnum) == false)
                {
                    throw new InvalidOperationException("no ES API");
                }
            }
            else if (api != null && api.Api != KhronosVersion.ApiGles2 && api.Api != KhronosVersion.ApiGles1)
            {
                throw new InvalidOperationException($"'{api}' API not available");
            }

            // Create context
            if ((context = Egl.CreateContext(Display, _Config, sharedContext, attribsList)) == IntPtr.Zero)
            {
                throw new EglException(Egl.GetError());
            }

            // Create native surface (pixel format pending)
            // @todo Back-buffer?
            if (_NativeSurface != null && _NativeSurface.Handle == IntPtr.Zero)
            {
                _NativeSurface.CreateHandle(_Config, new[] { Egl.NONE });
            }

            return(context);
        }