alanb's picture

Help problem with changing to version 0.9-8.1 from 0.3.14 and GLWidget

Hi,
I have been using a very old version of opentk (0.3.14) with GLWidget for quite a while in some software Im writing. Yesterday I hit a bug in this old version so decided to upgrade. I downloaded 0.9.8.1 and built it ok on opensuse 11.1. Thought everything would be ok if I just swapped the dlls in my project, I renamed the imports to OpenTK.Graphics.OpenGL; etc and built my project. No compilation errors. However when I run I get

Quote:

Unhandled Exception: System.InvalidOperationException: No GraphicsContext available in the calling thread.
at OpenTK.Graphics.GL.LoadAll () [0x00000]

So could someone tell me how things have changed or how to solve my problem? Looking at your example code I also suspect that GL.LoadAll() is deprecated but again dont know what the changes are. I saw your example using windows forms + GLcontrol. However I have a lot of time invested in my Gtk based project so swapping over to windows forms would be impossible. I am not writing a major 3D game or anything like that I just want a Gdk window to display some simple 3D paths so have not spent any time on openGL other than to learn the basics. I am prepared to change over to GLControl if that can be embedded in a Gtk Widget so my question is can it? I use monodevelop and tried browsing the opentk dll but couldnt see any reference to the control. Also monodevelop reported nothing available when I tried to add items to the toolbox from opentk.dll and opentk.utilities.dll.
I would rather progress than go back to the earlier versions so any help would be appreciated.
Thanks
Alan


Comments

the Fiddler's picture

Your code should work fine after a simple change: add a call to GraphicsContext.CreateDummyContext() as soon as you create the OpenGL context through your Gtk Widget.

OpenTK 0.9.8 is much stricter than 0.3.14 regarding OpenGL. One of the changes is that it now requires the creation of an OpenGL context prior to the use of OpenGL commands. Since you are creating the context from an external library, you need to inform OpenTK of the context's existence - hence the CreateDummyContext() method.

Another change is that the debug version of OpenTK.dll will now check for OpenGL errors automatically. This is *very* useful while developing an application, as it makes debugging much easier. Just remember to switch to the release OpenTK.dll when distributing your application (the debug version carries a hefty performance hit).

Edit: as part of the ongoing documentation effort, I have added a page that explains how to use external contexts with OpenTK.

alanb's picture

