Introduction
This is a simple example about using OpenGL in CSharp application.
The Workflow of Using OpenGL
- Create OpenGL with a specific area.
- Create a DIB (Device independent bitmap)
- Create OpenGL rendering context and set the device
- Make the OpenGL render context the current rendering context
Note: When we create the OpenGL, we don’t need any device handle. We will create a device handle with DIB by ourselves. Then set the created handle to OpenGL. But the graphics on this device handle can't be shown, so we should copy the graphics to the view when we want to show the graphics of the DIB.
- Do some initialization for OpenGL.
- Draw graphics with OpenGL.
- Make the OpenGL rendering context the current rendering context.
- Draw graphics with OpenGL.
- Swap buffers.
- Copy image to the view of control.
Note: In fact, we draw the graphics to the DIB. Then copy the graphics from the DIB to the specific view area.
public OpenGLBox()
{
InitializeComponent();
bool bRet = m_gl.Create(Width, Height);
Debug.Assert(bRet == true);
m_gl.ShadeModel(OpenGL.SMOOTH);
m_gl.ClearColor(0.0f, 0.0f, 0.0f, 0.0f);
m_gl.ClearDepth(1.0f);
m_gl.Enable(OpenGL.DEPTH_TEST);
m_gl.DepthFunc(OpenGL.LEQUAL);
m_gl.Hint(OpenGL.PERSPECTIVE_CORRECTION_HINT, OpenGL.NICEST);
}
protected override void OnPaint(PaintEventArgs e)
{
m_gl.MakeCurrent();
if (OpenGLRender != null)
OpenGLRender(this, e);
m_gl.SwapBuffers();
e.Graphics.DrawImageUnscaled(m_gl.OpenGLBitmap, 0, 0);
}
public virtual unsafe bool Create(int width, int height)
{
if (width == 0 || height == 0)
return false;
m_DIBSection.Create(width, height, 24);
if (handleRenderContext == IntPtr.Zero)
handleRenderContext = wglCreateContext(m_DIBSection.HDC);
handleDeviceContext = m_DIBSection.HDC;
wglMakeCurrent(m_DIBSection.HDC, handleRenderContext);
return true;
}
public DIBSection()
{
IntPtr screenDC = GetDC(IntPtr.Zero);
hDC = CreateCompatibleDC(screenDC);
}
public virtual unsafe bool Create(int width, int height, uint bitCount)
{
this.width = width;
this.height = height;
Destroy();
BITMAPINFO info = new BITMAPINFO();
info.biSize = 40;
info.biBitCount = (Int16)bitCount;
info.biPlanes = 1;
info.biWidth = width;
info.biHeight = height;
IntPtr ppvBits;
hBitmap = CreateDIBSection(hDC, info, DIB_RGB_COLORS,
out ppvBits, IntPtr.Zero, 0);
SelectObject(hDC, hBitmap);
SetPixelFormat(bitCount);
return true;
}
History
This is the first version. It is easy to add some complicated functions.