4

SharpGL 2.1

For those who are interested, I’m now starting development of SharpGL 2.1. SharpGL 2.1 will primarily be a release to implement features and fix bugs that users have added to the Codeplex site. The actual features and bugs that’ll be sorted are on the CodePlex site – just search for release ‘SharpGL 2.1′.

This will also be the first release of SharpGL that will be published on Nuget.

7

SharpGL 2.0

SharpGL 2.0 has been released – hit the codeplex site to get it: http://sharpgl.codeplex.com/

Some new features:

  • Full support for all OpenGL functions up to OpenGL 4.2
  • Full support for all commonly used OpenGL extensions
  • Support for WinForms applications
  • Support for WPF applications (without resorting to WinForms hosts)
  • A powerful scene graph including polygons, shaders, NURBs and more
  • Many sample applications as starting points for your own projects.
  • Visual Studio Extension with SharpGL project templates for WPF and WinForms.
And a few screenshots:
 
 The Radial Blur Sample

The New Project Types

WPF Support

Text Rendering

8

SharpGL 2.0 Beta 1 Released

It’s been a long time coming, but the first Beta of SharpGL 2.0 is finally here!

The Beta is on CodePlex at: http://sharpgl.codeplex.com/releases/view/74704

This includes the binaries, example applications and full source code.

Some of the more exciting features are:

  • Full hardware acceleration
  • OpenGL Extensions
  • Full core functionality up to OpenGL 4.2
  • Native WPF Control
Below is a screenshot of SharpGL in a WPF application:
 
 
 
And here’s a link to a new CodeProject article describing how to use SharpGL in a WPF application:
 
 
Please try out SharpGL 2.0 Beta 1 and let me know what you think!
2

Importing OpenGL Extensions Functions with wglGetProcAddress

There are only a small set of the core OpenGL functions that can be imported via p/invoke – the majority of OpenGL functions are actually extension functions which are supported only on specific video cards. OpenGL offers a function called wglGetProcAddress which can return the address of a named function – but how do we deal with this in the managed world?

Here’s a brief description of how it’s handled in SharpGL. As of this morning, SharpGL’s latest version contains all core functions up to OpenGL 4.2 and all standard extensions up to OpenGL 4.2. This takes the support for OpenGL to the latest version – August 2011.

First we must import the wglGetProcAddress function:

[DllImport("opengl32.dll")]
public static extern IntPtr wglGetProcAddress(string name);

This is the correect p/invoke method of importing this function, however it returns an IntPtr, which we cannot call as a function. We could change the return type to a delegate but this function can return essentially any type of delegate – so where do we go from here?

Well the next step is to define the delegates we want to use – they must have exactly the same name as the OpenGL functions and use the correct parameters for marshalling. Here are a couple of delegates for OpenGL 1.4:

private delegate void glBlendFuncSeparate (uint sfactorRGB, uint dfactorRGB, uint sfactorAlpha, uint dfactorAlpha);

private delegate void glMultiDrawArrays (uint mode, int[] first, int[] count, int primcount);

Now we must create a function which will turn an IntPtr into a delegate and invoke it:

/// <summary>
/// The set of extension functions.
/// </summary>
private Dictionary<string, Delegate> extensionFunctions = new Dictionary<string, Delegate>();

/// <summary>
/// Invokes an extension function.
/// </summary>
/// <typeparam name="T">The extension delegate type.</typeparam>
/// <param name="args">The arguments to the pass to the function.</param>
/// <returns>The return value of the extension function.</returns>
private object InvokeExtensionFunction<T>(params object[] args)
{
    //  Get the type of the extension function.
    Type delegateType = typeof(T);

    //  Get the name of the extension function.
    string name = delegateType.Name;

    //  Does the dictionary contain our extension function?
    Delegate del = null;
    if (extensionFunctions.ContainsKey(name) == false)
    {
        //  We haven't loaded it yet. Load it now.
        IntPtr proc = Win32.wglGetProcAddress(name);
        if (proc == IntPtr.Zero)
            throw new Exception("Extension function " + name + " not supported");

        //  Get the delegate for the function pointer.
        del = Marshal.GetDelegateForFunctionPointer(proc, delegateType);
        if (del == null)
            throw new Exception("Extension function " + name + " not supported");

        //  Add to the dictionary.
        extensionFunctions.Add(name, del);
    }

    //  Get the delegate.
    del = extensionFunctions[name];

    //  Try and invoke it.
    object result = null;
    try
    {
        result = del.DynamicInvoke(args);
    }
    catch
    {
        throw new Exception("Cannot invoke extension function " + name);
    }

    return result;
}

We now have a generalised way to invoke an extension function. The loaded functions are stored in a dictionary keyed by name so that the heavy lifting is only done the first time we try to invoke the function.  We can finally add the functions to the class as below:

public void BlendFuncSeparate(uint sfactorRGB, uint dfactorRGB, uint sfactorAlpha, uint dfactorAlpha)
{
    InvokeExtensionFunction<glBlendFuncSeparate>(sfactorRGB, dfactorRGB, sfactorAlpha, dfactorAlpha);
}

public void MultiDrawArrays(uint mode, int[] first, int[] count, int primcount)
{
    InvokeExtensionFunction<glMultiDrawArrays>(mode, first, count, primcount);
}

This is pretty cool – we can invoke any extension function as long as we have defined a delegate for it. What’s more, by making the InvokeExtensionFunction function public we can allow other developers to provide their own delegates and invoke other extension functions.

This is the technique used in SharpGL 2.0 to import extension functions – the Core/OpenGLExtensions.cs file contains thousands of lines of functions defined like this, however knowing how to invoke any kind of delegate is a useful skill in the managed world, so this trick could be used in other places.

The version of SharpGL this post relates to is at:

http://sharpgl.codeplex.com/SourceControl/changeset/view/4474

0

SharpGL 2.0: Hardware Acceleration

It took a bit of working out, but finally SharpGL can support hardware acceleration. Previously, all rendering in SharpGL was done to a DIB Section, the result of this would be blitted to the screen. Much playing around has shown that in fact this is problematic – rendering to DIB sections can never be hardware accelerated.

To hardware accelerate rendering, the rendering must be to a window or a pixel buffer. This has introduced an architectural change to SharpGL – the handling of a render context and any supporting objects (DIB sections, windows etc) is handled by a class that implements the IRenderContextProvider interface. This interface specifies that render context providers must be able to Create, Destroy, Resize and Blit.

SharpGL 2.0 now has two render context providers, DIBSectionRenderContext provider which uses a DIB Section as previously and HiddenWindowRenderContextProvider which renders to a hidden window. The hidden window render context provider allows full hardware acceleration.

I will be adding a new example application to the solution which shows rendering with the two providers side by side.

So don’t forget: DIB Sections can’t be accelerated.

0

Trials and Tribulations with SharpGL 2.0

SharpGL has not been updated for a while, the original CoreProject article is at: http://www.codeproject.com/KB/openGL/sharpgl.aspx

Recently I have begun work on SharpGL 2.0, with plans to address some of the issues people have had with SharpGL 1.83. In preparation there is a public accessible repository on CodePlex: http://sharpgl.codeplex.com/ check it soon, it will shortly be online.

Trying to squeeze acceptible performance from SharpGL has so far been an interesting task, I have found out many interesting things on the way, I’ll be posting small snippets as I work on SharpGL 2.0 describing how I’m improving the performance and structure of the library.