I understand in principle what you are saying however practice is another matter as I did not write the GLWidget code. I have looked through the GLWidget code and tried putting GraphicsContext.CreateDummyContext() in several places but I still get the same error message. Perhaps you could suggest where, as I see no place which has an explicit call to CreateContext(). I have taken some liberties with the GLWidget code included below in that I have deleted all the windows stuff leaving just the X part. When I know where to put the call to CreateDummyContext() I will reinstate the complete version.
Thanks
Alan

 public class GLWidget : DrawingArea, IDisposable
    {
        static PlatformID platformID = System.Environment.OSVersion.Platform;
 
        bool doubleBuffer = true;
        public new bool DoubleBuffered
        {
            get { return doubleBuffer; }
            set { doubleBuffer = value; }
        }
 
        byte colorBits = 24;
        public byte ColorBits
        {
            get { return colorBits; }
            set { colorBits = value; }
        }
 
        byte alphaBits = 0;
        public byte AlphaBits
        {
            get { return alphaBits; }
            set { alphaBits = value; }
        }
 
        byte depthBits = 32;
        public byte DepthBits
        {
            get { return depthBits; }
            set { depthBits = value; }
        }
 
        byte stencilBits = 0;
        public byte StencilBits
        {
            get { return stencilBits; }
            set { stencilBits = value; }
        }
 
        HandleRef renderingContextHandle;
        public HandleRef RenderingContextHandle
        {
            get { return renderingContextHandle; }
        }
 
        Gdk.Visual visual = null;
        static GLWidget globalSharedContextWidget = null;	
        GLWidget sharedContextWidget;
 
        public GLWidget()
			 : this(null)
        {
			if( globalSharedContextWidget == null)
			{
				globalSharedContextWidget = this;
			}
			else
			{
				sharedContextWidget = globalSharedContextWidget;
			}
        }
 
        public GLWidget(GLWidget sharedContextWidget)
        {
            base.DoubleBuffered = false;
            Realized += new EventHandler(HandleRealized);
			ExposeEvent += new ExposeEventHandler(HandleExposeEvent);
 
            this.sharedContextWidget = sharedContextWidget;
 
        }
 
        public override void Dispose()
        {
            base.Dispose();
 
            glXDestroyContext(gdk_x11_display_get_xdisplay(visual.Screen.Display.Handle), renderingContextHandle);
        }
 
        void HandleRealized(object sender, EventArgs eventArgs)
        {
           int[] attributeList = new int[24];
           int attributeIndex = 0;
 
           attributeList[attributeIndex++] = GLX_RGBA;
           if (doubleBuffer) attributeList[attributeIndex++] = GLX_DOUBLEBUFFER;
 
           attributeList[attributeIndex++] = GLX_RED_SIZE;
           attributeList[attributeIndex++] = 1;
 
           attributeList[attributeIndex++] = GLX_GREEN_SIZE;
           attributeList[attributeIndex++] = 1;
 
           attributeList[attributeIndex++] = GLX_BLUE_SIZE;
           attributeList[attributeIndex++] = 1;
 
           if (alphaBits != 0)
           {
               attributeList[attributeIndex++] = GLX_ALPHA_SIZE;
               attributeList[attributeIndex++] = 1;
           }
 
           if (depthBits != 0)
           {
              attributeList[attributeIndex++] = GLX_DEPTH_SIZE;
              attributeList[attributeIndex++] = 1;
           }
 
           if (stencilBits != 0)
           {
              attributeList[attributeIndex++] = GLX_STENCIL_SIZE;
              attributeList[attributeIndex++] = 1;
           }
 
           attributeList[attributeIndex++] = GLX_NONE;
 
           IntPtr xDisplay = gdk_x11_display_get_xdisplay(Screen.Display.Handle);
           IntPtr visualIntPtr = IntPtr.Zero;
 
           try
           {
               visualIntPtr = glXChooseVisual(xDisplay, Screen.Number, attributeList);
           }
           catch (DllNotFoundException e)
           {
               throw new Exception("OpenGL dll not found!", e);
           }
           catch (EntryPointNotFoundException enf)
           {
               throw new Exception("Glx entry point not found!", enf);
           }
 
           if (visualIntPtr == IntPtr.Zero)
           {
             throw new Exception("Visual");
           }
 
           XVisualInfo xVisualInfo = (XVisualInfo)Marshal.PtrToStructure(visualIntPtr, typeof(XVisualInfo));
 
           IntPtr xRenderingContext = IntPtr.Zero;
 
 
 
           if (sharedContextWidget != null)
           {
               GLWidget primaryWidget = sharedContextWidget;
               while (primaryWidget.sharedContextWidget != null) primaryWidget = primaryWidget.sharedContextWidget;
 
               if (primaryWidget.RenderingContextHandle.Handle != IntPtr.Zero)
               {
                  xRenderingContext = glXCreateContext(xDisplay, visualIntPtr, primaryWidget.RenderingContextHandle, true);
               }
                else
               {
                   xRenderingContext = glXCreateContext(xDisplay, visualIntPtr, new HandleRef(null, IntPtr.Zero), true);
                   this.sharedContextWidget = null;
                   primaryWidget.sharedContextWidget = this;
               }
           }
           else
           {
                  xRenderingContext = glXCreateContext(xDisplay, visualIntPtr, new HandleRef(null, IntPtr.Zero), true);
           }
 
 
           if (xRenderingContext == IntPtr.Zero)
           {
              throw new Exception("Unable to create rendering context");
           }
 
           renderingContextHandle = new HandleRef(this, xRenderingContext);
           visual = (Gdk.Visual)GLib.Object.GetObject(gdk_x11_screen_lookup_visual(Screen.Handle, xVisualInfo.visualid));
 
           if (visualIntPtr != IntPtr.Zero)
           {
               XFree(visualIntPtr);
           }
	  OpenTK.Graphics.GraphicsContext.CreateDummyContext(); ********* I thought here but it doesnt seem to make a difference *********************88 
        }
 
		void HandleExposeEvent(object o, ExposeEventArgs args)
		{
			MakeCurrent();
 
			OnRender();
 
			SwapBuffers();
		}
 
		public event EventHandler Render;
		public virtual void OnRender()
		{
			if( Render != null )
			{
				try
				{
					Render(this, EventArgs.Empty);
				}
				catch( NullReferenceException ) { }
			}
		}
 
        public bool MakeCurrent()
        {
           return glXMakeCurrent(gdk_x11_display_get_xdisplay(GdkWindow.Display.Handle), gdk_x11_drawable_get_xid(GdkWindow.Handle), renderingContextHandle);
        }
 
        public void SwapBuffers()
        {
           glXSwapBuffers(gdk_x11_display_get_xdisplay(GdkWindow.Display.Handle), gdk_x11_drawable_get_xid(GdkWindow.Handle));
        }
 
 
        #region X
 
		const string linux_libgl_name = "libGL.so.1";
		const string linux_libx11_name = "libX11.so.6";
		const string linux_libgdk_x11_name = "libgdk-x11-2.0.so.0";
 
        [SuppressUnmanagedCodeSecurity, DllImport(linux_libx11_name)]
        static extern void XFree(IntPtr handle);
 
        [SuppressUnmanagedCodeSecurity, DllImport(linux_libx11_name)]
        internal static extern uint XVisualIDFromVisual(IntPtr visual);
 
        [SuppressUnmanagedCodeSecurity, DllImport(linux_libgl_name)]
        static extern IntPtr glXCreateContext(IntPtr display, IntPtr visualInfo, HandleRef shareList, bool direct);
 
        [SuppressUnmanagedCodeSecurity, DllImport(linux_libgl_name)]
        static extern IntPtr glXChooseVisual(IntPtr display, int screen, int[] attr);
 
        [SuppressUnmanagedCodeSecurity, DllImport(linux_libgl_name)]
        static extern void glXDestroyContext(IntPtr display, HandleRef ctx);
 
        [SuppressUnmanagedCodeSecurity, DllImport(linux_libgl_name)]
        static extern bool glXMakeCurrent(IntPtr display, uint xdrawable, HandleRef ctx);
 
        [SuppressUnmanagedCodeSecurity, DllImport(linux_libgl_name)]
        static extern void glXSwapBuffers(IntPtr display, uint drawable);
 
        [SuppressUnmanagedCodeSecurity, DllImport(linux_libgdk_x11_name)]
        static extern uint gdk_x11_drawable_get_xid(IntPtr d);
 
        [SuppressUnmanagedCodeSecurity, DllImport(linux_libgdk_x11_name)]
        static extern IntPtr gdk_x11_display_get_xdisplay(IntPtr d);
 
        //[SuppressUnmanagedCodeSecurity, DllImport(linux_libgdk_x11_name)]
        //static extern IntPtr gdk_x11_visual_get_xvisual(IntPtr d);
 
        [SuppressUnmanagedCodeSecurity, DllImport(linux_libgdk_x11_name)]
        static extern IntPtr gdk_x11_screen_lookup_visual(IntPtr screen, uint xvisualid);
 
        const int GLX_NONE = 0;
        const int GLX_USE_GL = 1;
        const int GLX_BUFFER_SIZE = 2;
        const int GLX_LEVEL = 3;
        const int GLX_RGBA = 4;
        const int GLX_DOUBLEBUFFER = 5;
        const int GLX_STEREO = 6;
        const int GLX_AUX_BUFFERS = 7;
        const int GLX_RED_SIZE = 8;
        const int GLX_GREEN_SIZE = 9;
        const int GLX_BLUE_SIZE = 10;
        const int GLX_ALPHA_SIZE = 11;
        const int GLX_DEPTH_SIZE = 12;
        const int GLX_STENCIL_SIZE = 13;
        const int GLX_ACCUM_RED_SIZE = 14;
        const int GLX_ACCUM_GREEN_SIZE = 15;
        const int GLX_ACCUM_BLUE_SIZE = 16;
        const int GLX_ACCUM_ALPHA_SIZE = 17;
 
        [StructLayout(LayoutKind.Sequential)]
        private struct XVisualInfo
        {
            public IntPtr visual;
            public uint visualid;
            public int screen;
            public int depth;
            public int c_class;
            public uint red_mask;
            public uint blue_mask;
            public uint green_mask;
            public int colormap_size;
            public int bits_per_rgb;
        }
        #endregion
    }
