Summary (TL:DR version)
Ultimately our goal is to be able to utilize OpenGL ES code in a WPF application natively (i.e. not SharpGL, etc.) and without A
I have uploaded a github project that demonstrates how to integrate OpenGL rendering into a WPF application via OpenTK.GLControl.
The code is surprisingly simple:
WindowsFormsHost
to the WPF applicationOpenTK.GLControl
and attach it to the WindowsFormsHost
GraphicsContextFlags.Default
for a desktop OpenGL contextGraphicsContextFlags.Embedded
for an OpenGL ES (ANGLE) contextHint: OpenTK and OpenTK.GLControl are also available as NuGet packages. There is a new release due tomorrow with improved ANGLE support.
Note that the WindowsFormsHost approach is subject to airspace restrictions. If this is an issue, see my answer here for a solution.
// This code is public domain
#define USE_ANGLE
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Forms;
using System.Windows.Forms.Integration;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;
using OpenTK;
using OpenTK.Graphics;
#if USE_ANGLE
using OpenTK.Graphics.ES20;
#else
using OpenTK.Graphics.OpenGL;
#endif
namespace WPF.Angle
{
/// <summary>
/// Interaction logic for MainWindow.xaml
/// </summary>
public partial class MainWindow : Window
{
GLControl glControl;
public MainWindow()
{
InitializeComponent();
}
private void WindowsFormsHost_Initialized(object sender, EventArgs e)
{
var flags = GraphicsContextFlags.Default;
#if USE_ANGLE
flags = GraphicsContextFlags.Embedded;
#endif
glControl = new GLControl(new GraphicsMode(32, 24), 2, 0, flags);
glControl.MakeCurrent();
glControl.Paint += GLControl_Paint;
glControl.Dock = DockStyle.Fill;
(sender as WindowsFormsHost).Child = glControl;
}
private void GLControl_Paint(object sender, PaintEventArgs e)
{
GL.ClearColor(
(float)Red.Value,
(float)Green.Value,
(float)Blue.Value,
1);
GL.Clear(
ClearBufferMask.ColorBufferBit |
ClearBufferMask.DepthBufferBit |
ClearBufferMask.StencilBufferBit);
glControl.SwapBuffers();
}
private void Slider_ValueChanged(object sender, RoutedPropertyChangedEventArgs<double> e)
{
glControl.Invalidate();
}
}
}