Send a suggestion!

We're building a brand new version of the site, and we'd love to hear your ideas

Members

Technology Zones

IBM Learning Center

Articles

Hosted By

MaximumASP

Info

Rated
Read 81,304 times

Contents

Related Categories

OpenGL and C# - Part 1 - An OpenGL Control

Trialution

An OpenGL Control

What we need to do now is add a class named OurView. Make it a derived class from OpenGLControl. I will show you the code for the class now.

using System;
using System.Drawing;
using System.Windows.Forms;
using CsGL.OpenGL;
namespace SimpleOpenGL
{
    public class OurView : OpenGLControl
    {
        public OurView(): base()
        {
            this.KeyDown += new KeyEventHandler(OurView_OnKeyDown);
        }
        public override void glDraw()
        {    
            GL.glClear(GL.GL_COLOR_BUFFER_BIT | GL.GL_DEPTH_BUFFER_BIT); // Clear The Screen And The Depth Buffer    
            GL.glLoadIdentity();                 // Reset The Current Modelview Matrix        
            // TODO: Draw a box or something
//             this.SwapBuffer(); // swap Buffers
        }
        protected override void InitGLContext()
        {
            GL.glShadeModel(GL.GL_SMOOTH);         // Set Smooth Shading                
            GL.glClearColor(0.0f, 0.0f, 0.0f, 0.5f);     // BackGround Color        
            GL.glClearDepth(1.0f);                 // Depth buffer setup            
            GL.glEnable(GL.GL_DEPTH_TEST);         // Enables Depth Testing            
            GL.glDepthFunc(GL.GL_LEQUAL);             // The Type Of Depth Test To Do    
            GL.glHint(GL.GL_PERSPECTIVE_CORRECTION_HINT, GL.GL_NICEST);     /* Really Nice Perspective Calculations */    
        }
        protected override void OnSizeChanged(EventArgs e)
        {
            base.OnSizeChanged(e);
       
            Size s = Size;
            double aspect_ratio = (double)s.Width /(double) s.Height;
            GL.glMatrixMode(GL.GL_PROJECTION); // Select The Projection Matrix
            GL.glLoadIdentity(); // Reset The Projection Matrix
           
            // Calculate The Aspect Ratio Of The Window
            GL.gluPerspective(45.0f, aspect_ratio, 0.1f, 100.0f);
   
            GL.glMatrixMode(GL.GL_MODELVIEW); // Select The Modelview Matrix
            GL.glLoadIdentity();// Reset The Modelview Matrix
        }
        protected void OurView_OnKeyDown(object Sender, KeyEventArgs kea)
        {
            if (kea.KeyCode == Keys.Q && kea.Modifiers == Keys.Shift)
            {
                Application.Exit();
            }
        }
    }
}

You may notice that this is almost the base code from NeHe. And yes it is I created it with the NeHe base code in mind. I won’t go for every gl function in detail you can read here, lesson 1 & 2 for that.

Now we have the control we can add it to our form. Add this in the class

private SimpleOpenGL.OurView view;

Ok add this after the InitializeComponent function.

this.view = new SimpleOpenGL.OurView();
this.view.Parent = this;
this.view.Dock = DockStyle.Fill; // Will fill whole form

You can now try to run your form. Everything is running perfect. But there is one more thing our form is only render once. And when you resize it, it will render another time. To solve this problem we’re going to add a thread which will render the scene over and over again (how it should).

Ok first thing to do is add a thread. Put this underneath the other declarations.

private static Thread thrOpenGL;

Then underneath the view properties.

thrOpenGL = new Thread(new ThreadStart(OpenGL_Start));
thrOpenGL.Start();
Then the function OpenGL_Start.
private void OpenGL_Start()
{
    for (;;) // infinity loop for rendering
    {
        this.view.Refresh();
    }
}

If you would run the application now you might notice that when you close the form you program isn’t really exit cause the thread is still running to solve this we add this code at the end of the Dispose function. But for people who don’t use the Visual Studio .Net I will show you the whole function.

protected override void Dispose( bool disposing )
{
    if( disposing )
    {
        if (components != null)
        {
            components.Dispose();
        }
    }
    base.Dispose( disposing );
    // Abort the OpenGL Thread
    // otherwise it will last rendering forever
    thrOpenGL.Abort();
}

We are done with our OpenGL control now but it is hard to show off to your friends when you only have a black window. Like this.BackColor = Color.Black;in the main form constructor will do the same thing.

I'm doing first year Informatica at academy of Amsterdam

Comments

  • Re: [3930] OpenGL and C# - Part 1

    Posted by mpuma on 01 Feb 2008

    I also get this error.  One way of circunventing is by setting the boolean


    CheckForIllegalCrossThreadCalls = false...

  • Re: [3930] OpenGL and C# - Part 1

    Posted by James2432 on 10 Feb 2007

    I get the fallowing exception:  Cross-Thread operation not valid: Control "accessed from a thread other than it was created on.

    in this:

    for (; ; ) // infinity loop for rendering

  • Re: [3930] OpenGL and C# - Part 1

    Posted by dreamlabs on 02 Jun 2006

    when i download the zip file for Csgl one of the files is missing, what should I do? I have looked over the web for other places that have the file, no luck.   

  • Cube doesn't appear...

    Posted by specode on 24 Nov 2005

    I am not sure but I think there is a misstyped variable name "Position", I wonder if its "fPlusPostion".

    Cube.cs Line 76
    ----
    this.ViewPort = 0;
    this.fMinusPosition = 0f...

  • Posted by echoSwe on 10 Jul 2005

    I have the same problem, but I do actually have that line in place in the constructor of OurView.

    I tried this:

    [code]
       Cube cb = new Cube();
       cb.CubeColorBlue = 0.7f;
       cb.CubeColorGreen = 0....