zahirtezcan's picture

IIRC CreateDummyContext method requires an active context on the current thread. So, calling such method should be no problem after MakeCurrent call.

JTalton's picture

I'll see what I can work out and get the GLWidget site updated with relevant information. It will be a few days.

JTalton's picture

It's been a few days. Still have not found the time. :(

JTalton's picture

After creating a GLContext using the GLWidget code and making the context current, I call CreateDummyContext and get

System.NullReferenceException: Object reference not set to an instance of an object.
at OpenTK.Platform.Windows.Wgl.GetCurrentContext()
at OpenTK.Platform.Windows.WinFactory.b__0()
at OpenTK.Graphics.GraphicsContext.CreateDummyContext()

On a related note, I would like to get GLWidget to create a context using the underlying context code that OpenTK uses.
Related Post: http://www.opentk.com/node/903
I used MonoDevelop on Windows and I am not seeing the issue I previously mentioned. I will have to test some things.

objarni's picture

Isn't this related to http://www.opentk.com/node/993 ?

the Fiddler's picture

Any chance for a stack trace from a debug version of OpenTK? It might help.

There are two ways to make GLWidget work with OpenTK directly: either make it depend on OpenTK or create a third, "glue" assembly that acts as the bridge between OpenTK and GLWidget. The actual code will resemble EGL: you'll need to fill a WinWindowInfo, X11WindowInfo or CarbonWindowInfo struct and pass it to the GraphicsContext constructor (along with any other parameters you wish to set, e.g. OpenGL version).These structs hold platform-specific information that is used to contsruct the context (a window handle and a DC for WinWindowInfo, a window handle, display connection and visual for X11WindowInfo etc). GLWidget should already have this information available, so the actual implementation should be relatively simple.

