SharpGL & OpenGL backward compatibility

Sep 17, 2014 at 11:30 AM
Hi,

while testing with Sharp GL (OpenGL Version 4.0) I found that a lot of the functions I remembered from a training some years ago did not work (e.g. Begin(), End(), Vertex(), Perspective, ...).

When I tried using the SharpGL libraries compiled in DEBUG mode, I got a the error message "Extension function XXX not supported". This message is always created when you specify an OpenGL version you want to use where the used method is marked as deprecated.

Which methods are deprecated and which not is explained in the OpenGL X.XX API Quick Reference Cards provided here:
http://www.opengl.org/sdk/docs/
Every content shown in blue is deprecated.

Currently there is no build in possibility (that I've found) that enables backward compatibility.

For me, I've changed the class RenderContextProvider; Method UpdateContextVersion to:
        protected void UpdateContextVersion(OpenGL gl)
        {
            //  If the request version number is anything up to and including 2.1, standard render contexts
            //  will provide what we need (as long as the graphics card drivers are up to date).
            var requestedVersionNumber = VersionAttribute.GetVersionAttribute(requestedOpenGLVersion);
            if (requestedVersionNumber.IsAtLeastVersion(3, 0) == false)
            {
                createdOpenGLVersion = requestedOpenGLVersion;
                return;
            }

            //  Now the none-trivial case. We must use the WGL_ARB_create_context extension to 
            //  attempt to create a 3.0+ context.
            try
            {
                int[] attributes = 
                {
                    OpenGL.WGL_CONTEXT_MAJOR_VERSION_ARB, requestedVersionNumber.Major,  
                    OpenGL.WGL_CONTEXT_MINOR_VERSION_ARB, requestedVersionNumber.Minor,
                    OpenGL.WGL_CONTEXT_FLAGS_ARB, 0,
                    OpenGL.WGL_CONTEXT_PROFILE_MASK_ARB, OpenGL.WGL_CONTEXT_COMPATIBILITY_PROFILE_BIT_ARB,
                    0
                };
                var hrc = gl.CreateContextAttribsARB(IntPtr.Zero, attributes);
                Win32.wglMakeCurrent(IntPtr.Zero, IntPtr.Zero);
                Win32.wglDeleteContext(renderContextHandle);
                Win32.wglMakeCurrent(deviceContextHandle, hrc);
                renderContextHandle = hrc; 
            }
            catch(Exception)
            {
                //  TODO: can we actually get the real version?
                createdOpenGLVersion = OpenGLVersion.OpenGL2_1;
            }
        }
I changed the int[] attributes part, where you can specify how your render context should be initialized.

you can find an explanation of the attributes under:
https://www.opengl.org/registry/specs/ARB/wgl_create_context.txt

As I expect others to have the same problem as me, maybe the controls can be modified to have a "backward compatibility mode enabled" property.

Another "problem" with the current controls is, that it uses methods which are deprecated in higher version.

For example:
/// <summary>
        /// Handles the SizeChanged event of the OpenGLControl control.
        /// </summary>
        /// <param name="sender">The source of the event.</param>
        /// <param name="e">The <see cref="System.Windows.SizeChangedEventArgs"/> instance containing the event data.</param>
        void OpenGLControl_SizeChanged(object sender, SizeChangedEventArgs e)
        {
            //  Lock on OpenGL.
            lock (gl)
            {
                int width = (int)e.NewSize.Width;
                int height = (int)e.NewSize.Height;
                gl.SetDimensions(width, height);

                //  Set the viewport.
                gl.Viewport(0, 0, width, height);

                //  If we have a project handler, call it...
                if (width != -1 && height != -1)
                {
                    var handler = Resized;
                    if (handler != null)
                        handler(this, eventArgsFast);
                    else
                    {
                        //  Otherwise we do our own projection.
-->                        gl.MatrixMode(OpenGL.GL_PROJECTION);
-->                        gl.LoadIdentity();

                        // Calculate The Aspect Ratio Of The Window
-->                        gl.Perspective(45.0f, (float)width / (float)height, 0.1f, 100.0f);

-->                        gl.MatrixMode(OpenGL.GL_MODELVIEW);
-->                        gl.LoadIdentity();
                    }
                }
            }
        }
As each call to a deprecated method throws an exception and as exception handling is expensive I would guess that this might also have an impact on performance (Maybe not the SizeChanged eventhandler as shown above, but definitely the DrawText call for the FPS).

Cheers

Thomas