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.