In both cases, we'll need to make a few changes in OpenTK to expose some internal types to the world - let me take a look.

Edit @objarni: good memory, this is the issue. I'll track this down.

the Fiddler's picture

Ok, the necessary classes and enums are now public (SVN trunk). This code can be changed as needed to accommodate the GLWidget - please let me know if you need any help with this task. I am going to hunt down the GetCurrentContext bug now.

the Fiddler's picture

Ok, this issue should be fixed now.

JTalton's picture

grabbed the latest code on my Ubuntu machine
svn co https://opentk.svn.sourceforge.net/svnroot/opentk/trunk opentk
went to opentk/Build and ran "mono Build.exe vs"
opened opentk/Build/OpenTK.sln with MonoDevelop

In OpenTK/Compute/CL10/CL.cs there are 126 errors about
Argument type `uint' is not CLS-compliant(CS3001)

I havn't looked in the issue yet. If anyone has a quick fix, I'd love to hear it.

the Fiddler's picture

Thanks, I didn't test on Mono prior to the latest code drop. CS3001 (CLS-compliance) should be a warning, not an error (I think this has been fixed in Mono 2.2 or 2.4).

Quick solution: try checking out from the 0.9.8 branch (svn co https://opentk.svn.sourceforge.net/svnroot/opentk/branches/0.9.8).

Long solution: I'll have to find out why the generator is not marking those methods as CLSCompliant(false).

objarni's picture

If anyone has a server left over, it could be used to do "continous integration".

That means the server will, at some interval (say once an hour) or triggered by a new SVN rev found, run a build-script that:

1) updates from SVN
2) runs Build
3) compiles solution
4) create output HTML report

.. to check if everything still compiles. The result could be published as a static HTML file, accessible from the web.

Assuming the server runs linux, it could use VirtualBox to build for Windows, and mono for linux. I guess VirtualBox could be used for Mac OSX too?

What is the point of this arrangement? Well it works as a "health monitor" for the OpenTK trunk, meaning commits to it would quickly be discovered to "have regressions" (errors). In essence, it speeds up the feedback loop of OpenTK development, since these forums/users does not have to report "trivial" errors.

I find these things interesting -- I could work on the Ubuntu-part of the build script at home. :)

More info on Continous Integration from wikipedia: http://en.wikipedia.org/wiki/Continuous_integration

the Fiddler's picture

I've been thinking about that the past couple of days, but unfortunately I don't have an always-on server at this point (my desktop uses more than 200W at idle so it's out of the question - which is strange, as I definitely recall it using something closer to 110W a few weeks ago).

Apart from the build results, this could also be used to provide nightly builds, which could be quite useful.

Finally, I *think* it could be possible to add a pre-commit hook to Sourceforge and reject any commits that would break the build. Also useful, as you don't always have access to all operating systems for testing.

Back on topic, I have fixed the CLS-compliance issue but I'm hitting a very strange compiler bug (that doesn't manifest on the GL bindings, for some reason):

namespace OpenTK.Compute.CL10
{
    using System;
    using System.Runtime.InteropServices;
    ...
    public static unsafe IntPtr EnqueueMapBuffer(..., [Out] int* errcode_ret) { ... }
}

The last line is generating a "type or namespace Out not found" error. Change Out to OutAttribute and it works.

Strange.

objarni's picture

Finally, I *think* it could be possible to add a pre-commit hook to Sourceforge and reject any commits that would break the build. Also useful, as you don't always have access to all operating systems for testing.

Yep that is another solution - but knowing how lazy a developer is (me at least), the check-if-all-platforms-still-builds is a step that is often skipped "Nah it still works, that was a small fix" :)

(how would sf.net know if it does not compile..? do they provide build servers for multiple platforms? Isn't that kind of hard being the largest OSS host in the world, I mean providing build tools for each and any project?)

the Fiddler's picture

Compilation issues are now fixed. Still need to add a workaround for gmcs 2.4.2 bug #530270, but it should otherwise be working fine now.

A quick google search indicates that the idea for a pre-commit hook on sourceforge is a dead end. However a server that performs hourly builds would be great!

The main issue is that we'll probably need to use xbuild from trunk to compile OpenTK (no released version works correctly up to now) and there's a good chance not even that will work. Nant was also not working last time I tried, which means we might have to write manual build scripts (not terribly hard) or makefiles (harder but probably safer). Or fix xbuild.

Edit @objarni: do you mind filing a task for the build server whenever you find the time?

Edit 2: I have added a workaround for gmcs bug #530270. OpenTK finally compiles with Mono 2.4.2!

Sometimes I feel like I'm spending more time to work around incompatibilities and bugs between different platforms/compilers than actually writing code...

objarni's picture

Done, please edit the details, which I'm unsure of. (Maybe the task should be broken up into subtasks, like building for different OSs..?)

Link to task.

the Fiddler's picture

Thanks.

I forgot to mention that the CLS-compliance bug is fixed, as is bug #993: Possible bug in GraphicsContext.CreateDummyContext().

JTalton's picture

I have a GLWidget for Windows that works great, creating the GraphicsContext using the OpenTK code.

Stripped down version:

public class GLWidget : DrawingArea
{
	IGraphicsContext graphicsContext;
	GraphicsMode graphicsMode;
	IWindowInfo windowInfo;
	int major, minor;
	GraphicsContextFlags graphicsContextFlags;
 
	public GLWidget(GraphicsMode graphicsMode, int major, int minor, GraphicsContextFlags graphicsContextFlags)
	{
		this.graphicsMode = graphicsMode;
		this.major = major;
		this.minor = minor;
		this.graphicsContextFlags = graphicsContextFlags;
	}
 
	// Called when a widget is realized. (window handles and such are valid)
	protected override void OnRealized()
	{
		base.OnRealized();
 
		IntPtr windowHandle;
		if (Configuration.RunningOnWindows) windowHandle = gdk_win32_drawable_get_handle(GdkWindow.Handle);
		else if (Configuration.RunningOnX11) windowHandle = GdkWindow.Handle; // This may need to be tested
		else if (Configuration.RunningOnMacOS) windowHandle = GdkWindow.Handle; // This may need to be tested
		else throw new PlatformNotSupportedException();
 
		windowInfo = OpenTK.Platform.Utilities.CreateWindowInfo(graphicsMode, windowHandle);
		graphicsContext = new GraphicsContext(graphicsMode, windowInfo, major, minor, graphicsContextFlags);
		graphicsContext.MakeCurrent(windowInfo);
		GL.LoadAll();
 
		GL.ClearColor(1.0f, 0, 0, 1);
	}		
 
	// Called when the widget needs to be (fully or partially) redrawn.
	protected override bool OnExposeEvent(Gdk.EventExpose eventExpose)
	{
		graphicsContext.MakeCurrent(windowInfo);
		GL.Clear(ClearBufferMask.ColorBufferBit); // Only here for testing - should be done in expose event
		bool result = base.OnExposeEvent(eventExpose);
		eventExpose.Window.Display.Sync(); // Add Sync call to fix resize rendering problem (Jay L. T. Cornwall)
		graphicsContext.SwapBuffers();
		return true;
	}
}

I will do some testing tonight on Linux.

I do believe there will be a problem with OpenTK.Platform.Utilities.CreateWindowInfo() for Linux in that it calls System.Windows.Forms.XplatUIX11 to get the window information, which I do not think works with GTK#. A possible solution would be that if the XplatUIX11 calls failed, we would try the GDK calls.

Question: Is the GraphicsContext automatically a shared context or do I need to handle that in GLWidget?

JTalton's picture

Found the information on the Shared Context.
Attached the file for the GLWidget if anyone wants to review or try out. I've only tried it on Windows, but it seems to work good.
GTK# from Novel for Windows is here: http://ftp.novell.com/pub/mono/gtk-sharp/gtk-sharp-2.12.9-2.win32.msi

the Fiddler's picture

I am using this code to test on Linux, but it results in a segmentation fault (no error, no exception, no stack trace...)

I admit I had forgotten about the Platform.Utilities.CreateWindowInfo method. This method was written to help the WinForms GLControl, which might explain the failure.

There were no plans to make OpenTK extensible like this at first. We will probably need to make a few (relatively simple) changes to add-ons like GLWidget to work reliably, but this will pay off in the end.

using System;
using Gtk;
using OpenTK.Graphics;
 
namespace test
{
    public class EntryPoint
    {
        public static void Main()
        {
            Application.Init();
 
            var window = new Window("GLWidget/OpenTK Test.");
            window.Resize(640, 480);
            var glwidget = new GLWidget();
            glwidget.ColorAlphaBPP = glwidget.ColorBlueBPP = glwidget.ColorGreenBPP = glwidget.ColorRedBPP = 8;
            glwidget.RenderFrame += (sender, e) =>
            {
                GL.Clear(ClearBufferMask.ColorBufferBit);
            };
 
            window.Add(glwidget);
            window.ShowAll();
 
            Application.Run();
        }
    }
}

Investigating.

JTalton's picture

I will be looking at it tonight on Linux also. When the GLWidget is created, it gets the GraphicsContext.Default and sets the default values to that. In my previous testing calling GraphicsContext.Default on Linux in my GTK# application was causing an error. That might be the first line to look at.

JTalton's picture

Made progress on Linux. I have the GLWidget working with only minor changes to the OpenTK.Platform.Utilities.CreateWindowInfo() code. I had to move calls around in GLWidget because it appears the GDK.Drawable is not valid until the Expose Event. Resizing is causing a crash and a few things are hard coded. More to come.

objarni's picture

Great news JTalton! How easy is GTK+ to code, compared to Windows.Forms? Is there a designer? Do you plan to release the GLWidget as a contributed project to the OpenTK community?

the Fiddler's picture

Nice!

You can simplify the code a bit if you replace Accumulator*BPP, Color*BPP, Depth, Stereo etc fields with a single GraphicsMode reference - unless there is a reason why these properties exist like this?

GTK# is pretty easy to use and much more powerful than WinForms. Ever tried designing a resolution- or font-independent WinForm? It's impossible! The biggest issue with GTK# is that it doesn't work very well on MacOS right now (this is an issue with the underlying GTK+ libraries).

MonoDevelop ships with a GTK# designer, IIRC.

JTalton's picture

You can simplify the code a bit if you replace Accumulator*BPP, Color*BPP, Depth, Stereo etc fields with a single GraphicsMode reference - unless there is a reason why these properties exist like this?
Yes, I separated them out so that if you make a widget library for MonoDevelop those properties would be easily editable in the designer. I'm not sure how the designer would handle a GraphicsMode. If you have thoughts on this, I'd love to hear it.

Yes, I agree that GTK# is much better than WinForms and it's crossplatform support is getting better and better. The GTK# installer is available for MacOS and MonoDevelop for OSX is using it.

I'm going to clean up the code and document it better. After Linux is 100% I will be testing on my Mac. I will probably add GLWidget as a contributed project here on the OpenTK site and keep the source hosted at sourceforge. I'd like to get screen shots of it running on all three platforms. Of course it would be nice to have something cool in the GLWidget to show off. Maybe someone has an idea for a OpenGL 3.0+ demo that could be running in the GLWidget? It would be nice to describe the screen shot as a GTK# OpenGL widget using OpenTK to render using OpenGL 3.X.

the Fiddler's picture

It's probably possible to to create a custom designer for MonoDevelop/GTK#, but I don't know how.

Per-pixel lighting with parallax/relief mapping is a sure bet for a simple but impressive demo.

JTalton's picture

Cleaned up GLWidget a little more.

  • Windows - Works good.
  • Linux - Needs more testing.
  • MacOSX - Needs work.

Attached a patch file for Utilities.cs that added two new functions.

public static IWindowInfo CreateWindowInfo(Graphics.GraphicsMode mode, IntPtr windowHandle, IntPtr display)
private static IWindowInfo CreateX11WindowInfo(Graphics.GraphicsMode mode, IntPtr windowHandle, IntPtr display)

These are much like the WinForms ones but have a display handle parameter and are used for GTK.

alanb's picture

Just pulled updated GLWidget from sourceforge. Compiled ok but seems to have changed in that there is now no Render event handler to hook into. So where do I now place my openGL code? Is it in the ExposeEvent handler of my widget that contains the GLWidget?

Alan

alanb's picture

OOps sorry,
Forget last message I just looked at the GLWidget code supplied in last post. Obviously updated version and newer than that on sourceforge. (Shoulld have done that in the first place). Will test in my code.
Alan