Search code examples
c#openglopentk

How to render using OpenTK GLWidget in Monodevelop?


I'm trying to use this GLWidget thing to develop using OpenTK and GTK#, it seems like a good thing, but sadly there's next to no documentation for it. I'm trying to understand how to render anything in that Widget. So far, I created a monodevelop solution, added references to OpenTK and GLWidget, now i see GLWidget in Stetic's tool pane, I added a Vbox, with two slots, in the upper one i added a menu bar, and in the lower one the famous GLWidget. I also created an event handler for the OnRender event and the Initialized event, but I can't even draw a triangle. Has anyone ever worked with GLWidget and can give some advice to me? Here's my MainWindow.cs code:

   using System;
   using Gtk;
   using OpenTK;
   using OpenTK.Graphics;
   using OpenTK.Graphics.OpenGL;
   using OpenTK.Audio;
   using OpenTK.Audio.OpenAL;
   using OpenTK.Input;

   public partial class MainWindow : Gtk.Window{

    public MainWindow () : base(Gtk.WindowType.Toplevel)
    {
    Build ();
     }

   protected void GLWidgetInitialize (object sender, System.EventArgs e)
   {
    int width = 0, height = 0;
    //glwidget7.GdkWindow.GetSize(out width, out height);   
    this.vbox3.GetSizeRequest(out width, out height);
    GL.Viewport(0, 0, width, height);
    GL.ClearColor(1.0f, 1.0f,1.0f,1.0f);
    GL.Clear(ClearBufferMask.ColorBufferBit);
}

protected void OnDeleteEvent (object sender, DeleteEventArgs a)
{
    Application.Quit ();
    a.RetVal = true;
}


protected void OnRenderFrameWidget (object sender, System.EventArgs e)
{

    GL.ClearColor(1.0f, 1.0f,1.0f,1.0f);
    GL.Begin(BeginMode.Triangles);

        GL.Color3(1.0f, 1.0f, 0.0f); GL.Vertex3(-1.0f, -1.0f, 4.0f);
        GL.Color3(1.0f, 0.0f, 0.0f); GL.Vertex3(1.0f, -1.0f, 4.0f);
        GL.Color3(0.2f, 0.9f, 1.0f); GL.Vertex3(0.0f, 1.0f, 4.0f);

    GL.End();
}

}

By the way, changing GLClearColor values does make my GLWidget change the background color.


Solution

  • Well, I was finally able to get it working, the MainWindow code should look something like this:

      public partial class MainWindow : Gtk.Window
      {
    
    public bool GLinit;
    
    public MainWindow () : base(Gtk.WindowType.Toplevel)
    {
        Build ();
        GLinit = false;
    }
    
    protected virtual void GLWidgetInitialize (object sender, System.EventArgs e)
    {
        //this might be overkill to some people, but worked for me
        
        int width = 0, height = 0;  
        this.vbox3.GetSizeRequest(out width, out height);
        float aspectRatio = width/ height; 
        GL.Viewport(0, 0, width, height);
        GL.ClearColor(1.0f, 1.0f,1.0f,1.0f);
        GL.Clear(ClearBufferMask.ColorBufferBit);
        GL.MatrixMode(MatrixMode.Modelview);
        GL.LoadIdentity();
        GL.ShadeModel(ShadingModel.Smooth);         
        Matrix4 projection = Matrix4.CreatePerspectiveFieldOfView((float)Math.PI / 4, aspectRatio, 1.0f, 64.0f);
        GL.MatrixMode(MatrixMode.Projection);           
        GL.LoadMatrix(ref projection);          
        GL.ClearDepth(1);              
        GL.Disable(EnableCap.DepthTest);    
        GL.Enable(EnableCap.Texture2D); 
        GL.Enable(EnableCap.Blend);
        GL.DepthFunc(DepthFunction.Always);     
        GL.Hint(HintTarget.PerspectiveCorrectionHint, HintMode.Nicest); 
        //add idle event handler to process rendering whenever and as long as time is availble.
        GLinit = true;
        GLib.Idle.Add(new GLib.IdleHandler(OnIdleProcessMain));
            
    }
    
    protected void OnDeleteEvent (object sender, DeleteEventArgs a)
    {
        Application.Quit ();
        a.RetVal = true;
    }
    
    
    protected void RenderFrame(){
        
        //Here's where you write your OpenGL code to draw whatever you want
                //Don't forget to swap your buffers
        
            OpenTK.Graphics.GraphicsContext.CurrentContext.SwapBuffers();
        
    }
        
    protected bool OnIdleProcessMain ()
    {
        if (!GLinit) return false;
        else{
                 RenderFrame();
             return true;
        }
    }   
     }
    

    For more information, see here: http://www.opentk.com/node/2910 (Archived)